From 50c8c6f68b43d1ef1dd68fb1df114fc5c204d96b Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Fri, 13 Feb 2015 13:05:20 +0300 Subject: [PATCH] Basic completion within secondary constructors body and delegation call --- .../kotlin/resolve/BodyResolver.java | 16 +++++++------ .../kotlin/resolve/lazy/ElementResolver.java | 19 +++++++++++++++ .../idea/completion/KeywordCompletion.kt | 2 +- .../common/InSecondaryConstructorBody.kt | 14 +++++++++++ .../InSecondaryConstructorDefaultParameter.kt | 13 ++++++++++ .../InSecondaryConstructorDelegationCall.kt | 13 ++++++++++ ...condaryConstructorFirstDefaultParameter.kt | 13 ++++++++++ .../JSBasicCompletionTestGenerated.java | 24 +++++++++++++++++++ .../JvmBasicCompletionTestGenerated.java | 24 +++++++++++++++++++ 9 files changed, 130 insertions(+), 8 deletions(-) create mode 100644 idea/testData/completion/basic/common/InSecondaryConstructorBody.kt create mode 100644 idea/testData/completion/basic/common/InSecondaryConstructorDefaultParameter.kt create mode 100644 idea/testData/completion/basic/common/InSecondaryConstructorDelegationCall.kt create mode 100644 idea/testData/completion/basic/common/InSecondaryConstructorFirstDefaultParameter.kt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java index eaf10300f0b..a3e2a3e5d9d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BodyResolver.java @@ -125,7 +125,9 @@ public class BodyResolver { private void resolveSecondaryConstructors(@NotNull BodiesResolveContext c) { for (Map.Entry 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; Set visitedConstructors = Sets.newHashSet(); @@ -134,14 +136,13 @@ public class BodyResolver { } } - private void resolveSecondaryConstructorBody( + public void resolveSecondaryConstructorBody( @NotNull final BodiesResolveContext c, + @NotNull final BindingTrace trace, @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 : "When resolving body it should be class descriptor with resolution scopes"; @@ -152,7 +153,7 @@ public class BodyResolver { new Function1() { @Override public Void invoke(@NotNull JetScope headerInnerScope) { - resolveSecondaryConstructorDelegationCall(c, headerInnerScope, constructor, descriptor); + resolveSecondaryConstructorDelegationCall(c, trace, headerInnerScope, constructor, descriptor); return null; } }); @@ -160,6 +161,7 @@ public class BodyResolver { private void resolveSecondaryConstructorDelegationCall( @NotNull BodiesResolveContext c, + @NotNull BindingTrace trace, @NotNull JetScope scope, @NotNull JetSecondaryConstructor constructor, @NotNull ConstructorDescriptor descriptor diff --git a/idea/ide-common/src/org/jetbrains/kotlin/resolve/lazy/ElementResolver.java b/idea/ide-common/src/org/jetbrains/kotlin/resolve/lazy/ElementResolver.java index 61d8682ad20..a76927eed18 100644 --- a/idea/ide-common/src/org/jetbrains/kotlin/resolve/lazy/ElementResolver.java +++ b/idea/ide-common/src/org/jetbrains/kotlin/resolve/lazy/ElementResolver.java @@ -77,6 +77,7 @@ public abstract class ElementResolver { jetElement, JetNamedFunction.class, JetClassInitializer.class, + JetSecondaryConstructor.class, JetProperty.class, JetParameter.class, JetDelegationSpecifierList.class, @@ -150,6 +151,9 @@ public abstract class ElementResolver { else if (resolveElement instanceof JetClassInitializer) { initializerAdditionalResolve(resolveSession, (JetClassInitializer) resolveElement, trace, file, statementFilter); } + else if (resolveElement instanceof JetSecondaryConstructor) { + secondaryConstructorAdditionalResolve(resolveSession, (JetSecondaryConstructor) resolveElement, trace, file, statementFilter); + } else if (resolveElement instanceof JetProperty) { propertyAdditionalResolve(resolveSession, (JetProperty) resolveElement, trace, file, statementFilter); } @@ -405,6 +409,21 @@ public abstract class ElementResolver { 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( ResolveSession resolveSession, JetClass klass, diff --git a/idea/src/org/jetbrains/kotlin/idea/completion/KeywordCompletion.kt b/idea/src/org/jetbrains/kotlin/idea/completion/KeywordCompletion.kt index a4755ee598b..36d1e04b45b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/completion/KeywordCompletion.kt +++ b/idea/src/org/jetbrains/kotlin/idea/completion/KeywordCompletion.kt @@ -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( CommentFilter(), diff --git a/idea/testData/completion/basic/common/InSecondaryConstructorBody.kt b/idea/testData/completion/basic/common/InSecondaryConstructorBody.kt new file mode 100644 index 00000000000..11213b887fb --- /dev/null +++ b/idea/testData/completion/basic/common/InSecondaryConstructorBody.kt @@ -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 + + } + + fun foo() = 1 +} + +// EXIST: prop, abc, another, foo, local, topLevel +// ABSENT: arg diff --git a/idea/testData/completion/basic/common/InSecondaryConstructorDefaultParameter.kt b/idea/testData/completion/basic/common/InSecondaryConstructorDefaultParameter.kt new file mode 100644 index 00000000000..a10508db80c --- /dev/null +++ b/idea/testData/completion/basic/common/InSecondaryConstructorDefaultParameter.kt @@ -0,0 +1,13 @@ +fun topLevel() = 1 + +class A(val prop: Int, arg: Int) { + val another = 1 + constructor(abc: Int = ): this(1, 1) { + val local = 1 + } + + fun foo() = 1 +} + +// EXIST: topLevel, abc +// ABSENT: arg, local, prop, another, foo diff --git a/idea/testData/completion/basic/common/InSecondaryConstructorDelegationCall.kt b/idea/testData/completion/basic/common/InSecondaryConstructorDelegationCall.kt new file mode 100644 index 00000000000..cd9e406e651 --- /dev/null +++ b/idea/testData/completion/basic/common/InSecondaryConstructorDelegationCall.kt @@ -0,0 +1,13 @@ +fun topLevel() = 1 + +class A(val prop: Int, arg: Int) { + val another = 1 + constructor(abc: Int): this(1, ) { + val local = 1 + } + + fun foo() = 1 +} + +// EXIST: abc, topLevel +// ABSENT: arg, local, prop, another, foo diff --git a/idea/testData/completion/basic/common/InSecondaryConstructorFirstDefaultParameter.kt b/idea/testData/completion/basic/common/InSecondaryConstructorFirstDefaultParameter.kt new file mode 100644 index 00000000000..2240ee6b534 --- /dev/null +++ b/idea/testData/completion/basic/common/InSecondaryConstructorFirstDefaultParameter.kt @@ -0,0 +1,13 @@ +fun topLevel() = 1 + +class A(val prop: Int, arg: Int) { + val another = 1 + constructor(abc: Int, x: Int = ): this(1, 1) { + val local = 1 + } + + fun foo() = 1 +} + +// EXIST: abc, topLevel, x +// ABSENT: arg, local, prop, another, foo diff --git a/idea/tests/org/jetbrains/kotlin/completion/JSBasicCompletionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/completion/JSBasicCompletionTestGenerated.java index 6eecb952e22..a5c228d1aa4 100644 --- a/idea/tests/org/jetbrains/kotlin/completion/JSBasicCompletionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/completion/JSBasicCompletionTestGenerated.java @@ -607,6 +607,30 @@ public class JSBasicCompletionTestGenerated extends AbstractJSBasicCompletionTes 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") public void testInTypeAnnotation() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/InTypeAnnotation.kt"); diff --git a/idea/tests/org/jetbrains/kotlin/completion/JvmBasicCompletionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/completion/JvmBasicCompletionTestGenerated.java index 2299e0a5181..af0ad9c6571 100644 --- a/idea/tests/org/jetbrains/kotlin/completion/JvmBasicCompletionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/completion/JvmBasicCompletionTestGenerated.java @@ -607,6 +607,30 @@ public class JvmBasicCompletionTestGenerated extends AbstractJvmBasicCompletionT 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") public void testInTypeAnnotation() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/completion/basic/common/InTypeAnnotation.kt");