forked from OSchip/llvm-project
Add a callback for recovering using a typo correction.
Also keep track of the stack of Exprs visited during the tree transform so the callback can be passed the parent of the TypoExpr. llvm-svn: 220697
This commit is contained in:
parent
9ab7fb6b73
commit
8363f04ee6
|
@ -2592,6 +2592,8 @@ public:
|
|||
bool VolatileThis);
|
||||
|
||||
typedef std::function<void(const TypoCorrection &)> TypoDiagnosticGenerator;
|
||||
typedef std::function<ExprResult(Sema &, TypoExpr *, TypoCorrection)>
|
||||
TypoRecoveryCallback;
|
||||
|
||||
private:
|
||||
bool CppLookupName(LookupResult &R, Scope *S);
|
||||
|
@ -2599,6 +2601,7 @@ private:
|
|||
struct TypoExprState {
|
||||
std::unique_ptr<TypoCorrectionConsumer> Consumer;
|
||||
TypoDiagnosticGenerator DiagHandler;
|
||||
TypoRecoveryCallback RecoveryHandler;
|
||||
};
|
||||
|
||||
/// \brief The set of unhandled TypoExprs and their associated state.
|
||||
|
@ -2606,7 +2609,8 @@ private:
|
|||
|
||||
/// \brief Creates a new TypoExpr AST node.
|
||||
TypoExpr *createDelayedTypo(std::unique_ptr<TypoCorrectionConsumer> TCC,
|
||||
TypoDiagnosticGenerator TDG);
|
||||
TypoDiagnosticGenerator TDG,
|
||||
TypoRecoveryCallback TRC);
|
||||
|
||||
// \brief The set of known/encountered (unique, canonicalized) NamespaceDecls.
|
||||
//
|
||||
|
@ -2718,7 +2722,7 @@ public:
|
|||
CXXScopeSpec *SS,
|
||||
std::unique_ptr<CorrectionCandidateCallback> CCC,
|
||||
TypoDiagnosticGenerator TDG,
|
||||
CorrectTypoKind Mode,
|
||||
TypoRecoveryCallback TRC, CorrectTypoKind Mode,
|
||||
DeclContext *MemberContext = nullptr,
|
||||
bool EnteringContext = false,
|
||||
const ObjCObjectPointerType *OPT = nullptr);
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/Sema/DeclSpec.h"
|
||||
#include "clang/Sema/Ownership.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
|
||||
namespace clang {
|
||||
|
|
|
@ -5996,13 +5996,17 @@ public:
|
|||
// For the first TypoExpr and an uncached TypoExpr, find the next likely
|
||||
// typo correction and return it.
|
||||
while (TypoCorrection TC = State.Consumer->getNextCorrection()) {
|
||||
LookupResult R(SemaRef,
|
||||
State.Consumer->getLookupResult().getLookupNameInfo(),
|
||||
State.Consumer->getLookupResult().getLookupKind());
|
||||
if (!TC.isKeyword())
|
||||
R.addDecl(TC.getCorrectionDecl());
|
||||
ExprResult NE =
|
||||
SemaRef.BuildDeclarationNameExpr(CXXScopeSpec(), R, false);
|
||||
ExprResult NE;
|
||||
if (State.RecoveryHandler) {
|
||||
NE = State.RecoveryHandler(SemaRef, E, TC);
|
||||
} else {
|
||||
LookupResult R(SemaRef,
|
||||
State.Consumer->getLookupResult().getLookupNameInfo(),
|
||||
State.Consumer->getLookupResult().getLookupKind());
|
||||
if (!TC.isKeyword())
|
||||
R.addDecl(TC.getCorrectionDecl());
|
||||
NE = SemaRef.BuildDeclarationNameExpr(CXXScopeSpec(), R, false);
|
||||
}
|
||||
assert(!NE.isUnset() &&
|
||||
"Typo was transformed into a valid-but-null ExprResult");
|
||||
if (!NE.isInvalid())
|
||||
|
|
|
@ -4332,6 +4332,9 @@ TypoCorrection Sema::CorrectTypo(const DeclarationNameInfo &TypoName,
|
|||
/// \param TDG A TypoDiagnosticGenerator functor that will be used to print
|
||||
/// diagnostics when the actual typo correction is attempted.
|
||||
///
|
||||
/// \param TRC A TypoRecoveryCallback functor that will be used to build an
|
||||
/// Expr from a typo correction candidate.
|
||||
///
|
||||
/// \param MemberContext if non-NULL, the context in which to look for
|
||||
/// a member access expression.
|
||||
///
|
||||
|
@ -4350,7 +4353,7 @@ TypoExpr *Sema::CorrectTypoDelayed(
|
|||
const DeclarationNameInfo &TypoName, Sema::LookupNameKind LookupKind,
|
||||
Scope *S, CXXScopeSpec *SS,
|
||||
std::unique_ptr<CorrectionCandidateCallback> CCC,
|
||||
TypoDiagnosticGenerator TDG, CorrectTypoKind Mode,
|
||||
TypoDiagnosticGenerator TDG, TypoRecoveryCallback TRC, CorrectTypoKind Mode,
|
||||
DeclContext *MemberContext, bool EnteringContext,
|
||||
const ObjCObjectPointerType *OPT) {
|
||||
assert(CCC && "CorrectTypoDelayed requires a CorrectionCandidateCallback");
|
||||
|
@ -4375,7 +4378,7 @@ TypoExpr *Sema::CorrectTypoDelayed(
|
|||
return nullptr;
|
||||
|
||||
ExprEvalContexts.back().NumTypos++;
|
||||
return createDelayedTypo(std::move(Consumer), std::move(TDG));
|
||||
return createDelayedTypo(std::move(Consumer), std::move(TDG), std::move(TRC));
|
||||
}
|
||||
|
||||
void TypoCorrection::addCorrectionDecl(NamedDecl *CDecl) {
|
||||
|
@ -4575,14 +4578,15 @@ void Sema::diagnoseTypo(const TypoCorrection &Correction,
|
|||
<< CorrectedQuotedStr << (ErrorRecovery ? FixItHint() : FixTypo);
|
||||
}
|
||||
|
||||
TypoExpr *
|
||||
Sema::createDelayedTypo(std::unique_ptr<TypoCorrectionConsumer> TCC,
|
||||
TypoDiagnosticGenerator TDG) {
|
||||
TypoExpr *Sema::createDelayedTypo(std::unique_ptr<TypoCorrectionConsumer> TCC,
|
||||
TypoDiagnosticGenerator TDG,
|
||||
TypoRecoveryCallback TRC) {
|
||||
assert(TCC && "createDelayedTypo requires a valid TypoCorrectionConsumer");
|
||||
auto TE = new (Context) TypoExpr(Context.DependentTy);
|
||||
auto &State = DelayedTypos[TE];
|
||||
State.Consumer = std::move(TCC);
|
||||
State.DiagHandler = std::move(TDG);
|
||||
State.RecoveryHandler = std::move(TRC);
|
||||
return TE;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue