@@ -277,49 +277,6 @@ static bool areAnyDependentFilesInvalidated(
277277 });
278278}
279279
280- // / Get interface hash of \p SF including the type members in the file.
281- // /
282- // / See if the inteface of the function and types visible from a function body
283- // / has changed since the last completion. If they haven't changed, completion
284- // / can reuse the existing AST of the source file. \c SF->getInterfaceHash() is
285- // / not enough because it doesn't take the interface of the type members into
286- // / account. For example:
287- // /
288- // / struct S {
289- // / func foo() {}
290- // / }
291- // / func main(val: S) {
292- // / val.<HERE>
293- // / }
294- // /
295- // / In this case, we need to ensure that the interface of \c S hasn't changed.
296- // / Note that we don't care about local types (i.e. type declarations inside
297- // / function bodies, closures, or top level statement bodies) because they are
298- // / not visible from other functions where the completion is happening.
299- static Fingerprint getInterfaceHashIncludingTypeMembers (const SourceFile *SF) {
300- // / FIXME: Gross. Hashing multiple "hash" values.
301- llvm::MD5 hash;
302- hash.update (SF->getInterfaceHash ().getRawValue ());
303-
304- std::function<void (IterableDeclContext *)> hashTypeBodyFingerprints =
305- [&](IterableDeclContext *IDC) {
306- if (auto fp = IDC->getBodyFingerprint ())
307- hash.update (fp->getRawValue ());
308- for (auto *member : IDC->getParsedMembers ())
309- if (auto *childIDC = dyn_cast<IterableDeclContext>(member))
310- hashTypeBodyFingerprints (childIDC);
311- };
312-
313- for (auto *D : SF->getTopLevelDecls ()) {
314- if (auto IDC = dyn_cast<IterableDeclContext>(D))
315- hashTypeBodyFingerprints (IDC);
316- }
317-
318- llvm::MD5::MD5Result result;
319- hash.final (result);
320- return Fingerprint{std::move (result)};
321- }
322-
323280} // namespace
324281
325282bool CompletionInstance::performCachedOperationIfPossible (
@@ -396,8 +353,26 @@ bool CompletionInstance::performCachedOperationIfPossible(
396353 switch (newInfo.Kind ) {
397354 case CodeCompletionDelayedDeclKind::FunctionBody: {
398355 // If the interface has changed, AST must be refreshed.
399- const auto oldInterfaceHash = getInterfaceHashIncludingTypeMembers (oldSF);
400- const auto newInterfaceHash = getInterfaceHashIncludingTypeMembers (tmpSF);
356+ // See if the inteface of the function and types visible from a function
357+ // body has changed since the last completion. If they haven't changed,
358+ // completion can reuse the existing AST of the source file.
359+ // \c getInterfaceHash() is not enough because it doesn't take the interface
360+ // of the type members into account. For example:
361+ //
362+ // struct S {
363+ // func foo() {}
364+ // }
365+ // func main(val: S) {
366+ // val.<HERE>
367+ // }
368+ //
369+ // In this case, we need to ensure that the interface of \c S hasn't
370+ // changed. Note that we don't care about local types (i.e. type
371+ // declarations inside function bodies, closures, or top level statement
372+ // bodies) because they are not visible from other functions where the
373+ // completion is happening.
374+ const auto oldInterfaceHash = oldSF->getInterfaceHashIncludingTypeMembers ();
375+ const auto newInterfaceHash = tmpSF->getInterfaceHashIncludingTypeMembers ();
401376 if (oldInterfaceHash != newInterfaceHash)
402377 return false ;
403378
0 commit comments