Fix invalid usage of descriptorToDeclaration in GotoSuperActionHandler
This commit is contained in:
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user