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());
}
Example #2
0
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());
}
Example #3
0
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.
}
Example #5
0
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());
  }
}