Basic completion within secondary constructors

body and delegation call
This commit is contained in:
Denis Zharkov
2015-02-13 13:05:20 +03:00
parent 7d963e8e07
commit 50c8c6f68b
9 changed files with 130 additions and 8 deletions
@@ -125,7 +125,9 @@ public class BodyResolver {
private void resolveSecondaryConstructors(@NotNull BodiesResolveContext c) { private void resolveSecondaryConstructors(@NotNull BodiesResolveContext c) {
for (Map.Entry<JetSecondaryConstructor, ConstructorDescriptor> entry : c.getSecondaryConstructors().entrySet()) { for (Map.Entry<JetSecondaryConstructor, ConstructorDescriptor> entry : c.getSecondaryConstructors().entrySet()) {
resolveSecondaryConstructorBody(c, entry.getKey(), entry.getValue()); JetScope declaringScope = c.getDeclaringScopes().apply(entry.getKey());
assert declaringScope != null : "Declaring scope should be registered before body resolve";
resolveSecondaryConstructorBody(c, trace, entry.getKey(), entry.getValue(), declaringScope);
} }
if (c.getSecondaryConstructors().isEmpty()) return; if (c.getSecondaryConstructors().isEmpty()) return;
Set<ConstructorDescriptor> visitedConstructors = Sets.newHashSet(); Set<ConstructorDescriptor> visitedConstructors = Sets.newHashSet();
@@ -134,14 +136,13 @@ public class BodyResolver {
} }
} }
private void resolveSecondaryConstructorBody( public void resolveSecondaryConstructorBody(
@NotNull final BodiesResolveContext c, @NotNull final BodiesResolveContext c,
@NotNull final BindingTrace trace,
@NotNull final JetSecondaryConstructor constructor, @NotNull final JetSecondaryConstructor constructor,
@NotNull final ConstructorDescriptor descriptor @NotNull final ConstructorDescriptor descriptor,
@NotNull JetScope bodyDeclaringScope
) { ) {
JetScope bodyDeclaringScope = c.getDeclaringScopes().apply(constructor);
assert bodyDeclaringScope != null : "Declaring scope should be registered before body resolve";
assert descriptor.getContainingDeclaration() instanceof ClassDescriptorWithResolutionScopes assert descriptor.getContainingDeclaration() instanceof ClassDescriptorWithResolutionScopes
: "When resolving body it should be class descriptor with resolution scopes"; : "When resolving body it should be class descriptor with resolution scopes";
@@ -152,7 +153,7 @@ public class BodyResolver {
new Function1<JetScope, Void>() { new Function1<JetScope, Void>() {
@Override @Override
public Void invoke(@NotNull JetScope headerInnerScope) { public Void invoke(@NotNull JetScope headerInnerScope) {
resolveSecondaryConstructorDelegationCall(c, headerInnerScope, constructor, descriptor); resolveSecondaryConstructorDelegationCall(c, trace, headerInnerScope, constructor, descriptor);
return null; return null;
} }
}); });
@@ -160,6 +161,7 @@ public class BodyResolver {
private void resolveSecondaryConstructorDelegationCall( private void resolveSecondaryConstructorDelegationCall(
@NotNull BodiesResolveContext c, @NotNull BodiesResolveContext c,
@NotNull BindingTrace trace,
@NotNull JetScope scope, @NotNull JetScope scope,
@NotNull JetSecondaryConstructor constructor, @NotNull JetSecondaryConstructor constructor,
@NotNull ConstructorDescriptor descriptor @NotNull ConstructorDescriptor descriptor
@@ -77,6 +77,7 @@ public abstract class ElementResolver {
jetElement, jetElement,
JetNamedFunction.class, JetNamedFunction.class,
JetClassInitializer.class, JetClassInitializer.class,
JetSecondaryConstructor.class,
JetProperty.class, JetProperty.class,
JetParameter.class, JetParameter.class,
JetDelegationSpecifierList.class, JetDelegationSpecifierList.class,
@@ -150,6 +151,9 @@ public abstract class ElementResolver {
else if (resolveElement instanceof JetClassInitializer) { else if (resolveElement instanceof JetClassInitializer) {
initializerAdditionalResolve(resolveSession, (JetClassInitializer) resolveElement, trace, file, statementFilter); initializerAdditionalResolve(resolveSession, (JetClassInitializer) resolveElement, trace, file, statementFilter);
} }
else if (resolveElement instanceof JetSecondaryConstructor) {
secondaryConstructorAdditionalResolve(resolveSession, (JetSecondaryConstructor) resolveElement, trace, file, statementFilter);
}
else if (resolveElement instanceof JetProperty) { else if (resolveElement instanceof JetProperty) {
propertyAdditionalResolve(resolveSession, (JetProperty) resolveElement, trace, file, statementFilter); propertyAdditionalResolve(resolveSession, (JetProperty) resolveElement, trace, file, statementFilter);
} }
@@ -405,6 +409,21 @@ public abstract class ElementResolver {
bodyResolver.resolveFunctionBody(createEmptyContext(resolveSession), trace, namedFunction, functionDescriptor, scope); bodyResolver.resolveFunctionBody(createEmptyContext(resolveSession), trace, namedFunction, functionDescriptor, scope);
} }
private void secondaryConstructorAdditionalResolve(
ResolveSession resolveSession,
JetSecondaryConstructor constructor,
BindingTrace trace,
JetFile file,
@NotNull StatementFilter statementFilter
) {
JetScope scope = resolveSession.getScopeProvider().getResolutionScopeForDeclaration(constructor);
ConstructorDescriptor constructorDescriptor = (ConstructorDescriptor) resolveSession.resolveToDescriptor(constructor);
ForceResolveUtil.forceResolveAllContents(constructorDescriptor);
BodyResolver bodyResolver = createBodyResolver(resolveSession, trace, file, statementFilter);
bodyResolver.resolveSecondaryConstructorBody(createEmptyContext(resolveSession), trace, constructor, constructorDescriptor, scope);
}
private void constructorAdditionalResolve( private void constructorAdditionalResolve(
ResolveSession resolveSession, ResolveSession resolveSession,
JetClass klass, JetClass klass,
@@ -68,7 +68,7 @@ object KeywordCompletion {
} }
} }
private val FUNCTION_KEYWORDS = listOf(GET_KEYWORD, SET_KEYWORD) private val FUNCTION_KEYWORDS = listOf(GET_KEYWORD, SET_KEYWORD, CONSTRUCTOR_KEYWORD)
private val GENERAL_FILTER = NotFilter(OrFilter( private val GENERAL_FILTER = NotFilter(OrFilter(
CommentFilter(), CommentFilter(),
@@ -0,0 +1,14 @@
fun topLevel() = 1
class A(val prop: Int, arg: Int) {
val another = 1
constructor(abc: Int): this(1, 2) {
val local = 1
<caret>
}
fun foo() = 1
}
// EXIST: prop, abc, another, foo, local, topLevel
// ABSENT: arg
@@ -0,0 +1,13 @@
fun topLevel() = 1
class A(val prop: Int, arg: Int) {
val another = 1
constructor(abc: Int = <caret>): this(1, 1) {
val local = 1
}
fun foo() = 1
}
// EXIST: topLevel, abc
// ABSENT: arg, local, prop, another, foo
@@ -0,0 +1,13 @@
fun topLevel() = 1
class A(val prop: Int, arg: Int) {
val another = 1
constructor(abc: Int): this(1, <caret>) {
val local = 1
}
fun foo() = 1
}
// EXIST: abc, topLevel
// ABSENT: arg, local, prop, another, foo
@@ -0,0 +1,13 @@
fun topLevel() = 1
class A(val prop: Int, arg: Int) {
val another = 1
constructor(abc: Int, x: Int = <caret>): this(1, 1) {
val local = 1
}
fun foo() = 1
}
// EXIST: abc, topLevel, x
// ABSENT: arg, local, prop, another, foo
@@ -607,6 +607,30 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes
doTest(fileName); doTest(fileName);
} }
@TestMetadata("InSecondaryConstructorBody.kt")
public void testInSecondaryConstructorBody() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/InSecondaryConstructorBody.kt");
doTest(fileName);
}
@TestMetadata("InSecondaryConstructorDefaultParameter.kt")
public void testInSecondaryConstructorDefaultParameter() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/InSecondaryConstructorDefaultParameter.kt");
doTest(fileName);
}
@TestMetadata("InSecondaryConstructorDelegationCall.kt")
public void testInSecondaryConstructorDelegationCall() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/InSecondaryConstructorDelegationCall.kt");
doTest(fileName);
}
@TestMetadata("InSecondaryConstructorFirstDefaultParameter.kt")
public void testInSecondaryConstructorFirstDefaultParameter() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/InSecondaryConstructorFirstDefaultParameter.kt");
doTest(fileName);
}
@TestMetadata("InTypeAnnotation.kt") @TestMetadata("InTypeAnnotation.kt")
public void testInTypeAnnotation() throws Exception { public void testInTypeAnnotation() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/InTypeAnnotation.kt"); String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/InTypeAnnotation.kt");
@@ -607,6 +607,30 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT
doTest(fileName); doTest(fileName);
} }
@TestMetadata("InSecondaryConstructorBody.kt")
public void testInSecondaryConstructorBody() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/InSecondaryConstructorBody.kt");
doTest(fileName);
}
@TestMetadata("InSecondaryConstructorDefaultParameter.kt")
public void testInSecondaryConstructorDefaultParameter() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/InSecondaryConstructorDefaultParameter.kt");
doTest(fileName);
}
@TestMetadata("InSecondaryConstructorDelegationCall.kt")
public void testInSecondaryConstructorDelegationCall() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/InSecondaryConstructorDelegationCall.kt");
doTest(fileName);
}
@TestMetadata("InSecondaryConstructorFirstDefaultParameter.kt")
public void testInSecondaryConstructorFirstDefaultParameter() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/InSecondaryConstructorFirstDefaultParameter.kt");
doTest(fileName);
}
@TestMetadata("InTypeAnnotation.kt") @TestMetadata("InTypeAnnotation.kt")
public void testInTypeAnnotation() throws Exception { public void testInTypeAnnotation() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/InTypeAnnotation.kt"); String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/InTypeAnnotation.kt");