Fix invalid usage of descriptorToDeclaration in GotoSuperActionHandler

This commit is contained in:
Pavel V. Talanov
2013-10-07 15:56:00 +04:00
parent 3aeb565a60
commit 4a217d8cde
8 changed files with 192 additions and 7 deletions
@@ -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<PsiElement> 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.<PsiElement>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<CallableMemberDescriptor> getDirectlyOverriddenDeclarations(@NotNull CallableMemberDescriptor descriptor) {
Set<CallableMemberDescriptor> result = Sets.newHashSet();
Set<? extends CallableMemberDescriptor> 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);
}
}
@@ -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");
}
@@ -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 <caret>f() {}
}
// FILE: after.kt
trait A {
fun <caret>f() {}
}
trait B : A
open class C(b : B) : B by b, A {
}
class D(b : B) : C(b) {
override fun f() {}
}
@@ -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 <caret>f: Int = 2
}
// FILE: after.kt
trait A {
val <caret>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
}
@@ -0,0 +1,24 @@
// FILE: before.kt
trait A {
fun f() {}
}
trait B : A
trait C : B, A
class SomeClass() : C {
override fun <caret>f() {}
}
// FILE: after.kt
trait A {
fun <caret>f() {}
}
trait B : A
trait C : B, A
class SomeClass() : C {
override fun f() {}
}
@@ -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 <caret>f() {}
}
// FILE: after.kt
trait A {
fun f() {}
}
trait B : A {
override fun <caret>f() {}
}
trait C : B, A
class SomeClass() : C {
override fun f() {}
}
@@ -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 <caret>f: Int = 4
}
// FILE: after.kt
trait A {
val <caret>f: Int
get() = 2
}
trait B : A
trait C : B, A
class SomeClass() : C {
override val f: Int = 4
}
@@ -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");