Skip to content

Commit 51777d5

Browse files
committed
[CodeCompletion] Move TypeCheckCompletionCallbacks to IDE
1 parent 458ce70 commit 51777d5

15 files changed

+206
-174
lines changed

include/swift/AST/ASTContext.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,6 @@ namespace swift {
130130
class IndexSubset;
131131
struct SILAutoDiffDerivativeFunctionKey;
132132
struct InterfaceSubContextDelegate;
133-
class TypeCheckCompletionCallback;
134133

135134
enum class KnownProtocolKind : uint8_t;
136135

@@ -146,6 +145,10 @@ namespace syntax {
146145
class SyntaxArena;
147146
}
148147

148+
namespace ide {
149+
class TypeCheckCompletionCallback;
150+
}
151+
149152
/// Lists the set of "known" Foundation entities that are used in the
150153
/// compiler.
151154
///
@@ -281,7 +284,7 @@ class ASTContext final {
281284
/// the cancellation might return with any result.
282285
std::shared_ptr<std::atomic<bool>> CancellationFlag = nullptr;
283286

284-
TypeCheckCompletionCallback *CompletionCallback = nullptr;
287+
ide::TypeCheckCompletionCallback *CompletionCallback = nullptr;
285288

286289
/// The request-evaluator that is used to process various requests.
287290
Evaluator evaluator;

include/swift/IDE/ArgumentCompletion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#include "swift/IDE/CodeCompletionConsumer.h"
1717
#include "swift/IDE/CodeCompletionContext.h"
1818
#include "swift/IDE/PossibleParamInfo.h"
19-
#include "swift/Sema/CodeCompletionTypeChecking.h"
19+
#include "swift/IDE/TypeCheckCompletionCallback.h"
2020

2121
namespace swift {
2222
namespace ide {

include/swift/IDE/DotExprCompletion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
#include "swift/IDE/CodeCompletionConsumer.h"
1717
#include "swift/IDE/CodeCompletionContext.h"
18-
#include "swift/Sema/CodeCompletionTypeChecking.h"
18+
#include "swift/IDE/TypeCheckCompletionCallback.h"
1919

2020
namespace swift {
2121
namespace ide {

include/swift/IDE/ExprCompletion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
#include "swift/IDE/CodeCompletionConsumer.h"
1717
#include "swift/IDE/CodeCompletionContext.h"
18-
#include "swift/Sema/CodeCompletionTypeChecking.h"
18+
#include "swift/IDE/TypeCheckCompletionCallback.h"
1919

2020
namespace swift {
2121
namespace ide {

include/swift/IDE/KeyPathCompletion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
#include "swift/IDE/CodeCompletionConsumer.h"
1717
#include "swift/IDE/CodeCompletionContext.h"
18-
#include "swift/Sema/CodeCompletionTypeChecking.h"
18+
#include "swift/IDE/TypeCheckCompletionCallback.h"
1919

2020
namespace swift {
2121
namespace ide {
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
//===--- TypeCheckCompletionCallback.h -----------------------------------===//
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_IDE_TYPECHECKCOMPLETIONCALLBACK_H
19+
#define SWIFT_IDE_TYPECHECKCOMPLETIONCALLBACK_H
20+
21+
#include "swift/AST/Expr.h"
22+
#include "swift/AST/Type.h"
23+
#include "swift/Basic/LLVM.h"
24+
#include "llvm/ADT/DenseMap.h"
25+
#include "llvm/ADT/SmallVector.h"
26+
27+
namespace swift {
28+
class Decl;
29+
class DeclContext;
30+
class Type;
31+
class ValueDecl;
32+
class CodeCompletionExpr;
33+
34+
namespace constraints {
35+
class ConstraintSystem;
36+
class Solution;
37+
} // namespace constraints
38+
39+
namespace ide {
40+
41+
class TypeCheckCompletionCallback {
42+
bool GotCallback = false;
43+
44+
public:
45+
virtual ~TypeCheckCompletionCallback() {}
46+
47+
/// Called for each solution produced while type-checking an expression
48+
/// that the code completion expression participates in.
49+
virtual void sawSolution(const constraints::Solution &solution) {
50+
GotCallback = true;
51+
};
52+
53+
/// True if at least one solution was passed via the \c sawSolution
54+
/// callback.
55+
bool gotCallback() const { return GotCallback; }
56+
57+
/// Typecheck the code completion expression in its outermost expression
58+
/// context, calling \c sawSolution for each solution formed.
59+
virtual void fallbackTypeCheck(DeclContext *DC);
60+
};
61+
62+
// MARK: - Utility functions for subclasses of TypeCheckCompletionCallback
63+
64+
Type getTypeForCompletion(const constraints::Solution &S, Expr *E);
65+
66+
/// Whether the given completion expression is the only expression in its
67+
/// containing closure or function body and its value is implicitly returned.
68+
///
69+
/// If these conditions are met, code completion needs to avoid penalizing
70+
/// completion results that don't match the expected return type when
71+
/// computing type relations, as since no return statement was explicitly
72+
/// written by the user, it's possible they intend the single expression not
73+
/// as the return value but merely the first entry in a multi-statement body
74+
/// they just haven't finished writing yet.
75+
bool isImplicitSingleExpressionReturn(constraints::ConstraintSystem &CS,
76+
Expr *CompletionExpr);
77+
78+
} // namespace ide
79+
} // namespace swift
80+
81+
#endif // SWIFT_IDE_TYPECHECKCOMPLETIONCALLBACK_H

include/swift/IDE/UnresolvedMemberCompletion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
#include "swift/IDE/CodeCompletionConsumer.h"
1717
#include "swift/IDE/CodeCompletionContext.h"
18-
#include "swift/Sema/CodeCompletionTypeChecking.h"
18+
#include "swift/IDE/TypeCheckCompletionCallback.h"
1919

2020
namespace swift {
2121
namespace ide {

include/swift/Sema/CodeCompletionTypeChecking.h

Lines changed: 0 additions & 60 deletions
This file was deleted.

include/swift/Sema/CompletionContextFinder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#include "swift/AST/ASTNode.h"
1717
#include "swift/AST/ASTWalker.h"
1818
#include "swift/AST/Expr.h"
19-
#include "swift/Sema/CodeCompletionTypeChecking.h"
19+
#include "swift/IDE/TypeCheckCompletionCallback.h"
2020

2121
namespace swift {
2222

include/swift/Sema/IDETypeChecking.h

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -159,20 +159,6 @@ namespace swift {
159159
constraints::SolutionApplicationTarget &target, bool needsPrecheck,
160160
llvm::function_ref<void(const constraints::Solution &)> callback);
161161

162-
Type getTypeForCompletion(const constraints::Solution &S, Expr *E);
163-
164-
/// Whether the given completion expression is the only expression in its
165-
/// containing closure or function body and its value is implicitly returned.
166-
///
167-
/// If these conditions are met, code completion needs to avoid penalizing
168-
/// completion results that don't match the expected return type when
169-
/// computing type relations, as since no return statement was explicitly
170-
/// written by the user, it's possible they intend the single expression not
171-
/// as the return value but merely the first entry in a multi-statement body
172-
/// they just haven't finished writing yet.
173-
bool isImplicitSingleExpressionReturn(constraints::ConstraintSystem &CS,
174-
Expr *CompletionExpr);
175-
176162
LookupResult
177163
lookupSemanticMember(DeclContext *DC, Type ty, DeclName name);
178164

lib/IDE/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ add_swift_host_library(swiftIDE STATIC
3030
REPLCodeCompletion.cpp
3131
SwiftSourceDocInfo.cpp
3232
SyntaxModel.cpp
33+
TypeCheckCompletionCallback.cpp
3334
UnresolvedMemberCompletion.cpp
3435
Utils.cpp
3536
IDETypeChecking.cpp

lib/IDE/CodeCompletion.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@
4242
#include "swift/IDE/DotExprCompletion.h"
4343
#include "swift/IDE/ExprCompletion.h"
4444
#include "swift/IDE/KeyPathCompletion.h"
45+
#include "swift/IDE/TypeCheckCompletionCallback.h"
4546
#include "swift/IDE/UnresolvedMemberCompletion.h"
4647
#include "swift/IDE/Utils.h"
4748
#include "swift/Parse/CodeCompletionCallbacks.h"
48-
#include "swift/Sema/CodeCompletionTypeChecking.h"
4949
#include "swift/Sema/IDETypeChecking.h"
5050
#include "swift/Strings.h"
5151
#include "swift/Subsystems.h"
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
//===--- TypeCheckCompletionCallback.cpp ----------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "swift/IDE/TypeCheckCompletionCallback.h"
14+
#include "swift/Sema/CompletionContextFinder.h"
15+
#include "swift/Sema/ConstraintSystem.h"
16+
#include "swift/Sema/IDETypeChecking.h"
17+
18+
using namespace swift;
19+
using namespace swift::ide;
20+
using namespace swift::constraints;
21+
22+
void TypeCheckCompletionCallback::fallbackTypeCheck(DeclContext *DC) {
23+
assert(!GotCallback);
24+
25+
CompletionContextFinder finder(DC);
26+
if (!finder.hasCompletionExpr())
27+
return;
28+
29+
auto fallback = finder.getFallbackCompletionExpr();
30+
if (!fallback)
31+
return;
32+
33+
SolutionApplicationTarget completionTarget(fallback->E, fallback->DC,
34+
CTP_Unused, Type(),
35+
/*isDiscared=*/true);
36+
typeCheckForCodeCompletion(completionTarget, /*needsPrecheck=*/true,
37+
[&](const Solution &S) { sawSolution(S); });
38+
}
39+
40+
// MARK: - Utility functions for subclasses of TypeCheckCompletionCallback
41+
42+
Type swift::ide::getTypeForCompletion(const constraints::Solution &S, Expr *E) {
43+
if (!S.hasType(E)) {
44+
assert(false && "Expression wasn't type checked?");
45+
return nullptr;
46+
}
47+
48+
auto &CS = S.getConstraintSystem();
49+
50+
// To aid code completion, we need to attempt to convert type placeholders
51+
// back into underlying generic parameters if possible, since type
52+
// of the code completion expression is used as "expected" (or contextual)
53+
// type so it's helpful to know what requirements it has to filter
54+
// the list of possible member candidates e.g.
55+
//
56+
// \code
57+
// func test<T: P>(_: [T]) {}
58+
//
59+
// test(42.#^MEMBERS^#)
60+
// \code
61+
//
62+
// It's impossible to resolve `T` in this case but code completion
63+
// expression should still have a type of `[T]` instead of `[<<hole>>]`
64+
// because it helps to produce correct contextual member list based on
65+
// a conformance requirement associated with generic parameter `T`.
66+
if (isa<CodeCompletionExpr>(E)) {
67+
auto completionTy = S.getType(E).transform([&](Type type) -> Type {
68+
if (auto *typeVar = type->getAs<TypeVariableType>())
69+
return S.getFixedType(typeVar);
70+
return type;
71+
});
72+
73+
return S.simplifyType(completionTy.transform([&](Type type) {
74+
if (auto *placeholder = type->getAs<PlaceholderType>()) {
75+
if (auto *typeVar =
76+
placeholder->getOriginator().dyn_cast<TypeVariableType *>()) {
77+
if (auto *GP = typeVar->getImpl().getGenericParameter()) {
78+
// Code completion depends on generic parameter type being
79+
// represented in terms of `ArchetypeType` since it's easy
80+
// to extract protocol requirements from it.
81+
if (auto *GPD = GP->getDecl())
82+
return GPD->getInnermostDeclContext()->mapTypeIntoContext(GP);
83+
}
84+
}
85+
86+
return Type(CS.getASTContext().TheUnresolvedType);
87+
}
88+
89+
return type;
90+
}));
91+
}
92+
93+
return S.getResolvedType(E);
94+
}
95+
96+
bool swift::ide::isImplicitSingleExpressionReturn(ConstraintSystem &CS,
97+
Expr *CompletionExpr) {
98+
Expr *ParentExpr = CS.getParentExpr(CompletionExpr);
99+
if (!ParentExpr)
100+
return CS.getContextualTypePurpose(CompletionExpr) == CTP_ReturnSingleExpr;
101+
102+
if (auto *ParentCE = dyn_cast<ClosureExpr>(ParentExpr)) {
103+
if (ParentCE->hasSingleExpressionBody() &&
104+
ParentCE->getSingleExpressionBody() == CompletionExpr) {
105+
ASTNode Last = ParentCE->getBody()->getLastElement();
106+
return !Last.isStmt(StmtKind::Return) || Last.isImplicit();
107+
}
108+
}
109+
return false;
110+
}

0 commit comments

Comments
 (0)