r220696 - Add simple way for a CorrectionCandidateCallback to reject exact

Kaelyn Takata rikka at google.com
Mon Oct 27 11:07:40 PDT 2014


Author: rikka
Date: Mon Oct 27 13:07:40 2014
New Revision: 220696

URL: http://llvm.org/viewvc/llvm-project?rev=220696&view=rev
Log:
Add simple way for a CorrectionCandidateCallback to reject exact
matches of the typo.

Also be more proactive about checking a correction's visibility so that
a correction requiring a module import can be distinguished from the
original typo even if it looks identical. Otherwise the correction will
be excluded and the diagnostic about needing the module import won't be
emitted.

Note that no change was made to checkCorrectionVisibility other than
moving where it is at in SemaLookup.cpp.

Modified:
    cfe/trunk/include/clang/Sema/TypoCorrection.h
    cfe/trunk/lib/Sema/SemaLookup.cpp

Modified: cfe/trunk/include/clang/Sema/TypoCorrection.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/TypoCorrection.h?rev=220696&r1=220695&r2=220696&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/TypoCorrection.h (original)
+++ cfe/trunk/include/clang/Sema/TypoCorrection.h Mon Oct 27 13:07:40 2014
@@ -247,11 +247,13 @@ class CorrectionCandidateCallback {
 public:
   static const unsigned InvalidDistance = TypoCorrection::InvalidDistance;
 
-  CorrectionCandidateCallback()
+  explicit CorrectionCandidateCallback(IdentifierInfo *Typo = nullptr,
+                                       NestedNameSpecifier *TypoNNS = nullptr)
       : WantTypeSpecifiers(true), WantExpressionKeywords(true),
         WantCXXNamedCasts(true), WantFunctionLikeCasts(true),
         WantRemainingKeywords(true), WantObjCSuper(false),
-        IsObjCIvarLookup(false), IsAddressOfOperand(false) {}
+        IsObjCIvarLookup(false), IsAddressOfOperand(false), Typo(Typo),
+        TypoNNS(TypoNNS) {}
 
   virtual ~CorrectionCandidateCallback() {}
 
@@ -274,9 +276,14 @@ public:
   /// the default RankCandidate returns either 0 or InvalidDistance depending
   /// whether ValidateCandidate returns true or false.
   virtual unsigned RankCandidate(const TypoCorrection &candidate) {
-    return ValidateCandidate(candidate) ? 0 : InvalidDistance;
+    return (!MatchesTypo(candidate) && ValidateCandidate(candidate))
+               ? 0
+               : InvalidDistance;
   }
 
+  void setTypoName(IdentifierInfo *II) { Typo = II; }
+  void setTypoNNS(NestedNameSpecifier *NNS) { TypoNNS = NNS; }
+
   // Flags for context-dependent keywords. WantFunctionLikeCasts is only
   // used/meaningful when WantCXXNamedCasts is false.
   // TODO: Expand these to apply to non-keywords or possibly remove them.
@@ -290,6 +297,18 @@ public:
   // when looking up results.
   bool IsObjCIvarLookup;
   bool IsAddressOfOperand;
+
+protected:
+  bool MatchesTypo(const TypoCorrection &candidate) {
+    return Typo && candidate.isResolved() && !candidate.requiresImport() &&
+           candidate.getCorrectionAsIdentifierInfo() == Typo &&
+           // FIXME: This probably does not return true when both
+           // NestedNameSpecifiers have the same textual representation.
+           candidate.getCorrectionSpecifier() == TypoNNS;
+  }
+
+  IdentifierInfo *Typo;
+  NestedNameSpecifier *TypoNNS;
 };
 
 /// @brief Simple template class for restricting typo correction candidates

Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=220696&r1=220695&r2=220696&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Mon Oct 27 13:07:40 2014
@@ -3278,6 +3278,49 @@ static void LookupPotentialTypoResult(Se
                                       bool isObjCIvarLookup,
                                       bool FindHidden);
 
+/// \brief Check whether the declarations found for a typo correction are
+/// visible, and if none of them are, convert the correction to an 'import
+/// a module' correction.
+static void checkCorrectionVisibility(Sema &SemaRef, TypoCorrection &TC) {
+  if (TC.begin() == TC.end())
+    return;
+
+  TypoCorrection::decl_iterator DI = TC.begin(), DE = TC.end();
+
+  for (/**/; DI != DE; ++DI)
+    if (!LookupResult::isVisible(SemaRef, *DI))
+      break;
+  // Nothing to do if all decls are visible.
+  if (DI == DE)
+    return;
+
+  llvm::SmallVector<NamedDecl*, 4> NewDecls(TC.begin(), DI);
+  bool AnyVisibleDecls = !NewDecls.empty();
+
+  for (/**/; DI != DE; ++DI) {
+    NamedDecl *VisibleDecl = *DI;
+    if (!LookupResult::isVisible(SemaRef, *DI))
+      VisibleDecl = findAcceptableDecl(SemaRef, *DI);
+
+    if (VisibleDecl) {
+      if (!AnyVisibleDecls) {
+        // Found a visible decl, discard all hidden ones.
+        AnyVisibleDecls = true;
+        NewDecls.clear();
+      }
+      NewDecls.push_back(VisibleDecl);
+    } else if (!AnyVisibleDecls && !(*DI)->isModulePrivate())
+      NewDecls.push_back(*DI);
+  }
+
+  if (NewDecls.empty())
+    TC = TypoCorrection();
+  else {
+    TC.setCorrectionDecls(NewDecls);
+    TC.setRequiresImport(!AnyVisibleDecls);
+  }
+}
+
 // Fill the supplied vector with the IdentifierInfo pointers for each piece of
 // the given NestedNameSpecifier (i.e. given a NestedNameSpecifier "foo::bar::",
 // fill the vector with the IdentifierInfo pointers for "foo" and "bar").
@@ -3388,9 +3431,11 @@ void TypoCorrectionConsumer::addCorrecti
     return;
 
   // If the correction is resolved but is not viable, ignore it.
-  if (Correction.isResolved() &&
-      !isCandidateViable(*CorrectionValidator, Correction))
-    return;
+  if (Correction.isResolved()) {
+    checkCorrectionVisibility(SemaRef, Correction);
+    if (!Correction || !isCandidateViable(*CorrectionValidator, Correction))
+      return;
+  }
 
   TypoResultList &CList =
       CorrectionResults[Correction.getEditDistance(false)][Name];
@@ -3464,7 +3509,7 @@ const TypoCorrection &TypoCorrectionCons
     }
 
     TypoCorrection TC = RI->second.pop_back_val();
-    if (TC.isResolved() || resolveCorrection(TC)) {
+    if (TC.isResolved() || TC.requiresImport() || resolveCorrection(TC)) {
       ValidatedCorrections.push_back(TC);
       return ValidatedCorrections[CurrentTCIndex];
     }
@@ -3512,6 +3557,7 @@ retry_lookup:
     // Store all of the Decls for overloaded symbols
     for (auto *TRD : Result)
       Candidate.addCorrectionDecl(TRD);
+    checkCorrectionVisibility(SemaRef, Candidate);
     if (!isCandidateViable(*CorrectionValidator, Candidate)) {
       if (SearchNamespaces)
         QualifiedResults.push_back(Candidate);
@@ -3945,49 +3991,6 @@ static void AddKeywordsToConsumer(Sema &
   }
 }
 
-/// \brief Check whether the declarations found for a typo correction are
-/// visible, and if none of them are, convert the correction to an 'import
-/// a module' correction.
-static void checkCorrectionVisibility(Sema &SemaRef, TypoCorrection &TC) {
-  if (TC.begin() == TC.end())
-    return;
-
-  TypoCorrection::decl_iterator DI = TC.begin(), DE = TC.end();
-
-  for (/**/; DI != DE; ++DI)
-    if (!LookupResult::isVisible(SemaRef, *DI))
-      break;
-  // Nothing to do if all decls are visible.
-  if (DI == DE)
-    return;
-
-  llvm::SmallVector<NamedDecl*, 4> NewDecls(TC.begin(), DI);
-  bool AnyVisibleDecls = !NewDecls.empty();
-
-  for (/**/; DI != DE; ++DI) {
-    NamedDecl *VisibleDecl = *DI;
-    if (!LookupResult::isVisible(SemaRef, *DI))
-      VisibleDecl = findAcceptableDecl(SemaRef, *DI);
-
-    if (VisibleDecl) {
-      if (!AnyVisibleDecls) {
-        // Found a visible decl, discard all hidden ones.
-        AnyVisibleDecls = true;
-        NewDecls.clear();
-      }
-      NewDecls.push_back(VisibleDecl);
-    } else if (!AnyVisibleDecls && !(*DI)->isModulePrivate())
-      NewDecls.push_back(*DI);
-  }
-
-  if (NewDecls.empty())
-    TC = TypoCorrection();
-  else {
-    TC.setCorrectionDecls(NewDecls);
-    TC.setRequiresImport(!AnyVisibleDecls);
-  }
-}
-
 std::unique_ptr<TypoCorrectionConsumer> Sema::makeTypoCorrectionConsumer(
     const DeclarationNameInfo &TypoName, Sema::LookupNameKind LookupKind,
     Scope *S, CXXScopeSpec *SS,





More information about the cfe-commits mailing list