16
16
#include " swift/AST/GenericEnvironment.h"
17
17
#include " swift/AST/NameLookup.h"
18
18
#include " swift/AST/USRGeneration.h"
19
+ #include " swift/IDE/TypeCheckCompletionCallback.h"
19
20
#include " swift/Parse/IDEInspectionCallbacks.h"
20
21
#include " swift/Sema/IDETypeChecking.h"
22
+ #include " swift/Sema/ConstraintSystem.h"
21
23
#include " clang/AST/Attr.h"
22
24
#include " clang/AST/Decl.h"
23
25
@@ -30,7 +32,7 @@ class ConformingMethodListCallbacks : public CodeCompletionCallbacks,
30
32
ArrayRef<const char *> ExpectedTypeNames;
31
33
ConformingMethodListConsumer &Consumer;
32
34
SourceLoc Loc;
33
- Expr *ParsedExpr = nullptr ;
35
+ CodeCompletionExpr *CCExpr = nullptr ;
34
36
DeclContext *CurDeclContext = nullptr ;
35
37
36
38
void getMatchingMethods (Type T,
@@ -56,34 +58,67 @@ class ConformingMethodListCallbacks : public CodeCompletionCallbacks,
56
58
void ConformingMethodListCallbacks::completeDotExpr (CodeCompletionExpr *E,
57
59
SourceLoc DotLoc) {
58
60
CurDeclContext = P.CurDeclContext ;
59
- ParsedExpr = E-> getBase () ;
61
+ CCExpr = E;
60
62
}
61
63
62
64
void ConformingMethodListCallbacks::completePostfixExpr (CodeCompletionExpr *E,
63
65
bool hasSpace) {
64
66
CurDeclContext = P.CurDeclContext ;
65
- ParsedExpr = E-> getBase () ;
67
+ CCExpr = E;
66
68
}
67
69
68
- void ConformingMethodListCallbacks::doneParsing (SourceFile *SrcFile) {
69
- if (!ParsedExpr)
70
- return ;
70
+ class ConformingMethodListCallback : public TypeCheckCompletionCallback {
71
+ public:
72
+ struct Result {
73
+ Type Ty;
71
74
72
- typeCheckContextAt (TypeCheckASTNodeAtLocContext::declContext (CurDeclContext),
73
- ParsedExpr->getLoc ());
75
+ // / Types of variables that were determined in the solution that produced
76
+ // / this result. This in particular includes parameters of closures that
77
+ // / were type-checked with the code completion expression.
78
+ llvm::SmallDenseMap<const VarDecl *, Type> SolutionSpecificVarTypes;
79
+ };
80
+ private:
81
+ CodeCompletionExpr *CCExpr;
74
82
75
- Type T = ParsedExpr-> getType () ;
83
+ SmallVector<Result> Results ;
76
84
77
- // Type check the expression if needed.
78
- if (!T || T->is <ErrorType>()) {
79
- ConcreteDeclRef ReferencedDecl = nullptr ;
80
- auto optT = getTypeOfCompletionContextExpr (P.Context , CurDeclContext,
81
- CompletionTypeCheckKind::Normal,
82
- ParsedExpr, ReferencedDecl);
83
- if (!optT)
85
+ void sawSolutionImpl (const constraints::Solution &S) override {
86
+ if (!S.hasType (CCExpr->getBase ())) {
84
87
return ;
85
- T = *optT;
88
+ }
89
+ if (Type T = getTypeForCompletion (S, CCExpr->getBase ())) {
90
+ llvm::SmallDenseMap<const VarDecl *, Type> SolutionSpecificVarTypes;
91
+ getSolutionSpecificVarTypes (S, SolutionSpecificVarTypes);
92
+ Results.push_back ({T, SolutionSpecificVarTypes});
93
+ }
94
+ }
95
+
96
+ public:
97
+ ConformingMethodListCallback (CodeCompletionExpr *CCExpr) : CCExpr(CCExpr) {}
98
+
99
+ ArrayRef<Result> getResults () const { return Results; }
100
+ };
101
+
102
+ void ConformingMethodListCallbacks::doneParsing (SourceFile *SrcFile) {
103
+ if (!CCExpr || !CCExpr->getBase ())
104
+ return ;
105
+
106
+ ConformingMethodListCallback TypeCheckCallback (CCExpr);
107
+ {
108
+ llvm::SaveAndRestore<TypeCheckCompletionCallback *> CompletionCollector (
109
+ Context.CompletionCallback , &TypeCheckCallback);
110
+ typeCheckContextAt (
111
+ TypeCheckASTNodeAtLocContext::declContext (CurDeclContext),
112
+ CCExpr->getLoc ());
113
+ }
114
+
115
+ if (TypeCheckCallback.getResults ().size () != 1 ) {
116
+ // Either no results or results were ambiguous, which we cannot handle.
117
+ return ;
86
118
}
119
+ auto Res = TypeCheckCallback.getResults ()[0 ];
120
+ Type T = Res.Ty ;
121
+ WithSolutionSpecificVarTypesRAII VarType (Res.SolutionSpecificVarTypes );
87
122
88
123
if (!T || T->is <ErrorType>() || T->is <UnresolvedType>())
89
124
return ;
0 commit comments