[CodeCompletion] Find parsed expression from typechecked decl context

Instead of re-typechecking parsed expression, find typechecked
expression that corresponds to the parsed expression from the
typechecked decl context, because the sub expressions of the parsed
expression can be weirdly mutated/replaced by decl context typechecking.

rdar://problem/48141174
This commit is contained in:
Rintaro Ishizaki
2019-02-28 16:47:35 -08:00
parent 3f76e63b6e
commit 82b5f2a195
8 changed files with 119 additions and 38 deletions

View File

@@ -1292,9 +1292,14 @@ class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks {
// FIXME: if it's ErrorType but we've already typechecked we shouldn't
// typecheck again. rdar://21466394
if (CheckKind == CompletionTypeCheckKind::Normal &&
ParsedExpr->getType() && !ParsedExpr->getType()->is<ErrorType>())
return std::make_pair(ParsedExpr->getType(),
ParsedExpr->getReferencedDecl());
ParsedExpr->getType() && !ParsedExpr->getType()->is<ErrorType>()) {
auto refDecl = ParsedExpr->getReferencedDecl();
if (!refDecl) {
if (auto apply = dyn_cast<ApplyExpr>(ParsedExpr))
refDecl = apply->getFn()->getReferencedDecl();
}
return std::make_pair(ParsedExpr->getType(), refDecl);
}
prepareForRetypechecking(ParsedExpr);
@@ -3283,18 +3288,18 @@ public:
if (leadingSequence.empty())
return LHS;
assert(leadingSequence.size() % 2 == 0);
SmallVector<Expr *, 3> sequence(leadingSequence.begin(),
leadingSequence.end());
sequence.push_back(LHS);
SourceRange sequenceRange(leadingSequence.front()->getStartLoc(),
LHS->getEndLoc());
auto *expr = findParsedExpr(CurrDeclContext, sequenceRange);
if (!expr)
return LHS;
Expr *expr =
SequenceExpr::create(CurrDeclContext->getASTContext(), sequence);
prepareForRetypechecking(expr);
if (!typeCheckExpression(const_cast<DeclContext *>(CurrDeclContext),
expr)) {
if (expr->getType() && !expr->getType()->hasError())
return expr;
prepareForRetypechecking(expr);
if (!typeCheckExpression(const_cast<DeclContext *>(CurrDeclContext), expr))
return expr;
}
return LHS;
}
@@ -4860,6 +4865,11 @@ void CodeCompletionCallbacksImpl::doneParsing() {
Optional<Type> ExprType;
ConcreteDeclRef ReferencedDecl = nullptr;
if (ParsedExpr) {
if (auto *checkedExpr = findParsedExpr(CurDeclContext,
ParsedExpr->getSourceRange())) {
ParsedExpr = checkedExpr;
}
if (auto typechecked = typeCheckParsedExpr()) {
ExprType = typechecked->first;
ReferencedDecl = typechecked->second;