diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java index 92d00b19766..c7d29b0d031 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java @@ -38,7 +38,9 @@ import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl; import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.calls.CallResolverUtil; -import org.jetbrains.jet.lang.resolve.constants.*; +import org.jetbrains.jet.lang.resolve.constants.ArrayValue; +import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; +import org.jetbrains.jet.lang.resolve.constants.JavaClassValue; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.types.JetType; @@ -107,15 +109,6 @@ public class CodegenUtil { return KotlinBuiltIns.getInstance().getAnyType(); } - @NotNull - public static T unwrapFakeOverride(T member) { - while (member.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { - //noinspection unchecked - member = (T) member.getOverriddenDescriptors().iterator().next(); - } - return member; - } - @Nullable public static FunctionDescriptor getDeclaredFunctionByRawSignature( @NotNull ClassDescriptor owner, diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index e8bd90537af..970d37f52aa 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -32,12 +32,12 @@ import org.jetbrains.asm4.MethodVisitor; import org.jetbrains.asm4.Type; import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.asm4.commons.Method; -import org.jetbrains.jet.codegen.inline.InlineCodegen; -import org.jetbrains.jet.codegen.inline.NameGenerator; import org.jetbrains.jet.codegen.binding.CalculatedClosure; import org.jetbrains.jet.codegen.binding.CodegenBinding; import org.jetbrains.jet.codegen.binding.MutableClosure; import org.jetbrains.jet.codegen.context.*; +import org.jetbrains.jet.codegen.inline.InlineCodegen; +import org.jetbrains.jet.codegen.inline.NameGenerator; import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethod; import org.jetbrains.jet.codegen.signature.JvmMethodSignature; import org.jetbrains.jet.codegen.state.GenerationState; @@ -1641,7 +1641,7 @@ public class ExpressionCodegen extends JetVisitor implem descriptor = descriptor.getOriginal(); if (descriptor instanceof CallableMemberDescriptor) { - CallableMemberDescriptor memberDescriptor = unwrapFakeOverride((CallableMemberDescriptor) descriptor); + CallableMemberDescriptor memberDescriptor = DescriptorUtils.unwrapFakeOverride((CallableMemberDescriptor) descriptor); IntrinsicMethod intrinsic = state.getIntrinsics().getIntrinsic(memberDescriptor); if (intrinsic != null) { @@ -1859,7 +1859,7 @@ public class ExpressionCodegen extends JetVisitor implem Type owner; CallableMethod callableMethod = callableGetter != null ? callableGetter : callableSetter; - propertyDescriptor = unwrapFakeOverride(propertyDescriptor); + propertyDescriptor = DescriptorUtils.unwrapFakeOverride(propertyDescriptor); if (callableMethod == null) { owner = typeMapper.getOwner(isBackingFieldInAnotherClass ? propertyDescriptor.getContainingDeclaration() : propertyDescriptor, context.getContextKind(), isCallInsideSameModuleAsDeclared(propertyDescriptor, context)); @@ -2117,7 +2117,7 @@ public class ExpressionCodegen extends JetVisitor implem ((SimpleFunctionDescriptor) descriptor).getInlineStrategy().isInline(); CallGenerator callGenerator = !isInline ? defaulCallGenerator : - new InlineCodegen(this, state, (SimpleFunctionDescriptor) unwrapFakeOverride( + new InlineCodegen(this, state, (SimpleFunctionDescriptor) DescriptorUtils.unwrapFakeOverride( (CallableMemberDescriptor) descriptor.getOriginal()), call); if (resolvedCall instanceof VariableAsFunctionResolvedCall) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java index 4d1ceaf4a4c..a805c4b670c 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java @@ -55,8 +55,7 @@ import static org.jetbrains.jet.codegen.AsmUtil.getTraitImplThisParameterType; import static org.jetbrains.jet.codegen.CodegenUtil.*; import static org.jetbrains.jet.codegen.FunctionTypesUtil.getFunctionTraitClassName; import static org.jetbrains.jet.codegen.binding.CodegenBinding.*; -import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isAnnotationClass; -import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isAnonymousObject; +import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE; public class JetTypeMapper extends BindingTraceAware { diff --git a/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java b/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java index 28c69dc4c66..e85426346b8 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java @@ -469,4 +469,19 @@ public class DescriptorUtils { return isTopLevelDeclaration(descriptor) || containing instanceof ClassDescriptor && isTopLevelOrInnerClass((ClassDescriptor) containing); } + + // This method works correctly because every fake override has a declaration among its ancestors, and no fake override is allowed + // to have two different declarations among its ancestors, none of which is an ancestor of the other + @NotNull + public static D unwrapFakeOverride(@NotNull D descriptor) { + while (descriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { + Set overridden = descriptor.getOverriddenDescriptors(); + if (overridden.isEmpty()) { + throw new IllegalStateException("Fake override should have at least one overridden descriptor: " + descriptor); + } + //noinspection unchecked + descriptor = (D) overridden.iterator().next(); + } + return descriptor; + } } diff --git a/idea/src/org/jetbrains/jet/plugin/completion/DescriptorLookupConverter.java b/idea/src/org/jetbrains/jet/plugin/completion/DescriptorLookupConverter.java index 3db7ce15d6d..e460300098b 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/DescriptorLookupConverter.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/DescriptorLookupConverter.java @@ -162,12 +162,7 @@ public final class DescriptorLookupConverter { @NotNull BindingContext bindingContext, @NotNull DeclarationDescriptor descriptor) { if (descriptor instanceof CallableMemberDescriptor) { - CallableMemberDescriptor callableMemberDescriptor = (CallableMemberDescriptor) descriptor; - while (callableMemberDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { - // TODO: need to know all of them - callableMemberDescriptor = callableMemberDescriptor.getOverriddenDescriptors().iterator().next(); - } - descriptor = callableMemberDescriptor; + descriptor = DescriptorUtils.unwrapFakeOverride((CallableMemberDescriptor) descriptor); } return createLookupElement(analyzer, descriptor, BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor)); } diff --git a/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledNavigationUtils.java b/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledNavigationUtils.java index fe6a6bc4589..02e4803615a 100644 --- a/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledNavigationUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/libraries/DecompiledNavigationUtils.java @@ -28,8 +28,6 @@ import org.jetbrains.jet.lang.resolve.java.PackageClassUtils; import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileFinder; import org.jetbrains.jet.lang.resolve.name.FqName; -import java.util.Set; - import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getFqName; import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getFqNameSafe; @@ -72,18 +70,11 @@ public final class DecompiledNavigationUtils { //TODO: should be done via some generic mechanism @NotNull - private static DeclarationDescriptor getEffectiveReferencedDescriptor(@NotNull DeclarationDescriptor referencedDescriptor) { - if (referencedDescriptor instanceof CallableMemberDescriptor) { - CallableMemberDescriptor callableMemberDescriptor = (CallableMemberDescriptor) referencedDescriptor; - CallableMemberDescriptor.Kind kind = callableMemberDescriptor.getKind(); - if (kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { - Set overriddenDescriptors = - callableMemberDescriptor.getOverriddenDescriptors(); - //TODO: several descriptors - return getEffectiveReferencedDescriptor(overriddenDescriptors.iterator().next()); - } + private static DeclarationDescriptor getEffectiveReferencedDescriptor(@NotNull DeclarationDescriptor descriptor) { + if (descriptor instanceof CallableMemberDescriptor) { + return DescriptorUtils.unwrapFakeOverride((CallableMemberDescriptor) descriptor); } - return referencedDescriptor; + return descriptor; } diff --git a/idea/src/org/jetbrains/jet/plugin/references/BuiltInsReferenceResolver.java b/idea/src/org/jetbrains/jet/plugin/references/BuiltInsReferenceResolver.java index 3a4dc9d955e..1a65f441aec 100644 --- a/idea/src/org/jetbrains/jet/plugin/references/BuiltInsReferenceResolver.java +++ b/idea/src/org/jetbrains/jet/plugin/references/BuiltInsReferenceResolver.java @@ -56,6 +56,8 @@ import java.util.Collections; import java.util.HashSet; import java.util.Set; +import static org.jetbrains.jet.lang.resolve.DescriptorUtils.unwrapFakeOverride; + public class BuiltInsReferenceResolver extends AbstractProjectComponent { private static final File BUILT_INS_COMPILABLE_SRC_DIR = new File("core/builtins/src", KotlinBuiltIns.BUILT_INS_PACKAGE_NAME_STRING); @@ -178,11 +180,7 @@ public class BuiltInsReferenceResolver extends AbstractProjectComponent { 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()); + return findCurrentDescriptorForMember(unwrapFakeOverride((CallableMemberDescriptor) originalDescriptor).getOriginal()); } DeclarationDescriptor containingDeclaration = findCurrentDescriptor(originalDescriptor.getContainingDeclaration());