Skip to content

Commit 3597652

Browse files
committed
[CodeCompletion] Make sawSolution non-final and override sawSolutionImpl from subclasses
This eliminates a source of bugs if subclasses of `TypeCheckCompletionCallback` forget to call the superclass’s implementation of `sawSolution` from their overridden method.
1 parent 03d819f commit 3597652

11 files changed

+22
-25
lines changed

include/swift/IDE/ArgumentCompletion.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,13 @@ class ArgumentTypeCheckCompletionCallback : public TypeCheckCompletionCallback {
6363
SmallVectorImpl<PossibleParamInfo> &Params,
6464
SmallVectorImpl<Type> &Types);
6565

66+
void sawSolutionImpl(const constraints::Solution &solution) override;
67+
6668
public:
6769
ArgumentTypeCheckCompletionCallback(CodeCompletionExpr *CompletionExpr,
6870
DeclContext *DC)
6971
: CompletionExpr(CompletionExpr), DC(DC) {}
7072

71-
void sawSolution(const constraints::Solution &solution) override;
72-
7373
/// \param IncludeSignature Whether to include a suggestion for the entire
7474
/// function signature instead of suggesting individual labels. Used when
7575
/// completing after the opening '(' of a function call \param Loc The

include/swift/IDE/DotExprCompletion.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ class DotExprTypeCheckCompletionCallback : public TypeCheckCompletionCallback {
4343
SmallVector<Result, 4> Results;
4444
llvm::DenseMap<std::pair<Type, Decl *>, size_t> BaseToSolutionIdx;
4545

46+
void sawSolutionImpl(const constraints::Solution &solution) override;
47+
4648
public:
4749
DotExprTypeCheckCompletionCallback(CodeCompletionExpr *CompletionExpr,
4850
DeclContext *DC)
@@ -52,8 +54,6 @@ class DotExprTypeCheckCompletionCallback : public TypeCheckCompletionCallback {
5254
/// \c sawSolution for each solution formed.
5355
void fallbackTypeCheck(DeclContext *DC) override;
5456

55-
void sawSolution(const constraints::Solution &solution) override;
56-
5757
void deliverResults(Expr *BaseExpr, DeclContext *DC, SourceLoc DotLoc,
5858
bool IsInSelector, CodeCompletionContext &CompletionCtx,
5959
CodeCompletionConsumer &Consumer);

include/swift/IDE/ExprCompletion.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,14 @@ class ExprTypeCheckCompletionCallback : public TypeCheckCompletionCallback {
4646

4747
SmallVector<Result, 4> Results;
4848

49+
void sawSolutionImpl(const constraints::Solution &solution) override;
50+
4951
public:
5052
/// \param DC The decl context in which the \p CompletionExpr occurs.
5153
ExprTypeCheckCompletionCallback(CodeCompletionExpr *CompletionExpr,
5254
DeclContext *DC)
5355
: CompletionExpr(CompletionExpr), DC(DC) {}
5456

55-
void sawSolution(const constraints::Solution &solution) override;
56-
5757
/// \param CCLoc The location of the code completion token.
5858
void deliverResults(SourceLoc CCLoc,
5959
ide::CodeCompletionContext &CompletionCtx,

include/swift/IDE/KeyPathCompletion.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ class KeyPathTypeCheckCompletionCallback : public TypeCheckCompletionCallback {
3232
KeyPathExpr *KeyPath;
3333
SmallVector<Result, 4> Results;
3434

35+
void sawSolutionImpl(const constraints::Solution &solution) override;
36+
3537
public:
3638
KeyPathTypeCheckCompletionCallback(KeyPathExpr *KeyPath) : KeyPath(KeyPath) {}
3739

38-
void sawSolution(const constraints::Solution &solution) override;
39-
4040
void deliverResults(DeclContext *DC, SourceLoc DotLoc,
4141
ide::CodeCompletionContext &CompletionCtx,
4242
CodeCompletionConsumer &Consumer);

include/swift/IDE/TypeCheckCompletionCallback.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,19 @@ namespace ide {
4141
class TypeCheckCompletionCallback {
4242
bool GotCallback = false;
4343

44+
protected:
45+
/// Subclasses of \c TypeCheckCompletionCallback handle solutions discovered
46+
/// by the constraint system in this function
47+
virtual void sawSolutionImpl(const constraints::Solution &solution) = 0;
48+
4449
public:
4550
virtual ~TypeCheckCompletionCallback() {}
4651

4752
/// Called for each solution produced while type-checking an expression
4853
/// that the code completion expression participates in.
49-
virtual void sawSolution(const constraints::Solution &solution) {
54+
void sawSolution(const constraints::Solution &solution) {
5055
GotCallback = true;
56+
sawSolutionImpl(solution);
5157
};
5258

5359
/// True if at least one solution was passed via the \c sawSolution

include/swift/IDE/UnresolvedMemberCompletion.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,13 @@ class UnresolvedMemberTypeCheckCompletionCallback
4040
SmallVector<Result, 4> ExprResults;
4141
SmallVector<Result, 1> EnumPatternTypes;
4242

43+
void sawSolutionImpl(const constraints::Solution &solution) override;
44+
4345
public:
4446
UnresolvedMemberTypeCheckCompletionCallback(
4547
CodeCompletionExpr *CompletionExpr, DeclContext *DC)
4648
: CompletionExpr(CompletionExpr), DC(DC) {}
4749

48-
void sawSolution(const constraints::Solution &solution) override;
49-
5050
void deliverResults(DeclContext *DC, SourceLoc DotLoc,
5151
ide::CodeCompletionContext &CompletionCtx,
5252
CodeCompletionConsumer &Consumer);

lib/IDE/ArgumentCompletion.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,7 @@ bool ArgumentTypeCheckCompletionCallback::addPossibleParams(
9090
return ShowGlobalCompletions;
9191
}
9292

93-
void ArgumentTypeCheckCompletionCallback::sawSolution(const Solution &S) {
94-
TypeCheckCompletionCallback::sawSolution(S);
95-
93+
void ArgumentTypeCheckCompletionCallback::sawSolutionImpl(const Solution &S) {
9694
Type ExpectedTy = getTypeForCompletion(S, CompletionExpr);
9795

9896
auto &CS = S.getConstraintSystem();

lib/IDE/DotExprCompletion.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,8 @@ void DotExprTypeCheckCompletionCallback::fallbackTypeCheck(DeclContext *DC) {
4444
[&](const Solution &S) { sawSolution(S); });
4545
}
4646

47-
void DotExprTypeCheckCompletionCallback::sawSolution(
47+
void DotExprTypeCheckCompletionCallback::sawSolutionImpl(
4848
const constraints::Solution &S) {
49-
TypeCheckCompletionCallback::sawSolution(S);
5049
auto &CS = S.getConstraintSystem();
5150
auto *ParsedExpr = CompletionExpr->getBase();
5251
auto *SemanticExpr = ParsedExpr->getSemanticsProvidingExpr();

lib/IDE/ExprCompletion.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,8 @@ using namespace swift;
1919
using namespace swift::ide;
2020
using namespace swift::constraints;
2121

22-
void ExprTypeCheckCompletionCallback::sawSolution(
22+
void ExprTypeCheckCompletionCallback::sawSolutionImpl(
2323
const constraints::Solution &S) {
24-
TypeCheckCompletionCallback::sawSolution(S);
25-
2624
auto &CS = S.getConstraintSystem();
2725

2826
Type ExpectedTy = getTypeForCompletion(S, CompletionExpr);

lib/IDE/KeyPathCompletion.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,8 @@ using namespace swift;
1919
using namespace swift::constraints;
2020
using namespace swift::ide;
2121

22-
void KeyPathTypeCheckCompletionCallback::sawSolution(
22+
void KeyPathTypeCheckCompletionCallback::sawSolutionImpl(
2323
const constraints::Solution &S) {
24-
TypeCheckCompletionCallback::sawSolution(S);
25-
2624
// Determine the code completion.
2725
size_t ComponentIndex = 0;
2826
for (auto &Component : KeyPath->getComponents()) {

lib/IDE/UnresolvedMemberCompletion.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,8 @@ static VarDecl *getMatchVarIfInPatternMatch(CodeCompletionExpr *CompletionExpr,
8080
}
8181
}
8282

83-
void UnresolvedMemberTypeCheckCompletionCallback::sawSolution(
83+
void UnresolvedMemberTypeCheckCompletionCallback::sawSolutionImpl(
8484
const constraints::Solution &S) {
85-
TypeCheckCompletionCallback::sawSolution(S);
86-
8785
auto &CS = S.getConstraintSystem();
8886
Type ExpectedTy = getTypeForCompletion(S, CompletionExpr);
8987

0 commit comments

Comments
 (0)