Skip to content

Commit 627cbd8

Browse files
committed
Revert "[CodeCompletion] Migrate key path completion to be solver based"
This reverts commit e333291.
1 parent 48e883c commit 627cbd8

19 files changed

+74
-238
lines changed

include/swift/AST/Expr.h

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5409,7 +5409,6 @@ class KeyPathExpr : public Expr {
54095409
/// - a resolved ValueDecl, referring to
54105410
/// - a subscript index expression, which may or may not be resolved
54115411
/// - an optional chaining, forcing, or wrapping component
5412-
/// - a code completion token
54135412
class Component {
54145413
public:
54155414
enum class Kind: unsigned {
@@ -5424,7 +5423,6 @@ class KeyPathExpr : public Expr {
54245423
Identity,
54255424
TupleElement,
54265425
DictionaryKey,
5427-
CodeCompletion,
54285426
};
54295427

54305428
private:
@@ -5600,12 +5598,8 @@ class KeyPathExpr : public Expr {
56005598
SourceLoc loc) {
56015599
return Component(fieldNumber, elementType, loc);
56025600
}
5603-
5604-
static Component forCodeCompletion(SourceLoc Loc) {
5605-
return Component(nullptr, {}, nullptr, {}, {}, Kind::CodeCompletion,
5606-
Type(), Loc);
5607-
}
5608-
5601+
5602+
56095603
SourceLoc getLoc() const {
56105604
return Loc;
56115605
}
@@ -5643,7 +5637,6 @@ class KeyPathExpr : public Expr {
56435637
case Kind::UnresolvedSubscript:
56445638
case Kind::UnresolvedProperty:
56455639
case Kind::Invalid:
5646-
case Kind::CodeCompletion:
56475640
return false;
56485641
}
56495642
llvm_unreachable("unhandled kind");
@@ -5664,7 +5657,6 @@ class KeyPathExpr : public Expr {
56645657
case Kind::Identity:
56655658
case Kind::TupleElement:
56665659
case Kind::DictionaryKey:
5667-
case Kind::CodeCompletion:
56685660
return nullptr;
56695661
}
56705662
llvm_unreachable("unhandled kind");
@@ -5685,7 +5677,6 @@ class KeyPathExpr : public Expr {
56855677
case Kind::Identity:
56865678
case Kind::TupleElement:
56875679
case Kind::DictionaryKey:
5688-
case Kind::CodeCompletion:
56895680
llvm_unreachable("no subscript labels for this kind");
56905681
}
56915682
llvm_unreachable("unhandled kind");
@@ -5709,7 +5700,6 @@ class KeyPathExpr : public Expr {
57095700
case Kind::Identity:
57105701
case Kind::TupleElement:
57115702
case Kind::DictionaryKey:
5712-
case Kind::CodeCompletion:
57135703
return {};
57145704
}
57155705
llvm_unreachable("unhandled kind");
@@ -5733,7 +5723,6 @@ class KeyPathExpr : public Expr {
57335723
case Kind::Property:
57345724
case Kind::Identity:
57355725
case Kind::TupleElement:
5736-
case Kind::CodeCompletion:
57375726
llvm_unreachable("no unresolved name for this kind");
57385727
}
57395728
llvm_unreachable("unhandled kind");
@@ -5754,7 +5743,6 @@ class KeyPathExpr : public Expr {
57545743
case Kind::Identity:
57555744
case Kind::TupleElement:
57565745
case Kind::DictionaryKey:
5757-
case Kind::CodeCompletion:
57585746
return false;
57595747
}
57605748
llvm_unreachable("unhandled kind");
@@ -5775,7 +5763,6 @@ class KeyPathExpr : public Expr {
57755763
case Kind::Identity:
57765764
case Kind::TupleElement:
57775765
case Kind::DictionaryKey:
5778-
case Kind::CodeCompletion:
57795766
llvm_unreachable("no decl ref for this kind");
57805767
}
57815768
llvm_unreachable("unhandled kind");
@@ -5796,7 +5783,6 @@ class KeyPathExpr : public Expr {
57965783
case Kind::Property:
57975784
case Kind::Subscript:
57985785
case Kind::DictionaryKey:
5799-
case Kind::CodeCompletion:
58005786
llvm_unreachable("no field number for this kind");
58015787
}
58025788
llvm_unreachable("unhandled kind");

include/swift/Sema/CodeCompletionTypeChecking.h

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -116,29 +116,6 @@ namespace swift {
116116
void sawSolution(const constraints::Solution &solution) override;
117117
};
118118

119-
class KeyPathTypeCheckCompletionCallback
120-
: public TypeCheckCompletionCallback {
121-
public:
122-
struct Result {
123-
/// The type on which completion should occur, i.e. a result type of the
124-
/// previous component.
125-
Type BaseType;
126-
/// Whether code completion happens on the key path's root.
127-
bool OnRoot;
128-
};
129-
130-
private:
131-
KeyPathExpr *KeyPath;
132-
SmallVector<Result, 4> Results;
133-
134-
public:
135-
KeyPathTypeCheckCompletionCallback(KeyPathExpr *KeyPath)
136-
: KeyPath(KeyPath) {}
137-
138-
ArrayRef<Result> getResults() const { return Results; }
139-
140-
void sawSolution(const constraints::Solution &solution) override;
141-
};
142119
}
143120

144121
#endif

lib/AST/ASTDumper.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2880,9 +2880,6 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
28802880
PrintWithColorRAII(OS, IdentifierColor)
28812881
<< " key='" << component.getUnresolvedDeclName() << "'";
28822882
break;
2883-
case KeyPathExpr::Component::Kind::CodeCompletion:
2884-
PrintWithColorRAII(OS, ASTNodeColor) << "completion";
2885-
break;
28862883
}
28872884
PrintWithColorRAII(OS, TypeColor)
28882885
<< " type='" << GetTypeOfKeyPathComponent(E, i) << "'";

lib/AST/ASTWalker.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1125,7 +1125,6 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
11251125
case KeyPathExpr::Component::Kind::Identity:
11261126
case KeyPathExpr::Component::Kind::TupleElement:
11271127
case KeyPathExpr::Component::Kind::DictionaryKey:
1128-
case KeyPathExpr::Component::Kind::CodeCompletion:
11291128
// No subexpr to visit.
11301129
break;
11311130
}

lib/AST/Expr.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2399,7 +2399,6 @@ void KeyPathExpr::Component::setSubscriptIndexHashableConformances(
23992399
case Kind::Identity:
24002400
case Kind::TupleElement:
24012401
case Kind::DictionaryKey:
2402-
case Kind::CodeCompletion:
24032402
llvm_unreachable("no hashable conformances for this kind");
24042403
}
24052404
}

lib/IDE/CodeCompletion.cpp

Lines changed: 51 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6727,28 +6727,6 @@ void deliverUnresolvedMemberResults(
67276727
deliverCompletionResults(CompletionCtx, Lookup, DC, Consumer);
67286728
}
67296729

6730-
void deliverKeyPathResults(
6731-
ArrayRef<KeyPathTypeCheckCompletionCallback::Result> Results,
6732-
DeclContext *DC, SourceLoc DotLoc,
6733-
ide::CodeCompletionContext &CompletionCtx,
6734-
CodeCompletionConsumer &Consumer) {
6735-
ASTContext &Ctx = DC->getASTContext();
6736-
CompletionLookup Lookup(CompletionCtx.getResultSink(), Ctx, DC,
6737-
&CompletionCtx);
6738-
6739-
if (DotLoc.isValid()) {
6740-
Lookup.setHaveDot(DotLoc);
6741-
}
6742-
Lookup.shouldCheckForDuplicates(Results.size() > 1);
6743-
6744-
for (auto &Result : Results) {
6745-
Lookup.setIsSwiftKeyPathExpr(Result.OnRoot);
6746-
Lookup.getValueExprCompletions(Result.BaseType);
6747-
}
6748-
6749-
deliverCompletionResults(CompletionCtx, Lookup, DC, Consumer);
6750-
}
6751-
67526730
void deliverDotExprResults(
67536731
ArrayRef<DotExprTypeCheckCompletionCallback::Result> Results,
67546732
Expr *BaseExpr, DeclContext *DC, SourceLoc DotLoc, bool IsInSelector,
@@ -6840,21 +6818,6 @@ bool CodeCompletionCallbacksImpl::trySolverCompletion(bool MaybeFuncBody) {
68406818
CompletionContext, Consumer);
68416819
return true;
68426820
}
6843-
case CompletionKind::KeyPathExprSwift: {
6844-
assert(CurDeclContext);
6845-
6846-
// CodeCompletionCallbacks::completeExprKeyPath takes a \c KeyPathExpr,
6847-
// so we can safely cast the \c ParsedExpr back to a \c KeyPathExpr.
6848-
auto KeyPath = cast<KeyPathExpr>(ParsedExpr);
6849-
KeyPathTypeCheckCompletionCallback Lookup(KeyPath);
6850-
llvm::SaveAndRestore<TypeCheckCompletionCallback *> CompletionCollector(
6851-
Context.CompletionCallback, &Lookup);
6852-
typeCheckContextAt(CurDeclContext, CompletionLoc);
6853-
6854-
deliverKeyPathResults(Lookup.getResults(), CurDeclContext, DotLoc,
6855-
CompletionContext, Consumer);
6856-
return true;
6857-
}
68586821
default:
68596822
return false;
68606823
}
@@ -6975,10 +6938,60 @@ void CodeCompletionCallbacksImpl::doneParsing() {
69756938
case CompletionKind::None:
69766939
case CompletionKind::DotExpr:
69776940
case CompletionKind::UnresolvedMember:
6978-
case CompletionKind::KeyPathExprSwift:
69796941
llvm_unreachable("should be already handled");
69806942
return;
69816943

6944+
case CompletionKind::KeyPathExprSwift: {
6945+
auto KPE = dyn_cast<KeyPathExpr>(ParsedExpr);
6946+
auto BGT = (*ExprType)->getAs<BoundGenericType>();
6947+
if (!KPE || !BGT || BGT->getGenericArgs().size() != 2)
6948+
break;
6949+
assert(!KPE->isObjC());
6950+
6951+
if (DotLoc.isValid())
6952+
Lookup.setHaveDot(DotLoc);
6953+
6954+
bool OnRoot = !KPE->getComponents().front().isValid();
6955+
Lookup.setIsSwiftKeyPathExpr(OnRoot);
6956+
6957+
Type baseType = BGT->getGenericArgs()[OnRoot ? 0 : 1];
6958+
if (OnRoot && baseType->is<UnresolvedType>()) {
6959+
// Infer the root type of the keypath from the context type.
6960+
ExprContextInfo ContextInfo(CurDeclContext, ParsedExpr);
6961+
for (auto T : ContextInfo.getPossibleTypes()) {
6962+
if (auto unwrapped = T->getOptionalObjectType())
6963+
T = unwrapped;
6964+
6965+
// If the context type is any of the KeyPath types, use it.
6966+
if (T->getAnyNominal() && T->getAnyNominal()->getKeyPathTypeKind() &&
6967+
!T->hasUnresolvedType() && T->is<BoundGenericType>()) {
6968+
baseType = T->castTo<BoundGenericType>()->getGenericArgs()[0];
6969+
break;
6970+
}
6971+
6972+
// KeyPath can be used as a function that receives its root type.
6973+
if (T->is<AnyFunctionType>()) {
6974+
auto *fnType = T->castTo<AnyFunctionType>();
6975+
if (fnType->getNumParams() == 1) {
6976+
const AnyFunctionType::Param &param = fnType->getParams()[0];
6977+
baseType = param.getParameterType();
6978+
break;
6979+
}
6980+
}
6981+
}
6982+
}
6983+
if (!OnRoot && KPE->getComponents().back().getKind() ==
6984+
KeyPathExpr::Component::Kind::OptionalWrap) {
6985+
// KeyPath expr with '?' (e.g. '\Ty.[0].prop?.another').
6986+
// Although expected type is optional, we should unwrap it because it's
6987+
// unwrapped.
6988+
baseType = baseType->getOptionalObjectType();
6989+
}
6990+
6991+
Lookup.getValueExprCompletions(baseType);
6992+
break;
6993+
}
6994+
69826995
case CompletionKind::StmtOrExpr:
69836996
case CompletionKind::ForEachSequence:
69846997
case CompletionKind::PostfixExprBeginning: {

lib/IDE/SourceEntityWalker.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,6 @@ std::pair<bool, Expr *> SemaAnnotator::walkToExprPre(Expr *E) {
494494
case KeyPathExpr::Component::Kind::OptionalForce:
495495
case KeyPathExpr::Component::Kind::Identity:
496496
case KeyPathExpr::Component::Kind::DictionaryKey:
497-
case KeyPathExpr::Component::Kind::CodeCompletion:
498497
break;
499498
}
500499
}

lib/IDE/SwiftSourceDocInfo.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,6 @@ std::pair<bool, Expr*> NameMatcher::walkToExprPre(Expr *E) {
440440
break;
441441
case KeyPathExpr::Component::Kind::DictionaryKey:
442442
case KeyPathExpr::Component::Kind::Invalid:
443-
case KeyPathExpr::Component::Kind::CodeCompletion:
444443
break;
445444
case KeyPathExpr::Component::Kind::OptionalForce:
446445
case KeyPathExpr::Component::Kind::OptionalChain:

lib/Parse/ParseExpr.cpp

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -659,26 +659,21 @@ ParserResult<Expr> Parser::parseExprKeyPath() {
659659
if (rootResult.isNull() && pathResult.isNull())
660660
return nullptr;
661661

662+
auto keypath =
663+
new (Context) KeyPathExpr(backslashLoc, rootResult.getPtrOrNull(),
664+
pathResult.getPtrOrNull(), hasLeadingDot);
665+
662666
// Handle code completion.
663667
if ((Tok.is(tok::code_complete) && !Tok.isAtStartOfLine()) ||
664668
(Tok.is(tok::period) && peekToken().isAny(tok::code_complete))) {
665669
SourceLoc DotLoc;
666670
consumeIf(tok::period, DotLoc);
667-
668-
// Add the code completion expression to the path result.
669-
CodeCompletionExpr *CC = new (Context)
670-
CodeCompletionExpr(pathResult.getPtrOrNull(), Tok.getLoc());
671-
auto keypath = new (Context)
672-
KeyPathExpr(backslashLoc, rootResult.getPtrOrNull(), CC, hasLeadingDot);
673671
if (CodeCompletion)
674672
CodeCompletion->completeExprKeyPath(keypath, DotLoc);
675673
consumeToken(tok::code_complete);
676674
return makeParserCodeCompletionResult(keypath);
677675
}
678676

679-
auto keypath =
680-
new (Context) KeyPathExpr(backslashLoc, rootResult.getPtrOrNull(),
681-
pathResult.getPtrOrNull(), hasLeadingDot);
682677
return makeParserResult(parseStatus, keypath);
683678
}
684679

lib/SILGen/SILGenExpr.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3736,7 +3736,6 @@ RValue RValueEmitter::visitKeyPathExpr(KeyPathExpr *E, SGFContext C) {
37363736
case KeyPathExpr::Component::Kind::Invalid:
37373737
case KeyPathExpr::Component::Kind::UnresolvedProperty:
37383738
case KeyPathExpr::Component::Kind::UnresolvedSubscript:
3739-
case KeyPathExpr::Component::Kind::CodeCompletion:
37403739
llvm_unreachable("not resolved");
37413740
break;
37423741

lib/Sema/CSApply.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,6 @@ static bool buildObjCKeyPathString(KeyPathExpr *E,
377377
case KeyPathExpr::Component::Kind::Invalid:
378378
case KeyPathExpr::Component::Kind::UnresolvedProperty:
379379
case KeyPathExpr::Component::Kind::UnresolvedSubscript:
380-
case KeyPathExpr::Component::Kind::CodeCompletion:
381380
// Don't bother building the key path string if the key path didn't even
382381
// resolve.
383382
return false;
@@ -4939,8 +4938,7 @@ namespace {
49394938
}
49404939
break;
49414940
}
4942-
case KeyPathExpr::Component::Kind::Invalid:
4943-
case KeyPathExpr::Component::Kind::CodeCompletion: {
4941+
case KeyPathExpr::Component::Kind::Invalid: {
49444942
auto component = origComponent;
49454943
component.setComponentType(leafTy);
49464944
resolvedComponents.push_back(component);

lib/Sema/CSGen.cpp

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3122,7 +3122,6 @@ namespace {
31223122
if (!rootObjectTy || rootObjectTy->hasError())
31233123
return Type();
31243124

3125-
CS.setType(rootRepr, rootObjectTy);
31263125
// Allow \Derived.property to be inferred as \Base.property to
31273126
// simulate a sort of covariant conversion from
31283127
// KeyPath<Derived, T> to KeyPath<Base, T>.
@@ -3144,13 +3143,7 @@ namespace {
31443143
switch (auto kind = component.getKind()) {
31453144
case KeyPathExpr::Component::Kind::Invalid:
31463145
break;
3147-
case KeyPathExpr::Component::Kind::CodeCompletion:
3148-
// We don't know what the code completion might resolve to, so we are
3149-
// creating a new type variable for its result, which might be a hole.
3150-
base = CS.createTypeVariable(
3151-
resultLocator,
3152-
TVO_CanBindToLValue | TVO_CanBindToNoEscape | TVO_CanBindToHole);
3153-
break;
3146+
31543147
case KeyPathExpr::Component::Kind::UnresolvedProperty:
31553148
// This should only appear in resolved ASTs, but we may need to
31563149
// re-type-check the constraints during failure diagnosis.
@@ -3246,8 +3239,7 @@ namespace {
32463239
// If there was an optional chaining component, the end result must be
32473240
// optional.
32483241
if (didOptionalChain) {
3249-
auto objTy = CS.createTypeVariable(locator, TVO_CanBindToNoEscape |
3250-
TVO_CanBindToHole);
3242+
auto objTy = CS.createTypeVariable(locator, TVO_CanBindToNoEscape);
32513243
componentTypeVars.push_back(objTy);
32523244

32533245
auto optTy = OptionalType::get(objTy);
@@ -3258,8 +3250,8 @@ namespace {
32583250

32593251
auto baseLocator =
32603252
CS.getConstraintLocator(E, ConstraintLocator::KeyPathValue);
3261-
auto rvalueBase = CS.createTypeVariable(
3262-
baseLocator, TVO_CanBindToNoEscape | TVO_CanBindToHole);
3253+
auto rvalueBase = CS.createTypeVariable(baseLocator,
3254+
TVO_CanBindToNoEscape);
32633255
CS.addConstraint(ConstraintKind::Equal, base, rvalueBase, locator);
32643256

32653257
// The result is a KeyPath from the root to the end component.

lib/Sema/CSSimplify.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9511,12 +9511,7 @@ ConstraintSystem::simplifyKeyPathConstraint(
95119511
case KeyPathExpr::Component::Kind::Invalid:
95129512
case KeyPathExpr::Component::Kind::Identity:
95139513
break;
9514-
9515-
case KeyPathExpr::Component::Kind::CodeCompletion: {
9516-
anyComponentsUnresolved = true;
9517-
capability = ReadOnly;
9518-
break;
9519-
}
9514+
95209515
case KeyPathExpr::Component::Kind::Property:
95219516
case KeyPathExpr::Component::Kind::Subscript:
95229517
case KeyPathExpr::Component::Kind::UnresolvedProperty:

0 commit comments

Comments
 (0)