diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CallableMethod.java b/compiler/backend/src/org/jetbrains/jet/codegen/CallableMethod.java index 9b5888566d1..fea60bcc202 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CallableMethod.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CallableMethod.java @@ -1,7 +1,6 @@ package org.jetbrains.jet.codegen; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; @@ -12,14 +11,13 @@ import java.util.List; /** * @author yole + * @author alex.tkacman */ public class CallableMethod implements Callable { private String owner; private final Method signature; - private final int invokeOpcode; + private int invokeOpcode; private final List valueParameterTypes; - private boolean acceptsTypeArguments = false; - private boolean ownerFromCall = false; private DeclarationDescriptor thisClass = null; private DeclarationDescriptor receiverClass = null; private Type generateCalleeType = null; @@ -35,10 +33,6 @@ public class CallableMethod implements Callable { return owner; } - public void setOwner(String owner) { - this.owner = owner; - } - public Method getSignature() { return signature; } @@ -51,14 +45,6 @@ public class CallableMethod implements Callable { return valueParameterTypes; } - public boolean acceptsTypeArguments() { - return acceptsTypeArguments; - } - - public void setAcceptsTypeArguments(boolean acceptsTypeArguments) { - this.acceptsTypeArguments = acceptsTypeArguments; - } - public void setNeedsReceiver(@Nullable DeclarationDescriptor receiverClass) { this.receiverClass = receiverClass; } @@ -67,14 +53,6 @@ public class CallableMethod implements Callable { this.thisClass = receiverClass; } - public boolean isOwnerFromCall() { - return ownerFromCall; - } - - public void setOwnerFromCall(boolean ownerFromCall) { - this.ownerFromCall = ownerFromCall; - } - void invoke(InstructionAdapter v) { v.visitMethodInsn(getInvokeOpcode(), getOwner(), getSignature().getName(), getSignature().getDescriptor()); } @@ -106,5 +84,4 @@ public class CallableMethod implements Callable { public DeclarationDescriptor getThisClass() { return thisClass; } - } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilder.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilder.java index ad49c8c56ce..b55adbc5dad 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilder.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilder.java @@ -21,8 +21,8 @@ public class ClassBuilder { int access, String name, String desc, - String signature, - Object value) { + @Nullable String signature, + @Nullable Object value) { return v.visitField(access, name, desc, signature, value); } @@ -49,11 +49,11 @@ public class ClassBuilder { return v; } - public void defineClass(int version, int access, String name, String signature, String superName, String[] interfaces) { + public void defineClass(int version, int access, String name, @Nullable String signature, String superName, String[] interfaces) { v.visit(version, access, name, signature, superName, interfaces); } - public void visitSource(String name, String debug) { + public void visitSource(String name, @Nullable String debug) { v.visitSource(name, debug); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassContext.java index 3e1200388ab..34b0c6062b6 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassContext.java @@ -1,5 +1,6 @@ package org.jetbrains.jet.codegen; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; @@ -61,7 +62,7 @@ public class ClassContext { return new ClassContext(descriptor, OwnerKind.NAMESPACE, null, this, null); } - public ClassContext intoClass(FunctionOrClosureCodegen closure, ClassDescriptor descriptor, OwnerKind kind) { + public ClassContext intoClass(@Nullable FunctionOrClosureCodegen closure, ClassDescriptor descriptor, OwnerKind kind) { final StackValue thisValue; thisValue = StackValue.local(0, JetTypeMapper.TYPE_OBJECT); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java index 01c767cfd25..914708d6721 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java @@ -3,8 +3,10 @@ package org.jetbrains.jet.codegen; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassKind; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.types.JetType; -import org.objectweb.asm.Type; + +import java.util.List; /** * @author abreslav @@ -62,4 +64,38 @@ public class CodegenUtil { return hasOuterTypeInfo(outerClassDescriptor); } + + public static boolean hasDerivedTypeInfoField(JetType type, boolean exceptOwn) { + if(!exceptOwn) { + if(!isInterface(type)) + if(hasTypeInfoField(type)) + return true; + } + + for (JetType jetType : type.getConstructor().getSupertypes()) { + if(hasDerivedTypeInfoField(jetType, false)) + return true; + } + + return false; + } + + public static boolean hasTypeInfoField(JetType type) { + List parameters = type.getConstructor().getParameters(); + for (TypeParameterDescriptor parameter : parameters) { + if(parameter.isReified()) + return true; + } + + for (JetType jetType : type.getConstructor().getSupertypes()) { + if(hasTypeInfoField(jetType)) + return true; + } + + ClassDescriptor outerClassDescriptor = getOuterClassDescriptor(type.getConstructor().getDeclarationDescriptor()); + if(outerClassDescriptor == null) + return false; + + return hasTypeInfoField(outerClassDescriptor.getDefaultType()); + } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 1792a90c644..a22ee10ccad 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -760,9 +760,10 @@ public class ExpressionCodegen extends JetVisitor { PsiElement declaration = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor); if (declaration instanceof PsiField) { + final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor; PsiField psiField = (PsiField) declaration; - final String owner = JetTypeMapper.jvmName(psiField.getContainingClass()); - final Type fieldType = JetTypeMapper.psiTypeToAsm(psiField.getType()); + final String owner = typeMapper.getOwner(propertyDescriptor, OwnerKind.IMPLEMENTATION); + final Type fieldType = typeMapper.mapType(propertyDescriptor.getReturnType()); final boolean isStatic = psiField.hasModifierProperty(PsiModifier.STATIC); if (!isStatic) { receiver.put(JetTypeMapper.TYPE_OBJECT, v); @@ -825,6 +826,7 @@ public class ExpressionCodegen extends JetVisitor { ClassDescriptor propReceiverDescriptor = (ClassDescriptor) propertyDescriptor.getContainingDeclaration(); if(!CodegenUtil.isInterface(propReceiverDescriptor) && CodegenUtil.isInterface(receiverType.getConstructor().getDeclarationDescriptor())) { // I hope it happens only in case of required super class for traits + assert propReceiverDescriptor != null; v.checkcast(typeMapper.mapType(propReceiverDescriptor.getDefaultType())); } } @@ -895,9 +897,7 @@ public class ExpressionCodegen extends JetVisitor { else { owner = typeMapper.getOwner(functionDescriptor, OwnerKind.IMPLEMENTATION); if(containingDeclaration instanceof JavaClassDescriptor) { - PsiClass psiElement = (PsiClass) bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, containingDeclaration); - assert psiElement != null; - isInterface = psiElement.isInterface(); + isInterface = CodegenUtil.isInterface(containingDeclaration); } else { if(containingDeclaration instanceof ClassDescriptor && ((ClassDescriptor) containingDeclaration).getKind() == ClassKind.OBJECT) @@ -970,7 +970,15 @@ public class ExpressionCodegen extends JetVisitor { } private StackValue invokeFunction(JetCallExpression expression, DeclarationDescriptor fd, StackValue receiver) { - Callable callableMethod = resolveToCallable(fd); + boolean superCall = false; + if (expression.getParent() instanceof JetQualifiedExpression) { + final JetExpression receiverExpression = ((JetQualifiedExpression) expression.getParent()).getReceiverExpression(); + if(receiverExpression instanceof JetSuperExpression) { + superCall = true; + } + } + + Callable callableMethod = resolveToCallable(fd, superCall); return invokeCallable(fd, callableMethod, expression, receiver); } @@ -1002,22 +1010,19 @@ public class ExpressionCodegen extends JetVisitor { return StackValue.none(); } - private Callable resolveToCallable(DeclarationDescriptor fd) { + private Callable resolveToCallable(DeclarationDescriptor fd, boolean superCall) { final IntrinsicMethod intrinsic = intrinsics.getIntrinsic(fd); if (intrinsic != null) { return intrinsic; } - PsiElement declarationPsiElement = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, fd); CallableMethod callableMethod; - if (declarationPsiElement instanceof PsiMethod || declarationPsiElement instanceof JetNamedFunction) { - callableMethod = typeMapper.mapToCallableMethod((PsiNamedElement) declarationPsiElement, null); - } - else if (fd instanceof VariableAsFunctionDescriptor) { + if (fd instanceof VariableAsFunctionDescriptor) { + assert !superCall; callableMethod = asCallableMethod((FunctionDescriptor) fd); } else if (fd instanceof FunctionDescriptor) { - callableMethod = typeMapper.mapToCallableMethod((FunctionDescriptor) fd, null); + callableMethod = typeMapper.mapToCallableMethod((FunctionDescriptor) fd, superCall, OwnerKind.IMPLEMENTATION); } else { throw new UnsupportedOperationException("can't resolve declaration to callable: " + fd); @@ -1042,10 +1047,7 @@ public class ExpressionCodegen extends JetVisitor { if (calleeType != null && expression instanceof JetCallExpression) { gen(expression.getCalleeExpression(), calleeType); } - if (callableMethod.isOwnerFromCall()) { - setOwnerFromCall(callableMethod, expression); - } - + if (callableMethod.isNeedsThis()) { if(callableMethod.isNeedsReceiver()) { generateThisOrOuter((ClassDescriptor) callableMethod.getThisClass()).put(JetTypeMapper.TYPE_OBJECT, v); @@ -1053,7 +1055,7 @@ public class ExpressionCodegen extends JetVisitor { } else { if (receiver == StackValue.none()) { - generateThisOrOuter((ClassDescriptor) callableMethod.getThisClass()).put(JetTypeMapper.TYPE_OBJECT, v);; + generateThisOrOuter((ClassDescriptor) callableMethod.getThisClass()).put(JetTypeMapper.TYPE_OBJECT, v); } else { receiver.put(JetTypeMapper.TYPE_OBJECT, v); @@ -1071,28 +1073,13 @@ public class ExpressionCodegen extends JetVisitor { } int mask = pushMethodArguments(expression, callableMethod.getValueParameterTypes()); - if (callableMethod.acceptsTypeArguments()) { - pushTypeArguments(expression); - } + pushTypeArguments(expression); if(mask == 0) callableMethod.invoke(v); else callableMethod.invokeWithDefault(v, mask); } - private void setOwnerFromCall(CallableMethod callableMethod, JetCallElement expression) { - if (expression.getParent() instanceof JetQualifiedExpression) { - final JetExpression receiver = ((JetQualifiedExpression) expression.getParent()).getReceiverExpression(); - JetType expressionType = bindingContext.get(BindingContext.EXPRESSION_TYPE, receiver); - assert expressionType != null; - DeclarationDescriptor declarationDescriptor = expressionType.getConstructor().getDeclarationDescriptor(); - PsiElement ownerDeclaration = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, declarationDescriptor); - if (ownerDeclaration instanceof PsiClass) { - callableMethod.setOwner(typeMapper.mapType(expressionType).getInternalName()); - } - } - } - private static JetExpression getReceiverForSelector(PsiElement expression) { if (expression.getParent() instanceof JetDotQualifiedExpression && !isReceiver(expression)) { final JetDotQualifiedExpression parent = (JetDotQualifiedExpression) expression.getParent(); @@ -1362,7 +1349,7 @@ public class ExpressionCodegen extends JetVisitor { } else { DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference()); - final Callable callable = resolveToCallable(op); + final Callable callable = resolveToCallable(op, false); if (callable instanceof IntrinsicMethod) { IntrinsicMethod intrinsic = (IntrinsicMethod) callable; return intrinsic.generate(this, v, expressionType(expression), expression, @@ -1388,6 +1375,7 @@ public class ExpressionCodegen extends JetVisitor { } else { FunctionDescriptor op = (FunctionDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference()); + assert op != null; leftValue.put(typeMapper.mapType(op.getValueParameters().get(0).getOutType()), v); genToJVMStack(expression.getRight()); v.swap(); @@ -1647,7 +1635,7 @@ public class ExpressionCodegen extends JetVisitor { private StackValue generateAugmentedAssignment(JetBinaryExpression expression) { DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference()); - final Callable callable = resolveToCallable(op); + final Callable callable = resolveToCallable(op, false); final JetExpression lhs = expression.getLeft(); // if(lhs instanceof JetArrayAccessExpression) { @@ -1726,7 +1714,7 @@ public class ExpressionCodegen extends JetVisitor { @Override public StackValue visitPrefixExpression(JetPrefixExpression expression, StackValue receiver) { DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationSign()); - final Callable callable = resolveToCallable(op); + final Callable callable = resolveToCallable(op, false); if (callable instanceof IntrinsicMethod) { IntrinsicMethod intrinsic = (IntrinsicMethod) callable; return intrinsic.generate(this, v, expressionType(expression), expression, @@ -1831,11 +1819,12 @@ public class ExpressionCodegen extends JetVisitor { final PsiElement declaration = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, constructorDescriptor); Type type; if (declaration instanceof PsiMethod) { - type = generateJavaConstructorCall(expression, (PsiMethod) declaration); + type = generateJavaConstructorCall(expression); } else if (constructorDescriptor instanceof ConstructorDescriptor) { //noinspection ConstantConditions JetType expressionType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression); + assert expressionType != null; type = typeMapper.mapType(expressionType, OwnerKind.IMPLEMENTATION); if (type.getSort() == Type.ARRAY) { generateNewArray(expression, expressionType); @@ -1856,7 +1845,7 @@ public class ExpressionCodegen extends JetVisitor { else { // this$0 need to be put on stack v.dup(); - v.load(0, JetTypeMapper.jetImplementationType(classDecl)); + v.load(0, typeMapper.jetImplementationType(classDecl)); } } else { @@ -1875,19 +1864,23 @@ public class ExpressionCodegen extends JetVisitor { } private void pushTypeArguments(JetCallElement expression) { - ResolvedCall resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getCalleeExpression()); + JetExpression calleeExpression = expression.getCalleeExpression(); + ResolvedCall resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, calleeExpression); if(resolvedCall != null) { Map typeArguments = resolvedCall.getTypeArguments(); CallableDescriptor resultingDescriptor = resolvedCall.getCandidateDescriptor(); for (TypeParameterDescriptor typeParameterDescriptor : resultingDescriptor.getTypeParameters()) { - JetType jetType = typeArguments.get(typeParameterDescriptor); - generateTypeInfo(jetType); + if(typeParameterDescriptor.isReified()) { + JetType jetType = typeArguments.get(typeParameterDescriptor); + generateTypeInfo(jetType); + } } } else { - for (JetTypeProjection jetTypeArgument : expression.getTypeArguments()) { - pushTypeArgument(jetTypeArgument); - } + throw new UnsupportedOperationException(); +// for (JetTypeProjection jetTypeArgument : expression.getTypeArguments()) { +// pushTypeArgument(jetTypeArgument); +// } } } @@ -1896,12 +1889,13 @@ public class ExpressionCodegen extends JetVisitor { generateTypeInfo(typeArgument); } - private Type generateJavaConstructorCall(JetCallExpression expression, PsiMethod constructor) { - PsiClass javaClass = constructor.getContainingClass(); - Type type = JetTypeMapper.psiClassType(javaClass); + private Type generateJavaConstructorCall(JetCallExpression expression) { + FunctionDescriptor descriptor = (FunctionDescriptor) resolveCalleeDescriptor(expression); + ClassDescriptor javaClass = (ClassDescriptor) descriptor.getContainingDeclaration(); + Type type = typeMapper.mapType(javaClass.getDefaultType()); v.anew(type); v.dup(); - final CallableMethod callableMethod = JetTypeMapper.mapToCallableMethod(constructor); + final CallableMethod callableMethod = typeMapper.mapToCallableMethod(descriptor, false, OwnerKind.IMPLEMENTATION); invokeMethodWithArguments(callableMethod, expression, StackValue.none()); return type; } @@ -1984,14 +1978,15 @@ public class ExpressionCodegen extends JetVisitor { gen(array, arrayType); final List indices = expression.getIndexExpressions(); FunctionDescriptor operationDescriptor = (FunctionDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, expression); + assert operationDescriptor != null; if (arrayType.getSort() == Type.ARRAY && indices.size() == 1 && operationDescriptor.getValueParameters().get(0).getOutType().equals(state.getStandardLibrary().getIntType())) { for (JetExpression index : indices) { gen(index, Type.INT_TYPE); } + assert type != null; if(state.getStandardLibrary().getArray().equals(type.getConstructor().getDeclarationDescriptor())) { JetType elementType = type.getArguments().get(0).getType(); Type notBoxed = typeMapper.mapType(elementType); - Type boxed = JetTypeMapper.boxType(notBoxed); return StackValue.arrayElement(notBoxed, true); } else { @@ -1999,28 +1994,30 @@ public class ExpressionCodegen extends JetVisitor { } } else { - CallableMethod accessor = typeMapper.mapToCallableMethod(operationDescriptor, OwnerKind.IMPLEMENTATION); + CallableMethod accessor = typeMapper.mapToCallableMethod(operationDescriptor, false, OwnerKind.IMPLEMENTATION); boolean isGetter = accessor.getSignature().getName().equals("get"); ResolvedCall resolvedSetCall = bindingContext.get(BindingContext.INDEXED_LVALUE_SET, expression); FunctionDescriptor setterDescriptor = resolvedSetCall == null ? null : resolvedSetCall.getResultingDescriptor(); - CallableMethod setter = resolvedSetCall == null ? null : typeMapper.mapToCallableMethod(setterDescriptor, OwnerKind.IMPLEMENTATION); + CallableMethod setter = resolvedSetCall == null ? null : typeMapper.mapToCallableMethod(setterDescriptor, false, OwnerKind.IMPLEMENTATION); ResolvedCall resolvedGetCall = bindingContext.get(BindingContext.INDEXED_LVALUE_GET, expression); FunctionDescriptor getterDescriptor = resolvedGetCall == null ? null : resolvedGetCall.getResultingDescriptor(); - CallableMethod getter = resolvedGetCall == null ? null : typeMapper.mapToCallableMethod(getterDescriptor, OwnerKind.IMPLEMENTATION); + CallableMethod getter = resolvedGetCall == null ? null : typeMapper.mapToCallableMethod(getterDescriptor, false, OwnerKind.IMPLEMENTATION); Type asmType; Type[] argumentTypes = accessor.getSignature().getArgumentTypes(); int index = 0; if(isGetter) { + assert getterDescriptor != null; if(getterDescriptor.getReceiverParameter().exists()) { index++; } asmType = accessor.getSignature().getReturnType(); } else { + assert setterDescriptor != null; if(setterDescriptor.getReceiverParameter().exists()) { index++; } @@ -2035,46 +2032,6 @@ public class ExpressionCodegen extends JetVisitor { } } - public void _derefArray(JetType type) { - if (state.getStandardLibrary().getArray().equals(type.getConstructor().getDeclarationDescriptor())) { - JetType elementType = type.getArguments().get(0).getType(); - JetStandardLibrary standardLibrary = state.getStandardLibrary(); - if (elementType.equals(standardLibrary.getIntType())) { - v.getfield("jet/arrays/JetIntArray", "array", "[I"); - } - else if (elementType.equals(standardLibrary.getLongType())) { - v.getfield("jet/arrays/JetLongArray", "array", "[J"); - } - else if (elementType.equals(standardLibrary.getShortType())) { - v.getfield("jet/arrays/JetShortArray", "array", "[S"); - } - else if (elementType.equals(standardLibrary.getByteType())) { - v.getfield("jet/arrays/JetByteArray", "array", "[B"); - } - else if (elementType.equals(standardLibrary.getCharType())) { - v.getfield("jet/arrays/JetCharArray", "array", "[C"); - } - else if (elementType.equals(standardLibrary.getFloatType())) { - v.getfield("jet/arrays/JetFloatArray", "array", "[F"); - } - else if (elementType.equals(standardLibrary.getDoubleType())) { - v.getfield("jet/arrays/JetDoubleArray", "array", "[D"); - } - else if (elementType.equals(standardLibrary.getBooleanType())) { - v.getfield("jet/arrays/JetBooleanArray", "array", "[Z"); - } - else { - if(typeMapper.isGenericsArray(type)) { - v.visitTypeInsn(Opcodes.CHECKCAST, "jet/arrays/JetArray"); - } - else { - v.getfield("jet/arrays/JetGenericArray", "array", "[Ljava/lang/Object;"); - v.visitTypeInsn(Opcodes.CHECKCAST, "[" + typeMapper.mapType(elementType).getDescriptor()); - } - } - } - } - @Override public StackValue visitThrowExpression(JetThrowExpression expression, StackValue receiver) { gen(expression.getThrownExpression(), JetTypeMapper.TYPE_OBJECT); @@ -2326,7 +2283,7 @@ public class ExpressionCodegen extends JetVisitor { return; } - if(!typeMapper.hasTypeInfoField(jetType) && !(bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, jetType.getConstructor().getDeclarationDescriptor()) instanceof PsiClass)) { + if(!CodegenUtil.hasTypeInfoField(jetType) && !(bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, jetType.getConstructor().getDeclarationDescriptor()) instanceof PsiClass)) { // TODO: we need some better checks here v.getstatic(typeMapper.mapType(jetType, OwnerKind.IMPLEMENTATION).getInternalName(), "$staticTypeInfo", "Ljet/typeinfo/TypeInfo;"); return; @@ -2383,12 +2340,13 @@ public class ExpressionCodegen extends JetVisitor { DeclarationDescriptor containingDeclaration = typeParameterDescriptor.getContainingDeclaration(); if (context.getContextClass() instanceof ClassDescriptor) { ClassDescriptor descriptor = (ClassDescriptor) context.getContextClass(); + assert containingDeclaration != null; JetType defaultType = ((ClassDescriptor)containingDeclaration).getDefaultType(); Type ownerType = typeMapper.mapType(defaultType); ownerType = JetTypeMapper.boxType(ownerType); if (containingDeclaration == context.getContextClass()) { if(!CodegenUtil.isInterface(descriptor)) { - if (typeMapper.hasTypeInfoField(defaultType)) { + if (CodegenUtil.hasTypeInfoField(defaultType)) { v.load(0, JetTypeMapper.TYPE_OBJECT); v.getfield(ownerType.getInternalName(), "$typeInfo", "Ljet/typeinfo/TypeInfo;"); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index f71f58aef92..e4d9fe7464b 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -33,8 +33,9 @@ public class FunctionCodegen { } public void gen(JetNamedFunction f) { - Method method = state.getTypeMapper().mapToCallableMethod(f, owner.getContextKind()).getSignature(); final FunctionDescriptor functionDescriptor = state.getBindingContext().get(BindingContext.FUNCTION, f); + assert functionDescriptor != null; + Method method = state.getTypeMapper().mapToCallableMethod(functionDescriptor, false, owner.getContextKind()).getSignature(); generateMethod(f, method, functionDescriptor); } @@ -105,9 +106,7 @@ public class FunctionCodegen { iv.areturn(jvmSignature.getReturnType()); } else { - for (int i = 0; i < paramDescrs.size(); i++) { - ValueParameterDescriptor parameter = paramDescrs.get(i); - + for (ValueParameterDescriptor parameter : paramDescrs) { Type sharedVarType = codegen.getSharedVarType(parameter); Type localVarType = state.getTypeMapper().mapType(parameter.getOutType()); if (sharedVarType != null) { @@ -253,6 +252,7 @@ public class FunctionCodegen { iv.ifeq(loadArg); JetParameter jetParameter = (JetParameter) state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, parameterDescriptor); + assert jetParameter != null; codegen.gen(jetParameter.getDefaultValue(), t); endArg = new Label(); @@ -270,7 +270,8 @@ public class FunctionCodegen { } for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) { - iv.load(var++, JetTypeMapper.TYPE_OBJECT); + if(typeParameterDescriptor.isReified()) + iv.load(var++, JetTypeMapper.TYPE_OBJECT); } if(!isStatic) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 98838271061..246ec23a07a 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -40,12 +40,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { for (JetDelegationSpecifier specifier : delegationSpecifiers) { JetType superType = state.getBindingContext().get(BindingContext.TYPE, specifier.getTypeReference()); + assert superType != null; ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); PsiElement superPsi = state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, superClassDescriptor); if (superPsi instanceof PsiClass) { PsiClass psiClass = (PsiClass) superPsi; String fqn = psiClass.getQualifiedName(); + assert fqn != null; if (psiClass.isInterface()) { superInterfaces.add(fqn.replace('.', '/')); } @@ -55,7 +57,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { while (psiClass != null) { for (PsiClass ifs : psiClass.getInterfaces()) { - superInterfaces.add(ifs.getQualifiedName().replace('.', '/')); + String qualifiedName = ifs.getQualifiedName(); + assert qualifiedName != null; + superInterfaces.add(qualifiedName.replace('.', '/')); } psiClass = psiClass.getSuperClass(); } @@ -67,7 +71,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } else { if(superPsi == null || ((JetClass)superPsi).isTrait()) - superInterfaces.add(JetTypeMapper.jvmNameForInterface(superClassDescriptor)); + superInterfaces.add(state.getTypeMapper().jvmNameForImplementation(superClassDescriptor, OwnerKind.IMPLEMENTATION)); } } return superInterfaces; @@ -127,6 +131,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { for (JetDelegationSpecifier specifier : delegationSpecifiers) { if (specifier instanceof JetDelegatorToSuperClass || specifier instanceof JetDelegatorToSuperCall) { JetType superType = state.getBindingContext().get(BindingContext.TYPE, specifier.getTypeReference()); + assert superType != null; ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); final PsiElement declaration = state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, superClassDescriptor); if (declaration != null) { @@ -161,12 +166,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } generateGetTypeInfo(); - //genGetSuperTypesTypeInfo(); } private void generateFieldForObjectInstance() { if (isNonLiteralObject()) { - Type type = JetTypeMapper.jetImplementationType(descriptor); + Type type = state.getTypeMapper().jetImplementationType(descriptor); v.newField(myClass, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "$instance", type.getDescriptor(), null, null); staticInitializerChunks.add(new CodeChunk() { @@ -176,7 +180,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { v.anew(Type.getObjectType(name)); v.dup(); v.invokespecial(name, "", "()V"); - v.putstatic(name, "$instance", JetTypeMapper.jetImplementationType(descriptor).getDescriptor()); + v.putstatic(name, "$instance", state.getTypeMapper().jetImplementationType(descriptor).getDescriptor()); } }); @@ -272,7 +276,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { HashSet overridden = new HashSet(); for (JetDeclaration declaration : myClass.getDeclarations()) { if (declaration instanceof JetFunction) { - overridden.addAll(state.getBindingContext().get(BindingContext.FUNCTION, declaration).getOverriddenDescriptors()); + FunctionDescriptor functionDescriptor = state.getBindingContext().get(BindingContext.FUNCTION, declaration); + assert functionDescriptor != null; + overridden.addAll(functionDescriptor.getOverriddenDescriptors()); } } @@ -284,6 +290,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { else { JetType superType = state.getBindingContext().get(BindingContext.TYPE, superCall.getTypeReference()); List parameterTypes = new ArrayList(); + assert superType != null; ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); if (CodegenUtil.hasThis0(superClassDescriptor)) { iv.load(1, JetTypeMapper.TYPE_OBJECT); @@ -313,9 +320,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { codegen.genToJVMStack(((JetDelegatorByExpressionSpecifier) specifier).getDelegateExpression()); JetType superType = state.getBindingContext().get(BindingContext.TYPE, specifier.getTypeReference()); + assert superType != null; ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); String delegateField = "$delegate_" + n; - Type fieldType = JetTypeMapper.jetInterfaceType(superClassDescriptor); + Type fieldType = state.getTypeMapper().jetImplementationType(superClassDescriptor); String fieldDesc = fieldType.getDescriptor(); v.newField(specifier, Opcodes.ACC_PRIVATE, delegateField, fieldDesc, /*TODO*/null, null); iv.putfield(classname, delegateField, fieldDesc); @@ -323,14 +331,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { JetClass superClass = (JetClass) state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, superClassDescriptor); final ClassContext delegateContext = context.intoClass(null, superClassDescriptor, new OwnerKind.DelegateKind(StackValue.field(fieldType, classname, delegateField, false), - JetTypeMapper.jvmNameForInterface(superClassDescriptor))); + state.getTypeMapper().jvmNameForImplementation(superClassDescriptor, OwnerKind.IMPLEMENTATION))); generateDelegates(superClass, delegateContext, overridden); } } final ClassDescriptor outerDescriptor = getOuterClassDescriptor(); if (outerDescriptor != null && outerDescriptor.getKind() != ClassKind.OBJECT) { - final Type type = JetTypeMapper.jetImplementationType(outerDescriptor); + final Type type = state.getTypeMapper().jetImplementationType(outerDescriptor); String interfaceDesc = type.getDescriptor(); final String fieldName = "this$0"; v.newField(myClass, Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, fieldName, interfaceDesc, null, null); @@ -339,7 +347,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { iv.putfield(classname, fieldName, interfaceDesc); } - if (state.getTypeMapper().hasTypeInfoField(descriptor.getDefaultType()) && kind == OwnerKind.IMPLEMENTATION) { + if (CodegenUtil.hasTypeInfoField(descriptor.getDefaultType()) && kind == OwnerKind.IMPLEMENTATION) { generateTypeInfoInitializer(frameMap.getFirstTypeParameter(), frameMap.getTypeParameterCount(), iv); } @@ -450,14 +458,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { ConstructorDescriptor constructorDescriptor, ConstructorFrameMap frameMap) { ClassDescriptor classDecl = constructorDescriptor.getContainingDeclaration(); - PsiElement declaration = state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, classDecl); Type type; - if (declaration instanceof PsiClass) { - type = JetTypeMapper.psiClassType((PsiClass) declaration); - } - else { - type = JetTypeMapper.jetImplementationType(classDecl); - } + type = state.getTypeMapper().jetImplementationType(classDecl); iv.load(0, type); @@ -671,7 +673,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if (declaration instanceof JetProperty) { propertyCodegen.gen((JetProperty) declaration); } - else if (declaration instanceof JetFunction) { + else if (declaration instanceof JetNamedFunction) { if (!overriden.contains(state.getBindingContext().get(BindingContext.FUNCTION, declaration))) { functionCodegen.gen((JetNamedFunction) declaration); } @@ -706,8 +708,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { return; JetType defaultType = descriptor.getDefaultType(); - if(state.getTypeMapper().hasTypeInfoField(defaultType)) { - if(!state.getTypeMapper().hasDerivedTypeInfoField(defaultType, true)) { + if(CodegenUtil.hasTypeInfoField(defaultType)) { + if(!CodegenUtil.hasDerivedTypeInfoField(defaultType, true)) { v.newField(myClass, Opcodes.ACC_PRIVATE, "$typeInfo", "Ljet/typeinfo/TypeInfo;", null, null); MethodVisitor mv = v.newMethod(myClass, Opcodes.ACC_PUBLIC, "getTypeInfo", "()Ljet/typeinfo/TypeInfo;", null, null); @@ -773,51 +775,4 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { private void generateClassObject(JetClassObject declaration) { state.forClass().generate(context, declaration.getObjectDeclaration()); } - - private void genGetSuperTypesTypeInfo() { - if(!(myClass instanceof JetClass) || ((JetClass)myClass).isTrait()) { - return; - } - - String sig = getGetSuperTypesTypeInfoSignature(descriptor.getDefaultType()); - - final MethodVisitor mv = v.newMethod(myClass, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, - "$$getSuperTypesTypeInfo", - sig, - null /* TODO */, - null); - mv.visitCode(); - InstructionAdapter v = new InstructionAdapter(mv); - - ExpressionCodegen codegen = new ExpressionCodegen(v, new FrameMap(), Type.VOID_TYPE, context, state); - - v.load(0, JetTypeMapper.TYPE_OBJECT); - - int k = 1; - for (TypeParameterDescriptor parameterDescriptor : descriptor.getTypeConstructor().getParameters()) { - codegen.addTypeParameter(parameterDescriptor, StackValue.local(k++, JetTypeMapper.TYPE_TYPEINFO)); - } - - for(JetType superType : descriptor.getTypeConstructor().getSupertypes()) { - for (TypeProjection typeProjection : superType.getArguments()) { - codegen.generateTypeInfo(typeProjection.getType()); - } - v.invokestatic(state.getTypeMapper().mapType(superType).getInternalName(), "$$getSuperTypesTypeInfo", getGetSuperTypesTypeInfoSignature(superType)); - } - - v.areturn(Type.VOID_TYPE); - mv.visitMaxs(0, 0); - mv.visitEnd(); - } - - private static String getGetSuperTypesTypeInfoSignature(JetType type) { - List typeParameters = type.getConstructor().getParameters(); - StringBuilder sb = new StringBuilder("(Ljava/util/Set;"); - for(TypeParameterDescriptor tp : typeParameters) - sb.append("Ljet/typeinfo/TypeInfo;"); - sb.append(")V"); - - return sb.toString(); - } - } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index 66737f8de1e..e889f3b0323 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -15,7 +15,6 @@ import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.resolve.DescriptorRenderer; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; -import org.objectweb.asm.commons.InstructionAdapter; import org.objectweb.asm.commons.Method; import java.util.*; @@ -57,7 +56,9 @@ public class JetTypeMapper { private final Map classNamesForAnonymousClasses = new HashMap(); private final Map anonymousSubclassesCount = new HashMap(); - private final HashMap knowTypes = new HashMap(); + private final HashMap knowTypeNames = new HashMap(); + private final HashMap knowTypes = new HashMap(); + public static final Type TYPE_FUNCTION1 = Type.getObjectType("jet/Function1"); public static final Type TYPE_ITERATOR = Type.getObjectType("jet/Iterator"); public static final Type TYPE_INT_RANGE = Type.getObjectType("jet/IntRange"); @@ -75,14 +76,7 @@ public class JetTypeMapper { this.standardLibrary = standardLibrary; this.bindingContext = bindingContext; initKnownTypes(); - } - - static String jvmName(PsiClass psiClass) { - final String qName = psiClass.getQualifiedName(); - if (qName == null) { - throw new UnsupportedOperationException("can't evaluate JVM name for anonymous class " + psiClass); - } - return qName.replace(".", "/"); + initKnownTypeNames(); } public static boolean isIntPrimitive(Type type) { @@ -102,68 +96,6 @@ public class JetTypeMapper { || type == Type.VOID_TYPE; } - static Type psiTypeToAsm(PsiType type) { - if(type instanceof PsiArrayType) { - PsiArrayType psiArrayType = (PsiArrayType) type; - return Type.getType("[" + psiTypeToAsm(psiArrayType.getComponentType()).getDescriptor()); - } - - if (type instanceof PsiPrimitiveType) { - if (type == PsiType.VOID) { - return Type.VOID_TYPE; - } - if (type == PsiType.INT) { - return Type.INT_TYPE; - } - if (type == PsiType.LONG) { - return Type.LONG_TYPE; - } - if (type == PsiType.BOOLEAN) { - return Type.BOOLEAN_TYPE; - } - if (type == PsiType.BYTE) { - return Type.BYTE_TYPE; - } - if (type == PsiType.SHORT) { - return Type.SHORT_TYPE; - } - if (type == PsiType.CHAR) { - return Type.CHAR_TYPE; - } - if (type == PsiType.FLOAT) { - return Type.FLOAT_TYPE; - } - if (type == PsiType.DOUBLE) { - return Type.DOUBLE_TYPE; - } - } - if (type instanceof PsiClassType) { - PsiClass psiClass = ((PsiClassType) type).resolve(); - if (psiClass instanceof PsiTypeParameter) { - final PsiClassType[] extendsListTypes = psiClass.getExtendsListTypes(); - if (extendsListTypes.length > 0) { - throw new UnsupportedOperationException("should return common supertype"); - } - return TYPE_OBJECT; - } - if (psiClass == null) { - throw new UnsupportedOperationException("unresolved PsiClassType: " + type); - } - return psiClassType(psiClass); - } - throw new UnsupportedOperationException("don't know how to map type " + type + " to ASM"); - } - - static Method getMethodDescriptor(PsiMethod method) { - Type returnType = method.isConstructor() ? Type.VOID_TYPE : psiTypeToAsm(method.getReturnType()); - PsiParameter[] parameters = method.getParameterList().getParameters(); - Type[] parameterTypes = new Type[parameters.length]; - for (int i = 0; i < parameters.length; i++) { - parameterTypes[i] = psiTypeToAsm(parameters[i].getType()); - } - return new Method(method.isConstructor() ? "" : method.getName(), Type.getMethodDescriptor(returnType, parameterTypes)); - } - public static Type getBoxedType(final Type type) { switch (type.getSort()) { case Type.BYTE: @@ -186,44 +118,8 @@ public class JetTypeMapper { return type; } - public boolean hasTypeInfoField(JetType type) { - if(type.getConstructor().getParameters().size() > 0) { - if(!(bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, type.getConstructor().getDeclarationDescriptor()) instanceof PsiClass)) - return true; - } - - for (JetType jetType : type.getConstructor().getSupertypes()) { - if(hasTypeInfoField(jetType)) - return true; - } - - ClassDescriptor outerClassDescriptor = CodegenUtil.getOuterClassDescriptor(type.getConstructor().getDeclarationDescriptor()); - if(outerClassDescriptor == null) - return false; - - return hasTypeInfoField(outerClassDescriptor.getDefaultType()); - } - - public boolean hasDerivedTypeInfoField(JetType type, boolean exceptOwn) { - if(!exceptOwn) { - if(!CodegenUtil.isInterface(type)) - if(hasTypeInfoField(type)) - return true; - } - - for (JetType jetType : type.getConstructor().getSupertypes()) { - if(hasDerivedTypeInfoField(jetType, false)) - return true; - } - - return false; - } - public String jvmName(ClassDescriptor jetClass, OwnerKind kind) { PsiElement declaration = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, jetClass); - if (declaration instanceof PsiClass) { - return jvmName((PsiClass) declaration); - } if (declaration instanceof JetObjectDeclaration && ((JetObjectDeclaration) declaration).isObjectLiteral()) { final PsiElement parent = declaration.getParent(); if (parent instanceof JetClassObject) { @@ -245,15 +141,15 @@ public class JetTypeMapper { return jvmName(descriptor, OwnerKind.IMPLEMENTATION); } - private static String jetJvmName(ClassDescriptor jetClass, OwnerKind kind) { + private String jetJvmName(ClassDescriptor jetClass, OwnerKind kind) { if (jetClass.getKind() == ClassKind.OBJECT) { - return jvmNameForImplementation(jetClass); + return jvmNameForImplementation(jetClass, OwnerKind.IMPLEMENTATION); } else if (kind == OwnerKind.IMPLEMENTATION) { - return jvmNameForImplementation(jetClass); + return jvmNameForImplementation(jetClass, OwnerKind.IMPLEMENTATION); } else if (kind == OwnerKind.TRAIT_IMPL) { - return jvmNameForTraitImpl(jetClass); + return jvmNameForImplementation(jetClass, OwnerKind.IMPLEMENTATION) + "$$TImpl"; } else { assert false : "Unsuitable kind"; @@ -268,16 +164,8 @@ public class JetTypeMapper { return Type.getType("L" + jvmName(jetClass, kind) + ";"); } - static Type psiClassType(PsiClass psiClass) { - return Type.getType("L" + jvmName(psiClass) + ";"); - } - - static Type jetInterfaceType(ClassDescriptor classDescriptor) { - return Type.getType("L" + jvmNameForInterface(classDescriptor) + ";"); - } - - static Type jetImplementationType(ClassDescriptor classDescriptor) { - return Type.getType("L" + jvmNameForImplementation(classDescriptor) + ";"); + Type jetImplementationType(ClassDescriptor classDescriptor) { + return Type.getType("L" + jvmNameForImplementation(classDescriptor, OwnerKind.IMPLEMENTATION) + ";"); } public static String jvmName(JetNamespace namespace) { @@ -288,30 +176,22 @@ public class JetTypeMapper { return NamespaceCodegen.getJVMClassName(DescriptorRenderer.getFQName(namespace)); } - public static String jvmNameForInterface(ClassDescriptor descriptor) { - return DescriptorRenderer.getFQName(descriptor).replace('.', '/'); - } - - public static String jvmNameForImplementation(ClassDescriptor descriptor) { - return jvmNameForInterface(descriptor); - } - - private static String jvmNameForTraitImpl(ClassDescriptor descriptor) { - return jvmNameForInterface(descriptor) + "$$TImpl"; + public String jvmNameForImplementation(ClassDescriptor descriptor, OwnerKind kind) { + return mapType(descriptor.getDefaultType(), kind).getInternalName(); } public String getOwner(DeclarationDescriptor descriptor, OwnerKind kind) { String owner; - if (descriptor.getContainingDeclaration() instanceof NamespaceDescriptorImpl) { - owner = jvmName((NamespaceDescriptor) descriptor.getContainingDeclaration()); + DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); + if (containingDeclaration instanceof NamespaceDescriptor) { + owner = jvmName((NamespaceDescriptor) containingDeclaration); } - else if (descriptor.getContainingDeclaration() instanceof ClassDescriptor) { - ClassDescriptor classDescriptor = (ClassDescriptor) descriptor.getContainingDeclaration(); + else if (containingDeclaration instanceof ClassDescriptor) { + ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration; if (kind instanceof OwnerKind.DelegateKind) { kind = OwnerKind.IMPLEMENTATION; } else { - assert classDescriptor != null; if (classDescriptor.getKind() == ClassKind.OBJECT) { kind = OwnerKind.IMPLEMENTATION; } @@ -319,23 +199,19 @@ public class JetTypeMapper { owner = jvmName(classDescriptor, kind); } else { - throw new UnsupportedOperationException("don't know how to generate owner for parent " + descriptor.getContainingDeclaration()); + throw new UnsupportedOperationException("don't know how to generate owner for parent " + containingDeclaration); } return owner; } - @NotNull public Type mapReturnType(@NotNull final JetType jetType, OwnerKind kind) { + @NotNull public Type mapReturnType(final JetType jetType) { if (jetType.equals(JetStandardClasses.getUnitType()) || jetType.equals(JetStandardClasses.getNothingType())) { return Type.VOID_TYPE; } if (jetType.equals(JetStandardClasses.getNullableNothingType())) { return TYPE_OBJECT; } - return mapType(jetType, kind); - } - - @NotNull public Type mapReturnType(final JetType jetType) { - return mapReturnType(jetType, OwnerKind.IMPLEMENTATION); + return mapType(jetType, OwnerKind.IMPLEMENTATION); } @NotNull public Type mapType(final JetType jetType) { @@ -343,85 +219,9 @@ public class JetTypeMapper { } @NotNull public Type mapType(@NotNull final JetType jetType, OwnerKind kind) { - if (jetType.equals(JetStandardClasses.getNothingType()) || jetType.equals(JetStandardClasses.getNullableNothingType())) { - return TYPE_NOTHING; - } - if (jetType.equals(standardLibrary.getIntType())) { - return Type.INT_TYPE; - } - if (jetType.equals(standardLibrary.getNullableIntType())) { - return JL_INTEGER_TYPE; - } - if (jetType.equals(standardLibrary.getLongType())) { - return Type.LONG_TYPE; - } - if (jetType.equals(standardLibrary.getNullableLongType())) { - return JL_LONG_TYPE; - } - if (jetType.equals(standardLibrary.getShortType())) { - return Type.SHORT_TYPE; - } - if (jetType.equals(standardLibrary.getNullableShortType())) { - return JL_SHORT_TYPE; - } - if (jetType.equals(standardLibrary.getByteType())) { - return Type.BYTE_TYPE; - } - if (jetType.equals(standardLibrary.getNullableByteType())) { - return JL_BYTE_TYPE; - } - if (jetType.equals(standardLibrary.getCharType())) { - return Type.CHAR_TYPE; - } - if (jetType.equals(standardLibrary.getNullableCharType())) { - return JL_CHAR_TYPE; - } - if (jetType.equals(standardLibrary.getFloatType())) { - return Type.FLOAT_TYPE; - } - if (jetType.equals(standardLibrary.getNullableFloatType())) { - return JL_FLOAT_TYPE; - } - if (jetType.equals(standardLibrary.getDoubleType())) { - return Type.DOUBLE_TYPE; - } - if (jetType.equals(standardLibrary.getNullableDoubleType())) { - return JL_DOUBLE_TYPE; - } - if (jetType.equals(standardLibrary.getBooleanType())) { - return Type.BOOLEAN_TYPE; - } - if (jetType.equals(standardLibrary.getNullableBooleanType())) { - return JL_BOOLEAN_TYPE; - } - if(jetType.equals(standardLibrary.getByteArrayType())){ - return ARRAY_BYTE_TYPE; - } - if(jetType.equals(standardLibrary.getShortArrayType())){ - return ARRAY_SHORT_TYPE; - } - if(jetType.equals(standardLibrary.getIntArrayType())){ - return ARRAY_INT_TYPE; - } - if(jetType.equals(standardLibrary.getLongArrayType())){ - return ARRAY_LONG_TYPE; - } - if(jetType.equals(standardLibrary.getFloatArrayType())){ - return ARRAY_FLOAT_TYPE; - } - if(jetType.equals(standardLibrary.getDoubleArrayType())){ - return ARRAY_DOUBLE_TYPE; - } - if(jetType.equals(standardLibrary.getCharArrayType())){ - return ARRAY_CHAR_TYPE; - } - if(jetType.equals(standardLibrary.getBooleanArrayType())){ - return ARRAY_BOOL_TYPE; - } - - if (jetType.equals(standardLibrary.getStringType()) || jetType.equals(standardLibrary.getNullableStringType())) { - return Type.getType(String.class); - } + Type known = knowTypes.get(jetType); + if(known != null) + return known; DeclarationDescriptor descriptor = jetType.getConstructor().getDeclarationDescriptor(); if (standardLibrary.getArray().equals(descriptor)) { @@ -439,7 +239,10 @@ public class JetTypeMapper { } if (descriptor instanceof ClassDescriptor) { - return Type.getObjectType(jvmName((ClassDescriptor) descriptor, kind)); + String name = DescriptorRenderer.getFQName(descriptor).replace('.', '/'); + if(name.startsWith("")) + name = name.substring("".length()+1); + return Type.getObjectType(name + (kind == OwnerKind.TRAIT_IMPL ? "$$TImpl" : "")); } if (descriptor instanceof TypeParameterDescriptor) { @@ -503,6 +306,54 @@ public class JetTypeMapper { } + public CallableMethod mapToCallableMethod(FunctionDescriptor functionDescriptor, boolean superCall, OwnerKind kind) { + if(functionDescriptor == null) + return null; + + final DeclarationDescriptor functionParent = functionDescriptor.getContainingDeclaration(); + final List valueParameterTypes = new ArrayList(); + Method descriptor = mapSignature(functionDescriptor.getOriginal(), valueParameterTypes, kind); + String owner; + int invokeOpcode; + ClassDescriptor thisClass; + if (functionParent instanceof NamespaceDescriptor) { + assert !superCall; + owner = NamespaceCodegen.getJVMClassName(DescriptorRenderer.getFQName(functionParent)); + invokeOpcode = Opcodes.INVOKESTATIC; + thisClass = null; + } + else if (functionDescriptor instanceof ConstructorDescriptor) { + assert !superCall; + ClassDescriptor containingClass = (ClassDescriptor) functionParent; + owner = jvmName(containingClass, OwnerKind.IMPLEMENTATION); + invokeOpcode = Opcodes.INVOKESPECIAL; + thisClass = null; + } + else if (functionParent instanceof ClassDescriptor) { + ClassDescriptor containingClass = (ClassDescriptor) functionParent; + boolean isInterface = CodegenUtil.isInterface(containingClass); + owner = jvmName(containingClass, isInterface && superCall ? OwnerKind.TRAIT_IMPL : OwnerKind.IMPLEMENTATION); + invokeOpcode = isInterface + ? (superCall ? Opcodes.INVOKESTATIC : Opcodes.INVOKEINTERFACE) + : (superCall ? Opcodes.INVOKESPECIAL : Opcodes.INVOKEVIRTUAL); + if(isInterface && superCall) { + descriptor = mapSignature(functionDescriptor.getOriginal(), valueParameterTypes, OwnerKind.TRAIT_IMPL); + } + thisClass = containingClass; + } + else { + throw new UnsupportedOperationException("unknown function parent"); + } + + final CallableMethod result = new CallableMethod(owner, descriptor, invokeOpcode, valueParameterTypes); + result.setNeedsThis(thisClass); + if(functionDescriptor.getReceiverParameter().exists()) { + result.setNeedsReceiver(functionDescriptor.getReceiverParameter().getType().getConstructor().getDeclarationDescriptor()); + } + + return result; + } + private Method mapSignature(FunctionDescriptor f, List valueParameterTypes, OwnerKind kind) { final ReceiverDescriptor receiverTypeRef = f.getReceiverParameter(); final JetType receiverType = !receiverTypeRef.exists() ? null : receiverTypeRef.getType(); @@ -527,95 +378,15 @@ public class JetTypeMapper { valueParameterTypes.add(type); parameterTypes.add(type); } - for (int n = f.getTypeParameters().size(); n > 0; n--) { - parameterTypes.add(TYPE_TYPEINFO); + for (TypeParameterDescriptor parameterDescriptor : f.getTypeParameters()) { + if(parameterDescriptor.isReified()) { + parameterTypes.add(TYPE_TYPEINFO); + } } - Type returnType = mapReturnType(f.getReturnType()); + Type returnType = f instanceof ConstructorDescriptor ? Type.VOID_TYPE : mapReturnType(f.getReturnType()); return new Method(f.getName(), returnType, parameterTypes.toArray(new Type[parameterTypes.size()])); } - public CallableMethod mapToCallableMethod(PsiNamedElement declaration, OwnerKind kind) { - if (declaration instanceof PsiMethod) { - return mapToCallableMethod((PsiMethod) declaration); - } - if (!(declaration instanceof JetNamedFunction)) { - throw new UnsupportedOperationException("unknown declaration type " + declaration); - } - JetNamedFunction f = (JetNamedFunction) declaration; - final FunctionDescriptor functionDescriptor = bindingContext.get(BindingContext.FUNCTION, f); - assert functionDescriptor != null; - return mapToCallableMethod(functionDescriptor, kind); - } - - static CallableMethod mapToCallableMethod(PsiMethod method) { - final PsiClass containingClass = method.getContainingClass(); - String owner = jvmName(containingClass); - Method signature = getMethodDescriptor(method); - List valueParameterTypes = new ArrayList(); - Collections.addAll(valueParameterTypes, signature.getArgumentTypes()); - int opcode; - boolean ownerFromCall = false; - DeclarationDescriptor thisClass = null; - if (method.isConstructor()) { - opcode = Opcodes.INVOKESPECIAL; - } - else if (method.hasModifierProperty(PsiModifier.STATIC)) { - opcode = Opcodes.INVOKESTATIC; - } - else { - assert containingClass != null; - if (containingClass.isInterface()) { - opcode = Opcodes.INVOKEINTERFACE; - } - else { - opcode = Opcodes.INVOKEVIRTUAL; - } - ownerFromCall = true; - thisClass = JetStandardClasses.getAny(); // todo - this is hack, correct descriptor needed - } - final CallableMethod result = new CallableMethod(owner, signature, opcode, valueParameterTypes); - result.setNeedsThis(thisClass); - result.setOwnerFromCall(ownerFromCall); - return result; - } - - public CallableMethod mapToCallableMethod(FunctionDescriptor functionDescriptor, OwnerKind kind) { - if(functionDescriptor == null) - return null; - - final DeclarationDescriptor functionParent = functionDescriptor.getContainingDeclaration(); - final List valueParameterTypes = new ArrayList(); - Method descriptor = mapSignature(functionDescriptor.getOriginal(), valueParameterTypes, kind); - String owner; - int invokeOpcode; - ClassDescriptor thisClass; - if (functionParent instanceof NamespaceDescriptor) { - owner = NamespaceCodegen.getJVMClassName(DescriptorRenderer.getFQName(functionParent)); - invokeOpcode = Opcodes.INVOKESTATIC; - thisClass = null; - } - else if (functionParent instanceof ClassDescriptor) { - ClassDescriptor containingClass = (ClassDescriptor) functionParent; - owner = jvmName(containingClass, OwnerKind.IMPLEMENTATION); - invokeOpcode = CodegenUtil.isInterface(containingClass) - ? Opcodes.INVOKEINTERFACE - : Opcodes.INVOKEVIRTUAL; - thisClass = containingClass; - } - else { - throw new UnsupportedOperationException("unknown function parent"); - } - - final CallableMethod result = new CallableMethod(owner, descriptor, invokeOpcode, valueParameterTypes); - result.setAcceptsTypeArguments(true); - result.setNeedsThis(thisClass); - if(functionDescriptor.getReceiverParameter().exists()) { - result.setNeedsReceiver(functionDescriptor.getReceiverParameter().getType().getConstructor().getDeclarationDescriptor()); - } - - return result; - } - public Method mapSignature(String name, FunctionDescriptor f) { final ReceiverDescriptor receiver = f.getReceiverParameter(); final List parameters = f.getValueParameters(); @@ -666,6 +437,7 @@ public class JetTypeMapper { return new Method(PropertyCodegen.getterName(descriptor.getName()), returnType, new Type[0]); else { ClassDescriptor containingDeclaration = (ClassDescriptor) descriptor.getContainingDeclaration(); + assert containingDeclaration != null; return new Method(PropertyCodegen.getterName(descriptor.getName()), returnType, new Type[] { mapType(containingDeclaration.getDefaultType()) }); } } @@ -681,6 +453,7 @@ public class JetTypeMapper { } else { ClassDescriptor containingDeclaration = (ClassDescriptor) descriptor.getContainingDeclaration(); + assert containingDeclaration != null; return new Method(PropertyCodegen.setterName(descriptor.getName()), Type.VOID_TYPE, new Type[] { mapType(containingDeclaration.getDefaultType()), paramType }); } } @@ -713,9 +486,7 @@ public class JetTypeMapper { List valueParameterTypes = new ArrayList(); final Method method = mapConstructorSignature(descriptor, valueParameterTypes); String owner = jvmName(descriptor.getContainingDeclaration(), kind); - final CallableMethod result = new CallableMethod(owner, method, Opcodes.INVOKESPECIAL, valueParameterTypes); - result.setAcceptsTypeArguments(!(bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor.getContainingDeclaration()) instanceof PsiClass)); - return result; + return new CallableMethod(owner, method, Opcodes.INVOKESPECIAL, valueParameterTypes); } static int getAccessModifiers(JetDeclaration p, int defaultFlags) { @@ -746,7 +517,7 @@ public class JetTypeMapper { } else { ClassDescriptor aClass = bindingContext.get(BindingContext.CLASS, container); - baseName = jvmNameForInterface(aClass); + baseName = jvmNameForImplementation(aClass, OwnerKind.IMPLEMENTATION); } Integer count = anonymousSubclassesCount.get(baseName); @@ -768,40 +539,90 @@ public class JetTypeMapper { return result; } - private void initKnownTypes() { - knowTypes.put(standardLibrary.getIntType(), "INT_TYPE_INFO"); - knowTypes.put(standardLibrary.getNullableIntType(), "NULLABLE_INT_TYPE_INFO"); - knowTypes.put(standardLibrary.getLongType(), "LONG_TYPE_INFO"); - knowTypes.put(standardLibrary.getNullableLongType(), "NULLABLE_LONG_TYPE_INFO"); - knowTypes.put(standardLibrary.getShortType(),"SHORT_TYPE_INFO"); - knowTypes.put(standardLibrary.getNullableShortType(),"NULLABLE_SHORT_TYPE_INFO"); - knowTypes.put(standardLibrary.getByteType(),"BYTE_TYPE_INFO"); - knowTypes.put(standardLibrary.getNullableByteType(),"NULLABLE_BYTE_TYPE_INFO"); - knowTypes.put(standardLibrary.getCharType(),"CHAR_TYPE_INFO"); - knowTypes.put(standardLibrary.getNullableCharType(),"NULLABLE_CHAR_TYPE_INFO"); - knowTypes.put(standardLibrary.getFloatType(),"FLOAT_TYPE_INFO"); - knowTypes.put(standardLibrary.getNullableFloatType(),"NULLABLE_FLOAT_TYPE_INFO"); - knowTypes.put(standardLibrary.getDoubleType(),"DOUBLE_TYPE_INFO"); - knowTypes.put(standardLibrary.getNullableDoubleType(),"NULLABLE_DOUBLE_TYPE_INFO"); - knowTypes.put(standardLibrary.getBooleanType(),"BOOLEAN_TYPE_INFO"); - knowTypes.put(standardLibrary.getNullableBooleanType(),"NULLABLE_BOOLEAN_TYPE_INFO"); - knowTypes.put(standardLibrary.getStringType(),"STRING_TYPE_INFO"); - knowTypes.put(standardLibrary.getNullableStringType(),"NULLABLE_STRING_TYPE_INFO"); - knowTypes.put(standardLibrary.getTuple0Type(),"TUPLE0_TYPE_INFO"); - knowTypes.put(standardLibrary.getNullableTuple0Type(),"NULLABLE_TUPLE0_TYPE_INFO"); + private void initKnownTypeNames() { + knowTypeNames.put(standardLibrary.getIntType(), "INT_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getNullableIntType(), "NULLABLE_INT_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getLongType(), "LONG_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getNullableLongType(), "NULLABLE_LONG_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getShortType(),"SHORT_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getNullableShortType(),"NULLABLE_SHORT_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getByteType(),"BYTE_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getNullableByteType(),"NULLABLE_BYTE_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getCharType(),"CHAR_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getNullableCharType(),"NULLABLE_CHAR_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getFloatType(),"FLOAT_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getNullableFloatType(),"NULLABLE_FLOAT_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getDoubleType(),"DOUBLE_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getNullableDoubleType(),"NULLABLE_DOUBLE_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getBooleanType(),"BOOLEAN_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getNullableBooleanType(),"NULLABLE_BOOLEAN_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getStringType(),"STRING_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getNullableStringType(),"NULLABLE_STRING_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getTuple0Type(),"TUPLE0_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getNullableTuple0Type(),"NULLABLE_TUPLE0_TYPE_INFO"); - knowTypes.put(standardLibrary.getIntArrayType(), "INT_ARRAY_TYPE_INFO"); - knowTypes.put(standardLibrary.getLongArrayType(), "LONG_ARRAY_TYPE_INFO"); - knowTypes.put(standardLibrary.getShortArrayType(),"SHORT_ARRAY_TYPE_INFO"); - knowTypes.put(standardLibrary.getByteArrayType(),"BYTE_ARRAY_TYPE_INFO"); - knowTypes.put(standardLibrary.getCharArrayType(),"CHAR_ARRAY_TYPE_INFO"); - knowTypes.put(standardLibrary.getFloatArrayType(),"FLOAT_ARRAY_TYPE_INFO"); - knowTypes.put(standardLibrary.getDoubleArrayType(),"DOUBLE_ARRAY_TYPE_INFO"); - knowTypes.put(standardLibrary.getBooleanArrayType(),"BOOLEAN_ARRAY_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getIntArrayType(), "INT_ARRAY_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getLongArrayType(), "LONG_ARRAY_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getShortArrayType(),"SHORT_ARRAY_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getByteArrayType(),"BYTE_ARRAY_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getCharArrayType(),"CHAR_ARRAY_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getFloatArrayType(),"FLOAT_ARRAY_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getDoubleArrayType(),"DOUBLE_ARRAY_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getBooleanArrayType(),"BOOLEAN_ARRAY_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getNullableIntArrayType(), "INT_ARRAY_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getNullableLongArrayType(), "LONG_ARRAY_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getNullableShortArrayType(),"SHORT_ARRAY_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getNullableByteArrayType(),"BYTE_ARRAY_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getNullableCharArrayType(),"CHAR_ARRAY_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getNullableFloatArrayType(),"FLOAT_ARRAY_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getNullableDoubleArrayType(),"DOUBLE_ARRAY_TYPE_INFO"); + knowTypeNames.put(standardLibrary.getNullableBooleanArrayType(),"BOOLEAN_ARRAY_TYPE_INFO"); + } + + private void initKnownTypes() { + knowTypes.put(JetStandardClasses.getNothingType(), TYPE_NOTHING); + knowTypes.put(JetStandardClasses.getNullableNothingType(), TYPE_NOTHING); + + knowTypes.put(standardLibrary.getIntType(), Type.INT_TYPE); + knowTypes.put(standardLibrary.getNullableIntType(), JL_INTEGER_TYPE); + knowTypes.put(standardLibrary.getLongType(), Type.LONG_TYPE); + knowTypes.put(standardLibrary.getNullableLongType(), JL_LONG_TYPE); + knowTypes.put(standardLibrary.getShortType(),Type.SHORT_TYPE); + knowTypes.put(standardLibrary.getNullableShortType(),JL_SHORT_TYPE); + knowTypes.put(standardLibrary.getByteType(),Type.BYTE_TYPE); + knowTypes.put(standardLibrary.getNullableByteType(),JL_BYTE_TYPE); + knowTypes.put(standardLibrary.getCharType(),Type.CHAR_TYPE); + knowTypes.put(standardLibrary.getNullableCharType(),JL_CHAR_TYPE); + knowTypes.put(standardLibrary.getFloatType(),Type.FLOAT_TYPE); + knowTypes.put(standardLibrary.getNullableFloatType(),JL_FLOAT_TYPE); + knowTypes.put(standardLibrary.getDoubleType(),Type.DOUBLE_TYPE); + knowTypes.put(standardLibrary.getNullableDoubleType(),JL_DOUBLE_TYPE); + knowTypes.put(standardLibrary.getBooleanType(),Type.BOOLEAN_TYPE); + knowTypes.put(standardLibrary.getNullableBooleanType(),JL_BOOLEAN_TYPE); + + knowTypes.put(standardLibrary.getStringType(),JL_STRING_TYPE); + knowTypes.put(standardLibrary.getNullableStringType(),JL_STRING_TYPE); + + knowTypes.put(standardLibrary.getIntArrayType(), ARRAY_INT_TYPE); + knowTypes.put(standardLibrary.getLongArrayType(), ARRAY_LONG_TYPE); + knowTypes.put(standardLibrary.getShortArrayType(),ARRAY_SHORT_TYPE); + knowTypes.put(standardLibrary.getByteArrayType(),ARRAY_BYTE_TYPE); + knowTypes.put(standardLibrary.getCharArrayType(),ARRAY_CHAR_TYPE); + knowTypes.put(standardLibrary.getFloatArrayType(),ARRAY_FLOAT_TYPE); + knowTypes.put(standardLibrary.getDoubleArrayType(),ARRAY_DOUBLE_TYPE); + knowTypes.put(standardLibrary.getBooleanArrayType(),ARRAY_BOOL_TYPE); + knowTypes.put(standardLibrary.getNullableIntArrayType(), ARRAY_INT_TYPE); + knowTypes.put(standardLibrary.getNullableLongArrayType(), ARRAY_LONG_TYPE); + knowTypes.put(standardLibrary.getNullableShortArrayType(),ARRAY_SHORT_TYPE); + knowTypes.put(standardLibrary.getNullableByteArrayType(),ARRAY_BYTE_TYPE); + knowTypes.put(standardLibrary.getNullableCharArrayType(),ARRAY_CHAR_TYPE); + knowTypes.put(standardLibrary.getNullableFloatArrayType(),ARRAY_FLOAT_TYPE); + knowTypes.put(standardLibrary.getNullableDoubleArrayType(),ARRAY_DOUBLE_TYPE); + knowTypes.put(standardLibrary.getNullableBooleanArrayType(),ARRAY_BOOL_TYPE); } public String isKnownTypeInfo(JetType jetType) { - return knowTypes.get(jetType); + return knowTypeNames.get(jetType); } public boolean isGenericsArray(JetType type) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java index 2bef71dfaa6..f31a07fa725 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java @@ -196,6 +196,11 @@ public class NamespaceCodegen { if (fqName.length() == 0) { return "namespace"; } - return fqName.replace('.', '/') + "/namespace"; + + String name = fqName.replace('.', '/') + "/namespace"; + if(name.startsWith("")) { + name = name.substring("".length() + 1, name.length() - ".namespace".length()); + } + return name; } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java index 1d58a515884..dd642a30533 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java @@ -132,7 +132,7 @@ public class IntrinsicMethods { final PsiMethod[] methods = stringPsiClass.findMethodsByName(stringMember.getName(), false); for (PsiMethod method : methods) { if (method.getParameterList().getParametersCount() == stringMethod.getValueParameters().size()) { - myMethods.put(stringMethod, new PsiMethodCall(method)); + myMethods.put(stringMethod, new PsiMethodCall(stringMethod)); } } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/PsiMethodCall.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/PsiMethodCall.java index 1025f23c5a6..ca76cd1e008 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/PsiMethodCall.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/PsiMethodCall.java @@ -1,10 +1,11 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiMethod; import org.jetbrains.jet.codegen.CallableMethod; import org.jetbrains.jet.codegen.ExpressionCodegen; +import org.jetbrains.jet.codegen.OwnerKind; import org.jetbrains.jet.codegen.StackValue; +import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.psi.JetCallExpression; import org.jetbrains.jet.lang.psi.JetExpression; import org.objectweb.asm.Type; @@ -14,18 +15,19 @@ import java.util.List; /** * @author yole + * @author alex.tkachman */ public class PsiMethodCall implements IntrinsicMethod { - private final PsiMethod myMethod; + private final FunctionDescriptor myMethod; - public PsiMethodCall(PsiMethod method) { + public PsiMethodCall(FunctionDescriptor method) { myMethod = method; } @Override public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List arguments, StackValue receiver) { - final CallableMethod callableMethod = codegen.getTypeMapper().mapToCallableMethod(myMethod, null); + final CallableMethod callableMethod = codegen.getTypeMapper().mapToCallableMethod(myMethod, false, OwnerKind.IMPLEMENTATION); codegen.invokeMethodWithArguments(callableMethod, (JetCallExpression) element, receiver); return StackValue.onStack(callableMethod.getSignature().getReturnType()); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java index 4bc50d96b78..6c641719c65 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java @@ -102,6 +102,15 @@ public class JetStandardLibrary { private JetType doubleArrayType; private JetType booleanArrayType; + private JetType nullableByteArrayType; + private JetType nullableCharArrayType; + private JetType nullableShortArrayType; + private JetType nullableIntArrayType; + private JetType nullableLongArrayType; + private JetType nullableFloatArrayType; + private JetType nullableDoubleArrayType; + private JetType nullableBooleanArrayType; + public JetType getTuple0Type() { return tuple0Type; } @@ -167,8 +176,21 @@ public class JetStandardLibrary { this.floatType = new JetTypeImpl(getFloat()); this.doubleType = new JetTypeImpl(getDouble()); this.booleanType = new JetTypeImpl(getBoolean()); + this.stringType = new JetTypeImpl(getString()); + this.nullableStringType = TypeUtils.makeNullable(stringType); + this.tuple0Type = new JetTypeImpl(JetStandardClasses.getTuple(0)); + this.nullableTuple0Type = TypeUtils.makeNullable(tuple0Type); + + this.nullableByteType = TypeUtils.makeNullable(byteType); + this.nullableCharType = TypeUtils.makeNullable(charType); + this.nullableShortType = TypeUtils.makeNullable(shortType); + this.nullableIntType = TypeUtils.makeNullable(intType); + this.nullableLongType = TypeUtils.makeNullable(longType); + this.nullableFloatType = TypeUtils.makeNullable(floatType); + this.nullableDoubleType = TypeUtils.makeNullable(doubleType); + this.nullableBooleanType = TypeUtils.makeNullable(booleanType); this.byteArrayClass = (ClassDescriptor) libraryScope.getClassifier("ByteArray"); this.charArrayClass = (ClassDescriptor) libraryScope.getClassifier("CharArray"); @@ -188,16 +210,14 @@ public class JetStandardLibrary { this.doubleArrayType = new JetTypeImpl(doubleArrayClass); this.booleanArrayType = new JetTypeImpl(booleanArrayClass); - this.nullableByteType = TypeUtils.makeNullable(byteType); - this.nullableCharType = TypeUtils.makeNullable(charType); - this.nullableShortType = TypeUtils.makeNullable(shortType); - this.nullableIntType = TypeUtils.makeNullable(intType); - this.nullableLongType = TypeUtils.makeNullable(longType); - this.nullableFloatType = TypeUtils.makeNullable(floatType); - this.nullableDoubleType = TypeUtils.makeNullable(doubleType); - this.nullableBooleanType = TypeUtils.makeNullable(booleanType); - this.nullableStringType = TypeUtils.makeNullable(stringType); - this.nullableTuple0Type = TypeUtils.makeNullable(tuple0Type); + this.nullableByteArrayType = TypeUtils.makeNullable(byteArrayType); + this.nullableCharArrayType = TypeUtils.makeNullable(charArrayType); + this.nullableShortArrayType = TypeUtils.makeNullable(shortArrayType); + this.nullableIntArrayType = TypeUtils.makeNullable(intArrayType); + this.nullableLongArrayType = TypeUtils.makeNullable(longArrayType); + this.nullableFloatArrayType = TypeUtils.makeNullable(floatArrayType); + this.nullableDoubleArrayType = TypeUtils.makeNullable(doubleArrayType); + this.nullableBooleanArrayType = TypeUtils.makeNullable(booleanArrayType); } } @@ -501,4 +521,36 @@ public class JetStandardLibrary { initStdClasses(); return booleanArrayClass; } + + public JetType getNullableByteArrayType() { + return nullableByteArrayType; + } + + public JetType getNullableCharArrayType() { + return nullableCharArrayType; + } + + public JetType getNullableShortArrayType() { + return nullableShortArrayType; + } + + public JetType getNullableIntArrayType() { + return nullableIntArrayType; + } + + public JetType getNullableLongArrayType() { + return nullableLongArrayType; + } + + public JetType getNullableFloatArrayType() { + return nullableFloatArrayType; + } + + public JetType getNullableDoubleArrayType() { + return nullableDoubleArrayType; + } + + public JetType getNullableBooleanArrayType() { + return nullableBooleanArrayType; + } } diff --git a/compiler/testData/codegen/super/basicmethod.jet b/compiler/testData/codegen/super/basicmethod.jet index ab735673036..bf0ba94e28a 100644 --- a/compiler/testData/codegen/super/basicmethod.jet +++ b/compiler/testData/codegen/super/basicmethod.jet @@ -1,13 +1,20 @@ -class N() : java.util.ArrayList() { - override fun add(el: String) : Boolean { - super.add(el) - return super.add(el + el) +import java.util.ArrayList +trait Tr { + fun extra() : String = "_" +} + +class N() : ArrayList(), Tr { + override fun add(el: Any) : Boolean { + super.add(el) + return super.add(el.toString() + super.extra() + el + extra()) } + + override fun extra() : String = super.extra() + super.extra() } fun box(): String { val n = N() n.add("239") - if (n.get(0) == "239" && n.get(1) == "239239") return "OK"; + if (n.get(0) == "239" && n.get(1) == "239_239__") return "OK"; return "fail"; } \ No newline at end of file