static InFlightDiagnostic diagnoseTypoCorrection(TypeChecker &tc, DeclNameLoc loc, ValueDecl *decl) { if (auto var = dyn_cast<VarDecl>(decl)) { // Suggest 'self' at the use point instead of pointing at the start // of the function. if (var->isSelfParameter()) return tc.diagnose(loc.getBaseNameLoc(), diag::note_typo_candidate, decl->getName().str()); } if (!decl->getLoc().isValid() && decl->getDeclContext()->isTypeContext()) { Decl *parentDecl = dyn_cast<ExtensionDecl>(decl->getDeclContext()); if (!parentDecl) parentDecl = cast<NominalTypeDecl>(decl->getDeclContext()); if (parentDecl->getLoc().isValid()) { StringRef kind = (isa<VarDecl>(decl) ? "property" : isa<ConstructorDecl>(decl) ? "initializer" : isa<FuncDecl>(decl) ? "method" : "member"); return tc.diagnose(parentDecl, diag::note_typo_candidate_implicit_member, decl->getName().str(), kind); } } return tc.diagnose(decl, diag::note_typo_candidate, decl->getName().str()); }
static InFlightDiagnostic diagnoseTypoCorrection(TypeChecker &tc, DeclNameLoc loc, ValueDecl *decl) { if (auto var = dyn_cast<VarDecl>(decl)) { // Suggest 'self' at the use point instead of pointing at the start // of the function. if (var->isSelfParameter()) return tc.diagnose(loc.getBaseNameLoc(), diag::note_typo_candidate, decl->getName().str()); } return tc.diagnose(decl, diag::note_typo_candidate, decl->getName().str()); }
bool SemaAnnotator::passReference(ValueDecl *D, Type Ty, DeclNameLoc Loc) { TypeDecl *CtorTyRef = nullptr; if (TypeDecl *TD = dyn_cast<TypeDecl>(D)) { if (!CtorRefs.empty() && Loc.isValid()) { Expr *Fn = CtorRefs.back()->getFn(); if (Fn->getLoc() == Loc.getBaseNameLoc()) { D = extractDecl(Fn); CtorTyRef = TD; } } } CharSourceRange Range = Lexer::getCharSourceRangeFromSourceRange(D->getASTContext().SourceMgr, Loc.getSourceRange()); bool Continue = SEWalker.visitDeclReference(D, Range, CtorTyRef, Ty); if (!Continue) Cancelled = true; return Continue; }
void TypeChecker::noteTypoCorrection(DeclName writtenName, DeclNameLoc loc, const LookupResult::Result &suggestion) { auto decl = suggestion.Decl; auto &&diagnostic = diagnoseTypoCorrection(*this, loc, decl); DeclName declName = decl->getFullName(); if (writtenName.getBaseName() != declName.getBaseName()) diagnostic.fixItReplace(loc.getBaseNameLoc(), declName.getBaseName().str()); // TODO: add fix-its for typo'ed argument labels. This is trickier // because of the reordering rules. }
static InFlightDiagnostic noteTypoCorrection(TypeChecker &tc, DeclNameLoc loc, ValueDecl *decl, bool wasClaimed) { if (auto var = dyn_cast<VarDecl>(decl)) { // Suggest 'self' at the use point instead of pointing at the start // of the function. if (var->isSelfParameter()) { if (wasClaimed) { // We don't need an extra note for this case because the programmer // knows what 'self' refers to. return InFlightDiagnostic(); } return tc.diagnose(loc.getBaseNameLoc(), diag::note_typo_candidate, var->getName().str()); } } if (Decl *parentDecl = findExplicitParentForImplicitDecl(decl)) { StringRef kind = (isa<VarDecl>(decl) ? "property" : isa<ConstructorDecl>(decl) ? "initializer" : isa<FuncDecl>(decl) ? "method" : "member"); return tc.diagnose(parentDecl, wasClaimed ? diag::implicit_member_declared_here : diag::note_typo_candidate_implicit_member, decl->getBaseName().userFacingName(), kind); } if (wasClaimed) { return tc.diagnose(decl, diag::decl_declared_here, decl->getBaseName()); } else { return tc.diagnose(decl, diag::note_typo_candidate, decl->getBaseName().userFacingName()); } }