Code completion: refactor code completion callbacks so that actual name lookups

happen after delayed parsing is finished.  This ensures that the AST for
delayed parsed code (for example, function body) is constructed.  This is
required for partial type checking of function bodies.


Swift SVN r7010
This commit is contained in:
Dmitri Hrybenko
2013-08-07 22:42:36 +00:00
parent 45a8e79021
commit 2bbef342f0
3 changed files with 73 additions and 31 deletions

View File

@@ -56,6 +56,10 @@ public:
/// \brief Complete expr-super after we have consumed the 'super' keyword and /// \brief Complete expr-super after we have consumed the 'super' keyword and
/// a dot. /// a dot.
virtual void completeExprSuperDot(SuperRefExpr *SRE) = 0; virtual void completeExprSuperDot(SuperRefExpr *SRE) = 0;
/// \brief Signals that the AST for the all the delayed-parsed code was
/// constructed. No \c complete*() callbacks will be done after this.
virtual void doneParsing() = 0;
}; };
/// \brief A factory to create instances of \c CodeCompletionCallbacks. /// \brief A factory to create instances of \c CodeCompletionCallbacks.

View File

@@ -338,6 +338,18 @@ class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks,
CodeCompletionConsumer &Consumer; CodeCompletionConsumer &Consumer;
TranslationUnit *const TU; TranslationUnit *const TU;
enum class CompletionKind {
DotExpr,
PostfixExprBeginning,
PostfixExpr,
SuperExpr,
SuperExprDot,
};
CompletionKind Kind;
Expr *ParsedExpr = nullptr;
DeclContext *CurDeclContext = nullptr;
/// \brief Set to true when we have delivered code completion results /// \brief Set to true when we have delivered code completion results
/// to the \c Consumer. /// to the \c Consumer.
bool DeliveredResults = false; bool DeliveredResults = false;
@@ -381,6 +393,8 @@ public:
void completeExprSuper(SuperRefExpr *SRE) override; void completeExprSuper(SuperRefExpr *SRE) override;
void completeExprSuperDot(SuperRefExpr *SRE) override; void completeExprSuperDot(SuperRefExpr *SRE) override;
void doneParsing() override;
void deliverCompletionResults(); void deliverCompletionResults();
// Implement swift::ModuleLoadListener. // Implement swift::ModuleLoadListener.
@@ -842,53 +856,75 @@ public:
} // end unnamed namespace } // end unnamed namespace
void CodeCompletionCallbacksImpl::completeDotExpr(Expr *E) { void CodeCompletionCallbacksImpl::completeDotExpr(Expr *E) {
if (!typecheckExpr(E)) Kind = CompletionKind::DotExpr;
return; ParsedExpr = E;
CurDeclContext = P.CurDeclContext;
CompletionLookup Lookup(CompletionContext, TU->Ctx, P.CurDeclContext);
Lookup.setHaveDot();
Lookup.getValueExprCompletions(E->getType());
deliverCompletionResults();
} }
void CodeCompletionCallbacksImpl::completePostfixExprBeginning() { void CodeCompletionCallbacksImpl::completePostfixExprBeginning() {
CompletionLookup Lookup(CompletionContext, TU->Ctx, P.CurDeclContext);
assert(P.Tok.is(tok::code_complete)); assert(P.Tok.is(tok::code_complete));
Lookup.getCompletionsInDeclContext(P.Tok.getLoc());
deliverCompletionResults(); Kind = CompletionKind::PostfixExprBeginning;
CurDeclContext = P.CurDeclContext;
} }
void CodeCompletionCallbacksImpl::completePostfixExpr(Expr *E) { void CodeCompletionCallbacksImpl::completePostfixExpr(Expr *E) {
if (!typecheckExpr(E)) Kind = CompletionKind::PostfixExpr;
return; ParsedExpr = E;
CurDeclContext = P.CurDeclContext;
CompletionLookup Lookup(CompletionContext, TU->Ctx, P.CurDeclContext);
Lookup.getValueExprCompletions(E->getType());
deliverCompletionResults();
} }
void CodeCompletionCallbacksImpl::completeExprSuper(SuperRefExpr *SRE) { void CodeCompletionCallbacksImpl::completeExprSuper(SuperRefExpr *SRE) {
if (!typecheckExpr(SRE)) Kind = CompletionKind::SuperExpr;
return; ParsedExpr = SRE;
CurDeclContext = P.CurDeclContext;
CompletionLookup Lookup(CompletionContext, TU->Ctx, P.CurDeclContext);
Lookup.setIsSuperRefExpr();
Lookup.getValueExprCompletions(SRE->getType());
deliverCompletionResults();
} }
void CodeCompletionCallbacksImpl::completeExprSuperDot(SuperRefExpr *SRE) { void CodeCompletionCallbacksImpl::completeExprSuperDot(SuperRefExpr *SRE) {
if (!typecheckExpr(SRE)) Kind = CompletionKind::SuperExprDot;
ParsedExpr = SRE;
CurDeclContext = P.CurDeclContext;
}
void CodeCompletionCallbacksImpl::doneParsing() {
if (ParsedExpr && !typecheckExpr(ParsedExpr))
return; return;
CompletionLookup Lookup(CompletionContext, TU->Ctx, P.CurDeclContext); switch (Kind) {
Lookup.setIsSuperRefExpr(); case CompletionKind::DotExpr: {
Lookup.setHaveDot(); CompletionLookup Lookup(CompletionContext, TU->Ctx, CurDeclContext);
Lookup.getValueExprCompletions(SRE->getType()); Lookup.setHaveDot();
Lookup.getValueExprCompletions(ParsedExpr->getType());
break;
}
case CompletionKind::PostfixExprBeginning: {
CompletionLookup Lookup(CompletionContext, TU->Ctx, CurDeclContext);
Lookup.getCompletionsInDeclContext(P.Tok.getLoc());
break;
}
case CompletionKind::PostfixExpr: {
CompletionLookup Lookup(CompletionContext, TU->Ctx, CurDeclContext);
Lookup.getValueExprCompletions(ParsedExpr->getType());
break;
}
case CompletionKind::SuperExpr: {
CompletionLookup Lookup(CompletionContext, TU->Ctx, CurDeclContext);
Lookup.setIsSuperRefExpr();
Lookup.getValueExprCompletions(ParsedExpr->getType());
break;
}
case CompletionKind::SuperExprDot: {
CompletionLookup Lookup(CompletionContext, TU->Ctx, CurDeclContext);
Lookup.setIsSuperRefExpr();
Lookup.setHaveDot();
Lookup.getValueExprCompletions(ParsedExpr->getType());
break;
}
}
deliverCompletionResults(); deliverCompletionResults();
} }

View File

@@ -90,6 +90,7 @@ private:
TheParser.setCodeCompletionCallbacks(CodeCompletion.get()); TheParser.setCodeCompletionCallbacks(CodeCompletion.get());
} }
TheParser.parseDeclFuncBodyDelayed(FD); TheParser.parseDeclFuncBodyDelayed(FD);
CodeCompletion->doneParsing();
} }
}; };
@@ -113,6 +114,7 @@ void parseDelayedTopLevelDecl(
CodeCompletionFactory->createCodeCompletionCallbacks(TheParser)); CodeCompletionFactory->createCodeCompletionCallbacks(TheParser));
TheParser.setCodeCompletionCallbacks(CodeCompletion.get()); TheParser.setCodeCompletionCallbacks(CodeCompletion.get());
TheParser.parseTopLevelCodeDeclDelayed(); TheParser.parseTopLevelCodeDeclDelayed();
CodeCompletion->doneParsing();
} }
} // unnamed namespace } // unnamed namespace