From b38e17181231a2e9f59e50e22a97c83b8b9f7a72 Mon Sep 17 00:00:00 2001 From: Stepan Koltsov Date: Sat, 7 Apr 2012 06:32:18 +0400 Subject: [PATCH] MapTypeMode and properly map builtins used in JetTypeMapper in JetTypeMapper * MapTypeMode contains no information not needed by JetTypeMapper * MapTypeMode has separate VALUE and IMPL values that are needed to compile builtins --- .../runConfigurations/All_Compiler_Tests.xml | 6 + .../jet/codegen/AnnotationCodegen.java | 8 +- .../jet/codegen/ClassBodyCodegen.java | 7 +- .../jetbrains/jet/codegen/ClosureCodegen.java | 18 ++- .../jetbrains/jet/codegen/CodegenContext.java | 11 +- .../jet/codegen/ExpressionCodegen.java | 22 +-- .../jet/codegen/FunctionCodegen.java | 30 ++-- .../jet/codegen/GenerationState.java | 14 +- .../codegen/ImplementationBodyCodegen.java | 89 ++++++----- .../jetbrains/jet/codegen/JetTypeMapper.java | 144 +++++++++++------- .../jetbrains/jet/codegen/MapTypeMode.java | 31 ++++ .../jet/codegen/ObjectOrClosureCodegen.java | 4 +- .../jet/codegen/PropertyCodegen.java | 7 +- .../org/jetbrains/jet/codegen/StackValue.java | 39 ++--- .../jet/codegen/TraitImplBodyCodegen.java | 2 +- .../codegen/intrinsics/JavaClassFunction.java | 8 +- .../jet/di/InjectorForJetTypeMapper.java | 3 + .../jet/di/InjectorForJvmCodegen.java | 4 + .../jet/compiler/CompileSession.java | 2 +- .../jetbrains/jet/codegen/TestlibTest.java | 4 +- .../jet/di/AllInjectorsGenerator.java | 2 + 21 files changed, 290 insertions(+), 165 deletions(-) create mode 100644 compiler/backend/src/org/jetbrains/jet/codegen/MapTypeMode.java diff --git a/.idea/runConfigurations/All_Compiler_Tests.xml b/.idea/runConfigurations/All_Compiler_Tests.xml index 2b6f5d383ef..14784b4f30e 100644 --- a/.idea/runConfigurations/All_Compiler_Tests.xml +++ b/.idea/runConfigurations/All_Compiler_Tests.xml @@ -23,10 +23,16 @@ + + + diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java index 537014e74ca..b44776df997 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java @@ -85,7 +85,7 @@ public abstract class AnnotationCodegen { return; } - String internalName = typeMapper.mapType(type).getDescriptor(); + String internalName = typeMapper.mapType(type, MapTypeMode.VALUE).getDescriptor(); AnnotationVisitor annotationVisitor = visitAnnotation(internalName, rp == RetentionPolicy.RUNTIME); getAnnotation(resolvedCall, annotationVisitor); @@ -138,7 +138,7 @@ public abstract class AnnotationCodegen { if(call != null) { if(call.getResultingDescriptor() instanceof PropertyDescriptor) { PropertyDescriptor descriptor = (PropertyDescriptor)call.getResultingDescriptor(); - annotationVisitor.visitEnum(keyName, typeMapper.mapType(descriptor.getReturnType()).getDescriptor(),descriptor.getName()); + annotationVisitor.visitEnum(keyName, typeMapper.mapType(descriptor.getReturnType(), MapTypeMode.VALUE).getDescriptor(), descriptor.getName()); return; } } @@ -160,7 +160,7 @@ public abstract class AnnotationCodegen { } } if(IntrinsicMethods.KOTLIN_JAVA_CLASS_FUNCTION.equals(value)) { - annotationVisitor.visit(keyName, typeMapper.mapType(call.getResultingDescriptor().getReturnType().getArguments().get(0).getType())); + annotationVisitor.visit(keyName, typeMapper.mapType(call.getResultingDescriptor().getReturnType().getArguments().get(0).getType(), MapTypeMode.VALUE)); return; } else if(IntrinsicMethods.KOTLIN_ARRAYS_ARRAY.equals(value)) { @@ -175,7 +175,7 @@ public abstract class AnnotationCodegen { else if(call.getResultingDescriptor() instanceof ConstructorDescriptor) { ConstructorDescriptor descriptor = (ConstructorDescriptor)call.getResultingDescriptor(); AnnotationVisitor visitor = annotationVisitor.visitAnnotation(keyName, typeMapper - .mapType(descriptor.getContainingDeclaration().getDefaultType()).getDescriptor()); + .mapType(descriptor.getContainingDeclaration().getDefaultType(), MapTypeMode.VALUE).getDescriptor()); getAnnotation(call, visitor); visitor.visitEnd(); return; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java index 142a8907710..89eddf97855 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java @@ -23,6 +23,7 @@ import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; import org.objectweb.asm.commons.InstructionAdapter; import java.util.ArrayList; @@ -124,11 +125,13 @@ public abstract class ClassBodyCodegen { if(state.getInjector().getJetStandardLibrary().isVolatile(propertyDescriptor)) { modifiers |= Opcodes.ACC_VOLATILE; } - v.newField(p, modifiers, p.getName(), state.getInjector().getJetTypeMapper().mapType(propertyDescriptor.getType()).getDescriptor(), null, null); + Type type = state.getInjector().getJetTypeMapper().mapType(propertyDescriptor.getType(), MapTypeMode.VALUE); + v.newField(p, modifiers, p.getName(), type.getDescriptor(), null, null); } } else { - v.newMethod(p, ACC_PUBLIC|ACC_ABSTRACT, p.getName(), "()" + state.getInjector().getJetTypeMapper().mapType(propertyDescriptor.getType()).getDescriptor(), null, null); + Type type = state.getInjector().getJetTypeMapper().mapType(propertyDescriptor.getType(), MapTypeMode.VALUE); + v.newMethod(p, ACC_PUBLIC | ACC_ABSTRACT, p.getName(), "()" + type.getDescriptor(), null, null); } } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java index c91eb9d7458..6b6d9584500 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java @@ -134,7 +134,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen { generateBridge(name, funDescriptor, fun, cv); captureThis = generateBody(funDescriptor, cv, (JetDeclarationWithBody) fun); ClassDescriptor thisDescriptor = context.getThisDescriptor(); - final Type enclosingType = thisDescriptor == null ? null : state.getInjector().getJetTypeMapper().mapType(thisDescriptor.getDefaultType()); + final Type enclosingType = thisDescriptor == null ? null : state.getInjector().getJetTypeMapper().mapType(thisDescriptor.getDefaultType(), MapTypeMode.VALUE); if (enclosingType == null) captureThis = null; @@ -224,14 +224,14 @@ public class ClosureCodegen extends ObjectOrClosureCodegen { int count = 1; if (receiver.exists()) { StackValue.local(count, JetTypeMapper.TYPE_OBJECT).put(JetTypeMapper.TYPE_OBJECT, iv); - StackValue.onStack(JetTypeMapper.TYPE_OBJECT).upcast(state.getInjector().getJetTypeMapper().mapType(receiver.getType()), iv); + StackValue.onStack(JetTypeMapper.TYPE_OBJECT).upcast(state.getInjector().getJetTypeMapper().mapType(receiver.getType(), MapTypeMode.VALUE), iv); count++; } final List params = funDescriptor.getValueParameters(); for (ValueParameterDescriptor param : params) { StackValue.local(count, JetTypeMapper.TYPE_OBJECT).put(JetTypeMapper.TYPE_OBJECT, iv); - StackValue.onStack(JetTypeMapper.TYPE_OBJECT).upcast(state.getInjector().getJetTypeMapper().mapType(param.getType()), iv); + StackValue.onStack(JetTypeMapper.TYPE_OBJECT).upcast(state.getInjector().getJetTypeMapper().mapType(param.getType(), MapTypeMode.VALUE), iv); count++; } @@ -268,7 +268,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen { int i = 0; if (captureThis != null) { - argTypes[i++] = state.getInjector().getJetTypeMapper().mapType(context.getThisDescriptor().getDefaultType()); + argTypes[i++] = state.getInjector().getJetTypeMapper().mapType(context.getThisDescriptor().getDefaultType(), MapTypeMode.VALUE); } if (captureReceiver != null) { @@ -278,7 +278,13 @@ public class ClosureCodegen extends ObjectOrClosureCodegen { for (DeclarationDescriptor descriptor : closure.keySet()) { if(descriptor instanceof VariableDescriptor && !(descriptor instanceof PropertyDescriptor)) { final Type sharedVarType = state.getInjector().getJetTypeMapper().getSharedVarType(descriptor); - final Type type = sharedVarType != null ? sharedVarType : state.getInjector().getJetTypeMapper().mapType(((VariableDescriptor) descriptor).getType()); + final Type type; + if (sharedVarType != null) { + type = sharedVarType; + } + else { + type = state.getInjector().getJetTypeMapper().mapType(((VariableDescriptor) descriptor).getType(), MapTypeMode.VALUE); + } argTypes[i++] = type; } else if(CodegenUtil.isNamedFun(descriptor, state.getBindingContext()) && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) { @@ -352,7 +358,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen { signatureWriter.visitTypeArgument(variance); final JetTypeMapper typeMapper = state.getInjector().getJetTypeMapper(); - final Type rawRetType = JetTypeMapper.boxType(typeMapper.mapType(type)); + final Type rawRetType = typeMapper.mapType(type, MapTypeMode.TYPE_PARAMETER); signatureWriter.visitClassType(rawRetType.getInternalName()); signatureWriter.visitEnd(); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java index f91c55491fa..51713615c6b 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java @@ -157,7 +157,7 @@ public abstract class CodegenContext { CallableDescriptor receiverDescriptor = getReceiverDescriptor(); if (receiverDescriptor != null) { - Type type = mapper.mapType(receiverDescriptor.getReceiverParameter().getType()); + Type type = mapper.mapType(receiverDescriptor.getReceiverParameter().getType(), MapTypeMode.VALUE); frameMap.enterTemp(type.getSize()); // Next slot for fake this } @@ -171,7 +171,7 @@ public abstract class CodegenContext { public Type jvmType(JetTypeMapper mapper) { if (contextType instanceof ClassDescriptor) { - return mapper.mapType(((ClassDescriptor) contextType).getDefaultType(), contextKind); + return mapper.mapType(((ClassDescriptor) contextType).getDefaultType(), JetTypeMapper.ownerKindToMapTypeMode(contextKind)); } else if (closure != null) { return Type.getObjectType(closure.name); @@ -200,7 +200,7 @@ public abstract class CodegenContext { while(cur != null && !(cur.getContextDescriptor() instanceof ClassDescriptor)) cur = cur.getParentContext(); - return cur == null ? null : typeMapper.mapType(((ClassDescriptor)cur.getContextDescriptor()).getDefaultType()); + return cur == null ? null : typeMapper.mapType(((ClassDescriptor) cur.getContextDescriptor()).getDefaultType(), MapTypeMode.IMPL); } public int getTypeInfoConstantIndex(JetType type) { @@ -282,7 +282,7 @@ public abstract class CodegenContext { public StackValue getReceiverExpression(JetTypeMapper typeMapper) { assert getReceiverDescriptor() != null; - Type asmType = typeMapper.mapType(getReceiverDescriptor().getReceiverParameter().getType()); + Type asmType = typeMapper.mapType(getReceiverDescriptor().getReceiverParameter().getType(), MapTypeMode.VALUE); return getThisDescriptor() != null ? StackValue.local(1, asmType) : StackValue.local(0, asmType); } @@ -390,8 +390,9 @@ public abstract class CodegenContext { super(contextType, contextKind, parentContext, closure); final Type type = enclosingClassType(typeMapper); + Type owner = closure.state.getInjector().getJetTypeMapper().mapType(contextType.getDefaultType(), MapTypeMode.IMPL); outerExpression = type != null - ? StackValue.field(type, closure.state.getInjector().getJetTypeMapper().mapType(contextType.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), "this$0", false) + ? StackValue.field(type, owner.getInternalName(), "this$0", false) : null; } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 3005e9e2c4f..8a79bb82e1f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -188,7 +188,7 @@ public class ExpressionCodegen extends JetVisitor { } private Type asmType(JetType type) { - return typeMapper.mapType(type); + return typeMapper.mapType(type, MapTypeMode.VALUE); } @Override @@ -801,7 +801,7 @@ public class ExpressionCodegen extends JetVisitor { if(entry.getKey() instanceof VariableDescriptor && !(entry.getKey() instanceof PropertyDescriptor)) { Type sharedVarType = typeMapper.getSharedVarType(entry.getKey()); if(sharedVarType == null) - sharedVarType = state.getInjector().getJetTypeMapper().mapType(((VariableDescriptor) entry.getKey()).getType()); + sharedVarType = state.getInjector().getJetTypeMapper().mapType(((VariableDescriptor) entry.getKey()).getType(), MapTypeMode.VALUE); consArgTypes.add(sharedVarType); entry.getValue().getOuterValue().put(sharedVarType, v); } @@ -1003,15 +1003,15 @@ public class ExpressionCodegen extends JetVisitor { ClassDescriptor classDescriptor = (ClassDescriptor) propertyDescriptor.getReturnType().getConstructor().getDeclarationDescriptor(); if(classDescriptor.getKind() == ClassKind.ENUM_ENTRY) { ClassDescriptor containing = (ClassDescriptor) classDescriptor.getContainingDeclaration().getContainingDeclaration(); - Type type = typeMapper.mapType(containing.getDefaultType(), OwnerKind.IMPLEMENTATION); + Type type = typeMapper.mapType(containing.getDefaultType(), MapTypeMode.VALUE); StackValue.field(type, type.getInternalName(), classDescriptor.getName(), true).put(TYPE_OBJECT, v); // todo: for now we don't generate classes for enum entries, so we need this hack - type = typeMapper.mapType(classDescriptor.getDefaultType(), OwnerKind.IMPLEMENTATION); + type = typeMapper.mapType(classDescriptor.getDefaultType(), MapTypeMode.VALUE); return StackValue.onStack(type); } else { - Type type = typeMapper.mapType(classDescriptor.getDefaultType(), OwnerKind.IMPLEMENTATION); + Type type = typeMapper.mapType(classDescriptor.getDefaultType(), MapTypeMode.VALUE); return StackValue.field(type, type.getInternalName(), "$instance", true); } } @@ -1074,9 +1074,9 @@ public class ExpressionCodegen extends JetVisitor { } final ClassDescriptor descriptor1 = bindingContext.get(BindingContext.CLASS, classObject.getObjectDeclaration()); assert descriptor1 != null; - final String type = typeMapper.mapType(descriptor1.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(); - return StackValue.field(Type.getObjectType(type), - typeMapper.mapType(((ClassDescriptor) descriptor).getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), + final Type type = typeMapper.mapType(descriptor1.getDefaultType(), MapTypeMode.VALUE); + return StackValue.field(type, + typeMapper.mapType(((ClassDescriptor) descriptor).getDefaultType(), MapTypeMode.IMPL).getInternalName(), "$classobj", true); } @@ -1375,7 +1375,7 @@ public class ExpressionCodegen extends JetVisitor { ClassDescriptor classReceiverDeclarationDescriptor = (ClassDescriptor) classReceiver.getDeclarationDescriptor(); if(CodegenUtil.isClassObject(classReceiverDeclarationDescriptor)) { ClassDescriptor containingDeclaration = (ClassDescriptor) classReceiverDeclarationDescriptor.getContainingDeclaration(); - Type classObjType = typeMapper.mapType(containingDeclaration.getDefaultType()); + Type classObjType = typeMapper.mapType(containingDeclaration.getDefaultType(), MapTypeMode.IMPL); v.getstatic(classObjType.getInternalName(), "$classobj", exprType.getDescriptor()); } else { @@ -2244,7 +2244,7 @@ public class ExpressionCodegen extends JetVisitor { //noinspection ConstantConditions JetType expressionType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression); assert expressionType != null; - type = typeMapper.mapType(expressionType, OwnerKind.IMPLEMENTATION); + type = typeMapper.mapType(expressionType, MapTypeMode.VALUE); if (type.getSort() == Type.ARRAY) { generateNewArray(expression, expressionType); } else { @@ -2322,7 +2322,7 @@ public class ExpressionCodegen extends JetVisitor { */ } else { - Type type = typeMapper.mapType(arrayType, OwnerKind.IMPLEMENTATION); + Type type = typeMapper.mapType(arrayType, MapTypeMode.VALUE); gen(args.get(0), Type.INT_TYPE); v.newarray(correctElementType(type)); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index 16d4cd76a97..6ec5072ac8b 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -215,7 +215,7 @@ public class FunctionCodegen { for (ValueParameterDescriptor parameter : paramDescrs) { Type sharedVarType = state.getInjector().getJetTypeMapper().getSharedVarType(parameter); if (sharedVarType != null) { - Type localVarType = state.getInjector().getJetTypeMapper().mapType(parameter.getType()); + Type localVarType = state.getInjector().getJetTypeMapper().mapType(parameter.getType(), MapTypeMode.VALUE); int index = frameMap.getIndex(parameter); mv.visitTypeInsn(NEW, sharedVarType.getInternalName()); mv.visitInsn(DUP); @@ -236,20 +236,20 @@ public class FunctionCodegen { int k = 0; if(expectedThisObject.exists()) { - Type type = state.getInjector().getJetTypeMapper().mapType(expectedThisObject.getType()); + Type type = state.getInjector().getJetTypeMapper().mapType(expectedThisObject.getType(), MapTypeMode.VALUE); // TODO: specify signature mv.visitLocalVariable("this", type.getDescriptor(), null, methodBegin, methodEnd, k++); } if(receiverParameter.exists()) { - Type type = state.getInjector().getJetTypeMapper().mapType(receiverParameter.getType()); + Type type = state.getInjector().getJetTypeMapper().mapType(receiverParameter.getType(), MapTypeMode.VALUE); // TODO: specify signature mv.visitLocalVariable("this$receiver", type.getDescriptor(), null, methodBegin, methodEnd, k); k += type.getSize(); } for (ValueParameterDescriptor parameter : paramDescrs) { - Type type = state.getInjector().getJetTypeMapper().mapType(parameter.getType()); + Type type = state.getInjector().getJetTypeMapper().mapType(parameter.getType(), MapTypeMode.VALUE); // TODO: specify signature mv.visitLocalVariable(parameter.getName(), type.getDescriptor(), null, methodBegin, methodEnd, k); k += type.getSize(); @@ -328,9 +328,13 @@ public class FunctionCodegen { int flags = ACC_PUBLIC | ACC_SYNTHETIC; // TODO. - String ownerInternalName = contextClass instanceof NamespaceDescriptor ? - NamespaceCodegen.getJVMClassName(DescriptorUtils.getFQName(contextClass).toSafe(), true) : - state.getInjector().getJetTypeMapper().mapType(((ClassDescriptor) contextClass).getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(); + String ownerInternalName; + if (contextClass instanceof NamespaceDescriptor) { + ownerInternalName = NamespaceCodegen.getJVMClassName(DescriptorUtils.getFQName(contextClass).toSafe(), true); + } + else { + ownerInternalName = state.getInjector().getJetTypeMapper().mapType(((ClassDescriptor) contextClass).getDefaultType(), MapTypeMode.IMPL).getInternalName(); + } String descriptor = jvmSignature.getDescriptor().replace(")","I)"); boolean isConstructor = "".equals(jvmSignature.getName()); @@ -353,7 +357,13 @@ public class FunctionCodegen { var++; } - Type receiverType = receiverParameter.exists() ? state.getInjector().getJetTypeMapper().mapType(receiverParameter.getType()) : Type.DOUBLE_TYPE; + Type receiverType; + if (receiverParameter.exists()) { + receiverType = state.getInjector().getJetTypeMapper().mapType(receiverParameter.getType(), MapTypeMode.VALUE); + } + else { + receiverType = Type.DOUBLE_TYPE; + } if(hasReceiver) { var += receiverType.getSize(); } @@ -481,7 +491,7 @@ public class FunctionCodegen { reg += argType.getSize(); } - iv.invokevirtual(state.getInjector().getJetTypeMapper().mapType(((ClassDescriptor) owner.getContextDescriptor()).getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), jvmSignature.getName(), jvmSignature.getDescriptor()); + iv.invokevirtual(state.getInjector().getJetTypeMapper().mapType(((ClassDescriptor) owner.getContextDescriptor()).getDefaultType(), MapTypeMode.VALUE).getInternalName(), jvmSignature.getName(), jvmSignature.getDescriptor()); if(JetTypeMapper.isPrimitive(jvmSignature.getReturnType()) && !JetTypeMapper.isPrimitive(overriden.getReturnType())) StackValue.valueOf(iv, jvmSignature.getReturnType()); if(jvmSignature.getReturnType() == Type.VOID_TYPE) @@ -525,7 +535,7 @@ public class FunctionCodegen { iv.load(0, JetTypeMapper.TYPE_OBJECT); field.put(field.type, iv); ClassDescriptor classDescriptor = (ClassDescriptor) overriddenDescriptor.getContainingDeclaration(); - String internalName = state.getInjector().getJetTypeMapper().mapType(classDescriptor.getDefaultType()).getInternalName(); + String internalName = state.getInjector().getJetTypeMapper().mapType(classDescriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(); if(classDescriptor.getKind() == ClassKind.TRAIT) iv.invokeinterface(internalName, method.getName(), method.getDescriptor()); else diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java b/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java index 03bdc90036e..92a7ce90742 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java @@ -35,6 +35,7 @@ import org.jetbrains.jet.lang.psi.JetObjectDeclaration; import org.jetbrains.jet.lang.psi.JetObjectLiteralExpression; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.java.AnalyzeExhaust; +import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode; import org.jetbrains.jet.utils.Progress; import java.util.List; @@ -51,15 +52,18 @@ public class GenerationState { public GenerationState(Project project, ClassBuilderFactory builderFactory, AnalyzeExhaust analyzeExhaust, List files) { - this(project, builderFactory, Progress.DEAF, analyzeExhaust, files); + this(project, builderFactory, Progress.DEAF, analyzeExhaust, files, CompilerSpecialMode.REGULAR); } - public GenerationState(Project project, ClassBuilderFactory builderFactory, Progress progress, @NotNull AnalyzeExhaust exhaust, @NotNull List files) { + public GenerationState(Project project, ClassBuilderFactory builderFactory, Progress progress, + @NotNull AnalyzeExhaust exhaust, @NotNull List files, @NotNull CompilerSpecialMode compilerSpecialMode) { this.project = project; this.progress = progress; this.analyzeExhaust = exhaust; this.files = files; - this.injector = new InjectorForJvmCodegen(analyzeExhaust.getStandardLibrary(), analyzeExhaust.getBindingContext(), this.files, project, this, builderFactory); + this.injector = new InjectorForJvmCodegen( + analyzeExhaust.getStandardLibrary(), analyzeExhaust.getBindingContext(), + this.files, project, compilerSpecialMode, this, builderFactory); } @NotNull @@ -84,11 +88,11 @@ public class GenerationState { } public ClassBuilder forClassImplementation(ClassDescriptor aClass) { - return getFactory().newVisitor(getInjector().getJetTypeMapper().mapType(aClass.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName() + ".class"); + return getFactory().newVisitor(getInjector().getJetTypeMapper().mapType(aClass.getDefaultType(), MapTypeMode.IMPL).getInternalName() + ".class"); } public ClassBuilder forTraitImplementation(ClassDescriptor aClass) { - return getFactory().newVisitor(getInjector().getJetTypeMapper().mapType(aClass.getDefaultType(), OwnerKind.TRAIT_IMPL).getInternalName() + ".class"); + return getFactory().newVisitor(getInjector().getJetTypeMapper().mapType(aClass.getDefaultType(), MapTypeMode.TRAIT_IMPL).getInternalName() + ".class"); } public Pair forAnonymousSubclass(JetExpression expression) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 0530f9df131..e1028c0ade3 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -124,7 +124,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { ClassDescriptor container = getContainingClassDescriptor(descriptor); if(container != null) { - v.visitOuterClass(typeMapper.mapType(container.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), null, null); + v.visitOuterClass(typeMapper.mapType(container.getDefaultType(), MapTypeMode.IMPL).getInternalName(), null, null); } for (DeclarationDescriptor declarationDescriptor : descriptor.getUnsubstitutedInnerClassesScope().getAllDescriptors()) { @@ -143,14 +143,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } // TODO: cache internal names - String outerClassInernalName = typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(); - String innerClassInternalName = typeMapper.mapType(innerClass.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(); + String outerClassInernalName = typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName(); + String innerClassInternalName = typeMapper.mapType(innerClass.getDefaultType(), MapTypeMode.IMPL).getInternalName(); v.visitInnerClass(innerClassInternalName, outerClassInernalName, innerClass.getName(), innerClassAccess); } if (descriptor.getClassObjectDescriptor() != null) { int innerClassAccess = ACC_PUBLIC | ACC_FINAL | ACC_STATIC; - String outerClassInernalName = typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(); + String outerClassInernalName = typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName(); v.visitInnerClass(outerClassInernalName + JvmAbi.CLASS_OBJECT_SUFFIX, outerClassInernalName, JvmAbi.CLASS_OBJECT_CLASS_NAME, innerClassAccess); } @@ -194,7 +194,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { signatureVisitor.writeClassBegin(superClass, false, false); signatureVisitor.writeClassEnd(); } else { - typeMapper.mapType(superClassType, OwnerKind.IMPLEMENTATION, signatureVisitor, true); + typeMapper.mapType(superClassType, signatureVisitor, MapTypeMode.TYPE_PARAMETER); } signatureVisitor.writeSuperclassEnd(); } @@ -209,7 +209,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); if (CodegenUtil.isInterface(superClassDescriptor)) { signatureVisitor.writeInterface(); - Type jvmName = typeMapper.mapType(superType, OwnerKind.IMPLEMENTATION, signatureVisitor, true); + Type jvmName = typeMapper.mapType(superType, signatureVisitor, MapTypeMode.TYPE_PARAMETER); signatureVisitor.writeInterfaceEnd(); superInterfacesLinkedHashSet.add(jvmName.getInternalName()); } @@ -224,7 +224,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } private String jvmName() { - return typeMapper.mapType(descriptor.getDefaultType(), kind).getInternalName(); + if (kind != OwnerKind.IMPLEMENTATION) { + throw new IllegalStateException("must not call this method with kind " + kind); + } + return typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName(); } protected void getSuperClass() { @@ -236,6 +239,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if(myClass instanceof JetClass && ((JetClass) myClass).isTrait()) return; + if (kind != OwnerKind.IMPLEMENTATION) { + throw new IllegalStateException("must be impl to reach this code: " + kind); + } + for (JetDelegationSpecifier specifier : delegationSpecifiers) { if (specifier instanceof JetDelegatorToSuperClass || specifier instanceof JetDelegatorToSuperCall) { JetType superType = bindingContext.get(BindingContext.TYPE, specifier.getTypeReference()); @@ -243,7 +250,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); if(!CodegenUtil.isInterface(superClassDescriptor)) { superClassType = superType; - superClass = typeMapper.mapType(superClassDescriptor.getDefaultType(), kind).getInternalName(); + superClass = typeMapper.mapType(superClassDescriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName(); superCall = specifier; } } @@ -376,7 +383,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { private void generateFieldForObjectInstance() { if (CodegenUtil.isNonLiteralObject(myClass)) { - Type type = typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION); + Type type = typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE); v.newField(myClass, ACC_PUBLIC | ACC_STATIC | ACC_FINAL, "$instance", type.getDescriptor(), null, null); staticInitializerChunks.add(new CodeChunk() { @@ -386,7 +393,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { v.anew(Type.getObjectType(name)); v.dup(); v.invokespecial(name, "", "()V"); - v.putstatic(name, "$instance", typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getDescriptor()); + v.putstatic(name, "$instance", typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getDescriptor()); } }); @@ -397,19 +404,19 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { final JetClassObject classObject = getClassObject(); if (classObject != null) { final ClassDescriptor descriptor1 = bindingContext.get(BindingContext.CLASS, classObject.getObjectDeclaration()); - Type type = Type.getObjectType(typeMapper.mapType(descriptor1.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName()); + Type type = Type.getObjectType(typeMapper.mapType(descriptor1.getDefaultType(), MapTypeMode.VALUE).getInternalName()); v.newField(classObject, ACC_PUBLIC | ACC_STATIC, "$classobj", type.getDescriptor(), null, null); staticInitializerChunks.add(new CodeChunk() { @Override public void generate(InstructionAdapter v) { final ClassDescriptor descriptor1 = bindingContext.get(BindingContext.CLASS, classObject.getObjectDeclaration()); - String name = typeMapper.mapType(descriptor1.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(); + String name = typeMapper.mapType(descriptor1.getDefaultType(), MapTypeMode.IMPL).getInternalName(); final Type classObjectType = Type.getObjectType(name); v.anew(classObjectType); v.dup(); v.invokespecial(name, "", "()V"); - v.putstatic(typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), "$classobj", + v.putstatic(typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), "$classobj", classObjectType.getDescriptor()); } }); @@ -426,6 +433,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } } + if (kind != OwnerKind.IMPLEMENTATION) { + throw new IllegalStateException("incorrect kind for primary constructor: " + kind); + } + ConstructorDescriptor constructorDescriptor = bindingContext.get(BindingContext.CONSTRUCTOR, myClass); CodegenContext.ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor, typeMapper); @@ -443,7 +454,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if (hasThis0) { signatureWriter.writeParameterType(JvmMethodParameterKind.THIS0); - typeMapper.mapType(typeMapper.getClosureAnnotator().getEclosingClassDescriptor(descriptor).getDefaultType(), OwnerKind.IMPLEMENTATION, signatureWriter, false); + typeMapper.mapType(typeMapper.getClosureAnnotator().getEclosingClassDescriptor(descriptor).getDefaultType(), signatureWriter, MapTypeMode.VALUE); signatureWriter.writeParameterTypeEnd(); } @@ -481,7 +492,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { for (DeclarationDescriptor descriptor : closure.closure.keySet()) { if(descriptor instanceof VariableDescriptor && !(descriptor instanceof PropertyDescriptor)) { final Type sharedVarType = typeMapper.getSharedVarType(descriptor); - final Type type = sharedVarType != null ? sharedVarType : state.getInjector().getJetTypeMapper().mapType(((VariableDescriptor) descriptor).getType()); + final Type type; + if (sharedVarType != null) { + type = sharedVarType; + } + else { + type = state.getInjector().getJetTypeMapper().mapType(((VariableDescriptor) descriptor).getType(), MapTypeMode.VALUE); + } consArgTypes.add(insert++, new JvmMethodParameterSignature(type, "", JvmMethodParameterKind.SHARED_VAR)); } else if(descriptor instanceof FunctionDescriptor) { @@ -561,7 +578,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { // codegen.addTypeParameter(descriptor.getTypeConstructor().getParameters().get(slot), StackValue.local(frameMap.getFirstTypeParameter() + slot, JetTypeMapper.TYPE_TYPEINFO)); // } - String classname = typeMapper.mapType(descriptor.getDefaultType(), kind).getInternalName(); + String classname = typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName(); final Type classType = Type.getType("L" + classname + ";"); HashSet overridden = new HashSet(); @@ -585,10 +602,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); if (typeMapper.hasThis0(superClassDescriptor)) { iv.load(1, JetTypeMapper.TYPE_OBJECT); - parameterTypes.add(typeMapper.mapType(typeMapper.getClosureAnnotator().getEclosingClassDescriptor(descriptor).getDefaultType(), OwnerKind.IMPLEMENTATION)); + parameterTypes.add(typeMapper.mapType(typeMapper.getClosureAnnotator().getEclosingClassDescriptor(descriptor).getDefaultType(), MapTypeMode.VALUE)); } Method superCallMethod = new Method("", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()])); - iv.invokespecial(typeMapper.mapType(superClassDescriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), "", superCallMethod.getDescriptor()); + iv.invokespecial(typeMapper.mapType(superClassDescriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), "", superCallMethod.getDescriptor()); } else { ConstructorDescriptor constructorDescriptor1 = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression().getConstructorReferenceExpression()); @@ -608,7 +625,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { assert superType != null; ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); String delegateField = "$delegate_" + (n++); - Type fieldType = typeMapper.mapType(superClassDescriptor.getDefaultType()); + Type fieldType = typeMapper.mapType(superClassDescriptor.getDefaultType(), MapTypeMode.VALUE); String fieldDesc = fieldType.getDescriptor(); v.newField(specifier, ACC_PRIVATE, delegateField, fieldDesc, /*TODO*/null, null); StackValue field = StackValue.field(fieldType, classname, delegateField, false); @@ -617,14 +634,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { JetClass superClass = (JetClass) bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, superClassDescriptor); final CodegenContext delegateContext = context.intoClass(superClassDescriptor, new OwnerKind.DelegateKind(StackValue.field(fieldType, classname, delegateField, false), - typeMapper.mapType(superClassDescriptor.getDefaultType()).getInternalName()), state.getInjector().getJetTypeMapper()); + typeMapper.mapType(superClassDescriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName()), state.getInjector().getJetTypeMapper()); generateDelegates(superClass, delegateContext, field); } } final ClassDescriptor outerDescriptor = typeMapper.getClosureAnnotator().getEclosingClassDescriptor(descriptor); if (typeMapper.hasThis0(descriptor) && outerDescriptor != null) { - final Type type = typeMapper.mapType(outerDescriptor.getDefaultType()); + final Type type = typeMapper.mapType(outerDescriptor.getDefaultType(), MapTypeMode.VALUE); String interfaceDesc = type.getDescriptor(); final String fieldName = "this$0"; v.newField(myClass, ACC_FINAL, fieldName, interfaceDesc, null, null); @@ -638,7 +655,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if(closure.captureReceiver != null) { iv.load(0, JetTypeMapper.TYPE_OBJECT); iv.load(1, closure.captureReceiver); - iv.putfield(typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), "receiver$0", closure.captureReceiver.getDescriptor()); + iv.putfield(typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), "receiver$0", closure.captureReceiver.getDescriptor()); k += closure.captureReceiver.getSize(); } @@ -647,12 +664,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if(varDescr instanceof VariableDescriptor && !(varDescr instanceof PropertyDescriptor)) { Type sharedVarType = typeMapper.getSharedVarType(varDescr); if(sharedVarType == null) { - sharedVarType = typeMapper.mapType(((VariableDescriptor) varDescr).getType()); + sharedVarType = typeMapper.mapType(((VariableDescriptor) varDescr).getType(), MapTypeMode.VALUE); } iv.load(0, JetTypeMapper.TYPE_OBJECT); iv.load(k, StackValue.refType(sharedVarType)); k += StackValue.refType(sharedVarType).getSize(); - iv.putfield(typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), "$" + varDescr.getName(), sharedVarType.getDescriptor()); + iv.putfield(typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), "$" + varDescr.getName(), sharedVarType.getDescriptor()); l++; } } @@ -663,7 +680,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { for (JetParameter parameter : constructorParameters) { if (parameter.getValOrVarNode() != null) { VariableDescriptor descriptor = paramDescrs.get(curParam); - Type type = typeMapper.mapType(descriptor.getType()); + Type type = typeMapper.mapType(descriptor.getType(), MapTypeMode.VALUE); iv.load(0, classType); iv.load(frameMap.getIndex(descriptor), type); iv.putfield(classname, descriptor.getName(), type.getDescriptor()); @@ -731,15 +748,16 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } JetType jetType = TraitImplBodyCodegen.getSuperClass(declaration, bindingContext); - Type type = typeMapper.mapType(jetType); - if(type.getInternalName().equals("java/lang/Object")) { + Type type = typeMapper.mapType(jetType, MapTypeMode.IMPL); + if (type.getInternalName().equals("java/lang/Object")) { jetType = declaration.getDefaultType(); - type = typeMapper.mapType(jetType); + type = typeMapper.mapType(jetType, MapTypeMode.IMPL); } String fdescriptor = functionOriginal.getDescriptor().replace("(","(" + type.getDescriptor()); - iv.invokestatic(typeMapper.mapType(((ClassDescriptor) fun.getContainingDeclaration()).getDefaultType(), OwnerKind.TRAIT_IMPL).getInternalName(), function.getName(), fdescriptor); - if(function.getReturnType().getSort() == Type.OBJECT) { + Type type1 = typeMapper.mapType(((ClassDescriptor) fun.getContainingDeclaration()).getDefaultType(), MapTypeMode.TRAIT_IMPL); + iv.invokestatic(type1.getInternalName(), function.getName(), fdescriptor); + if (function.getReturnType().getSort() == Type.OBJECT) { iv.checkcast(function.getReturnType()); } iv.areturn(function.getReturnType()); @@ -760,7 +778,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { iv.load(0, TYPE_OBJECT); if (classDecl.getContainingDeclaration() instanceof ClassDescriptor) { - iv.load(frameMap.getOuterThisIndex(), typeMapper.mapType(((ClassDescriptor) descriptor.getContainingDeclaration()).getDefaultType(), OwnerKind.IMPLEMENTATION)); + iv.load(frameMap.getOuterThisIndex(), typeMapper.mapType(((ClassDescriptor) descriptor.getContainingDeclaration()).getDefaultType(), MapTypeMode.IMPL)); } CallableMethod method = typeMapper.mapToCallableMethod(constructorDescriptor, kind, typeMapper.hasThis0(constructorDescriptor.getContainingDeclaration())); @@ -790,7 +808,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } else if (declaration instanceof JetEnumEntry && !((JetEnumEntry) declaration).hasPrimaryConstructor()) { String name = declaration.getName(); - final String desc = "L" + typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName() + ";"; + final String desc = "L" + typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName() + ";"; v.newField(declaration, ACC_PUBLIC | ACC_STATIC | ACC_FINAL, name, desc, null, null); if (myEnumConstants.isEmpty()) { staticInitializerChunks.add(new CodeChunk() { @@ -813,7 +831,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { ExpressionCodegen codegen = new ExpressionCodegen(v, new FrameMap(), Type.VOID_TYPE, context, state); for (JetEnumEntry enumConstant : myEnumConstants) { // TODO type and constructor parameters - String implClass = typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(); + String implClass = typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName(); final List delegationSpecifiers = enumConstant.getDelegationSpecifiers(); if (delegationSpecifiers.size() > 1) { @@ -896,7 +914,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if(compileTimeValue != null) { assert compileTimeValue != null; Object value = compileTimeValue.getValue(); - Type type = typeMapper.mapType(propertyDescriptor.getType()); + Type type = typeMapper.mapType(propertyDescriptor.getType(), MapTypeMode.VALUE); if(JetTypeMapper.isPrimitive(type)) { if( !propertyDescriptor.getType().isNullable() && value instanceof Number) { if(type == Type.INT_TYPE && ((Number)value).intValue() == 0) @@ -929,7 +947,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { codegen.gen(initializer, type); // @todo write directly to the field. Fix test excloset.jet::test6 String owner = typeMapper.getOwner(propertyDescriptor, OwnerKind.IMPLEMENTATION); - StackValue.property(propertyDescriptor.getName(), owner, owner, typeMapper.mapType(propertyDescriptor.getType()), false, false, false, null, null, 0).store(iv); + StackValue.property(propertyDescriptor.getName(), owner, owner, + typeMapper.mapType(propertyDescriptor.getType(), MapTypeMode.VALUE), false, false, false, null, null, 0).store(iv); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index 7d1b0a83a68..fa1d2bbd78e 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -63,6 +63,7 @@ public class JetTypeMapper { private JetStandardLibrary standardLibrary; public BindingContext bindingContext; private ClosureAnnotator closureAnnotator; + private CompilerSpecialMode compilerSpecialMode; @Inject @@ -80,6 +81,11 @@ public class JetTypeMapper { this.closureAnnotator = closureAnnotator; } + @Inject + public void setCompilerSpecialMode(CompilerSpecialMode compilerSpecialMode) { + this.compilerSpecialMode = compilerSpecialMode; + } + @PostConstruct public void init() { initKnownTypes(); @@ -129,6 +135,8 @@ public class JetTypeMapper { } public String getOwner(DeclarationDescriptor descriptor, OwnerKind kind) { + MapTypeMode mapTypeMode = ownerKindToMapTypeMode(kind); + String owner; DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); if (containingDeclaration instanceof NamespaceDescriptor) { @@ -137,14 +145,14 @@ public class JetTypeMapper { else if (containingDeclaration instanceof ClassDescriptor) { ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration; if (kind instanceof OwnerKind.DelegateKind) { - kind = OwnerKind.IMPLEMENTATION; + mapTypeMode = MapTypeMode.IMPL; } else { if (classDescriptor.getKind() == ClassKind.OBJECT) { - kind = OwnerKind.IMPLEMENTATION; + mapTypeMode = MapTypeMode.IMPL; } } - Type asmType = mapType(classDescriptor.getDefaultType(), kind); + Type asmType = mapType(classDescriptor.getDefaultType(), mapTypeMode); if (asmType.getSort() != Type.OBJECT) { throw new IllegalStateException(); } @@ -156,6 +164,18 @@ public class JetTypeMapper { return owner; } + public static MapTypeMode ownerKindToMapTypeMode(OwnerKind kind) { + if (kind == OwnerKind.IMPLEMENTATION || kind == OwnerKind.NAMESPACE) { + return MapTypeMode.IMPL; + } + else if (kind == OwnerKind.TRAIT_IMPL) { + return MapTypeMode.TRAIT_IMPL; + } + else { + throw new IllegalStateException("must not call this method with kind = " + kind); + } + } + private String jvmClassNameForNamespace(NamespaceDescriptor namespace) { FqName fqName = DescriptorUtils.getFQName(namespace).toSafe(); Boolean javaClassStatics = bindingContext.get(JavaBindingContext.NAMESPACE_IS_CLASS_STATICS, namespace); @@ -202,7 +222,7 @@ public class JetTypeMapper { } return TYPE_OBJECT; } - return mapType(jetType, OwnerKind.IMPLEMENTATION, signatureVisitor); + return mapType(jetType, signatureVisitor, MapTypeMode.VALUE); } private String getStableNameForObject(JetObjectDeclaration object, DeclarationDescriptor descriptor) { @@ -278,26 +298,33 @@ public class JetTypeMapper { return getContainingNamespace(parent); } - @NotNull public Type mapType(final JetType jetType) { - return mapType(jetType, (BothSignatureWriter) null); + @NotNull + public Type mapType(@NotNull final JetType jetType, @NotNull MapTypeMode kind) { + return mapType(jetType, null, kind); } - @NotNull private Type mapType(JetType jetType, @Nullable BothSignatureWriter signatureVisitor) { - return mapType(jetType, OwnerKind.IMPLEMENTATION, signatureVisitor); - } - - @NotNull public Type mapType(@NotNull final JetType jetType, OwnerKind kind) { - return mapType(jetType, kind, null); - } - - @NotNull private Type mapType(JetType jetType, OwnerKind kind, @Nullable BothSignatureWriter signatureVisitor) { - return mapType(jetType, kind, signatureVisitor, false); - } - - @NotNull public Type mapType(JetType jetType, OwnerKind kind, @Nullable BothSignatureWriter signatureVisitor, boolean boxPrimitive) { + @NotNull + public Type mapType(JetType jetType, @Nullable BothSignatureWriter signatureVisitor, @NotNull MapTypeMode kind) { Type known = knowTypes.get(jetType); if (known != null) { - return mapKnownAsmType(jetType, known, signatureVisitor, boxPrimitive); + if (kind == MapTypeMode.VALUE) { + return mapKnownAsmType(jetType, known, signatureVisitor, false); + } + else if (kind == MapTypeMode.TYPE_PARAMETER) { + return mapKnownAsmType(jetType, known, signatureVisitor, true); + } + else if (kind == MapTypeMode.TRAIT_IMPL) { + throw new IllegalStateException("TRAIT_IMPL is not possible for " + jetType); + } + else if (kind == MapTypeMode.IMPL) { + if (compilerSpecialMode != CompilerSpecialMode.BUILTINS) { + throw new IllegalStateException("must not map known type to IMPL when not compiling builtins: " + jetType); + } + // fall through + } + else { + throw new IllegalStateException("unknown kind: " + kind); + } } DeclarationDescriptor descriptor = jetType.getConstructor().getDeclarationDescriptor(); @@ -318,7 +345,7 @@ public class JetTypeMapper { if (signatureVisitor != null) { signatureVisitor.writeArrayType(jetType.isNullable()); - mapType(memberType, kind, signatureVisitor, true); + mapType(memberType, signatureVisitor, MapTypeMode.TYPE_PARAMETER); signatureVisitor.writeArrayEnd(); } @@ -350,7 +377,7 @@ public class JetTypeMapper { forceReal = false; } else { JvmClassName name = getClassFQName((ClassDescriptor) descriptor); - asmType = Type.getObjectType(name.getInternalName() + (kind == OwnerKind.TRAIT_IMPL ? JvmAbi.TRAIT_IMPL_SUFFIX : "")); + asmType = Type.getObjectType(name.getInternalName() + (kind == MapTypeMode.TRAIT_IMPL ? JvmAbi.TRAIT_IMPL_SUFFIX : "")); forceReal = isForceReal(name); } @@ -359,7 +386,7 @@ public class JetTypeMapper { for (TypeProjection proj : jetType.getArguments()) { // TODO: +- signatureVisitor.writeTypeArgument(proj.getProjectionKind()); - mapType(proj.getType(), kind, signatureVisitor, true); + mapType(proj.getType(), signatureVisitor, MapTypeMode.TYPE_PARAMETER); signatureVisitor.writeTypeArgumentEnd(); } signatureVisitor.writeClassEnd(); @@ -381,15 +408,19 @@ public class JetTypeMapper { throw new UnsupportedOperationException("Unknown type " + jetType); } - private Type mapKnownAsmType(JetType jetType, Type asmType, @Nullable BothSignatureWriter signatureVisitor, boolean genericTypeParameter) { - if (signatureVisitor != null) { - if (genericTypeParameter) { - visitAsmType(signatureVisitor, boxType(asmType), jetType.isNullable()); - } else { + private Type mapKnownAsmType(JetType jetType, Type asmType, @Nullable BothSignatureWriter signatureVisitor, boolean boxPrimitive) { + if (boxPrimitive) { + Type boxed = boxType(asmType); + if (signatureVisitor != null) { + visitAsmType(signatureVisitor, boxed, jetType.isNullable()); + } + return boxed; + } else { + if (signatureVisitor != null) { visitAsmType(signatureVisitor, asmType, jetType.isNullable()); } + return asmType; } - return asmType; } public static void visitAsmType(BothSignatureWriter visitor, Type asmType, boolean nullable) { @@ -435,7 +466,7 @@ public class JetTypeMapper { else if (functionDescriptor instanceof ConstructorDescriptor) { assert !superCall; ClassDescriptor containingClass = (ClassDescriptor) functionParent; - owner = mapType(containingClass.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(); + owner = mapType(containingClass.getDefaultType(), MapTypeMode.IMPL).getInternalName(); ownerForDefaultImpl = ownerForDefaultParam = owner; invokeOpcode = INVOKESPECIAL; thisClass = null; @@ -457,12 +488,12 @@ public class JetTypeMapper { receiver = currentOwner; } - ClassDescriptor containingClass = (ClassDescriptor) functionParent; + // TODO: TYPE_PARAMETER is hack here + boolean isInterface = originalIsInterface && currentIsInterface; - OwnerKind kind1 = isInterface && superCall ? OwnerKind.TRAIT_IMPL : OwnerKind.IMPLEMENTATION; - Type type = mapType(receiver.getDefaultType(), OwnerKind.IMPLEMENTATION); + Type type = mapType(receiver.getDefaultType(), MapTypeMode.TYPE_PARAMETER); owner = type.getInternalName(); - ownerForDefaultParam = mapType(((ClassDescriptor) declarationOwner).getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(); + ownerForDefaultParam = mapType(declarationOwner.getDefaultType(), MapTypeMode.TYPE_PARAMETER).getInternalName(); ownerForDefaultImpl = ownerForDefaultParam + (originalIsInterface ? JvmAbi.TRAIT_IMPL_SUFFIX : ""); @@ -518,10 +549,10 @@ public class JetTypeMapper { if(kind == OwnerKind.TRAIT_IMPL) { ClassDescriptor containingDeclaration = (ClassDescriptor) f.getContainingDeclaration(); JetType jetType = TraitImplBodyCodegen.getSuperClass(containingDeclaration, bindingContext); - Type type = mapType(jetType); + Type type = mapType(jetType, MapTypeMode.VALUE); if(type.getInternalName().equals("java/lang/Object")) { jetType = containingDeclaration.getDefaultType(); - type = mapType(jetType); + type = mapType(jetType, MapTypeMode.VALUE); } signatureVisitor.writeParameterType(JvmMethodParameterKind.THIS); @@ -531,13 +562,13 @@ public class JetTypeMapper { if (receiverType != null) { signatureVisitor.writeParameterType(JvmMethodParameterKind.RECEIVER); - mapType(receiverType, signatureVisitor); + mapType(receiverType, signatureVisitor, MapTypeMode.VALUE); signatureVisitor.writeParameterTypeEnd(); } for (ValueParameterDescriptor parameter : parameters) { signatureVisitor.writeParameterType(JvmMethodParameterKind.VALUE); - mapType(parameter.getType(), signatureVisitor); + mapType(parameter.getType(), signatureVisitor, MapTypeMode.VALUE); signatureVisitor.writeParameterTypeEnd(); } @@ -576,7 +607,7 @@ public class JetTypeMapper { for (JetType jetType : typeParameterDescriptor.getUpperBounds()) { if (jetType.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor) { if (!CodegenUtil.isInterface(jetType)) { - mapType(jetType, signatureVisitor); + mapType(jetType, signatureVisitor, MapTypeMode.TYPE_PARAMETER); break classBound; } } @@ -593,13 +624,13 @@ public class JetTypeMapper { if (jetType.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor) { if (CodegenUtil.isInterface(jetType)) { signatureVisitor.writeInterfaceBound(); - mapType(jetType, signatureVisitor); + mapType(jetType, signatureVisitor, MapTypeMode.TYPE_PARAMETER); signatureVisitor.writeInterfaceBoundEnd(); } } if (jetType.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor) { signatureVisitor.writeInterfaceBound(); - mapType(jetType, signatureVisitor); + mapType(jetType, signatureVisitor, MapTypeMode.TYPE_PARAMETER); signatureVisitor.writeInterfaceBoundEnd(); } } @@ -620,12 +651,12 @@ public class JetTypeMapper { final List parameters = f.getValueParameters(); if (receiver.exists()) { signatureWriter.writeParameterType(JvmMethodParameterKind.RECEIVER); - mapType(receiver.getType(), signatureWriter); + mapType(receiver.getType(), signatureWriter, MapTypeMode.VALUE); signatureWriter.writeParameterTypeEnd(); } for (ValueParameterDescriptor parameter : parameters) { signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE); - mapType(parameter.getType(), signatureWriter); + mapType(parameter.getType(), signatureWriter, MapTypeMode.VALUE); signatureWriter.writeParameterTypeEnd(); } @@ -653,20 +684,20 @@ public class JetTypeMapper { ClassDescriptor containingDeclaration = (ClassDescriptor) descriptor.getContainingDeclaration(); assert containingDeclaration != null; signatureWriter.writeParameterType(JvmMethodParameterKind.THIS); - mapType(containingDeclaration.getDefaultType(), signatureWriter); + mapType(containingDeclaration.getDefaultType(), signatureWriter, MapTypeMode.IMPL); signatureWriter.writeParameterTypeEnd(); } if(descriptor.getReceiverParameter().exists()) { signatureWriter.writeParameterType(JvmMethodParameterKind.RECEIVER); - mapType(descriptor.getReceiverParameter().getType(), signatureWriter); + mapType(descriptor.getReceiverParameter().getType(), signatureWriter, MapTypeMode.VALUE); signatureWriter.writeParameterTypeEnd(); } signatureWriter.writeParametersEnd(); signatureWriter.writeReturnType(); - mapType(descriptor.getType(), signatureWriter); + mapType(descriptor.getType(), signatureWriter, MapTypeMode.VALUE); signatureWriter.writeReturnTypeEnd(); JvmMethodSignature jvmMethodSignature = signatureWriter.makeJvmMethodSignature(name); @@ -694,18 +725,18 @@ public class JetTypeMapper { ClassDescriptor containingDeclaration = (ClassDescriptor) descriptor.getContainingDeclaration(); assert containingDeclaration != null; signatureWriter.writeParameterType(JvmMethodParameterKind.THIS); - mapType(containingDeclaration.getDefaultType(), signatureWriter); + mapType(containingDeclaration.getDefaultType(), signatureWriter, MapTypeMode.VALUE); signatureWriter.writeParameterTypeEnd(); } if(descriptor.getReceiverParameter().exists()) { signatureWriter.writeParameterType(JvmMethodParameterKind.RECEIVER); - mapType(descriptor.getReceiverParameter().getType(), signatureWriter); + mapType(descriptor.getReceiverParameter().getType(), signatureWriter, MapTypeMode.VALUE); signatureWriter.writeParameterTypeEnd(); } signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE); - mapType(outType, signatureWriter); + mapType(outType, signatureWriter, MapTypeMode.VALUE); signatureWriter.writeParameterTypeEnd(); signatureWriter.writeParametersEnd(); @@ -729,13 +760,13 @@ public class JetTypeMapper { if (hasThis0) { signatureWriter.writeParameterType(JvmMethodParameterKind.THIS0); - mapType(closureAnnotator.getEclosingClassDescriptor(descriptor.getContainingDeclaration()).getDefaultType(), OwnerKind.IMPLEMENTATION, signatureWriter); + mapType(closureAnnotator.getEclosingClassDescriptor(descriptor.getContainingDeclaration()).getDefaultType(), signatureWriter, MapTypeMode.VALUE); signatureWriter.writeParameterTypeEnd(); } for (ValueParameterDescriptor parameter : parameters) { signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE); - mapType(parameter.getType(), signatureWriter); + mapType(parameter.getType(), signatureWriter, MapTypeMode.VALUE); signatureWriter.writeParameterTypeEnd(); } @@ -748,7 +779,8 @@ public class JetTypeMapper { public CallableMethod mapToCallableMethod(ConstructorDescriptor descriptor, OwnerKind kind, boolean hasThis0) { final JvmMethodSignature method = mapConstructorSignature(descriptor, hasThis0); - String owner = mapType(descriptor.getContainingDeclaration().getDefaultType(), kind).getInternalName(); + MapTypeMode mapTypeMode = ownerKindToMapTypeMode(kind); + String owner = mapType(descriptor.getContainingDeclaration().getDefaultType(), mapTypeMode).getInternalName(); return new CallableMethod(owner, owner, owner, method, INVOKESPECIAL); } @@ -778,7 +810,7 @@ public class JetTypeMapper { Set result = new HashSet(); final ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, jetClass); if (classDescriptor != null) { - result.add(mapType(classDescriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName()); + result.add(mapType(classDescriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName()); } return result; } @@ -851,20 +883,20 @@ public class JetTypeMapper { public Type getSharedVarType(DeclarationDescriptor descriptor) { if(descriptor instanceof PropertyDescriptor) { - return StackValue.sharedTypeForType(mapType(((PropertyDescriptor) descriptor).getReceiverParameter().getType())); + return StackValue.sharedTypeForType(mapType(((PropertyDescriptor) descriptor).getReceiverParameter().getType(), MapTypeMode.VALUE)); } else if (descriptor instanceof SimpleFunctionDescriptor && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) { PsiElement psiElement = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor); return Type.getObjectType(closureAnnotator.classNameForAnonymousClass((JetElement) psiElement)); } else if (descriptor instanceof FunctionDescriptor) { - return StackValue.sharedTypeForType(mapType(((FunctionDescriptor) descriptor).getReceiverParameter().getType())); + return StackValue.sharedTypeForType(mapType(((FunctionDescriptor) descriptor).getReceiverParameter().getType(), MapTypeMode.VALUE)); } else if (descriptor instanceof VariableDescriptor) { Boolean aBoolean = bindingContext.get(BindingContext.MUST_BE_WRAPPED_IN_A_REF, (VariableDescriptor) descriptor); if (aBoolean != null && aBoolean) { JetType outType = ((VariableDescriptor) descriptor).getType(); - return StackValue.sharedTypeForType(mapType(outType)); + return StackValue.sharedTypeForType(mapType(outType, MapTypeMode.VALUE)); } else { return null; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/MapTypeMode.java b/compiler/backend/src/org/jetbrains/jet/codegen/MapTypeMode.java new file mode 100644 index 00000000000..e29d76067ac --- /dev/null +++ b/compiler/backend/src/org/jetbrains/jet/codegen/MapTypeMode.java @@ -0,0 +1,31 @@ +/* + * Copyright 2010-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.codegen; + +/** + * @author Stepan Koltsov + */ +public enum MapTypeMode { + /** jet.Int is mapped to Ljet/Int; */ + IMPL, + /** jet.Int is mapped to Ljet/Impl$TImpl; */ + TRAIT_IMPL, + /** jet.Int is mapped to I */ + VALUE, + /** jet.Int is mapped to Ljava/lang/Integer; */ + TYPE_PARAMETER, +} diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ObjectOrClosureCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ObjectOrClosureCodegen.java index 3778e881a26..747921ca25a 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ObjectOrClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ObjectOrClosureCodegen.java @@ -61,7 +61,7 @@ public class ObjectOrClosureCodegen { if (idx < 0) return null; final Type sharedVarType = state.getInjector().getJetTypeMapper().getSharedVarType(vd); - Type localType = state.getInjector().getJetTypeMapper().mapType(vd.getType()); + Type localType = state.getInjector().getJetTypeMapper().mapType(vd.getType(), MapTypeMode.VALUE); final Type type = sharedVarType != null ? sharedVarType : localType; StackValue outerValue = StackValue.local(idx, type); @@ -110,7 +110,7 @@ public class ObjectOrClosureCodegen { if(fcontext.getReceiverDescriptor() != fd) return null; - Type type = state.getInjector().getJetTypeMapper().mapType(fcontext.getReceiverDescriptor().getReceiverParameter().getType()); + Type type = state.getInjector().getJetTypeMapper().mapType(fcontext.getReceiverDescriptor().getReceiverParameter().getType(), MapTypeMode.VALUE); boolean isStatic = fcontext.getContextDescriptor().getContainingDeclaration() instanceof NamespaceDescriptor; StackValue outerValue = StackValue.local(isStatic ? 0 : 1, type); final String fieldName = "receiver$0"; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java index 7950140aa4f..91e754a410c 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java @@ -97,7 +97,8 @@ public class PropertyCodegen { if(state.getInjector().getJetStandardLibrary().isVolatile(propertyDescriptor)) { modifiers |= Opcodes.ACC_VOLATILE; } - FieldVisitor fieldVisitor = v.newField(p, modifiers, p.getName(), state.getInjector().getJetTypeMapper().mapType(propertyDescriptor.getType()).getDescriptor(), null, value); + Type type = state.getInjector().getJetTypeMapper().mapType(propertyDescriptor.getType(), MapTypeMode.VALUE); + FieldVisitor fieldVisitor = v.newField(p, modifiers, p.getName(), type.getDescriptor(), null, value); AnnotationCodegen.forField(fieldVisitor, state.getInjector().getJetTypeMapper()).genAnnotations(propertyDescriptor); } } @@ -189,7 +190,7 @@ public class PropertyCodegen { if (kind != OwnerKind.NAMESPACE) { iv.load(0, JetTypeMapper.TYPE_OBJECT); } - final Type type = state.getInjector().getJetTypeMapper().mapType(propertyDescriptor.getType()); + final Type type = state.getInjector().getJetTypeMapper().mapType(propertyDescriptor.getType(), MapTypeMode.VALUE); if ((kind instanceof OwnerKind.DelegateKind) != (propertyDescriptor.getKind() == FunctionDescriptor.Kind.DELEGATION)) { throw new IllegalStateException("mismatching kind in " + propertyDescriptor); @@ -269,7 +270,7 @@ public class PropertyCodegen { StubCodegen.generateStubThrow(mv); } else { InstructionAdapter iv = new InstructionAdapter(mv); - final Type type = state.getInjector().getJetTypeMapper().mapType(propertyDescriptor.getType()); + final Type type = state.getInjector().getJetTypeMapper().mapType(propertyDescriptor.getType(), MapTypeMode.VALUE); int paramCode = 0; if (kind != OwnerKind.NAMESPACE) { iv.load(0, JetTypeMapper.TYPE_OBJECT); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java index 4b8127fca44..5f7444a4c57 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java @@ -597,7 +597,7 @@ public abstract class StackValue { List valueParameters = resolvedGetCall.getResultingDescriptor().getValueParameters(); int firstParamIndex = -1; for(int i = valueParameters.size()-1; i >= 0; --i) { - Type type = codegen.typeMapper.mapType(valueParameters.get(i).getType()); + Type type = codegen.typeMapper.mapType(valueParameters.get(i).getType(), MapTypeMode.VALUE); int sz = type.getSize(); frame.enterTemp(sz); lastIndex += sz; @@ -619,7 +619,7 @@ public abstract class StackValue { ReceiverDescriptor receiverParameter = resolvedGetCall.getReceiverArgument(); int receiverIndex = -1; if(receiverParameter.exists()) { - Type type = codegen.typeMapper.mapType(receiverParameter.getType()); + Type type = codegen.typeMapper.mapType(receiverParameter.getType(), MapTypeMode.VALUE); int sz = type.getSize(); frame.enterTemp(sz); lastIndex += sz; @@ -643,7 +643,7 @@ public abstract class StackValue { if(thisIndex != -1) { if(receiverIndex != -1) { realReceiverIndex = receiverIndex; - realReceiverType = codegen.typeMapper.mapType(receiverParameter.getType()); + realReceiverType = codegen.typeMapper.mapType(receiverParameter.getType(), MapTypeMode.VALUE); } else { realReceiverIndex = thisIndex; @@ -652,7 +652,7 @@ public abstract class StackValue { } else { if(receiverIndex != -1) { - realReceiverType = codegen.typeMapper.mapType(receiverParameter.getType()); + realReceiverType = codegen.typeMapper.mapType(receiverParameter.getType(), MapTypeMode.VALUE); realReceiverIndex = receiverIndex; } else { @@ -677,7 +677,7 @@ public abstract class StackValue { int index = firstParamIndex; for(int i = 0; i != valueParameters.size(); ++i) { - Type type = codegen.typeMapper.mapType(valueParameters.get(i).getType()); + Type type = codegen.typeMapper.mapType(valueParameters.get(i).getType(), MapTypeMode.VALUE); int sz = type.getSize(); v.load(index-sz, type); index -= sz; @@ -689,7 +689,7 @@ public abstract class StackValue { } if(receiverIndex != -1) { - Type type = codegen.typeMapper.mapType(receiverParameter.getType()); + Type type = codegen.typeMapper.mapType(receiverParameter.getType(), MapTypeMode.VALUE); v.load(receiverIndex-type.getSize(), type); } @@ -705,7 +705,7 @@ public abstract class StackValue { index = firstParamIndex; for(int i = 0; i != valueParameters.size(); ++i) { - Type type = codegen.typeMapper.mapType(valueParameters.get(i).getType()); + Type type = codegen.typeMapper.mapType(valueParameters.get(i).getType(), MapTypeMode.VALUE); int sz = type.getSize(); v.load(index-sz, type); index -= sz; @@ -729,7 +729,7 @@ public abstract class StackValue { return false; for (ValueParameterDescriptor valueParameter : valueParameters) { - if (codegen.typeMapper.mapType(valueParameter.getType()).getSize() != 1) + if (codegen.typeMapper.mapType(valueParameter.getType(), MapTypeMode.VALUE).getSize() != 1) return false; } @@ -738,7 +738,7 @@ public abstract class StackValue { return false; } else { - if(codegen.typeMapper.mapType(call.getResultingDescriptor().getReceiverParameter().getType()).getSize() != 1) + if(codegen.typeMapper.mapType(call.getResultingDescriptor().getReceiverParameter().getType(), MapTypeMode.VALUE).getSize() != 1) return false; } @@ -1084,27 +1084,27 @@ public abstract class StackValue { if (thisObject.exists()) { if(callableMethod != null) { if(receiverArgument.exists()) { - return codegen.typeMapper.mapType(callableMethod.getReceiverClass()); + return codegen.typeMapper.mapType(callableMethod.getReceiverClass(), MapTypeMode.VALUE); } else { - return codegen.typeMapper.mapType(callableMethod.getThisType()); + return codegen.typeMapper.mapType(callableMethod.getThisType(), MapTypeMode.VALUE); } } else { if(receiverArgument.exists()) { - return codegen.typeMapper.mapType(descriptor.getReceiverParameter().getType()); + return codegen.typeMapper.mapType(descriptor.getReceiverParameter().getType(), MapTypeMode.VALUE); } else { - return codegen.typeMapper.mapType(descriptor.getExpectedThisObject().getType()); + return codegen.typeMapper.mapType(descriptor.getExpectedThisObject().getType(), MapTypeMode.VALUE); } } } else { if (receiverArgument.exists()) { if(callableMethod != null) - return codegen.typeMapper.mapType(callableMethod.getReceiverClass()); + return codegen.typeMapper.mapType(callableMethod.getReceiverClass(), MapTypeMode.VALUE); else - return codegen.typeMapper.mapType(descriptor.getReceiverParameter().getType()); + return codegen.typeMapper.mapType(descriptor.getReceiverParameter().getType(), MapTypeMode.VALUE); } else { return Type.VOID_TYPE; @@ -1120,7 +1120,12 @@ public abstract class StackValue { ReceiverDescriptor receiverArgument = resolvedCall.getReceiverArgument(); if (thisObject.exists()) { if(receiverArgument.exists()) { - codegen.generateFromResolvedCall(thisObject, callableMethod != null ? Type.getObjectType(callableMethod.getOwner()) : codegen.typeMapper.mapType(descriptor.getExpectedThisObject().getType())); + if (callableMethod != null) { + codegen.generateFromResolvedCall(thisObject, Type.getObjectType(callableMethod.getOwner())); + } + else { + codegen.generateFromResolvedCall(thisObject, codegen.typeMapper.mapType(descriptor.getExpectedThisObject().getType(), MapTypeMode.VALUE)); + } genReceiver(v, receiverArgument, type, descriptor.getReceiverParameter()); } else { @@ -1137,7 +1142,7 @@ public abstract class StackValue { private void genReceiver(InstructionAdapter v, ReceiverDescriptor receiverArgument, Type type, ReceiverDescriptor receiverParameter) { if(receiver == StackValue.none()) { if(receiverParameter != null) { - Type receiverType = codegen.typeMapper.mapType(receiverParameter.getType()); + Type receiverType = codegen.typeMapper.mapType(receiverParameter.getType(), MapTypeMode.VALUE); codegen.generateFromResolvedCall(receiverArgument, receiverType); StackValue.onStack(receiverType).put(type, v); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/TraitImplBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/TraitImplBodyCodegen.java index ae63faac03a..be2a3b1a9a0 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/TraitImplBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/TraitImplBodyCodegen.java @@ -74,6 +74,6 @@ public class TraitImplBodyCodegen extends ClassBodyCodegen { } private String jvmName() { - return state.getInjector().getJetTypeMapper().mapType(descriptor.getDefaultType(), OwnerKind.TRAIT_IMPL).getInternalName(); + return state.getInjector().getJetTypeMapper().mapType(descriptor.getDefaultType(), MapTypeMode.TRAIT_IMPL).getInternalName(); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/JavaClassFunction.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/JavaClassFunction.java index 21c879e9071..422061f1633 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/JavaClassFunction.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/JavaClassFunction.java @@ -19,10 +19,7 @@ package org.jetbrains.jet.codegen.intrinsics; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.codegen.ExpressionCodegen; -import org.jetbrains.jet.codegen.GenerationState; -import org.jetbrains.jet.codegen.JetTypeMapper; -import org.jetbrains.jet.codegen.StackValue; +import org.jetbrains.jet.codegen.*; import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.psi.JetCallExpression; import org.jetbrains.jet.lang.psi.JetExpression; @@ -43,7 +40,8 @@ public class JavaClassFunction implements IntrinsicMethod { JetCallExpression call = (JetCallExpression) element; ResolvedCall resolvedCall = codegen.getBindingContext().get(BindingContext.RESOLVED_CALL, call.getCalleeExpression()); CallableDescriptor resultingDescriptor = resolvedCall.getResultingDescriptor(); - Type type = state.getInjector().getJetTypeMapper().mapType(resultingDescriptor.getReturnType().getArguments().get(0).getType()); + Type type = state.getInjector().getJetTypeMapper().mapType( + resultingDescriptor.getReturnType().getArguments().get(0).getType(), MapTypeMode.VALUE); v.aconst(type); return StackValue.onStack(JetTypeMapper.JL_CLASS_TYPE); } diff --git a/compiler/backend/src/org/jetbrains/jet/di/InjectorForJetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/di/InjectorForJetTypeMapper.java index ee9a45e1b7a..ddbaad7230d 100644 --- a/compiler/backend/src/org/jetbrains/jet/di/InjectorForJetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/di/InjectorForJetTypeMapper.java @@ -22,6 +22,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext; import java.util.List; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.codegen.JetTypeMapper; +import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode; import org.jetbrains.jet.codegen.ClosureAnnotator; import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; import org.jetbrains.jet.lang.resolve.BindingContext; @@ -40,10 +41,12 @@ public class InjectorForJetTypeMapper { @NotNull List listOfJetFile ) { this.jetTypeMapper = new JetTypeMapper(); + CompilerSpecialMode compilerSpecialMode = CompilerSpecialMode.REGULAR; ClosureAnnotator closureAnnotator = new ClosureAnnotator(); this.jetTypeMapper.setBindingContext(bindingContext); this.jetTypeMapper.setClosureAnnotator(closureAnnotator); + this.jetTypeMapper.setCompilerSpecialMode(compilerSpecialMode); this.jetTypeMapper.setStandardLibrary(jetStandardLibrary); closureAnnotator.setBindingContext(bindingContext); diff --git a/compiler/backend/src/org/jetbrains/jet/di/InjectorForJvmCodegen.java b/compiler/backend/src/org/jetbrains/jet/di/InjectorForJvmCodegen.java index a133b8f6973..626c27bbf54 100644 --- a/compiler/backend/src/org/jetbrains/jet/di/InjectorForJvmCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/di/InjectorForJvmCodegen.java @@ -22,6 +22,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext; import java.util.List; import org.jetbrains.jet.lang.psi.JetFile; import com.intellij.openapi.project.Project; +import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.ClassBuilderFactory; import org.jetbrains.jet.codegen.JetTypeMapper; @@ -33,6 +34,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext; import java.util.List; import org.jetbrains.jet.lang.psi.JetFile; import com.intellij.openapi.project.Project; +import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode; import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.ClassBuilderFactory; import org.jetbrains.annotations.NotNull; @@ -51,6 +53,7 @@ public class InjectorForJvmCodegen { @NotNull BindingContext bindingContext, @NotNull List listOfJetFile, @NotNull Project project, + @NotNull CompilerSpecialMode compilerSpecialMode, @NotNull GenerationState generationState, @NotNull ClassBuilderFactory classBuilderFactory ) { @@ -63,6 +66,7 @@ public class InjectorForJvmCodegen { this.jetTypeMapper.setBindingContext(bindingContext); this.jetTypeMapper.setClosureAnnotator(closureAnnotator); + this.jetTypeMapper.setCompilerSpecialMode(compilerSpecialMode); this.jetTypeMapper.setStandardLibrary(jetStandardLibrary); this.intrinsics.setMyProject(project); diff --git a/compiler/cli/src/org/jetbrains/jet/compiler/CompileSession.java b/compiler/cli/src/org/jetbrains/jet/compiler/CompileSession.java index cc616bce02e..53e2ce87a40 100644 --- a/compiler/cli/src/org/jetbrains/jet/compiler/CompileSession.java +++ b/compiler/cli/src/org/jetbrains/jet/compiler/CompileSession.java @@ -221,7 +221,7 @@ public class CompileSession { public GenerationState generate(boolean module) { Project project = environment.getProject(); GenerationState generationState = new GenerationState(project, ClassBuilderFactories.binaries(stubs), - isVerbose ? new BackendProgress() : Progress.DEAF, bindingContext, sourceFiles); + isVerbose ? new BackendProgress() : Progress.DEAF, bindingContext, sourceFiles, compilerSpecialMode); generationState.compileCorrectFiles(CompilationErrorHandler.THROW_EXCEPTION); List plugins = environment.getCompilerPlugins(); diff --git a/compiler/tests/org/jetbrains/jet/codegen/TestlibTest.java b/compiler/tests/org/jetbrains/jet/codegen/TestlibTest.java index d0f5e51b177..31929f0178a 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/TestlibTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/TestlibTest.java @@ -112,9 +112,9 @@ public class TestlibTest extends CodegenTestCase { DescriptorUtils.addSuperTypes(descriptor.getDefaultType(), allSuperTypes); for(JetType type : allSuperTypes) { - String internalName = typeMapper.mapType(type).getInternalName(); + String internalName = typeMapper.mapType(type, MapTypeMode.IMPL).getInternalName(); if(internalName.equals("junit/framework/Test")) { - String name = typeMapper.mapType(descriptor.getDefaultType()).getInternalName(); + String name = typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName(); System.out.println(name); Class aClass = (Class) loader.loadClass(name.replace('/', '.')); if((aClass.getModifiers() & Modifier.ABSTRACT) == 0 diff --git a/injector-generator/src/org/jetbrains/jet/di/AllInjectorsGenerator.java b/injector-generator/src/org/jetbrains/jet/di/AllInjectorsGenerator.java index 22113e44678..7da2a677043 100644 --- a/injector-generator/src/org/jetbrains/jet/di/AllInjectorsGenerator.java +++ b/injector-generator/src/org/jetbrains/jet/di/AllInjectorsGenerator.java @@ -146,6 +146,7 @@ public class AllInjectorsGenerator { generator.addParameter(BindingContext.class); generator.addParameter(DiType.listOf(JetFile.class)); generator.addParameter(Project.class); + generator.addParameter(CompilerSpecialMode.class); generator.addPublicParameter(GenerationState.class); generator.addParameter(ClassBuilderFactory.class); generator.addPublicField(JetTypeMapper.class); @@ -160,6 +161,7 @@ public class AllInjectorsGenerator { generator.addParameter(BindingContext.class); generator.addParameter(DiType.listOf(JetFile.class)); generator.addPublicField(JetTypeMapper.class); + generator.addField(CompilerSpecialMode.REGULAR); generator.generate("compiler/backend/src", "org.jetbrains.jet.di", "InjectorForJetTypeMapper"); }