diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/referenceUtil.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/referenceUtil.kt index aa82bd3c958..1c8bbe8c31b 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/referenceUtil.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/references/referenceUtil.kt @@ -79,7 +79,7 @@ public fun PsiReference.matchesTarget(candidateTarget: PsiElement): Boolean { } } // TODO: Workaround for Kotlin constructor search in Java code. To be removed after refactoring of the search API - else if (this is PsiJavaCodeReferenceElement && unwrappedCandidate is JetSecondaryConstructor) { + else if (this is PsiJavaCodeReferenceElement && unwrappedCandidate is JetConstructor<*>) { var parent = getElement().getParent() if (parent is PsiAnonymousClass) { parent = parent.getParent() @@ -104,7 +104,7 @@ private fun PsiElement.isConstructorOf(unwrappedCandidate: PsiElement) = // call to Java constructor (this is PsiMethod && isConstructor() && getContainingClass() == unwrappedCandidate) || // call to Kotlin constructor - (this is JetSecondaryConstructor && getStrictParentOfType() == unwrappedCandidate) + (this is JetConstructor<*> && getClassOrObject() == unwrappedCandidate) fun AbstractJetReference.renameImplicitConventionalCall(newName: String?): JetExpression { if (newName == null) return expression diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/utils.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/utils.kt index 8440b875903..6887a3f2ce3 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/utils.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/search/usagesSearch/utils.kt @@ -86,7 +86,8 @@ fun PsiReference.isConstructorUsage(jetClassOrObject: JetClassOrObject): Boolean val descriptor = getConstructorCallDescriptor() if (descriptor !is ConstructorDescriptor) return false - return DescriptorToSourceUtils.descriptorToDeclaration(descriptor.getContainingDeclaration()) == jetClassOrObject + val declaration = DescriptorToSourceUtils.descriptorToDeclaration(descriptor.getContainingDeclaration()) + return declaration == jetClassOrObject || (declaration is JetConstructor<*> && declaration.getClassOrObject() == jetClassOrObject) } checkJavaUsage() || checkKotlinUsage() @@ -118,7 +119,7 @@ public fun PsiElement.processDelegationCallConstructorUsages(scope: SearchScope, private fun PsiElement.processDelegationCallKotlinConstructorUsages(scope: SearchScope, process: (JetConstructorDelegationCall) -> Unit) { val element = unwrapped val klass = when (element) { - is JetSecondaryConstructor -> element.getClassOrObject() + is JetConstructor<*> -> element.getClassOrObject() is JetClass -> element else -> return } diff --git a/idea/src/org/jetbrains/kotlin/idea/findUsages/KotlinFindUsagesHandlerFactory.kt b/idea/src/org/jetbrains/kotlin/idea/findUsages/KotlinFindUsagesHandlerFactory.kt index e55fc55928a..85110ddf11b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/findUsages/KotlinFindUsagesHandlerFactory.kt +++ b/idea/src/org/jetbrains/kotlin/idea/findUsages/KotlinFindUsagesHandlerFactory.kt @@ -46,14 +46,14 @@ public class KotlinFindUsagesHandlerFactory(project: Project) : FindUsagesHandle element is JetProperty || element is JetParameter || element is JetTypeParameter || - element is JetSecondaryConstructor + element is JetConstructor<*> public override fun createFindUsagesHandler(element: PsiElement, forHighlightUsages: Boolean): FindUsagesHandler? { val handler = when (element) { is JetClassOrObject -> KotlinFindClassUsagesHandler(element, this) - is JetNamedFunction, is JetProperty, is JetParameter, is JetSecondaryConstructor -> { + is JetNamedFunction, is JetProperty, is JetParameter, is JetConstructor<*> -> { val declaration = element as JetNamedDeclaration if (forHighlightUsages) return KotlinFindMemberUsagesHandler.getInstance(declaration, this) diff --git a/idea/src/org/jetbrains/kotlin/idea/findUsages/handlers/KotlinFindMemberUsagesHandler.java b/idea/src/org/jetbrains/kotlin/idea/findUsages/handlers/KotlinFindMemberUsagesHandler.java index 1fb3f39cda7..6467533fe7d 100644 --- a/idea/src/org/jetbrains/kotlin/idea/findUsages/handlers/KotlinFindMemberUsagesHandler.java +++ b/idea/src/org/jetbrains/kotlin/idea/findUsages/handlers/KotlinFindMemberUsagesHandler.java @@ -123,7 +123,7 @@ public abstract class KotlinFindMemberUsagesHandler getSearchHelper(KotlinCallableFindUsagesOptions options); private static Iterable getLightMethods(JetNamedDeclaration element) { - if (element instanceof JetNamedFunction || element instanceof JetSecondaryConstructor) { + if (element instanceof JetFunction) { PsiMethod method = LightClassUtil.getLightClassMethod((JetFunction) element); return method != null ? Collections.singletonList(method) : Collections.emptyList(); } @@ -163,7 +163,7 @@ public abstract class KotlinFindMemberUsagesHandler()?.getTextOffset() == offset + } } diff --git a/idea/testData/findUsages/java/findConstructorUsages/primaryConstructorByJavaRef.0.java b/idea/testData/findUsages/java/findConstructorUsages/primaryConstructorByJavaRef.0.java new file mode 100644 index 00000000000..37762d4b380 --- /dev/null +++ b/idea/testData/findUsages/java/findConstructorUsages/primaryConstructorByJavaRef.0.java @@ -0,0 +1,14 @@ +// PSI_ELEMENT: com.intellij.psi.PsiMethod +// OPTIONS: usages +// FIND_BY_REF +// WITH_FILE_NAME +class J extends A { + constructor(n: Int) { + super(n); + } + + static void test() { + new A(); + new A(1); + } +} \ No newline at end of file diff --git a/idea/testData/findUsages/java/findConstructorUsages/primaryConstructorByJavaRef.1.kt b/idea/testData/findUsages/java/findConstructorUsages/primaryConstructorByJavaRef.1.kt new file mode 100644 index 00000000000..4ba9192ca89 --- /dev/null +++ b/idea/testData/findUsages/java/findConstructorUsages/primaryConstructorByJavaRef.1.kt @@ -0,0 +1,14 @@ +open class A (n: Int) { + constructor(): this(1) +} + +class B: A { + constructor(n: Int): super(n) +} + +class C(): A(1) + +fun test() { + A() + A(1) +} \ No newline at end of file diff --git a/idea/testData/findUsages/java/findConstructorUsages/primaryConstructorByJavaRef.results.txt b/idea/testData/findUsages/java/findConstructorUsages/primaryConstructorByJavaRef.results.txt new file mode 100644 index 00000000000..3ce30d86ebe --- /dev/null +++ b/idea/testData/findUsages/java/findConstructorUsages/primaryConstructorByJavaRef.results.txt @@ -0,0 +1,6 @@ +[primaryConstructorByJavaRef.0.java] New instance creation (12: 13) new A(1); +[primaryConstructorByJavaRef.0.java] Unclassified usage (7: 9) super(n); +[primaryConstructorByJavaRef.1.kt] New instance creation (13: 5) A(1) +[primaryConstructorByJavaRef.1.kt] Supertype (9: 12) class C(): A(1) +[primaryConstructorByJavaRef.1.kt] Unclassified usage (2: 20) constructor(): this(1) +[primaryConstructorByJavaRef.1.kt] Unclassified usage (6: 26) constructor(n: Int): super(n) \ No newline at end of file diff --git a/idea/testData/findUsages/java/findConstructorUsages/primaryConstructorByJavaSuperRef.0.java b/idea/testData/findUsages/java/findConstructorUsages/primaryConstructorByJavaSuperRef.0.java new file mode 100644 index 00000000000..0836bd2004a --- /dev/null +++ b/idea/testData/findUsages/java/findConstructorUsages/primaryConstructorByJavaSuperRef.0.java @@ -0,0 +1,14 @@ +// PSI_ELEMENT: com.intellij.psi.PsiMethod +// OPTIONS: usages +// FIND_BY_REF +// WITH_FILE_NAME +class J extends A { + constructor(n: Int) { + super(n); + } + + static void test() { + new A(); + new A(1); + } +} \ No newline at end of file diff --git a/idea/testData/findUsages/java/findConstructorUsages/primaryConstructorByJavaSuperRef.1.kt b/idea/testData/findUsages/java/findConstructorUsages/primaryConstructorByJavaSuperRef.1.kt new file mode 100644 index 00000000000..4ba9192ca89 --- /dev/null +++ b/idea/testData/findUsages/java/findConstructorUsages/primaryConstructorByJavaSuperRef.1.kt @@ -0,0 +1,14 @@ +open class A (n: Int) { + constructor(): this(1) +} + +class B: A { + constructor(n: Int): super(n) +} + +class C(): A(1) + +fun test() { + A() + A(1) +} \ No newline at end of file diff --git a/idea/testData/findUsages/java/findConstructorUsages/primaryConstructorByJavaSuperRef.results.txt b/idea/testData/findUsages/java/findConstructorUsages/primaryConstructorByJavaSuperRef.results.txt new file mode 100644 index 00000000000..2bdabd17969 --- /dev/null +++ b/idea/testData/findUsages/java/findConstructorUsages/primaryConstructorByJavaSuperRef.results.txt @@ -0,0 +1,6 @@ +[primaryConstructorByJavaSuperRef.0.java] New instance creation (12: 13) new A(1); +[primaryConstructorByJavaSuperRef.0.java] Unclassified usage (7: 9) super(n); +[primaryConstructorByJavaSuperRef.1.kt] New instance creation (13: 5) A(1) +[primaryConstructorByJavaSuperRef.1.kt] Supertype (9: 12) class C(): A(1) +[primaryConstructorByJavaSuperRef.1.kt] Unclassified usage (2: 20) constructor(): this(1) +[primaryConstructorByJavaSuperRef.1.kt] Unclassified usage (6: 26) constructor(n: Int): super(n) \ No newline at end of file diff --git a/idea/testData/findUsages/kotlin/findPrimaryConstructorUsages/primaryConstructorByRef.0.kt b/idea/testData/findUsages/kotlin/findPrimaryConstructorUsages/primaryConstructorByRef.0.kt new file mode 100644 index 00000000000..3f0b1f6384f --- /dev/null +++ b/idea/testData/findUsages/kotlin/findPrimaryConstructorUsages/primaryConstructorByRef.0.kt @@ -0,0 +1,17 @@ +// PSI_ELEMENT: org.jetbrains.kotlin.psi.JetPrimaryConstructor +// OPTIONS: usages +// FIND_BY_REF +open class A (n: Int) { + constructor(): this(1) +} + +class B: A { + constructor(n: Int): super(n) +} + +class C(): A(1) + +fun test() { + A() + A(1) +} \ No newline at end of file diff --git a/idea/testData/findUsages/kotlin/findPrimaryConstructorUsages/primaryConstructorByRef.results.txt b/idea/testData/findUsages/kotlin/findPrimaryConstructorUsages/primaryConstructorByRef.results.txt new file mode 100644 index 00000000000..526995a8283 --- /dev/null +++ b/idea/testData/findUsages/kotlin/findPrimaryConstructorUsages/primaryConstructorByRef.results.txt @@ -0,0 +1,4 @@ +New instance creation (16: 5) A(1) +Supertype (12: 12) class C(): A(1) +Unclassified usage (5: 20) constructor(): this(1) +Unclassified usage (9: 26) constructor(n: Int): super(n) \ No newline at end of file diff --git a/idea/testData/findUsages/kotlin/findPrimaryConstructorUsages/primaryConstructorNoKeyword.0.kt b/idea/testData/findUsages/kotlin/findPrimaryConstructorUsages/primaryConstructorNoKeyword.0.kt new file mode 100644 index 00000000000..22fe97c3149 --- /dev/null +++ b/idea/testData/findUsages/kotlin/findPrimaryConstructorUsages/primaryConstructorNoKeyword.0.kt @@ -0,0 +1,16 @@ +// PSI_ELEMENT: org.jetbrains.kotlin.psi.JetPrimaryConstructor +// OPTIONS: usages +open class A (n: Int) { + constructor(): this(1) +} + +class B: A { + constructor(n: Int): super(n) +} + +class C(): A(1) + +fun test() { + A() + A(1) +} \ No newline at end of file diff --git a/idea/testData/findUsages/kotlin/findPrimaryConstructorUsages/primaryConstructorNoKeyword.results.txt b/idea/testData/findUsages/kotlin/findPrimaryConstructorUsages/primaryConstructorNoKeyword.results.txt new file mode 100644 index 00000000000..ea2175d571f --- /dev/null +++ b/idea/testData/findUsages/kotlin/findPrimaryConstructorUsages/primaryConstructorNoKeyword.results.txt @@ -0,0 +1,4 @@ +New instance creation (15: 5) A(1) +Supertype (11: 12) class C(): A(1) +Unclassified usage (4: 20) constructor(): this(1) +Unclassified usage (8: 26) constructor(n: Int): super(n) \ No newline at end of file diff --git a/idea/testData/findUsages/kotlin/findPrimaryConstructorUsages/primaryConstructorWithKeyword.0.kt b/idea/testData/findUsages/kotlin/findPrimaryConstructorUsages/primaryConstructorWithKeyword.0.kt new file mode 100644 index 00000000000..67e00ac0e79 --- /dev/null +++ b/idea/testData/findUsages/kotlin/findPrimaryConstructorUsages/primaryConstructorWithKeyword.0.kt @@ -0,0 +1,16 @@ +// PSI_ELEMENT: org.jetbrains.kotlin.psi.JetPrimaryConstructor +// OPTIONS: usages +open class A constructor(n: Int) { + constructor(): this(1) +} + +class B: A { + constructor(n: Int): super(n) +} + +class C(): A(1) + +fun test() { + A() + A(1) +} \ No newline at end of file diff --git a/idea/testData/findUsages/kotlin/findPrimaryConstructorUsages/primaryConstructorWithKeyword.results.txt b/idea/testData/findUsages/kotlin/findPrimaryConstructorUsages/primaryConstructorWithKeyword.results.txt new file mode 100644 index 00000000000..ea2175d571f --- /dev/null +++ b/idea/testData/findUsages/kotlin/findPrimaryConstructorUsages/primaryConstructorWithKeyword.results.txt @@ -0,0 +1,4 @@ +New instance creation (15: 5) A(1) +Supertype (11: 12) class C(): A(1) +Unclassified usage (4: 20) constructor(): this(1) +Unclassified usage (8: 26) constructor(n: Int): super(n) \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/findUsages/JetFindUsagesTestGenerated.java b/idea/tests/org/jetbrains/kotlin/findUsages/JetFindUsagesTestGenerated.java index ad73597e13f..3c17f2ad861 100644 --- a/idea/tests/org/jetbrains/kotlin/findUsages/JetFindUsagesTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/findUsages/JetFindUsagesTestGenerated.java @@ -736,6 +736,33 @@ public class JetFindUsagesTestGenerated extends AbstractJetFindUsagesTest { } } + @TestMetadata("idea/testData/findUsages/kotlin/findPrimaryConstructorUsages") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class FindPrimaryConstructorUsages extends AbstractJetFindUsagesTest { + public void testAllFilesPresentInFindPrimaryConstructorUsages() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/findUsages/kotlin/findPrimaryConstructorUsages"), Pattern.compile("^(.+)\\.0\\.kt$"), true); + } + + @TestMetadata("primaryConstructorByRef.0.kt") + public void testPrimaryConstructorByRef() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/findUsages/kotlin/findPrimaryConstructorUsages/primaryConstructorByRef.0.kt"); + doTest(fileName); + } + + @TestMetadata("primaryConstructorNoKeyword.0.kt") + public void testPrimaryConstructorNoKeyword() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/findUsages/kotlin/findPrimaryConstructorUsages/primaryConstructorNoKeyword.0.kt"); + doTest(fileName); + } + + @TestMetadata("primaryConstructorWithKeyword.0.kt") + public void testPrimaryConstructorWithKeyword() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/findUsages/kotlin/findPrimaryConstructorUsages/primaryConstructorWithKeyword.0.kt"); + doTest(fileName); + } + } + @TestMetadata("idea/testData/findUsages/kotlin/findPropertyUsages") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) @@ -1056,6 +1083,18 @@ public class JetFindUsagesTestGenerated extends AbstractJetFindUsagesTest { doTest(fileName); } + @TestMetadata("primaryConstructorByJavaRef.0.java") + public void testPrimaryConstructorByJavaRef() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/findUsages/java/findConstructorUsages/primaryConstructorByJavaRef.0.java"); + doTest(fileName); + } + + @TestMetadata("primaryConstructorByJavaSuperRef.0.java") + public void testPrimaryConstructorByJavaSuperRef() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/findUsages/java/findConstructorUsages/primaryConstructorByJavaSuperRef.0.java"); + doTest(fileName); + } + @TestMetadata("secondaryConstructorByJavaNewExpression.0.java") public void testSecondaryConstructorByJavaNewExpression() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/findUsages/java/findConstructorUsages/secondaryConstructorByJavaNewExpression.0.java");