From 2bbef342f02a7d7edc5bb8da09a1abdba293e899 Mon Sep 17 00:00:00 2001 From: Dmitri Hrybenko Date: Wed, 7 Aug 2013 22:42:36 +0000 Subject: [PATCH] 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 --- include/swift/Parse/CodeCompletionCallbacks.h | 4 + lib/IDE/CodeCompletion.cpp | 98 +++++++++++++------ lib/Parse/Parser.cpp | 2 + 3 files changed, 73 insertions(+), 31 deletions(-) diff --git a/include/swift/Parse/CodeCompletionCallbacks.h b/include/swift/Parse/CodeCompletionCallbacks.h index 8927b7cd206..f754efe866e 100644 --- a/include/swift/Parse/CodeCompletionCallbacks.h +++ b/include/swift/Parse/CodeCompletionCallbacks.h @@ -56,6 +56,10 @@ public: /// \brief Complete expr-super after we have consumed the 'super' keyword and /// a dot. 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. diff --git a/lib/IDE/CodeCompletion.cpp b/lib/IDE/CodeCompletion.cpp index dd52c1b58bb..dd122042c94 100644 --- a/lib/IDE/CodeCompletion.cpp +++ b/lib/IDE/CodeCompletion.cpp @@ -338,6 +338,18 @@ class CodeCompletionCallbacksImpl : public CodeCompletionCallbacks, CodeCompletionConsumer &Consumer; 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 /// to the \c Consumer. bool DeliveredResults = false; @@ -381,6 +393,8 @@ public: void completeExprSuper(SuperRefExpr *SRE) override; void completeExprSuperDot(SuperRefExpr *SRE) override; + void doneParsing() override; + void deliverCompletionResults(); // Implement swift::ModuleLoadListener. @@ -842,53 +856,75 @@ public: } // end unnamed namespace void CodeCompletionCallbacksImpl::completeDotExpr(Expr *E) { - if (!typecheckExpr(E)) - return; - - CompletionLookup Lookup(CompletionContext, TU->Ctx, P.CurDeclContext); - Lookup.setHaveDot(); - Lookup.getValueExprCompletions(E->getType()); - - deliverCompletionResults(); + Kind = CompletionKind::DotExpr; + ParsedExpr = E; + CurDeclContext = P.CurDeclContext; } void CodeCompletionCallbacksImpl::completePostfixExprBeginning() { - CompletionLookup Lookup(CompletionContext, TU->Ctx, P.CurDeclContext); assert(P.Tok.is(tok::code_complete)); - Lookup.getCompletionsInDeclContext(P.Tok.getLoc()); - deliverCompletionResults(); + Kind = CompletionKind::PostfixExprBeginning; + CurDeclContext = P.CurDeclContext; } void CodeCompletionCallbacksImpl::completePostfixExpr(Expr *E) { - if (!typecheckExpr(E)) - return; - - CompletionLookup Lookup(CompletionContext, TU->Ctx, P.CurDeclContext); - Lookup.getValueExprCompletions(E->getType()); - - deliverCompletionResults(); + Kind = CompletionKind::PostfixExpr; + ParsedExpr = E; + CurDeclContext = P.CurDeclContext; } void CodeCompletionCallbacksImpl::completeExprSuper(SuperRefExpr *SRE) { - if (!typecheckExpr(SRE)) - return; - - CompletionLookup Lookup(CompletionContext, TU->Ctx, P.CurDeclContext); - Lookup.setIsSuperRefExpr(); - Lookup.getValueExprCompletions(SRE->getType()); - - deliverCompletionResults(); + Kind = CompletionKind::SuperExpr; + ParsedExpr = SRE; + CurDeclContext = P.CurDeclContext; } void CodeCompletionCallbacksImpl::completeExprSuperDot(SuperRefExpr *SRE) { - if (!typecheckExpr(SRE)) + Kind = CompletionKind::SuperExprDot; + ParsedExpr = SRE; + CurDeclContext = P.CurDeclContext; +} + +void CodeCompletionCallbacksImpl::doneParsing() { + if (ParsedExpr && !typecheckExpr(ParsedExpr)) return; - CompletionLookup Lookup(CompletionContext, TU->Ctx, P.CurDeclContext); - Lookup.setIsSuperRefExpr(); - Lookup.setHaveDot(); - Lookup.getValueExprCompletions(SRE->getType()); + switch (Kind) { + case CompletionKind::DotExpr: { + CompletionLookup Lookup(CompletionContext, TU->Ctx, CurDeclContext); + 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(); } diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index dc0b1794da5..45da60cd546 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -90,6 +90,7 @@ private: TheParser.setCodeCompletionCallbacks(CodeCompletion.get()); } TheParser.parseDeclFuncBodyDelayed(FD); + CodeCompletion->doneParsing(); } }; @@ -113,6 +114,7 @@ void parseDelayedTopLevelDecl( CodeCompletionFactory->createCodeCompletionCallbacks(TheParser)); TheParser.setCodeCompletionCallbacks(CodeCompletion.get()); TheParser.parseTopLevelCodeDeclDelayed(); + CodeCompletion->doneParsing(); } } // unnamed namespace