Handle fake overrides of members of Any in BuiltInsReferenceResolver

This commit is contained in:
Alexander Udalov
2014-02-05 20:03:59 +04:00
parent 83d2436fb9
commit b8ec50f38c
6 changed files with 55 additions and 11 deletions
@@ -176,6 +176,15 @@ public class BuiltInsReferenceResolver extends AbstractProjectComponent {
@Nullable @Nullable
private DeclarationDescriptor findCurrentDescriptorForMember(@NotNull MemberDescriptor originalDescriptor) { private DeclarationDescriptor findCurrentDescriptorForMember(@NotNull MemberDescriptor originalDescriptor) {
if (originalDescriptor instanceof CallableMemberDescriptor &&
((CallableMemberDescriptor) originalDescriptor).getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
CallableMemberDescriptor descriptor = (CallableMemberDescriptor) originalDescriptor;
while (descriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
descriptor = descriptor.getOverriddenDescriptors().iterator().next();
}
return findCurrentDescriptorForMember(descriptor.getOriginal());
}
DeclarationDescriptor containingDeclaration = findCurrentDescriptor(originalDescriptor.getContainingDeclaration()); DeclarationDescriptor containingDeclaration = findCurrentDescriptor(originalDescriptor.getContainingDeclaration());
JetScope memberScope = getMemberScope(containingDeclaration); JetScope memberScope = getMemberScope(containingDeclaration);
if (memberScope == null) return null; if (memberScope == null) return null;
@@ -220,10 +229,7 @@ public class BuiltInsReferenceResolver extends AbstractProjectComponent {
return Collections.emptyList(); return Collections.emptyList();
} }
DeclarationDescriptor descriptor = declarationDescriptor; DeclarationDescriptor descriptor = findCurrentDescriptor(declarationDescriptor.getOriginal());
descriptor = descriptor.getOriginal();
descriptor = findCurrentDescriptor(descriptor);
if (descriptor != null) { if (descriptor != null) {
return BindingContextUtils.descriptorToDeclarations(bindingContext, descriptor); return BindingContextUtils.descriptorToDeclarations(bindingContext, descriptor);
} }
@@ -9,8 +9,14 @@ class C : Base<String, C, Unit>() {
override fun bar(value: () -> Unit): (String) -> Unit { override fun bar(value: () -> Unit): (String) -> Unit {
return super<Base>.bar(value) return super<Base>.bar(value)
} }
override fun equals(other: Any?): Boolean {
return super<Base>.equals(other)
}
override fun foo(value: C): C { override fun foo(value: C): C {
return super<Base>.foo(value) return super<Base>.foo(value)
} }
override fun hashCode(): Int {
return super<Base>.hashCode()
}
override val method: (String?) -> String = ? override val method: (String?) -> String = ?
} }
@@ -12,6 +12,12 @@ trait B {
class C : A(), B { class C : A(), B {
override fun equals(other: Any?): Boolean {
return super<A>.equals(other)
}
override fun hashCode(): Int {
return super<A>.hashCode()
}
override fun internalFun() { override fun internalFun() {
super<A>.internalFun() super<A>.internalFun()
} }
@@ -8,7 +8,13 @@ class C : A {
override fun bar(): String { override fun bar(): String {
return super<A>.bar() return super<A>.bar()
} }
override fun equals(other: Any?): Boolean {
return super<A>.equals(other)
}
override fun foo(value: String): Int { override fun foo(value: String): Int {
return super<A>.foo(value) return super<A>.foo(value)
} }
override fun hashCode(): Int {
return super<A>.hashCode()
}
} }
@@ -7,9 +7,15 @@ class C : A() {
val constant = 42 val constant = 42
// Some comment // Some comment
override val bar: Int = 0 override val bar: Int = 0
override fun equals(other: Any?): Boolean {
return super<A>.equals(other)
}
override fun foo(value: Int) { override fun foo(value: Int) {
super<A>.foo(value) super<A>.foo(value)
} }
override fun hashCode(): Int {
return super<A>.hashCode()
}
/* /*
Some another comment Some another comment
@@ -18,7 +18,6 @@ package org.jetbrains.jet.plugin.codeInsight;
import com.intellij.codeInsight.generation.OverrideImplementUtil; import com.intellij.codeInsight.generation.OverrideImplementUtil;
import com.intellij.codeInsight.generation.PsiMethodMember; import com.intellij.codeInsight.generation.PsiMethodMember;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.Result; import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.project.Project; import com.intellij.openapi.project.Project;
@@ -29,21 +28,23 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.testFramework.LightProjectDescriptor; import com.intellij.testFramework.LightProjectDescriptor;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
import com.intellij.util.SmartList; import com.intellij.util.SmartList;
import jet.Function1;
import junit.framework.Assert; import junit.framework.Assert;
import kotlin.KotlinPackage;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor; import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.psi.JetClassOrObject; import org.jetbrains.jet.lang.psi.JetClassOrObject;
import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.OverridingUtil;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.plugin.JetLightProjectDescriptor; import org.jetbrains.jet.plugin.JetLightProjectDescriptor;
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache;
import org.jetbrains.jet.plugin.project.ResolveSessionForBodies; import org.jetbrains.jet.plugin.project.ResolveSessionForBodies;
import java.util.ArrayList; import java.util.*;
import java.util.Collections;
import java.util.Comparator;
import java.util.Set;
public abstract class AbstractOverrideImplementTest extends LightCodeInsightFixtureTestCase { public abstract class AbstractOverrideImplementTest extends LightCodeInsightFixtureTestCase {
@NotNull @NotNull
@@ -128,8 +129,21 @@ public abstract class AbstractOverrideImplementTest extends LightCodeInsightFixt
final CallableMemberDescriptor singleToOverride; final CallableMemberDescriptor singleToOverride;
if (memberToOverride == null) { if (memberToOverride == null) {
assertEquals("Invalid number of available descriptors for override", 1, descriptors.size()); // Filter out fake overrides of members of Any (equals, hashCode, toString)
singleToOverride = descriptors.iterator().next(); List<CallableMemberDescriptor> filtered = KotlinPackage.filter(descriptors, new Function1<CallableMemberDescriptor, Boolean>() {
@Override
public Boolean invoke(CallableMemberDescriptor descriptor) {
ClassDescriptor any = KotlinBuiltIns.getInstance().getAny();
for (CallableMemberDescriptor overridden : OverridingUtil.getOverriddenDeclarations(descriptor)) {
if (overridden.getContainingDeclaration().equals(any)) {
return false;
}
}
return true;
}
});
assertEquals("Invalid number of available descriptors for override", 1, filtered.size());
singleToOverride = filtered.iterator().next();
} }
else { else {
CallableMemberDescriptor candidateToOverride = null; CallableMemberDescriptor candidateToOverride = null;