don't use PSI for calculating the type of first argument of trait function implementation

This commit is contained in:
Dmitry Jemerov
2012-07-13 16:12:33 +02:00
parent e182041eb9
commit 1ac60dae5e
11 changed files with 69 additions and 72 deletions
@@ -832,7 +832,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
reg += argType.getSize(); reg += argType.getSize();
} }
JetType jetType = TraitImplBodyCodegen.getSuperClass(declaration, bindingContext); JetType jetType = TraitImplBodyCodegen.getSuperClass(declaration);
Type type = typeMapper.mapType(jetType, MapTypeMode.IMPL); Type type = typeMapper.mapType(jetType, MapTypeMode.IMPL);
if (type.getInternalName().equals("java/lang/Object")) { if (type.getInternalName().equals("java/lang/Object")) {
jetType = declaration.getDefaultType(); jetType = declaration.getDefaultType();
@@ -710,7 +710,7 @@ public class JetTypeMapper {
if (kind == OwnerKind.TRAIT_IMPL) { if (kind == OwnerKind.TRAIT_IMPL) {
ClassDescriptor containingDeclaration = (ClassDescriptor) f.getContainingDeclaration(); ClassDescriptor containingDeclaration = (ClassDescriptor) f.getContainingDeclaration();
JetType jetType = TraitImplBodyCodegen.getSuperClass(containingDeclaration, bindingContext); JetType jetType = TraitImplBodyCodegen.getSuperClass(containingDeclaration);
Type type = mapType(jetType, MapTypeMode.VALUE); Type type = mapType(jetType, MapTypeMode.VALUE);
if(type.getInternalName().equals("java/lang/Object")) { if(type.getInternalName().equals("java/lang/Object")) {
jetType = containingDeclaration.getDefaultType(); jetType = containingDeclaration.getDefaultType();
@@ -16,12 +16,10 @@
package org.jetbrains.jet.codegen; 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.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.descriptors.ClassKind;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.psi.JetClassOrObject;
import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses; import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
@@ -33,30 +31,11 @@ public class TraitImplBodyCodegen extends ClassBodyCodegen {
super(aClass, context, v, state); super(aClass, context, v, state);
} }
//todo not needed when frontend will be able to calculate properly static JetType getSuperClass(ClassDescriptor classDescriptor) {
static JetType getSuperClass(ClassDescriptor myClassDescr, BindingContext bindingContext) { final List<ClassDescriptor> superclassDescriptors = DescriptorUtils.getSuperclassDescriptors(classDescriptor);
JetClassOrObject myClass = (JetClassOrObject) BindingContextUtils.classDescriptorToDeclaration(bindingContext, myClassDescr); for (ClassDescriptor descriptor : superclassDescriptors) {
if (myClass == null) if (descriptor.getKind() != ClassKind.TRAIT) {
return JetStandardClasses.getAnyType(); return descriptor.getDefaultType();
List<JetDelegationSpecifier> 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();
}
}
}
} }
} }
return JetStandardClasses.getAnyType(); return JetStandardClasses.getAnyType();
@@ -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.*;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses; import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import java.util.Collection; import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor.NO_RECEIVER; import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor.NO_RECEIVER;
@@ -310,4 +307,30 @@ public class DescriptorUtils {
} }
return false; return false;
} }
@NotNull
public static List<ClassDescriptor> getSuperclassDescriptors(@NotNull ClassDescriptor classDescriptor) {
Collection<? extends JetType> superclassTypes = classDescriptor.getTypeConstructor().getSupertypes();
List<ClassDescriptor> superClassDescriptors = new ArrayList<ClassDescriptor>();
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());
}
} }
@@ -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()
}
@@ -60,4 +60,8 @@ public class TraitsTest extends CodegenTestCase {
public void testKt2399() { public void testKt2399() {
blackBoxFile("regressions/kt2399.kt"); blackBoxFile("regressions/kt2399.kt");
} }
public void testTraitFuncCall() {
blackBoxFile("traits/traitFuncCall.kt");
}
} }
@@ -24,6 +24,7 @@ import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassKind; import org.jetbrains.jet.lang.descriptors.ClassKind;
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
import org.jetbrains.jet.lang.psi.*; 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.TemporaryVariable;
import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.context.TranslationContext;
import org.jetbrains.k2js.translate.general.AbstractTranslator; import org.jetbrains.k2js.translate.general.AbstractTranslator;
@@ -189,7 +190,7 @@ public final class ClassTranslator extends AbstractTranslator {
@NotNull @NotNull
private List<JsExpression> getSuperclassNameReferences() { private List<JsExpression> getSuperclassNameReferences() {
List<JsExpression> superclassReferences = new ArrayList<JsExpression>(); List<JsExpression> superclassReferences = new ArrayList<JsExpression>();
List<ClassDescriptor> superclassDescriptors = getSuperclassDescriptors(descriptor); List<ClassDescriptor> superclassDescriptors = DescriptorUtils.getSuperclassDescriptors(descriptor);
addAncestorClass(superclassReferences, superclassDescriptors); addAncestorClass(superclassReferences, superclassDescriptors);
addTraits(superclassReferences, superclassDescriptors); addTraits(superclassReferences, superclassDescriptors);
return superclassReferences; return superclassReferences;
@@ -32,7 +32,7 @@ import org.jetbrains.k2js.translate.utils.BindingUtils;
import java.util.Collections; import java.util.Collections;
import java.util.List; 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.JsAstUtils.*;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopRange; import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopRange;
import static org.jetbrains.k2js.translate.utils.TemporariesUtils.temporariesInitialization; import static org.jetbrains.k2js.translate.utils.TemporariesUtils.temporariesInitialization;
@@ -30,7 +30,7 @@ import org.jetbrains.k2js.translate.utils.BindingUtils;
import java.util.List; 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.JsAstUtils.*;
import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopRange; import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopRange;
import static org.jetbrains.k2js.translate.utils.TemporariesUtils.temporariesInitialization; import static org.jetbrains.k2js.translate.utils.TemporariesUtils.temporariesInitialization;
@@ -24,11 +24,11 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils; 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.ResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.VariableAsFunctionResolvedCall; import org.jetbrains.jet.lang.resolve.calls.VariableAsFunctionResolvedCall;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; 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_GET;
import static org.jetbrains.jet.lang.resolve.BindingContext.INDEXED_LVALUE_SET; 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.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 * @author Pavel Talanov
@@ -145,7 +146,7 @@ public final class BindingUtils {
public static boolean hasAncestorClass(@NotNull BindingContext context, @NotNull JetClassOrObject classDeclaration) { public static boolean hasAncestorClass(@NotNull BindingContext context, @NotNull JetClassOrObject classDeclaration) {
ClassDescriptor classDescriptor = getClassDescriptor(context, classDeclaration); ClassDescriptor classDescriptor = getClassDescriptor(context, classDeclaration);
List<ClassDescriptor> superclassDescriptors = getSuperclassDescriptors(classDescriptor); List<ClassDescriptor> superclassDescriptors = DescriptorUtils.getSuperclassDescriptors(classDescriptor);
return (JsDescriptorUtils.findAncestorClass(superclassDescriptors) != null); return (JsDescriptorUtils.findAncestorClass(superclassDescriptors) != null);
} }
@@ -166,7 +167,7 @@ public final class BindingUtils {
@NotNull @NotNull
public static ClassDescriptor getClassDescriptorForTypeReference(@NotNull BindingContext context, public static ClassDescriptor getClassDescriptorForTypeReference(@NotNull BindingContext context,
@NotNull JetTypeReference typeReference) { @NotNull JetTypeReference typeReference) {
return getClassDescriptorForType(getTypeByReference(context, typeReference)); return DescriptorUtils.getClassDescriptorForType(getTypeByReference(context, typeReference));
} }
@Nullable @Nullable
@@ -200,10 +201,6 @@ public final class BindingUtils {
return context.get(BindingContext.REFERENCE_TARGET, reference); return context.get(BindingContext.REFERENCE_TARGET, reference);
} }
public static boolean isNotAny(@NotNull DeclarationDescriptor superClassDescriptor) {
return !superClassDescriptor.equals(JetStandardClasses.getAny());
}
@NotNull @NotNull
public static ResolvedCall<?> getResolvedCall(@NotNull BindingContext context, public static ResolvedCall<?> getResolvedCall(@NotNull BindingContext context,
@NotNull JetExpression expression) { @NotNull JetExpression expression) {
@@ -24,20 +24,18 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils; 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.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; 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.jet.lang.types.expressions.OperatorConventions;
import org.jetbrains.k2js.config.LibrarySourcesConfig; import org.jetbrains.k2js.config.LibrarySourcesConfig;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isClassObject; import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isClassObject;
import static org.jetbrains.k2js.translate.utils.BindingUtils.isNotAny;
/** /**
* @author Pavel Talanov * @author Pavel Talanov
@@ -105,31 +103,9 @@ public final class JsDescriptorUtils {
return null; return null;
} }
@NotNull
public static List<ClassDescriptor> getSuperclassDescriptors(@NotNull ClassDescriptor classDescriptor) {
Collection<? extends JetType> superclassTypes = classDescriptor.getTypeConstructor().getSupertypes();
List<ClassDescriptor> superClassDescriptors = new ArrayList<ClassDescriptor>();
for (JetType type : superclassTypes) {
ClassDescriptor result = getClassDescriptorForType(type);
if (isNotAny(result)) {
superClassDescriptors.add(result);
}
}
return superClassDescriptors;
}
@Nullable @Nullable
public static ClassDescriptor getSuperclass(@NotNull ClassDescriptor classDescriptor) { public static ClassDescriptor getSuperclass(@NotNull ClassDescriptor classDescriptor) {
return findAncestorClass(getSuperclassDescriptors(classDescriptor)); return findAncestorClass(DescriptorUtils.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;
} }