diff options
author | Kaelyn Takata <rikka@google.com> | 2014-10-27 18:07:40 +0000 |
---|---|---|
committer | Kaelyn Takata <rikka@google.com> | 2014-10-27 18:07:40 +0000 |
commit | 1fc4384db372355024f4864f9da3058bd23d0712 (patch) | |
tree | e83380d6f36e51a274caeac239eda055f7d1c95a /lib/Sema/SemaLookup.cpp | |
parent | 4a3c68bb85aa70525f30ad2970272b908bf8359d (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@220696 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaLookup.cpp')
-rw-r--r-- | lib/Sema/SemaLookup.cpp | 97 |
1 files changed, 50 insertions, 47 deletions
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index 20102c90eb..afb56fe996 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -3278,6 +3278,49 @@ static void LookupPotentialTypoResult(Sema &SemaRef, 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::addCorrection(TypoCorrection Correction) { 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 &TypoCorrectionConsumer::getNextCorrection() { } 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 &SemaRef, } } -/// \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, |