Two additional methods are provided: one to return the current
correction (the last correction returned by getNextCorrection), and one
to "reset" the state so that getNextCorrection will return the previous
corrections before returning any new corrections.
Also ensure that all TypoCorrections have valid source ranges.
---
include/clang/Sema/SemaInternal.h | 31 ++++++++++++++++++++++++++-----
include/clang/Sema/TypoCorrection.h | 2 +-
lib/Sema/SemaLookup.cpp | 16 ++++++++++++----
3 files changed, 39 insertions(+), 10 deletions(-)
diff --git a/include/clang/Sema/SemaInternal.h b/include/clang/Sema/SemaInternal.h
index 70398bb..aaaa3e7 100644
--- a/include/clang/Sema/SemaInternal.h
+++ b/include/clang/Sema/SemaInternal.h
@@ -100,12 +100,14 @@ public:
std::unique_ptr<CorrectionCandidateCallback> CCC,
DeclContext *MemberContext,
bool EnteringContext)
- : Typo(TypoName.getName().getAsIdentifierInfo()), SemaRef(SemaRef), S(S),
- SS(SS), CorrectionValidator(std::move(CCC)), MemberContext(MemberContext),
- Result(SemaRef, TypoName, LookupKind),
+ : Typo(TypoName.getName().getAsIdentifierInfo()), CurrentTCIndex(0),
+ SemaRef(SemaRef), S(S), SS(SS), CorrectionValidator(std::move(CCC)),
+ MemberContext(MemberContext), Result(SemaRef, TypoName, LookupKind),
Namespaces(SemaRef.Context, SemaRef.CurContext, SS),
EnteringContext(EnteringContext), SearchNamespaces(false) {
Result.suppressDiagnostics();
+ // Arrange for ValidatedCorrections[0] to always be an empty correction.
+ ValidatedCorrections.push_back(TypoCorrection());
}
bool includeHiddenDecls() const override { return true; }
@@ -117,7 +119,9 @@ public:
void addKeywordResult(StringRef Keyword);
void addCorrection(TypoCorrection Correction);
- bool empty() const { return CorrectionResults.empty(); }
+ bool empty() const {
+ return CorrectionResults.empty() && ValidatedCorrections.size() == 1;
+ }
/// \brief Return the list of TypoCorrections for the given identifier from
/// the set of corrections that have the closest edit distance, if any.
@@ -147,7 +151,21 @@ public:
/// starting with the corrections that have the closest edit distance. An
/// empty TypoCorrection is returned once no more viable corrections remain
/// in the consumer.
- TypoCorrection getNextCorrection();
+ TypoCorrection &getNextCorrection();
+
+ /// \brief Get the last correction returned by getNextCorrection().
+ TypoCorrection &getCurrentCorrection() {
+ return CurrentTCIndex < ValidatedCorrections.size()
+ ? ValidatedCorrections[CurrentTCIndex]
+ : ValidatedCorrections[0]; // The empty correction.
+ }
+
+ /// \brief Reset the consumer's position in the stream of viable corrections
+ /// (i.e. getNextCorrection() will return each of the previously returned
+ /// corrections in order before returning any new corrections).
+ void resetCorrectionStream() {
+ CurrentTCIndex = 0;
+ }
ASTContext &getContext() const { return SemaRef.Context; }
const LookupResult &getLookupResult() const { return Result; }
@@ -223,6 +241,9 @@ private:
/// whether there is a keyword with this name.
TypoEditDistanceMap CorrectionResults;
+ SmallVector<TypoCorrection, 4> ValidatedCorrections;
+ size_t CurrentTCIndex;
+
Sema &SemaRef;
Scope *S;
CXXScopeSpec *SS;
diff --git a/include/clang/Sema/TypoCorrection.h b/include/clang/Sema/TypoCorrection.h
index bfa0214..addbd65 100644
--- a/include/clang/Sema/TypoCorrection.h
+++ b/include/clang/Sema/TypoCorrection.h
@@ -335,7 +335,7 @@ public:
class TypoDiagnosticGenerator {
public:
- virtual void operator()(TypoCorrection &&TC) = 0;
+ virtual void operator()(TypoCorrection &TC) = 0;
virtual ~TypoDiagnosticGenerator() = default;
};
}
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index fa5bdf7..c0fe2c3 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -3445,7 +3445,11 @@ void TypoCorrectionConsumer::addNamespaces(
}
}
-TypoCorrection TypoCorrectionConsumer::getNextCorrection() {
+TypoCorrection &TypoCorrectionConsumer::getNextCorrection() {
+ if (++CurrentTCIndex < ValidatedCorrections.size())
+ return ValidatedCorrections[CurrentTCIndex];
+
+ CurrentTCIndex = ValidatedCorrections.size();
while (!CorrectionResults.empty()) {
auto DI = CorrectionResults.begin();
if (DI->second.empty()) {
@@ -3461,16 +3465,20 @@ TypoCorrection TypoCorrectionConsumer::getNextCorrection() {
}
TypoCorrection TC = RI->second.pop_back_val();
- if (TC.isResolved() || resolveCorrection(TC))
- return TC;
+ if (TC.isResolved() || resolveCorrection(TC)) {
+ ValidatedCorrections.push_back(TC);
+ return ValidatedCorrections[CurrentTCIndex];
+ }
}
- return TypoCorrection();
+ return ValidatedCorrections[0]; // The empty correction.
}
bool TypoCorrectionConsumer::resolveCorrection(TypoCorrection &Candidate) {
IdentifierInfo *Name = Candidate.getCorrectionAsIdentifierInfo();
DeclContext *TempMemberContext = MemberContext;
CXXScopeSpec *TempSS = SS;
+ if (Candidate.getCorrectionRange().isInvalid())
+ Candidate.setCorrectionRange(TempSS, Result.getLookupNameInfo());
retry_lookup:
LookupPotentialTypoResult(SemaRef, Result, Name, S, TempSS, TempMemberContext,
EnteringContext,
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits