From 4a217d8cdeda2951caf1b91bf67727d1af0906b8 Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Mon, 7 Oct 2013 15:56:00 +0400 Subject: [PATCH] Fix invalid usage of descriptorToDeclaration in GotoSuperActionHandler --- .../jet/lang/resolve/BindingContextUtils.java | 36 +++++++++++++++---- .../codeInsight/GotoSuperActionHandler.java | 4 ++- .../navigation/gotoSuper/DelegatedFun.test | 27 ++++++++++++++ .../gotoSuper/DelegatedProperty.test | 29 +++++++++++++++ .../navigation/gotoSuper/FakeOverrideFun.test | 24 +++++++++++++ ...rideFunWithMostRelevantImplementation.test | 28 +++++++++++++++ .../gotoSuper/FakeOverrideProperty.test | 26 ++++++++++++++ .../navigation/JetGotoSuperTestGenerated.java | 25 +++++++++++++ 8 files changed, 192 insertions(+), 7 deletions(-) create mode 100644 idea/testData/navigation/gotoSuper/DelegatedFun.test create mode 100644 idea/testData/navigation/gotoSuper/DelegatedProperty.test create mode 100644 idea/testData/navigation/gotoSuper/FakeOverrideFun.test create mode 100644 idea/testData/navigation/gotoSuper/FakeOverrideFunWithMostRelevantImplementation.test create mode 100644 idea/testData/navigation/gotoSuper/FakeOverrideProperty.test diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContextUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContextUtils.java index 7d57f8dfa16..233fc4122a1 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContextUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContextUtils.java @@ -17,6 +17,7 @@ package org.jetbrains.jet.lang.resolve; import com.google.common.collect.Lists; +import com.google.common.collect.Sets; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; @@ -36,6 +37,7 @@ import org.jetbrains.jet.util.slicedmap.Slices; import java.util.*; +import static org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor.Kind.*; import static org.jetbrains.jet.lang.diagnostics.Errors.AMBIGUOUS_LABEL; import static org.jetbrains.jet.lang.resolve.BindingContext.AMBIGUOUS_LABEL_TARGET; import static org.jetbrains.jet.lang.resolve.BindingContext.DECLARATION_TO_DESCRIPTOR; @@ -49,7 +51,7 @@ public class BindingContextUtils { public DeclarationDescriptor normalize(DeclarationDescriptor declarationDescriptor) { if (declarationDescriptor instanceof CallableMemberDescriptor) { CallableMemberDescriptor callable = (CallableMemberDescriptor) declarationDescriptor; - if (callable.getKind() != CallableMemberDescriptor.Kind.DECLARATION) { + if (callable.getKind() != DECLARATION) { throw new IllegalStateException("non-declaration descriptors should be filtered out earlier: " + callable); } } @@ -169,7 +171,7 @@ public class BindingContextUtils { @Nullable public static PsiElement callableDescriptorToDeclaration(@NotNull BindingContext context, @NotNull CallableMemberDescriptor callable) { - if (callable.getKind() == CallableMemberDescriptor.Kind.SYNTHESIZED) { + if (callable.getKind() == SYNTHESIZED) { CallableMemberDescriptor original = callable.getOriginal(); if (original instanceof SynthesizedCallableMemberDescriptor) { DeclarationDescriptor base = ((SynthesizedCallableMemberDescriptor) original).getBaseForSynthesized(); @@ -178,7 +180,7 @@ public class BindingContextUtils { return null; } - if (callable.getKind() == CallableMemberDescriptor.Kind.DECLARATION) { + if (callable.getKind() == DECLARATION) { return doGetDescriptorToDeclaration(context, callable.getOriginal()); } @@ -194,7 +196,7 @@ public class BindingContextUtils { @NotNull private static List callableDescriptorToDeclarations(@NotNull BindingContext context, @NotNull CallableMemberDescriptor callable) { - if (callable.getKind() == CallableMemberDescriptor.Kind.SYNTHESIZED) { + if (callable.getKind() == SYNTHESIZED) { CallableMemberDescriptor original = callable.getOriginal(); if (original instanceof SynthesizedCallableMemberDescriptor) { DeclarationDescriptor base = ((SynthesizedCallableMemberDescriptor) original).getBaseForSynthesized(); @@ -203,7 +205,7 @@ public class BindingContextUtils { return Collections.emptyList(); } - if (callable.getKind() == CallableMemberDescriptor.Kind.DECLARATION) { + if (callable.getKind() == DECLARATION) { PsiElement psiElement = doGetDescriptorToDeclaration(context, callable); return psiElement != null ? Lists.newArrayList(psiElement) : Lists.newArrayList(); } @@ -224,7 +226,7 @@ public class BindingContextUtils { public static void recordFunctionDeclarationToDescriptor(@NotNull BindingTrace trace, @NotNull PsiElement psiElement, @NotNull SimpleFunctionDescriptor function) { - if (function.getKind() != CallableMemberDescriptor.Kind.DECLARATION) { + if (function.getKind() != DECLARATION) { throw new IllegalArgumentException("function of kind " + function.getKind() + " cannot have declaration"); } @@ -333,4 +335,26 @@ public class BindingContextUtils { } return false; } + + @NotNull + public static Set getDirectlyOverriddenDeclarations(@NotNull CallableMemberDescriptor descriptor) { + Set result = Sets.newHashSet(); + Set overriddenDescriptors = descriptor.getOverriddenDescriptors(); + for (CallableMemberDescriptor overriddenDescriptor : overriddenDescriptors) { + CallableMemberDescriptor.Kind kind = overriddenDescriptor.getKind(); + if (kind == DECLARATION) { + result.add(overriddenDescriptor); + } + else if (kind == FAKE_OVERRIDE || kind == DELEGATION) { + result.addAll(getDirectlyOverriddenDeclarations(overriddenDescriptor)); + } + else if (kind == SYNTHESIZED) { + //do nothing + } + else { + throw new AssertionError("Unexpected callable kind " + kind); + } + } + return OverridingUtil.filterOverrides(result); + } } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/GotoSuperActionHandler.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/GotoSuperActionHandler.java index e10432a69b5..077e33c4acb 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/GotoSuperActionHandler.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/GotoSuperActionHandler.java @@ -44,6 +44,8 @@ import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; import java.util.Collection; import java.util.List; +import static org.jetbrains.jet.lang.resolve.BindingContextUtils.getDirectlyOverriddenDeclarations; + public class GotoSuperActionHandler implements CodeInsightActionHandler { @Override public void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) { @@ -82,7 +84,7 @@ public class GotoSuperActionHandler implements CodeInsightActionHandler { message = JetBundle.message("goto.super.class.chooser.title"); } else if (descriptor instanceof CallableMemberDescriptor) { - superDescriptors = ((CallableMemberDescriptor) descriptor).getOverriddenDescriptors(); + superDescriptors = getDirectlyOverriddenDeclarations((CallableMemberDescriptor) descriptor); if (descriptor instanceof PropertyDescriptor) { message = JetBundle.message("goto.super.property.chooser.title"); } diff --git a/idea/testData/navigation/gotoSuper/DelegatedFun.test b/idea/testData/navigation/gotoSuper/DelegatedFun.test new file mode 100644 index 00000000000..34446d6ebd2 --- /dev/null +++ b/idea/testData/navigation/gotoSuper/DelegatedFun.test @@ -0,0 +1,27 @@ +// FILE: before.kt +trait A { + fun f() {} +} + +trait B : A + +open class C(b : B) : B by b, A { +} + +class D(b : B) : C(b) { + override fun f() {} +} + +// FILE: after.kt +trait A { + fun f() {} +} + +trait B : A + +open class C(b : B) : B by b, A { +} + +class D(b : B) : C(b) { + override fun f() {} +} diff --git a/idea/testData/navigation/gotoSuper/DelegatedProperty.test b/idea/testData/navigation/gotoSuper/DelegatedProperty.test new file mode 100644 index 00000000000..31b9ec75f24 --- /dev/null +++ b/idea/testData/navigation/gotoSuper/DelegatedProperty.test @@ -0,0 +1,29 @@ +// FILE: before.kt +trait A { + val f: Int + get() = 3 +} + +trait B : A + +open class C(b : B) : B by b, A { +} + +class D(b : B) : C(b) { + override val f: Int = 2 +} + +// FILE: after.kt +trait A { + val f: Int + get() = 3 +} + +trait B : A + +open class C(b : B) : B by b, A { +} + +class D(b : B) : C(b) { + override val f: Int = 2 +} \ No newline at end of file diff --git a/idea/testData/navigation/gotoSuper/FakeOverrideFun.test b/idea/testData/navigation/gotoSuper/FakeOverrideFun.test new file mode 100644 index 00000000000..42d689e87d0 --- /dev/null +++ b/idea/testData/navigation/gotoSuper/FakeOverrideFun.test @@ -0,0 +1,24 @@ +// FILE: before.kt +trait A { + fun f() {} +} + +trait B : A + +trait C : B, A + +class SomeClass() : C { + override fun f() {} +} +// FILE: after.kt +trait A { + fun f() {} +} + +trait B : A + +trait C : B, A + +class SomeClass() : C { + override fun f() {} +} \ No newline at end of file diff --git a/idea/testData/navigation/gotoSuper/FakeOverrideFunWithMostRelevantImplementation.test b/idea/testData/navigation/gotoSuper/FakeOverrideFunWithMostRelevantImplementation.test new file mode 100644 index 00000000000..11a4b60625a --- /dev/null +++ b/idea/testData/navigation/gotoSuper/FakeOverrideFunWithMostRelevantImplementation.test @@ -0,0 +1,28 @@ +// FILE: before.kt +trait A { + fun f() {} +} + +trait B : A { + override fun f() {} +} + +trait C : B, A + +class SomeClass() : C { + override fun f() {} +} +// FILE: after.kt +trait A { + fun f() {} +} + +trait B : A { + override fun f() {} +} + +trait C : B, A + +class SomeClass() : C { + override fun f() {} +} \ No newline at end of file diff --git a/idea/testData/navigation/gotoSuper/FakeOverrideProperty.test b/idea/testData/navigation/gotoSuper/FakeOverrideProperty.test new file mode 100644 index 00000000000..8212da6fb02 --- /dev/null +++ b/idea/testData/navigation/gotoSuper/FakeOverrideProperty.test @@ -0,0 +1,26 @@ +// FILE: before.kt +trait A { + val f: Int + get() = 2 +} + +trait B : A + +trait C : B, A + +class SomeClass() : C { + override val f: Int = 4 +} +// FILE: after.kt +trait A { + val f: Int + get() = 2 +} + +trait B : A + +trait C : B, A + +class SomeClass() : C { + override val f: Int = 4 +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/navigation/JetGotoSuperTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/navigation/JetGotoSuperTestGenerated.java index f02b35b2d66..94d0cd7449f 100644 --- a/idea/tests/org/jetbrains/jet/plugin/navigation/JetGotoSuperTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/navigation/JetGotoSuperTestGenerated.java @@ -41,6 +41,31 @@ public class JetGotoSuperTestGenerated extends JetAbstractGotoSuperTest { doTest("idea/testData/navigation/gotoSuper/ClassSimple.test"); } + @TestMetadata("DelegatedFun.test") + public void testDelegatedFun() throws Exception { + doTest("idea/testData/navigation/gotoSuper/DelegatedFun.test"); + } + + @TestMetadata("DelegatedProperty.test") + public void testDelegatedProperty() throws Exception { + doTest("idea/testData/navigation/gotoSuper/DelegatedProperty.test"); + } + + @TestMetadata("FakeOverrideFun.test") + public void testFakeOverrideFun() throws Exception { + doTest("idea/testData/navigation/gotoSuper/FakeOverrideFun.test"); + } + + @TestMetadata("FakeOverrideFunWithMostRelevantImplementation.test") + public void testFakeOverrideFunWithMostRelevantImplementation() throws Exception { + doTest("idea/testData/navigation/gotoSuper/FakeOverrideFunWithMostRelevantImplementation.test"); + } + + @TestMetadata("FakeOverrideProperty.test") + public void testFakeOverrideProperty() throws Exception { + doTest("idea/testData/navigation/gotoSuper/FakeOverrideProperty.test"); + } + @TestMetadata("FunctionSimple.test") public void testFunctionSimple() throws Exception { doTest("idea/testData/navigation/gotoSuper/FunctionSimple.test");