Skip to content

Commit a1ef6e4

Browse files
author
Nathan Hawes
authored
Merge pull request swiftlang#33749 from nathawes/new-member-completion
[CodeCompletion] Update member completion to handle ambiguous and invalid base expressions
2 parents 9de171a + b15c1fd commit a1ef6e4

30 files changed

+1008
-255
lines changed

include/swift/AST/ASTContext.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ namespace swift {
122122
class IndexSubset;
123123
struct SILAutoDiffDerivativeFunctionKey;
124124
struct InterfaceSubContextDelegate;
125+
class TypeCheckCompletionCallback;
125126

126127
enum class KnownProtocolKind : uint8_t;
127128

@@ -258,6 +259,8 @@ class ASTContext final {
258259
/// Diags - The diagnostics engine.
259260
DiagnosticEngine &Diags;
260261

262+
TypeCheckCompletionCallback *CompletionCallback = nullptr;
263+
261264
/// The request-evaluator that is used to process various requests.
262265
Evaluator evaluator;
263266

include/swift/IDE/CodeCompletion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -870,7 +870,7 @@ class CodeCompletionContext {
870870
/// but should not hide any results.
871871
SingleExpressionBody,
872872

873-
/// There are known contextual types.
873+
/// There are known contextual types, or there aren't but a nonvoid type is expected.
874874
Required,
875875
};
876876

include/swift/Parse/CodeCompletionCallbacks.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ class CodeCompletionCallbacks {
119119
virtual void setAttrTargetDeclKind(Optional<DeclKind> DK) {}
120120

121121
/// Complete expr-dot after we have consumed the dot.
122-
virtual void completeDotExpr(Expr *E, SourceLoc DotLoc) {};
122+
virtual void completeDotExpr(CodeCompletionExpr *E, SourceLoc DotLoc) {};
123123

124124
/// Complete the beginning of a statement or expression.
125125
virtual void completeStmtOrExpr(CodeCompletionExpr *E) {};

include/swift/Parse/Parser.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,15 @@ class Parser {
692692
Context.LangOpts.ParseForSyntaxTreeOnly;
693693
}
694694

695+
/// If a function or closure body consists of a single expression, determine
696+
/// whether we should turn wrap it in a return statement or not.
697+
///
698+
/// We don't do this transformation for non-solver-based code completion
699+
/// positions, as the source may be incomplete and the type mismatch in the
700+
/// return statement will just confuse the type checker.
701+
bool shouldSuppressSingleExpressionBodyTransform(
702+
ParserStatus Status, MutableArrayRef<ASTNode> BodyElems);
703+
695704
public:
696705
InFlightDiagnostic diagnose(SourceLoc Loc, Diagnostic Diag) {
697706
if (Diags.isDiagnosticPointsToFirstBadToken(Diag.getID()) &&
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
//===--- CodeCompletionTypeChecking.h --------------------------*- C++ -*-===//
2+
//
3+
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
4+
// Licensed under Apache License v2.0 with Runtime Library Exception
5+
//
6+
// See https://swift.org/LICENSE.txt for license information
7+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
8+
//
9+
//===----------------------------------------------------------------------===//
10+
//
11+
/// \file
12+
/// Provides TypeCheckCompletionCallback implementations for the various kinds
13+
/// of code completion. These extract and persist information needed to compute
14+
/// completion results from the solutions formed during expression typechecking.
15+
//
16+
//===----------------------------------------------------------------------===//
17+
18+
#ifndef SWIFT_SEMA_CODECOMPLETIONTYPECHECKING_H
19+
#define SWIFT_SEMA_CODECOMPLETIONTYPECHECKING_H
20+
21+
namespace swift {
22+
class Decl;
23+
class DeclContext;
24+
class Type;
25+
class ValueDecl;
26+
class CodeCompletionExpr;
27+
28+
namespace constraints {
29+
class Solution;
30+
}
31+
32+
class TypeCheckCompletionCallback {
33+
public:
34+
/// Called for each solution produced while type-checking an expression
35+
/// containing a code completion expression.
36+
virtual void sawSolution(const constraints::Solution &solution) = 0;
37+
virtual ~TypeCheckCompletionCallback() {}
38+
};
39+
40+
41+
/// Used to collect and store information needed to perform member completion
42+
/// (\c CompletionKind::DotExpr ) from the solutions formed during expression
43+
/// type-checking.
44+
class DotExprTypeCheckCompletionCallback: public TypeCheckCompletionCallback {
45+
public:
46+
struct Result {
47+
Type BaseTy;
48+
ValueDecl* BaseDecl;
49+
SmallVector<Type, 4> ExpectedTypes;
50+
bool ExpectsNonVoid;
51+
bool BaseIsStaticMetaType;
52+
bool IsSingleExpressionBody;
53+
};
54+
55+
private:
56+
DeclContext *DC;
57+
CodeCompletionExpr *CompletionExpr;
58+
SmallVector<Result, 4> Results;
59+
llvm::DenseMap<std::pair<Type, Decl*>, size_t> BaseToSolutionIdx;
60+
bool GotCallback = false;
61+
62+
public:
63+
DotExprTypeCheckCompletionCallback(DeclContext *DC,
64+
CodeCompletionExpr *CompletionExpr)
65+
: DC(DC), CompletionExpr(CompletionExpr) {}
66+
67+
/// Get the results collected from any sawSolutions() callbacks recevied so
68+
/// far.
69+
ArrayRef<Result> getResults() const { return Results; }
70+
71+
/// True if at least one solution was passed via the \c sawSolution
72+
/// callback.
73+
bool gotCallback() const { return GotCallback; }
74+
75+
/// Typecheck the code completion expression in isolation, calling
76+
/// \c sawSolution for each solution formed.
77+
void fallbackTypeCheck();
78+
79+
void sawSolution(const constraints::Solution &solution) override;
80+
};
81+
}
82+
83+
#endif

0 commit comments

Comments
 (0)