mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[CodeCompletion] Fix dot completion with non-nominals
Completion after dot inside an init (or any other parent expr with a nominal type) was incorrectly looking at the types of parent expressions whenever the base type was not a nominal (even an lvalue of a nominal wasn't working). This code to look at the type of the parent was never correct, and fortunately the type-checking issues that prompted it to be added in the first place have since been fixed, so we can just delete it. rdar://problem/25773358
This commit is contained in:
@@ -4887,37 +4887,17 @@ void CodeCompletionCallbacksImpl::doneParsing() {
|
|||||||
|
|
||||||
case CompletionKind::DotExpr: {
|
case CompletionKind::DotExpr: {
|
||||||
Lookup.setHaveDot(DotLoc);
|
Lookup.setHaveDot(DotLoc);
|
||||||
Type OriginalType = *ExprType;
|
|
||||||
Type ExprType = OriginalType;
|
|
||||||
|
|
||||||
// If there is no nominal type in the expr, try to find nominal types
|
if (isDynamicLookup(*ExprType))
|
||||||
// in the ancestors of the expr.
|
|
||||||
if (!OriginalType->getAnyNominal()) {
|
|
||||||
ExprParentFinder Walker(ParsedExpr, [&](ASTNode Node) {
|
|
||||||
if (auto E = Node.dyn_cast<Expr *>()) {
|
|
||||||
return E->getType() && E->getType()->getAnyNominal();
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
CurDeclContext->walkContext(Walker);
|
|
||||||
if (auto PCE = Walker.ParentClosest.dyn_cast<Expr *>()) {
|
|
||||||
ExprType = PCE->getType();
|
|
||||||
} else {
|
|
||||||
ExprType = OriginalType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isDynamicLookup(ExprType))
|
|
||||||
Lookup.setIsDynamicLookup();
|
Lookup.setIsDynamicLookup();
|
||||||
Lookup.initializeArchetypeTransformer(CurDeclContext, ExprType);
|
Lookup.initializeArchetypeTransformer(CurDeclContext, *ExprType);
|
||||||
|
|
||||||
CodeCompletionTypeContextAnalyzer TypeAnalyzer(CurDeclContext, ParsedExpr);
|
CodeCompletionTypeContextAnalyzer TypeAnalyzer(CurDeclContext, ParsedExpr);
|
||||||
llvm::SmallVector<Type, 2> PossibleTypes;
|
llvm::SmallVector<Type, 2> PossibleTypes;
|
||||||
if (TypeAnalyzer.Analyze(PossibleTypes)) {
|
if (TypeAnalyzer.Analyze(PossibleTypes)) {
|
||||||
Lookup.setExpectedTypes(PossibleTypes);
|
Lookup.setExpectedTypes(PossibleTypes);
|
||||||
}
|
}
|
||||||
Lookup.getValueExprCompletions(ExprType, ReferencedDecl.getDecl());
|
Lookup.getValueExprCompletions(*ExprType, ReferencedDecl.getDecl());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -171,6 +171,8 @@
|
|||||||
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=GENERIC_TYPEALIAS_2 | FileCheck %s -check-prefix=GENERIC_TYPEALIAS_2
|
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=GENERIC_TYPEALIAS_2 | FileCheck %s -check-prefix=GENERIC_TYPEALIAS_2
|
||||||
|
|
||||||
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=DEPRECATED_1 | FileCheck %s -check-prefix=DEPRECATED_1
|
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=DEPRECATED_1 | FileCheck %s -check-prefix=DEPRECATED_1
|
||||||
|
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=DOT_EXPR_NON_NOMINAL_1 | FileCheck %s -check-prefix=DOT_EXPR_NON_NOMINAL_1
|
||||||
|
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=DOT_EXPR_NON_NOMINAL_2 | FileCheck %s -check-prefix=DOT_EXPR_NON_NOMINAL_2
|
||||||
|
|
||||||
// Test code completion of expressions that produce a value.
|
// Test code completion of expressions that produce a value.
|
||||||
|
|
||||||
@@ -1890,3 +1892,26 @@ struct Deprecated {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// DEPRECATED_1: Decl[InstanceMethod]/CurrNominal/NotRecommended: deprecated({#x: Deprecated#})[#Void#];
|
// DEPRECATED_1: Decl[InstanceMethod]/CurrNominal/NotRecommended: deprecated({#x: Deprecated#})[#Void#];
|
||||||
|
|
||||||
|
struct Person {
|
||||||
|
var firstName: String
|
||||||
|
}
|
||||||
|
class Other { var nameFromOther: Int = 1 }
|
||||||
|
class TestDotExprWithNonNominal {
|
||||||
|
var other: Other
|
||||||
|
|
||||||
|
func test1() {
|
||||||
|
let person = Person(firstName: other.#^DOT_EXPR_NON_NOMINAL_1^#)
|
||||||
|
// DOT_EXPR_NON_NOMINAL_1-NOT: Instance
|
||||||
|
// DOT_EXPR_NON_NOMINAL_1: Decl[InstanceVar]/CurrNominal: nameFromOther[#Int#];
|
||||||
|
// DOT_EXPR_NON_NOMINAL_1-NOT: Instance
|
||||||
|
}
|
||||||
|
func test2() {
|
||||||
|
let person = Person(firstName: 1.#^DOT_EXPR_NON_NOMINAL_2^#)
|
||||||
|
// DOT_EXPR_NON_NOMINAL_2-NOT: other
|
||||||
|
// DOT_EXPR_NON_NOMINAL_2-NOT: firstName
|
||||||
|
// DOT_EXPR_NON_NOMINAL_2: Decl[InstanceVar]/CurrNominal: hashValue[#Int#];
|
||||||
|
// DOT_EXPR_NON_NOMINAL_2-NOT: other
|
||||||
|
// DOT_EXPR_NON_NOMINAL_2-NOT: firstName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user