diff --git a/idea/src/org/jetbrains/kotlin/idea/hierarchy/calls/KotlinCallerMethodsTreeStructure.java b/idea/src/org/jetbrains/kotlin/idea/hierarchy/calls/KotlinCallerMethodsTreeStructure.java index 6a7770892e1..5ae8945ba0e 100644 --- a/idea/src/org/jetbrains/kotlin/idea/hierarchy/calls/KotlinCallerMethodsTreeStructure.java +++ b/idea/src/org/jetbrains/kotlin/idea/hierarchy/calls/KotlinCallerMethodsTreeStructure.java @@ -23,6 +23,7 @@ import com.intellij.openapi.application.ReadActionProcessor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; import com.intellij.psi.*; +import com.intellij.psi.impl.light.LightMemberReference; import com.intellij.psi.search.SearchScope; import com.intellij.psi.search.searches.MethodReferencesSearch; import com.intellij.psi.search.searches.ReferencesSearch; @@ -114,7 +115,14 @@ public class KotlinCallerMethodsTreeStructure extends KotlinCallTreeStructure { processPsiMethodCallers(propertyMethods, descriptor, methodToDescriptorMap, searchScope, false); } if (element instanceof JetClassOrObject) { - processJetClassOrObjectCallers((JetClassOrObject) element, descriptor, methodToDescriptorMap, searchScope); + JetPrimaryConstructor constructor = ((JetClassOrObject) element).getPrimaryConstructor(); + if (constructor != null) { + PsiMethod lightMethod = LightClassUtil.getLightClassMethod(constructor); + processPsiMethodCallers(Collections.singleton(lightMethod), descriptor, methodToDescriptorMap, searchScope, false); + } + else { + processJetClassOrObjectCallers((JetClassOrObject) element, descriptor, methodToDescriptorMap, searchScope); + } } Object[] callers = methodToDescriptorMap.values().toArray(new Object[methodToDescriptorMap.size()]); @@ -205,6 +213,11 @@ public class KotlinCallerMethodsTreeStructure extends KotlinCallTreeStructure { return true; } } + else if (ref instanceof LightMemberReference) { + PsiElement refTarget = ref.resolve(); + // Accept implicit superclass constructor reference in Java code + if (!(refTarget instanceof PsiMethod && ((PsiMethod) refTarget).isConstructor())) return true; + } PsiElement refElement = ref.getElement(); if (PsiTreeUtil.getParentOfType(refElement, JetImportDirective.class, true) != null) return true; diff --git a/idea/testData/hierarchy/calls/callers/kotlinPrimaryConstructorImplicitCalls/KotlinPrimaryConstructorImplicitCalls_verification.xml b/idea/testData/hierarchy/calls/callers/kotlinPrimaryConstructorImplicitCalls/KotlinPrimaryConstructorImplicitCalls_verification.xml new file mode 100644 index 00000000000..02133749cb7 --- /dev/null +++ b/idea/testData/hierarchy/calls/callers/kotlinPrimaryConstructorImplicitCalls/KotlinPrimaryConstructorImplicitCalls_verification.xml @@ -0,0 +1,4 @@ + + + + diff --git a/idea/testData/hierarchy/calls/callers/kotlinPrimaryConstructorImplicitCalls/main0.kt b/idea/testData/hierarchy/calls/callers/kotlinPrimaryConstructorImplicitCalls/main0.kt new file mode 100644 index 00000000000..eca85407e5f --- /dev/null +++ b/idea/testData/hierarchy/calls/callers/kotlinPrimaryConstructorImplicitCalls/main0.kt @@ -0,0 +1,7 @@ +open class B() + +open class A : B { + constructor(a: Int) { + + } +} \ No newline at end of file diff --git a/idea/testData/hierarchy/calls/callers/kotlinPrimaryConstructorImplicitCalls/main1.java b/idea/testData/hierarchy/calls/callers/kotlinPrimaryConstructorImplicitCalls/main1.java new file mode 100644 index 00000000000..79760d15bba --- /dev/null +++ b/idea/testData/hierarchy/calls/callers/kotlinPrimaryConstructorImplicitCalls/main1.java @@ -0,0 +1,5 @@ +class JJ extends B { + JJ() { + + } +} \ No newline at end of file diff --git a/idea/testData/hierarchy/calls/callers/kotlinSecondaryConstructorImplicitCalls/KotlinSecondaryConstructorImplicitCalls_verification.xml b/idea/testData/hierarchy/calls/callers/kotlinSecondaryConstructorImplicitCalls/KotlinSecondaryConstructorImplicitCalls_verification.xml new file mode 100644 index 00000000000..5178b80ff8d --- /dev/null +++ b/idea/testData/hierarchy/calls/callers/kotlinSecondaryConstructorImplicitCalls/KotlinSecondaryConstructorImplicitCalls_verification.xml @@ -0,0 +1,4 @@ + + + + diff --git a/idea/testData/hierarchy/calls/callers/kotlinSecondaryConstructorImplicitCalls/main0.kt b/idea/testData/hierarchy/calls/callers/kotlinSecondaryConstructorImplicitCalls/main0.kt new file mode 100644 index 00000000000..57a5fdc0aa5 --- /dev/null +++ b/idea/testData/hierarchy/calls/callers/kotlinSecondaryConstructorImplicitCalls/main0.kt @@ -0,0 +1,11 @@ +open class B { + constructor() { + + } +} + +open class A : B { + constructor(a: Int) { + + } +} \ No newline at end of file diff --git a/idea/testData/hierarchy/calls/callers/kotlinSecondaryConstructorImplicitCalls/main1.java b/idea/testData/hierarchy/calls/callers/kotlinSecondaryConstructorImplicitCalls/main1.java new file mode 100644 index 00000000000..79760d15bba --- /dev/null +++ b/idea/testData/hierarchy/calls/callers/kotlinSecondaryConstructorImplicitCalls/main1.java @@ -0,0 +1,5 @@ +class JJ extends B { + JJ() { + + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/hierarchy/HierarchyTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/hierarchy/HierarchyTestGenerated.java index 5ee8df26e60..9822367de34 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/hierarchy/HierarchyTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/hierarchy/HierarchyTestGenerated.java @@ -358,6 +358,12 @@ public class HierarchyTestGenerated extends AbstractHierarchyTest { doCallerHierarchyTest(fileName); } + @TestMetadata("kotlinPrimaryConstructorImplicitCalls") + public void testKotlinPrimaryConstructorImplicitCalls() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/hierarchy/calls/callers/kotlinPrimaryConstructorImplicitCalls/"); + doCallerHierarchyTest(fileName); + } + @TestMetadata("kotlinPrivateClass") public void testKotlinPrivateClass() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/hierarchy/calls/callers/kotlinPrivateClass/"); @@ -388,6 +394,12 @@ public class HierarchyTestGenerated extends AbstractHierarchyTest { doCallerHierarchyTest(fileName); } + @TestMetadata("kotlinSecondaryConstructorImplicitCalls") + public void testKotlinSecondaryConstructorImplicitCalls() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/hierarchy/calls/callers/kotlinSecondaryConstructorImplicitCalls/"); + doCallerHierarchyTest(fileName); + } + @TestMetadata("kotlinUnresolvedFunction") public void testKotlinUnresolvedFunction() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/hierarchy/calls/callers/kotlinUnresolvedFunction/");