[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:
Ben Langmuir
2016-06-21 15:05:41 -07:00
parent 864bb61e93
commit 1c00cd9637
2 changed files with 28 additions and 23 deletions

View File

@@ -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;
} }

View File

@@ -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
}
}