diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 3ada20ae277..c4419f0e84a 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -832,7 +832,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { reg += argType.getSize(); } - JetType jetType = TraitImplBodyCodegen.getSuperClass(declaration, bindingContext); + JetType jetType = TraitImplBodyCodegen.getSuperClass(declaration); Type type = typeMapper.mapType(jetType, MapTypeMode.IMPL); if (type.getInternalName().equals("java/lang/Object")) { jetType = declaration.getDefaultType(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index 8c3fc02c1f4..c92931c773b 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -710,7 +710,7 @@ public class JetTypeMapper { if (kind == OwnerKind.TRAIT_IMPL) { ClassDescriptor containingDeclaration = (ClassDescriptor) f.getContainingDeclaration(); - JetType jetType = TraitImplBodyCodegen.getSuperClass(containingDeclaration, bindingContext); + JetType jetType = TraitImplBodyCodegen.getSuperClass(containingDeclaration); Type type = mapType(jetType, MapTypeMode.VALUE); if(type.getInternalName().equals("java/lang/Object")) { jetType = containingDeclaration.getDefaultType(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/TraitImplBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/TraitImplBodyCodegen.java index 1bfac1e0162..68f2df8d06a 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/TraitImplBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/TraitImplBodyCodegen.java @@ -16,12 +16,10 @@ package org.jetbrains.jet.codegen; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiElement; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; -import org.jetbrains.jet.lang.psi.*; -import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.resolve.BindingContextUtils; +import org.jetbrains.jet.lang.descriptors.ClassKind; +import org.jetbrains.jet.lang.psi.JetClassOrObject; +import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.lang.JetStandardClasses; import org.objectweb.asm.Opcodes; @@ -33,30 +31,11 @@ public class TraitImplBodyCodegen extends ClassBodyCodegen { super(aClass, context, v, state); } - //todo not needed when frontend will be able to calculate properly - static JetType getSuperClass(ClassDescriptor myClassDescr, BindingContext bindingContext) { - JetClassOrObject myClass = (JetClassOrObject) BindingContextUtils.classDescriptorToDeclaration(bindingContext, myClassDescr); - if (myClass == null) - return JetStandardClasses.getAnyType(); - List delegationSpecifiers = myClass.getDelegationSpecifiers(); - - for (JetDelegationSpecifier specifier : delegationSpecifiers) { - if (specifier instanceof JetDelegatorToSuperClass || specifier instanceof JetDelegatorToSuperCall) { - JetType superType = bindingContext.get(BindingContext.TYPE, specifier.getTypeReference()); - ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); - final PsiElement declaration = BindingContextUtils.classDescriptorToDeclaration(bindingContext, superClassDescriptor); - if (declaration != null) { - if (declaration instanceof PsiClass) { - if (!((PsiClass) declaration).isInterface()) { - return superClassDescriptor.getDefaultType(); - } - } - else if (declaration instanceof JetClass) { - if (!((JetClass) declaration).isTrait()) { - return superClassDescriptor.getDefaultType(); - } - } - } + static JetType getSuperClass(ClassDescriptor classDescriptor) { + final List superclassDescriptors = DescriptorUtils.getSuperclassDescriptors(classDescriptor); + for (ClassDescriptor descriptor : superclassDescriptors) { + if (descriptor.getKind() != ClassKind.TRAIT) { + return descriptor.getDefaultType(); } } return JetStandardClasses.getAnyType(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java index e5b2cf787f2..69958b70473 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java @@ -31,10 +31,7 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.lang.JetStandardClasses; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor.NO_RECEIVER; @@ -310,4 +307,30 @@ public class DescriptorUtils { } return false; } + + @NotNull + public static List getSuperclassDescriptors(@NotNull ClassDescriptor classDescriptor) { + Collection superclassTypes = classDescriptor.getTypeConstructor().getSupertypes(); + List superClassDescriptors = new ArrayList(); + for (JetType type : superclassTypes) { + ClassDescriptor result = getClassDescriptorForType(type); + if (isNotAny(result)) { + superClassDescriptors.add(result); + } + } + return superClassDescriptors; + } + + @NotNull + public static ClassDescriptor getClassDescriptorForType(@NotNull JetType type) { + DeclarationDescriptor superClassDescriptor = + type.getConstructor().getDeclarationDescriptor(); + assert superClassDescriptor instanceof ClassDescriptor + : "Superclass descriptor of a type should be of type ClassDescriptor"; + return (ClassDescriptor)superClassDescriptor; + } + + public static boolean isNotAny(@NotNull DeclarationDescriptor superClassDescriptor) { + return !superClassDescriptor.equals(JetStandardClasses.getAny()); + } } diff --git a/compiler/testData/codegen/traits/traitFuncCall.kt b/compiler/testData/codegen/traits/traitFuncCall.kt new file mode 100644 index 00000000000..e84d7931c56 --- /dev/null +++ b/compiler/testData/codegen/traits/traitFuncCall.kt @@ -0,0 +1,17 @@ +open class Foo() { + public fun k(): String = "K" +} + + +trait T: Foo { + public fun xyzzy(): String = o() + k() + public fun o(): String +} + +class TImpl(): Foo(), T { + public override fun o(): String = "O" +} + +fun box(): String { + return TImpl().xyzzy() +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/TraitsTest.java b/compiler/tests/org/jetbrains/jet/codegen/TraitsTest.java index 25e56a2e115..d56ba81d8ba 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/TraitsTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/TraitsTest.java @@ -60,4 +60,8 @@ public class TraitsTest extends CodegenTestCase { public void testKt2399() { blackBoxFile("regressions/kt2399.kt"); } + + public void testTraitFuncCall() { + blackBoxFile("traits/traitFuncCall.kt"); + } } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java index 4342a6f8035..ec17b6aecc1 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/declaration/ClassTranslator.java @@ -24,6 +24,7 @@ import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassKind; import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.k2js.translate.context.TemporaryVariable; import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.general.AbstractTranslator; @@ -189,7 +190,7 @@ public final class ClassTranslator extends AbstractTranslator { @NotNull private List getSuperclassNameReferences() { List superclassReferences = new ArrayList(); - List superclassDescriptors = getSuperclassDescriptors(descriptor); + List superclassDescriptors = DescriptorUtils.getSuperclassDescriptors(descriptor); addAncestorClass(superclassReferences, superclassDescriptors); addTraits(superclassReferences, superclassDescriptors); return superclassReferences; diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/ArrayForTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/ArrayForTranslator.java index a6811dc7c14..a671dbd3f41 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/ArrayForTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/ArrayForTranslator.java @@ -32,7 +32,7 @@ import org.jetbrains.k2js.translate.utils.BindingUtils; import java.util.Collections; import java.util.List; -import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getClassDescriptorForType; +import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getClassDescriptorForType; import static org.jetbrains.k2js.translate.utils.JsAstUtils.*; import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopRange; import static org.jetbrains.k2js.translate.utils.TemporariesUtils.temporariesInitialization; diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/RangeForTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/RangeForTranslator.java index f73da95b9c3..bf6a03abcd3 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/RangeForTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/RangeForTranslator.java @@ -30,7 +30,7 @@ import org.jetbrains.k2js.translate.utils.BindingUtils; import java.util.List; -import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getClassDescriptorForType; +import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getClassDescriptorForType; import static org.jetbrains.k2js.translate.utils.JsAstUtils.*; import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopRange; import static org.jetbrains.k2js.translate.utils.TemporariesUtils.temporariesInitialization; diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java index 9a197b3bb34..b28b8b1cf32 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/BindingUtils.java @@ -24,11 +24,11 @@ import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContextUtils; +import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.VariableAsFunctionResolvedCall; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.types.JetType; -import org.jetbrains.jet.lang.types.lang.JetStandardClasses; import java.util.ArrayList; import java.util.Collection; @@ -38,7 +38,8 @@ import java.util.Set; import static org.jetbrains.jet.lang.resolve.BindingContext.INDEXED_LVALUE_GET; import static org.jetbrains.jet.lang.resolve.BindingContext.INDEXED_LVALUE_SET; import static org.jetbrains.k2js.translate.utils.ErrorReportingUtils.message; -import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.*; +import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getContainedDescriptorsWhichAreNotPredefined; +import static org.jetbrains.k2js.translate.utils.JsDescriptorUtils.getNamespaceDescriptorHierarchy; /** * @author Pavel Talanov @@ -145,7 +146,7 @@ public final class BindingUtils { public static boolean hasAncestorClass(@NotNull BindingContext context, @NotNull JetClassOrObject classDeclaration) { ClassDescriptor classDescriptor = getClassDescriptor(context, classDeclaration); - List superclassDescriptors = getSuperclassDescriptors(classDescriptor); + List superclassDescriptors = DescriptorUtils.getSuperclassDescriptors(classDescriptor); return (JsDescriptorUtils.findAncestorClass(superclassDescriptors) != null); } @@ -166,7 +167,7 @@ public final class BindingUtils { @NotNull public static ClassDescriptor getClassDescriptorForTypeReference(@NotNull BindingContext context, @NotNull JetTypeReference typeReference) { - return getClassDescriptorForType(getTypeByReference(context, typeReference)); + return DescriptorUtils.getClassDescriptorForType(getTypeByReference(context, typeReference)); } @Nullable @@ -200,10 +201,6 @@ public final class BindingUtils { return context.get(BindingContext.REFERENCE_TARGET, reference); } - public static boolean isNotAny(@NotNull DeclarationDescriptor superClassDescriptor) { - return !superClassDescriptor.equals(JetStandardClasses.getAny()); - } - @NotNull public static ResolvedCall getResolvedCall(@NotNull BindingContext context, @NotNull JetExpression expression) { diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/JsDescriptorUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/JsDescriptorUtils.java index c6d5d40d412..e2af7076984 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/JsDescriptorUtils.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/JsDescriptorUtils.java @@ -24,20 +24,18 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContextUtils; +import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; -import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.expressions.OperatorConventions; import org.jetbrains.k2js.config.LibrarySourcesConfig; -import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Set; import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isClassObject; -import static org.jetbrains.k2js.translate.utils.BindingUtils.isNotAny; /** * @author Pavel Talanov @@ -105,31 +103,9 @@ public final class JsDescriptorUtils { return null; } - @NotNull - public static List getSuperclassDescriptors(@NotNull ClassDescriptor classDescriptor) { - Collection superclassTypes = classDescriptor.getTypeConstructor().getSupertypes(); - List superClassDescriptors = new ArrayList(); - for (JetType type : superclassTypes) { - ClassDescriptor result = getClassDescriptorForType(type); - if (isNotAny(result)) { - superClassDescriptors.add(result); - } - } - return superClassDescriptors; - } - @Nullable public static ClassDescriptor getSuperclass(@NotNull ClassDescriptor classDescriptor) { - return findAncestorClass(getSuperclassDescriptors(classDescriptor)); - } - - @NotNull - public static ClassDescriptor getClassDescriptorForType(@NotNull JetType type) { - DeclarationDescriptor superClassDescriptor = - type.getConstructor().getDeclarationDescriptor(); - assert superClassDescriptor instanceof ClassDescriptor - : "Superclass descriptor of a type should be of type ClassDescriptor"; - return (ClassDescriptor)superClassDescriptor; + return findAncestorClass(DescriptorUtils.getSuperclassDescriptors(classDescriptor)); }