[TypeChecker] Add a flag PreCheckFunctionBuilderRequest to suppress diagnostics

This commit is contained in:
Pavel Yaskevich
2020-08-17 10:16:45 -07:00
parent bc319779d5
commit b2982fa0e5
2 changed files with 24 additions and 11 deletions

View File

@@ -1843,6 +1843,7 @@ public:
struct PreCheckFunctionBuilderDescriptor { struct PreCheckFunctionBuilderDescriptor {
AnyFunctionRef Fn; AnyFunctionRef Fn;
bool SuppressDiagnostics;
private: private:
// NOTE: Since source tooling (e.g. code completion) might replace the body, // NOTE: Since source tooling (e.g. code completion) might replace the body,
@@ -1852,8 +1853,8 @@ private:
BraceStmt *Body; BraceStmt *Body;
public: public:
PreCheckFunctionBuilderDescriptor(AnyFunctionRef Fn) PreCheckFunctionBuilderDescriptor(AnyFunctionRef Fn, bool suppressDiagnostics)
: Fn(Fn), Body(Fn.getBody()) {} : Fn(Fn), SuppressDiagnostics(suppressDiagnostics), Body(Fn.getBody()) {}
friend llvm::hash_code friend llvm::hash_code
hash_value(const PreCheckFunctionBuilderDescriptor &owner) { hash_value(const PreCheckFunctionBuilderDescriptor &owner) {

View File

@@ -1485,9 +1485,11 @@ Optional<BraceStmt *> TypeChecker::applyFunctionBuilderBodyTransform(
// If we encountered an error or there was an explicit result type, // If we encountered an error or there was an explicit result type,
// bail out and report that to the caller. // bail out and report that to the caller.
auto &ctx = func->getASTContext(); auto &ctx = func->getASTContext();
auto request = PreCheckFunctionBuilderRequest{AnyFunctionRef(func)}; auto request =
switch (evaluateOrDefault( PreCheckFunctionBuilderRequest{{AnyFunctionRef(func),
ctx.evaluator, request, FunctionBuilderBodyPreCheck::Error)) { /*SuppressDiagnostics=*/false}};
switch (evaluateOrDefault(ctx.evaluator, request,
FunctionBuilderBodyPreCheck::Error)) {
case FunctionBuilderBodyPreCheck::Okay: case FunctionBuilderBodyPreCheck::Okay:
// If the pre-check was okay, apply the function-builder transform. // If the pre-check was okay, apply the function-builder transform.
break; break;
@@ -1619,7 +1621,8 @@ ConstraintSystem::matchFunctionBuilder(
// Pre-check the body: pre-check any expressions in it and look // Pre-check the body: pre-check any expressions in it and look
// for return statements. // for return statements.
auto request = PreCheckFunctionBuilderRequest{fn}; auto request =
PreCheckFunctionBuilderRequest{{fn, /*SuppressDiagnostics=*/false}};
switch (evaluateOrDefault(getASTContext().evaluator, request, switch (evaluateOrDefault(getASTContext().evaluator, request,
FunctionBuilderBodyPreCheck::Error)) { FunctionBuilderBodyPreCheck::Error)) {
case FunctionBuilderBodyPreCheck::Okay: case FunctionBuilderBodyPreCheck::Okay:
@@ -1705,14 +1708,17 @@ namespace {
class PreCheckFunctionBuilderApplication : public ASTWalker { class PreCheckFunctionBuilderApplication : public ASTWalker {
AnyFunctionRef Fn; AnyFunctionRef Fn;
bool SkipPrecheck = false; bool SkipPrecheck = false;
bool SuppressDiagnostics = false;
std::vector<ReturnStmt *> ReturnStmts; std::vector<ReturnStmt *> ReturnStmts;
bool HasError = false; bool HasError = false;
bool hasReturnStmt() const { return !ReturnStmts.empty(); } bool hasReturnStmt() const { return !ReturnStmts.empty(); }
public: public:
PreCheckFunctionBuilderApplication(AnyFunctionRef fn, bool skipPrecheck) PreCheckFunctionBuilderApplication(AnyFunctionRef fn, bool skipPrecheck,
: Fn(fn), SkipPrecheck(skipPrecheck) {} bool suppressDiagnostics)
: Fn(fn), SkipPrecheck(skipPrecheck),
SuppressDiagnostics(suppressDiagnostics) {}
const std::vector<ReturnStmt *> getReturnStmts() const { return ReturnStmts; } const std::vector<ReturnStmt *> getReturnStmts() const { return ReturnStmts; }
@@ -1753,7 +1759,9 @@ public:
E, DC, /*replaceInvalidRefsWithErrors=*/false); E, DC, /*replaceInvalidRefsWithErrors=*/false);
HasError |= transaction.hasDiagnostics(); HasError |= transaction.hasDiagnostics();
transaction.abort(); if (SuppressDiagnostics)
transaction.abort();
return std::make_pair(false, HasError ? nullptr : E); return std::make_pair(false, HasError ? nullptr : E);
} }
} }
@@ -1788,11 +1796,15 @@ FunctionBuilderBodyPreCheck PreCheckFunctionBuilderRequest::evaluate(
owner.Fn.getAbstractClosureExpr())) owner.Fn.getAbstractClosureExpr()))
skipPrecheck = shouldTypeCheckInEnclosingExpression(closure); skipPrecheck = shouldTypeCheckInEnclosingExpression(closure);
return PreCheckFunctionBuilderApplication(owner.Fn, false).run(); return PreCheckFunctionBuilderApplication(
owner.Fn, /*skipPrecheck=*/false,
/*suppressDiagnostics=*/owner.SuppressDiagnostics)
.run();
} }
std::vector<ReturnStmt *> TypeChecker::findReturnStatements(AnyFunctionRef fn) { std::vector<ReturnStmt *> TypeChecker::findReturnStatements(AnyFunctionRef fn) {
PreCheckFunctionBuilderApplication precheck(fn, true); PreCheckFunctionBuilderApplication precheck(fn, /*skipPreCheck=*/true,
/*SuppressDiagnostics=*/true);
(void)precheck.run(); (void)precheck.run();
return precheck.getReturnStmts(); return precheck.getReturnStmts();
} }