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
This commit is contained in:
Stepan Koltsov
2012-04-07 06:32:18 +04:00
parent d8e86b12aa
commit b38e171812
21 changed files with 290 additions and 165 deletions
+6
View File
@@ -23,10 +23,16 @@
</option> </option>
<envs /> <envs />
<patterns /> <patterns />
<RunnerSettings RunnerId="Debug">
<option name="DEBUG_PORT" value="" />
<option name="TRANSPORT" value="0" />
<option name="LOCAL" value="true" />
</RunnerSettings>
<RunnerSettings RunnerId="Profile "> <RunnerSettings RunnerId="Profile ">
<option name="myExternalizedOptions" value="&#10;additional-options2=onexit\=snapshot&#10;" /> <option name="myExternalizedOptions" value="&#10;additional-options2=onexit\=snapshot&#10;" />
</RunnerSettings> </RunnerSettings>
<RunnerSettings RunnerId="Run" /> <RunnerSettings RunnerId="Run" />
<ConfigurationWrapper RunnerId="Debug" />
<ConfigurationWrapper RunnerId="Run" /> <ConfigurationWrapper RunnerId="Run" />
<method /> <method />
</configuration> </configuration>
@@ -85,7 +85,7 @@ public abstract class AnnotationCodegen {
return; return;
} }
String internalName = typeMapper.mapType(type).getDescriptor(); String internalName = typeMapper.mapType(type, MapTypeMode.VALUE).getDescriptor();
AnnotationVisitor annotationVisitor = visitAnnotation(internalName, rp == RetentionPolicy.RUNTIME); AnnotationVisitor annotationVisitor = visitAnnotation(internalName, rp == RetentionPolicy.RUNTIME);
getAnnotation(resolvedCall, annotationVisitor); getAnnotation(resolvedCall, annotationVisitor);
@@ -138,7 +138,7 @@ public abstract class AnnotationCodegen {
if(call != null) { if(call != null) {
if(call.getResultingDescriptor() instanceof PropertyDescriptor) { if(call.getResultingDescriptor() instanceof PropertyDescriptor) {
PropertyDescriptor descriptor = (PropertyDescriptor)call.getResultingDescriptor(); 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; return;
} }
} }
@@ -160,7 +160,7 @@ public abstract class AnnotationCodegen {
} }
} }
if(IntrinsicMethods.KOTLIN_JAVA_CLASS_FUNCTION.equals(value)) { 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; return;
} }
else if(IntrinsicMethods.KOTLIN_ARRAYS_ARRAY.equals(value)) { else if(IntrinsicMethods.KOTLIN_ARRAYS_ARRAY.equals(value)) {
@@ -175,7 +175,7 @@ public abstract class AnnotationCodegen {
else if(call.getResultingDescriptor() instanceof ConstructorDescriptor) { else if(call.getResultingDescriptor() instanceof ConstructorDescriptor) {
ConstructorDescriptor descriptor = (ConstructorDescriptor)call.getResultingDescriptor(); ConstructorDescriptor descriptor = (ConstructorDescriptor)call.getResultingDescriptor();
AnnotationVisitor visitor = annotationVisitor.visitAnnotation(keyName, typeMapper AnnotationVisitor visitor = annotationVisitor.visitAnnotation(keyName, typeMapper
.mapType(descriptor.getContainingDeclaration().getDefaultType()).getDescriptor()); .mapType(descriptor.getContainingDeclaration().getDefaultType(), MapTypeMode.VALUE).getDescriptor());
getAnnotation(call, visitor); getAnnotation(call, visitor);
visitor.visitEnd(); visitor.visitEnd();
return; return;
@@ -23,6 +23,7 @@ import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter; import org.objectweb.asm.commons.InstructionAdapter;
import java.util.ArrayList; import java.util.ArrayList;
@@ -124,11 +125,13 @@ public abstract class ClassBodyCodegen {
if(state.getInjector().getJetStandardLibrary().isVolatile(propertyDescriptor)) { if(state.getInjector().getJetStandardLibrary().isVolatile(propertyDescriptor)) {
modifiers |= Opcodes.ACC_VOLATILE; 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 { 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);
} }
} }
} }
@@ -134,7 +134,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
generateBridge(name, funDescriptor, fun, cv); generateBridge(name, funDescriptor, fun, cv);
captureThis = generateBody(funDescriptor, cv, (JetDeclarationWithBody) fun); captureThis = generateBody(funDescriptor, cv, (JetDeclarationWithBody) fun);
ClassDescriptor thisDescriptor = context.getThisDescriptor(); 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) if (enclosingType == null)
captureThis = null; captureThis = null;
@@ -224,14 +224,14 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
int count = 1; int count = 1;
if (receiver.exists()) { if (receiver.exists()) {
StackValue.local(count, JetTypeMapper.TYPE_OBJECT).put(JetTypeMapper.TYPE_OBJECT, iv); 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++; count++;
} }
final List<ValueParameterDescriptor> params = funDescriptor.getValueParameters(); final List<ValueParameterDescriptor> params = funDescriptor.getValueParameters();
for (ValueParameterDescriptor param : params) { for (ValueParameterDescriptor param : params) {
StackValue.local(count, JetTypeMapper.TYPE_OBJECT).put(JetTypeMapper.TYPE_OBJECT, iv); 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++; count++;
} }
@@ -268,7 +268,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
int i = 0; int i = 0;
if (captureThis != null) { 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) { if (captureReceiver != null) {
@@ -278,7 +278,13 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
for (DeclarationDescriptor descriptor : closure.keySet()) { for (DeclarationDescriptor descriptor : closure.keySet()) {
if(descriptor instanceof VariableDescriptor && !(descriptor instanceof PropertyDescriptor)) { if(descriptor instanceof VariableDescriptor && !(descriptor instanceof PropertyDescriptor)) {
final Type sharedVarType = state.getInjector().getJetTypeMapper().getSharedVarType(descriptor); 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; argTypes[i++] = type;
} }
else if(CodegenUtil.isNamedFun(descriptor, state.getBindingContext()) && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) { else if(CodegenUtil.isNamedFun(descriptor, state.getBindingContext()) && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) {
@@ -352,7 +358,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
signatureWriter.visitTypeArgument(variance); signatureWriter.visitTypeArgument(variance);
final JetTypeMapper typeMapper = state.getInjector().getJetTypeMapper(); 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.visitClassType(rawRetType.getInternalName());
signatureWriter.visitEnd(); signatureWriter.visitEnd();
} }
@@ -157,7 +157,7 @@ public abstract class CodegenContext {
CallableDescriptor receiverDescriptor = getReceiverDescriptor(); CallableDescriptor receiverDescriptor = getReceiverDescriptor();
if (receiverDescriptor != null) { 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 frameMap.enterTemp(type.getSize()); // Next slot for fake this
} }
@@ -171,7 +171,7 @@ public abstract class CodegenContext {
public Type jvmType(JetTypeMapper mapper) { public Type jvmType(JetTypeMapper mapper) {
if (contextType instanceof ClassDescriptor) { if (contextType instanceof ClassDescriptor) {
return mapper.mapType(((ClassDescriptor) contextType).getDefaultType(), contextKind); return mapper.mapType(((ClassDescriptor) contextType).getDefaultType(), JetTypeMapper.ownerKindToMapTypeMode(contextKind));
} }
else if (closure != null) { else if (closure != null) {
return Type.getObjectType(closure.name); return Type.getObjectType(closure.name);
@@ -200,7 +200,7 @@ public abstract class CodegenContext {
while(cur != null && !(cur.getContextDescriptor() instanceof ClassDescriptor)) while(cur != null && !(cur.getContextDescriptor() instanceof ClassDescriptor))
cur = cur.getParentContext(); 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) { public int getTypeInfoConstantIndex(JetType type) {
@@ -282,7 +282,7 @@ public abstract class CodegenContext {
public StackValue getReceiverExpression(JetTypeMapper typeMapper) { public StackValue getReceiverExpression(JetTypeMapper typeMapper) {
assert getReceiverDescriptor() != null; 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); return getThisDescriptor() != null ? StackValue.local(1, asmType) : StackValue.local(0, asmType);
} }
@@ -390,8 +390,9 @@ public abstract class CodegenContext {
super(contextType, contextKind, parentContext, closure); super(contextType, contextKind, parentContext, closure);
final Type type = enclosingClassType(typeMapper); final Type type = enclosingClassType(typeMapper);
Type owner = closure.state.getInjector().getJetTypeMapper().mapType(contextType.getDefaultType(), MapTypeMode.IMPL);
outerExpression = type != null 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; : null;
} }
@@ -188,7 +188,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
} }
private Type asmType(JetType type) { private Type asmType(JetType type) {
return typeMapper.mapType(type); return typeMapper.mapType(type, MapTypeMode.VALUE);
} }
@Override @Override
@@ -801,7 +801,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
if(entry.getKey() instanceof VariableDescriptor && !(entry.getKey() instanceof PropertyDescriptor)) { if(entry.getKey() instanceof VariableDescriptor && !(entry.getKey() instanceof PropertyDescriptor)) {
Type sharedVarType = typeMapper.getSharedVarType(entry.getKey()); Type sharedVarType = typeMapper.getSharedVarType(entry.getKey());
if(sharedVarType == null) 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); consArgTypes.add(sharedVarType);
entry.getValue().getOuterValue().put(sharedVarType, v); entry.getValue().getOuterValue().put(sharedVarType, v);
} }
@@ -1003,15 +1003,15 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
ClassDescriptor classDescriptor = (ClassDescriptor) propertyDescriptor.getReturnType().getConstructor().getDeclarationDescriptor(); ClassDescriptor classDescriptor = (ClassDescriptor) propertyDescriptor.getReturnType().getConstructor().getDeclarationDescriptor();
if(classDescriptor.getKind() == ClassKind.ENUM_ENTRY) { if(classDescriptor.getKind() == ClassKind.ENUM_ENTRY) {
ClassDescriptor containing = (ClassDescriptor) classDescriptor.getContainingDeclaration().getContainingDeclaration(); 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); 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 // 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); return StackValue.onStack(type);
} }
else { 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); return StackValue.field(type, type.getInternalName(), "$instance", true);
} }
} }
@@ -1074,9 +1074,9 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
} }
final ClassDescriptor descriptor1 = bindingContext.get(BindingContext.CLASS, classObject.getObjectDeclaration()); final ClassDescriptor descriptor1 = bindingContext.get(BindingContext.CLASS, classObject.getObjectDeclaration());
assert descriptor1 != null; assert descriptor1 != null;
final String type = typeMapper.mapType(descriptor1.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(); final Type type = typeMapper.mapType(descriptor1.getDefaultType(), MapTypeMode.VALUE);
return StackValue.field(Type.getObjectType(type), return StackValue.field(type,
typeMapper.mapType(((ClassDescriptor) descriptor).getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), typeMapper.mapType(((ClassDescriptor) descriptor).getDefaultType(), MapTypeMode.IMPL).getInternalName(),
"$classobj", "$classobj",
true); true);
} }
@@ -1375,7 +1375,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
ClassDescriptor classReceiverDeclarationDescriptor = (ClassDescriptor) classReceiver.getDeclarationDescriptor(); ClassDescriptor classReceiverDeclarationDescriptor = (ClassDescriptor) classReceiver.getDeclarationDescriptor();
if(CodegenUtil.isClassObject(classReceiverDeclarationDescriptor)) { if(CodegenUtil.isClassObject(classReceiverDeclarationDescriptor)) {
ClassDescriptor containingDeclaration = (ClassDescriptor) classReceiverDeclarationDescriptor.getContainingDeclaration(); 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()); v.getstatic(classObjType.getInternalName(), "$classobj", exprType.getDescriptor());
} }
else { else {
@@ -2244,7 +2244,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
//noinspection ConstantConditions //noinspection ConstantConditions
JetType expressionType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression); JetType expressionType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression);
assert expressionType != null; assert expressionType != null;
type = typeMapper.mapType(expressionType, OwnerKind.IMPLEMENTATION); type = typeMapper.mapType(expressionType, MapTypeMode.VALUE);
if (type.getSort() == Type.ARRAY) { if (type.getSort() == Type.ARRAY) {
generateNewArray(expression, expressionType); generateNewArray(expression, expressionType);
} else { } else {
@@ -2322,7 +2322,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
*/ */
} }
else { else {
Type type = typeMapper.mapType(arrayType, OwnerKind.IMPLEMENTATION); Type type = typeMapper.mapType(arrayType, MapTypeMode.VALUE);
gen(args.get(0), Type.INT_TYPE); gen(args.get(0), Type.INT_TYPE);
v.newarray(correctElementType(type)); v.newarray(correctElementType(type));
} }
@@ -215,7 +215,7 @@ public class FunctionCodegen {
for (ValueParameterDescriptor parameter : paramDescrs) { for (ValueParameterDescriptor parameter : paramDescrs) {
Type sharedVarType = state.getInjector().getJetTypeMapper().getSharedVarType(parameter); Type sharedVarType = state.getInjector().getJetTypeMapper().getSharedVarType(parameter);
if (sharedVarType != null) { 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); int index = frameMap.getIndex(parameter);
mv.visitTypeInsn(NEW, sharedVarType.getInternalName()); mv.visitTypeInsn(NEW, sharedVarType.getInternalName());
mv.visitInsn(DUP); mv.visitInsn(DUP);
@@ -236,20 +236,20 @@ public class FunctionCodegen {
int k = 0; int k = 0;
if(expectedThisObject.exists()) { if(expectedThisObject.exists()) {
Type type = state.getInjector().getJetTypeMapper().mapType(expectedThisObject.getType()); Type type = state.getInjector().getJetTypeMapper().mapType(expectedThisObject.getType(), MapTypeMode.VALUE);
// TODO: specify signature // TODO: specify signature
mv.visitLocalVariable("this", type.getDescriptor(), null, methodBegin, methodEnd, k++); mv.visitLocalVariable("this", type.getDescriptor(), null, methodBegin, methodEnd, k++);
} }
if(receiverParameter.exists()) { if(receiverParameter.exists()) {
Type type = state.getInjector().getJetTypeMapper().mapType(receiverParameter.getType()); Type type = state.getInjector().getJetTypeMapper().mapType(receiverParameter.getType(), MapTypeMode.VALUE);
// TODO: specify signature // TODO: specify signature
mv.visitLocalVariable("this$receiver", type.getDescriptor(), null, methodBegin, methodEnd, k); mv.visitLocalVariable("this$receiver", type.getDescriptor(), null, methodBegin, methodEnd, k);
k += type.getSize(); k += type.getSize();
} }
for (ValueParameterDescriptor parameter : paramDescrs) { 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 // TODO: specify signature
mv.visitLocalVariable(parameter.getName(), type.getDescriptor(), null, methodBegin, methodEnd, k); mv.visitLocalVariable(parameter.getName(), type.getDescriptor(), null, methodBegin, methodEnd, k);
k += type.getSize(); k += type.getSize();
@@ -328,9 +328,13 @@ public class FunctionCodegen {
int flags = ACC_PUBLIC | ACC_SYNTHETIC; // TODO. int flags = ACC_PUBLIC | ACC_SYNTHETIC; // TODO.
String ownerInternalName = contextClass instanceof NamespaceDescriptor ? String ownerInternalName;
NamespaceCodegen.getJVMClassName(DescriptorUtils.getFQName(contextClass).toSafe(), true) : if (contextClass instanceof NamespaceDescriptor) {
state.getInjector().getJetTypeMapper().mapType(((ClassDescriptor) contextClass).getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(); 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)"); String descriptor = jvmSignature.getDescriptor().replace(")","I)");
boolean isConstructor = "<init>".equals(jvmSignature.getName()); boolean isConstructor = "<init>".equals(jvmSignature.getName());
@@ -353,7 +357,13 @@ public class FunctionCodegen {
var++; 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) { if(hasReceiver) {
var += receiverType.getSize(); var += receiverType.getSize();
} }
@@ -481,7 +491,7 @@ public class FunctionCodegen {
reg += argType.getSize(); 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())) if(JetTypeMapper.isPrimitive(jvmSignature.getReturnType()) && !JetTypeMapper.isPrimitive(overriden.getReturnType()))
StackValue.valueOf(iv, jvmSignature.getReturnType()); StackValue.valueOf(iv, jvmSignature.getReturnType());
if(jvmSignature.getReturnType() == Type.VOID_TYPE) if(jvmSignature.getReturnType() == Type.VOID_TYPE)
@@ -525,7 +535,7 @@ public class FunctionCodegen {
iv.load(0, JetTypeMapper.TYPE_OBJECT); iv.load(0, JetTypeMapper.TYPE_OBJECT);
field.put(field.type, iv); field.put(field.type, iv);
ClassDescriptor classDescriptor = (ClassDescriptor) overriddenDescriptor.getContainingDeclaration(); 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) if(classDescriptor.getKind() == ClassKind.TRAIT)
iv.invokeinterface(internalName, method.getName(), method.getDescriptor()); iv.invokeinterface(internalName, method.getName(), method.getDescriptor());
else else
@@ -35,6 +35,7 @@ import org.jetbrains.jet.lang.psi.JetObjectDeclaration;
import org.jetbrains.jet.lang.psi.JetObjectLiteralExpression; import org.jetbrains.jet.lang.psi.JetObjectLiteralExpression;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.java.AnalyzeExhaust; import org.jetbrains.jet.lang.resolve.java.AnalyzeExhaust;
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
import org.jetbrains.jet.utils.Progress; import org.jetbrains.jet.utils.Progress;
import java.util.List; import java.util.List;
@@ -51,15 +52,18 @@ public class GenerationState {
public GenerationState(Project project, ClassBuilderFactory builderFactory, AnalyzeExhaust analyzeExhaust, List<JetFile> files) { public GenerationState(Project project, ClassBuilderFactory builderFactory, AnalyzeExhaust analyzeExhaust, List<JetFile> 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<JetFile> files) { public GenerationState(Project project, ClassBuilderFactory builderFactory, Progress progress,
@NotNull AnalyzeExhaust exhaust, @NotNull List<JetFile> files, @NotNull CompilerSpecialMode compilerSpecialMode) {
this.project = project; this.project = project;
this.progress = progress; this.progress = progress;
this.analyzeExhaust = exhaust; this.analyzeExhaust = exhaust;
this.files = files; 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 @NotNull
@@ -84,11 +88,11 @@ public class GenerationState {
} }
public ClassBuilder forClassImplementation(ClassDescriptor aClass) { 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) { 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<String, ClassBuilder> forAnonymousSubclass(JetExpression expression) { public Pair<String, ClassBuilder> forAnonymousSubclass(JetExpression expression) {
@@ -124,7 +124,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
ClassDescriptor container = getContainingClassDescriptor(descriptor); ClassDescriptor container = getContainingClassDescriptor(descriptor);
if(container != null) { 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()) { for (DeclarationDescriptor declarationDescriptor : descriptor.getUnsubstitutedInnerClassesScope().getAllDescriptors()) {
@@ -143,14 +143,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
} }
// TODO: cache internal names // TODO: cache internal names
String outerClassInernalName = typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(); String outerClassInernalName = typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName();
String innerClassInternalName = typeMapper.mapType(innerClass.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(); String innerClassInternalName = typeMapper.mapType(innerClass.getDefaultType(), MapTypeMode.IMPL).getInternalName();
v.visitInnerClass(innerClassInternalName, outerClassInernalName, innerClass.getName(), innerClassAccess); v.visitInnerClass(innerClassInternalName, outerClassInernalName, innerClass.getName(), innerClassAccess);
} }
if (descriptor.getClassObjectDescriptor() != null) { if (descriptor.getClassObjectDescriptor() != null) {
int innerClassAccess = ACC_PUBLIC | ACC_FINAL | ACC_STATIC; 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); 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.writeClassBegin(superClass, false, false);
signatureVisitor.writeClassEnd(); signatureVisitor.writeClassEnd();
} else { } else {
typeMapper.mapType(superClassType, OwnerKind.IMPLEMENTATION, signatureVisitor, true); typeMapper.mapType(superClassType, signatureVisitor, MapTypeMode.TYPE_PARAMETER);
} }
signatureVisitor.writeSuperclassEnd(); signatureVisitor.writeSuperclassEnd();
} }
@@ -209,7 +209,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
if (CodegenUtil.isInterface(superClassDescriptor)) { if (CodegenUtil.isInterface(superClassDescriptor)) {
signatureVisitor.writeInterface(); signatureVisitor.writeInterface();
Type jvmName = typeMapper.mapType(superType, OwnerKind.IMPLEMENTATION, signatureVisitor, true); Type jvmName = typeMapper.mapType(superType, signatureVisitor, MapTypeMode.TYPE_PARAMETER);
signatureVisitor.writeInterfaceEnd(); signatureVisitor.writeInterfaceEnd();
superInterfacesLinkedHashSet.add(jvmName.getInternalName()); superInterfacesLinkedHashSet.add(jvmName.getInternalName());
} }
@@ -224,7 +224,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
} }
private String jvmName() { 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() { protected void getSuperClass() {
@@ -236,6 +239,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
if(myClass instanceof JetClass && ((JetClass) myClass).isTrait()) if(myClass instanceof JetClass && ((JetClass) myClass).isTrait())
return; return;
if (kind != OwnerKind.IMPLEMENTATION) {
throw new IllegalStateException("must be impl to reach this code: " + kind);
}
for (JetDelegationSpecifier specifier : delegationSpecifiers) { for (JetDelegationSpecifier specifier : delegationSpecifiers) {
if (specifier instanceof JetDelegatorToSuperClass || specifier instanceof JetDelegatorToSuperCall) { if (specifier instanceof JetDelegatorToSuperClass || specifier instanceof JetDelegatorToSuperCall) {
JetType superType = bindingContext.get(BindingContext.TYPE, specifier.getTypeReference()); JetType superType = bindingContext.get(BindingContext.TYPE, specifier.getTypeReference());
@@ -243,7 +250,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
if(!CodegenUtil.isInterface(superClassDescriptor)) { if(!CodegenUtil.isInterface(superClassDescriptor)) {
superClassType = superType; superClassType = superType;
superClass = typeMapper.mapType(superClassDescriptor.getDefaultType(), kind).getInternalName(); superClass = typeMapper.mapType(superClassDescriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName();
superCall = specifier; superCall = specifier;
} }
} }
@@ -376,7 +383,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
private void generateFieldForObjectInstance() { private void generateFieldForObjectInstance() {
if (CodegenUtil.isNonLiteralObject(myClass)) { 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); v.newField(myClass, ACC_PUBLIC | ACC_STATIC | ACC_FINAL, "$instance", type.getDescriptor(), null, null);
staticInitializerChunks.add(new CodeChunk() { staticInitializerChunks.add(new CodeChunk() {
@@ -386,7 +393,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
v.anew(Type.getObjectType(name)); v.anew(Type.getObjectType(name));
v.dup(); v.dup();
v.invokespecial(name, "<init>", "()V"); v.invokespecial(name, "<init>", "()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(); final JetClassObject classObject = getClassObject();
if (classObject != null) { if (classObject != null) {
final ClassDescriptor descriptor1 = bindingContext.get(BindingContext.CLASS, classObject.getObjectDeclaration()); 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); v.newField(classObject, ACC_PUBLIC | ACC_STATIC, "$classobj", type.getDescriptor(), null, null);
staticInitializerChunks.add(new CodeChunk() { staticInitializerChunks.add(new CodeChunk() {
@Override @Override
public void generate(InstructionAdapter v) { public void generate(InstructionAdapter v) {
final ClassDescriptor descriptor1 = bindingContext.get(BindingContext.CLASS, classObject.getObjectDeclaration()); 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); final Type classObjectType = Type.getObjectType(name);
v.anew(classObjectType); v.anew(classObjectType);
v.dup(); v.dup();
v.invokespecial(name, "<init>", "()V"); v.invokespecial(name, "<init>", "()V");
v.putstatic(typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), "$classobj", v.putstatic(typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), "$classobj",
classObjectType.getDescriptor()); 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); ConstructorDescriptor constructorDescriptor = bindingContext.get(BindingContext.CONSTRUCTOR, myClass);
CodegenContext.ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor, typeMapper); CodegenContext.ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor, typeMapper);
@@ -443,7 +454,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
if (hasThis0) { if (hasThis0) {
signatureWriter.writeParameterType(JvmMethodParameterKind.THIS0); 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(); signatureWriter.writeParameterTypeEnd();
} }
@@ -481,7 +492,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
for (DeclarationDescriptor descriptor : closure.closure.keySet()) { for (DeclarationDescriptor descriptor : closure.closure.keySet()) {
if(descriptor instanceof VariableDescriptor && !(descriptor instanceof PropertyDescriptor)) { if(descriptor instanceof VariableDescriptor && !(descriptor instanceof PropertyDescriptor)) {
final Type sharedVarType = typeMapper.getSharedVarType(descriptor); 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)); consArgTypes.add(insert++, new JvmMethodParameterSignature(type, "", JvmMethodParameterKind.SHARED_VAR));
} }
else if(descriptor instanceof FunctionDescriptor) { 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)); // 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 + ";"); final Type classType = Type.getType("L" + classname + ";");
HashSet<FunctionDescriptor> overridden = new HashSet<FunctionDescriptor>(); HashSet<FunctionDescriptor> overridden = new HashSet<FunctionDescriptor>();
@@ -585,10 +602,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
if (typeMapper.hasThis0(superClassDescriptor)) { if (typeMapper.hasThis0(superClassDescriptor)) {
iv.load(1, JetTypeMapper.TYPE_OBJECT); 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("<init>", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()])); Method superCallMethod = new Method("<init>", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()]));
iv.invokespecial(typeMapper.mapType(superClassDescriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), "<init>", superCallMethod.getDescriptor()); iv.invokespecial(typeMapper.mapType(superClassDescriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), "<init>", superCallMethod.getDescriptor());
} }
else { else {
ConstructorDescriptor constructorDescriptor1 = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression().getConstructorReferenceExpression()); ConstructorDescriptor constructorDescriptor1 = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression().getConstructorReferenceExpression());
@@ -608,7 +625,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
assert superType != null; assert superType != null;
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
String delegateField = "$delegate_" + (n++); String delegateField = "$delegate_" + (n++);
Type fieldType = typeMapper.mapType(superClassDescriptor.getDefaultType()); Type fieldType = typeMapper.mapType(superClassDescriptor.getDefaultType(), MapTypeMode.VALUE);
String fieldDesc = fieldType.getDescriptor(); String fieldDesc = fieldType.getDescriptor();
v.newField(specifier, ACC_PRIVATE, delegateField, fieldDesc, /*TODO*/null, null); v.newField(specifier, ACC_PRIVATE, delegateField, fieldDesc, /*TODO*/null, null);
StackValue field = StackValue.field(fieldType, classname, delegateField, false); 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); JetClass superClass = (JetClass) bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, superClassDescriptor);
final CodegenContext delegateContext = context.intoClass(superClassDescriptor, final CodegenContext delegateContext = context.intoClass(superClassDescriptor,
new OwnerKind.DelegateKind(StackValue.field(fieldType, classname, delegateField, false), 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); generateDelegates(superClass, delegateContext, field);
} }
} }
final ClassDescriptor outerDescriptor = typeMapper.getClosureAnnotator().getEclosingClassDescriptor(descriptor); final ClassDescriptor outerDescriptor = typeMapper.getClosureAnnotator().getEclosingClassDescriptor(descriptor);
if (typeMapper.hasThis0(descriptor) && outerDescriptor != null) { 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(); String interfaceDesc = type.getDescriptor();
final String fieldName = "this$0"; final String fieldName = "this$0";
v.newField(myClass, ACC_FINAL, fieldName, interfaceDesc, null, null); v.newField(myClass, ACC_FINAL, fieldName, interfaceDesc, null, null);
@@ -638,7 +655,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
if(closure.captureReceiver != null) { if(closure.captureReceiver != null) {
iv.load(0, JetTypeMapper.TYPE_OBJECT); iv.load(0, JetTypeMapper.TYPE_OBJECT);
iv.load(1, closure.captureReceiver); 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(); k += closure.captureReceiver.getSize();
} }
@@ -647,12 +664,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
if(varDescr instanceof VariableDescriptor && !(varDescr instanceof PropertyDescriptor)) { if(varDescr instanceof VariableDescriptor && !(varDescr instanceof PropertyDescriptor)) {
Type sharedVarType = typeMapper.getSharedVarType(varDescr); Type sharedVarType = typeMapper.getSharedVarType(varDescr);
if(sharedVarType == null) { 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(0, JetTypeMapper.TYPE_OBJECT);
iv.load(k, StackValue.refType(sharedVarType)); iv.load(k, StackValue.refType(sharedVarType));
k += StackValue.refType(sharedVarType).getSize(); 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++; l++;
} }
} }
@@ -663,7 +680,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
for (JetParameter parameter : constructorParameters) { for (JetParameter parameter : constructorParameters) {
if (parameter.getValOrVarNode() != null) { if (parameter.getValOrVarNode() != null) {
VariableDescriptor descriptor = paramDescrs.get(curParam); 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(0, classType);
iv.load(frameMap.getIndex(descriptor), type); iv.load(frameMap.getIndex(descriptor), type);
iv.putfield(classname, descriptor.getName(), type.getDescriptor()); iv.putfield(classname, descriptor.getName(), type.getDescriptor());
@@ -731,15 +748,16 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
} }
JetType jetType = TraitImplBodyCodegen.getSuperClass(declaration, bindingContext); JetType jetType = TraitImplBodyCodegen.getSuperClass(declaration, bindingContext);
Type type = typeMapper.mapType(jetType); Type type = typeMapper.mapType(jetType, MapTypeMode.IMPL);
if(type.getInternalName().equals("java/lang/Object")) { if (type.getInternalName().equals("java/lang/Object")) {
jetType = declaration.getDefaultType(); jetType = declaration.getDefaultType();
type = typeMapper.mapType(jetType); type = typeMapper.mapType(jetType, MapTypeMode.IMPL);
} }
String fdescriptor = functionOriginal.getDescriptor().replace("(","(" + type.getDescriptor()); String fdescriptor = functionOriginal.getDescriptor().replace("(","(" + type.getDescriptor());
iv.invokestatic(typeMapper.mapType(((ClassDescriptor) fun.getContainingDeclaration()).getDefaultType(), OwnerKind.TRAIT_IMPL).getInternalName(), function.getName(), fdescriptor); Type type1 = typeMapper.mapType(((ClassDescriptor) fun.getContainingDeclaration()).getDefaultType(), MapTypeMode.TRAIT_IMPL);
if(function.getReturnType().getSort() == Type.OBJECT) { iv.invokestatic(type1.getInternalName(), function.getName(), fdescriptor);
if (function.getReturnType().getSort() == Type.OBJECT) {
iv.checkcast(function.getReturnType()); iv.checkcast(function.getReturnType());
} }
iv.areturn(function.getReturnType()); iv.areturn(function.getReturnType());
@@ -760,7 +778,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
iv.load(0, TYPE_OBJECT); iv.load(0, TYPE_OBJECT);
if (classDecl.getContainingDeclaration() instanceof ClassDescriptor) { 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())); 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()) { else if (declaration instanceof JetEnumEntry && !((JetEnumEntry) declaration).hasPrimaryConstructor()) {
String name = declaration.getName(); 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); v.newField(declaration, ACC_PUBLIC | ACC_STATIC | ACC_FINAL, name, desc, null, null);
if (myEnumConstants.isEmpty()) { if (myEnumConstants.isEmpty()) {
staticInitializerChunks.add(new CodeChunk() { 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); ExpressionCodegen codegen = new ExpressionCodegen(v, new FrameMap(), Type.VOID_TYPE, context, state);
for (JetEnumEntry enumConstant : myEnumConstants) { for (JetEnumEntry enumConstant : myEnumConstants) {
// TODO type and constructor parameters // 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<JetDelegationSpecifier> delegationSpecifiers = enumConstant.getDelegationSpecifiers(); final List<JetDelegationSpecifier> delegationSpecifiers = enumConstant.getDelegationSpecifiers();
if (delegationSpecifiers.size() > 1) { if (delegationSpecifiers.size() > 1) {
@@ -896,7 +914,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
if(compileTimeValue != null) { if(compileTimeValue != null) {
assert compileTimeValue != null; assert compileTimeValue != null;
Object value = compileTimeValue.getValue(); Object value = compileTimeValue.getValue();
Type type = typeMapper.mapType(propertyDescriptor.getType()); Type type = typeMapper.mapType(propertyDescriptor.getType(), MapTypeMode.VALUE);
if(JetTypeMapper.isPrimitive(type)) { if(JetTypeMapper.isPrimitive(type)) {
if( !propertyDescriptor.getType().isNullable() && value instanceof Number) { if( !propertyDescriptor.getType().isNullable() && value instanceof Number) {
if(type == Type.INT_TYPE && ((Number)value).intValue() == 0) if(type == Type.INT_TYPE && ((Number)value).intValue() == 0)
@@ -929,7 +947,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
codegen.gen(initializer, type); codegen.gen(initializer, type);
// @todo write directly to the field. Fix test excloset.jet::test6 // @todo write directly to the field. Fix test excloset.jet::test6
String owner = typeMapper.getOwner(propertyDescriptor, OwnerKind.IMPLEMENTATION); 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);
} }
} }
@@ -63,6 +63,7 @@ public class JetTypeMapper {
private JetStandardLibrary standardLibrary; private JetStandardLibrary standardLibrary;
public BindingContext bindingContext; public BindingContext bindingContext;
private ClosureAnnotator closureAnnotator; private ClosureAnnotator closureAnnotator;
private CompilerSpecialMode compilerSpecialMode;
@Inject @Inject
@@ -80,6 +81,11 @@ public class JetTypeMapper {
this.closureAnnotator = closureAnnotator; this.closureAnnotator = closureAnnotator;
} }
@Inject
public void setCompilerSpecialMode(CompilerSpecialMode compilerSpecialMode) {
this.compilerSpecialMode = compilerSpecialMode;
}
@PostConstruct @PostConstruct
public void init() { public void init() {
initKnownTypes(); initKnownTypes();
@@ -129,6 +135,8 @@ public class JetTypeMapper {
} }
public String getOwner(DeclarationDescriptor descriptor, OwnerKind kind) { public String getOwner(DeclarationDescriptor descriptor, OwnerKind kind) {
MapTypeMode mapTypeMode = ownerKindToMapTypeMode(kind);
String owner; String owner;
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
if (containingDeclaration instanceof NamespaceDescriptor) { if (containingDeclaration instanceof NamespaceDescriptor) {
@@ -137,14 +145,14 @@ public class JetTypeMapper {
else if (containingDeclaration instanceof ClassDescriptor) { else if (containingDeclaration instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration; ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
if (kind instanceof OwnerKind.DelegateKind) { if (kind instanceof OwnerKind.DelegateKind) {
kind = OwnerKind.IMPLEMENTATION; mapTypeMode = MapTypeMode.IMPL;
} }
else { else {
if (classDescriptor.getKind() == ClassKind.OBJECT) { 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) { if (asmType.getSort() != Type.OBJECT) {
throw new IllegalStateException(); throw new IllegalStateException();
} }
@@ -156,6 +164,18 @@ public class JetTypeMapper {
return owner; 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) { private String jvmClassNameForNamespace(NamespaceDescriptor namespace) {
FqName fqName = DescriptorUtils.getFQName(namespace).toSafe(); FqName fqName = DescriptorUtils.getFQName(namespace).toSafe();
Boolean javaClassStatics = bindingContext.get(JavaBindingContext.NAMESPACE_IS_CLASS_STATICS, namespace); Boolean javaClassStatics = bindingContext.get(JavaBindingContext.NAMESPACE_IS_CLASS_STATICS, namespace);
@@ -202,7 +222,7 @@ public class JetTypeMapper {
} }
return TYPE_OBJECT; return TYPE_OBJECT;
} }
return mapType(jetType, OwnerKind.IMPLEMENTATION, signatureVisitor); return mapType(jetType, signatureVisitor, MapTypeMode.VALUE);
} }
private String getStableNameForObject(JetObjectDeclaration object, DeclarationDescriptor descriptor) { private String getStableNameForObject(JetObjectDeclaration object, DeclarationDescriptor descriptor) {
@@ -278,26 +298,33 @@ public class JetTypeMapper {
return getContainingNamespace(parent); return getContainingNamespace(parent);
} }
@NotNull public Type mapType(final JetType jetType) { @NotNull
return mapType(jetType, (BothSignatureWriter) null); public Type mapType(@NotNull final JetType jetType, @NotNull MapTypeMode kind) {
return mapType(jetType, null, kind);
} }
@NotNull private Type mapType(JetType jetType, @Nullable BothSignatureWriter signatureVisitor) { @NotNull
return mapType(jetType, OwnerKind.IMPLEMENTATION, signatureVisitor); public Type mapType(JetType jetType, @Nullable BothSignatureWriter signatureVisitor, @NotNull MapTypeMode kind) {
}
@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) {
Type known = knowTypes.get(jetType); Type known = knowTypes.get(jetType);
if (known != null) { 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(); DeclarationDescriptor descriptor = jetType.getConstructor().getDeclarationDescriptor();
@@ -318,7 +345,7 @@ public class JetTypeMapper {
if (signatureVisitor != null) { if (signatureVisitor != null) {
signatureVisitor.writeArrayType(jetType.isNullable()); signatureVisitor.writeArrayType(jetType.isNullable());
mapType(memberType, kind, signatureVisitor, true); mapType(memberType, signatureVisitor, MapTypeMode.TYPE_PARAMETER);
signatureVisitor.writeArrayEnd(); signatureVisitor.writeArrayEnd();
} }
@@ -350,7 +377,7 @@ public class JetTypeMapper {
forceReal = false; forceReal = false;
} else { } else {
JvmClassName name = getClassFQName((ClassDescriptor) descriptor); 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); forceReal = isForceReal(name);
} }
@@ -359,7 +386,7 @@ public class JetTypeMapper {
for (TypeProjection proj : jetType.getArguments()) { for (TypeProjection proj : jetType.getArguments()) {
// TODO: +- // TODO: +-
signatureVisitor.writeTypeArgument(proj.getProjectionKind()); signatureVisitor.writeTypeArgument(proj.getProjectionKind());
mapType(proj.getType(), kind, signatureVisitor, true); mapType(proj.getType(), signatureVisitor, MapTypeMode.TYPE_PARAMETER);
signatureVisitor.writeTypeArgumentEnd(); signatureVisitor.writeTypeArgumentEnd();
} }
signatureVisitor.writeClassEnd(); signatureVisitor.writeClassEnd();
@@ -381,15 +408,19 @@ public class JetTypeMapper {
throw new UnsupportedOperationException("Unknown type " + jetType); throw new UnsupportedOperationException("Unknown type " + jetType);
} }
private Type mapKnownAsmType(JetType jetType, Type asmType, @Nullable BothSignatureWriter signatureVisitor, boolean genericTypeParameter) { private Type mapKnownAsmType(JetType jetType, Type asmType, @Nullable BothSignatureWriter signatureVisitor, boolean boxPrimitive) {
if (signatureVisitor != null) { if (boxPrimitive) {
if (genericTypeParameter) { Type boxed = boxType(asmType);
visitAsmType(signatureVisitor, boxType(asmType), jetType.isNullable()); if (signatureVisitor != null) {
} else { visitAsmType(signatureVisitor, boxed, jetType.isNullable());
}
return boxed;
} else {
if (signatureVisitor != null) {
visitAsmType(signatureVisitor, asmType, jetType.isNullable()); visitAsmType(signatureVisitor, asmType, jetType.isNullable());
} }
return asmType;
} }
return asmType;
} }
public static void visitAsmType(BothSignatureWriter visitor, Type asmType, boolean nullable) { public static void visitAsmType(BothSignatureWriter visitor, Type asmType, boolean nullable) {
@@ -435,7 +466,7 @@ public class JetTypeMapper {
else if (functionDescriptor instanceof ConstructorDescriptor) { else if (functionDescriptor instanceof ConstructorDescriptor) {
assert !superCall; assert !superCall;
ClassDescriptor containingClass = (ClassDescriptor) functionParent; ClassDescriptor containingClass = (ClassDescriptor) functionParent;
owner = mapType(containingClass.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(); owner = mapType(containingClass.getDefaultType(), MapTypeMode.IMPL).getInternalName();
ownerForDefaultImpl = ownerForDefaultParam = owner; ownerForDefaultImpl = ownerForDefaultParam = owner;
invokeOpcode = INVOKESPECIAL; invokeOpcode = INVOKESPECIAL;
thisClass = null; thisClass = null;
@@ -457,12 +488,12 @@ public class JetTypeMapper {
receiver = currentOwner; receiver = currentOwner;
} }
ClassDescriptor containingClass = (ClassDescriptor) functionParent; // TODO: TYPE_PARAMETER is hack here
boolean isInterface = originalIsInterface && currentIsInterface; boolean isInterface = originalIsInterface && currentIsInterface;
OwnerKind kind1 = isInterface && superCall ? OwnerKind.TRAIT_IMPL : OwnerKind.IMPLEMENTATION; Type type = mapType(receiver.getDefaultType(), MapTypeMode.TYPE_PARAMETER);
Type type = mapType(receiver.getDefaultType(), OwnerKind.IMPLEMENTATION);
owner = type.getInternalName(); owner = type.getInternalName();
ownerForDefaultParam = mapType(((ClassDescriptor) declarationOwner).getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(); ownerForDefaultParam = mapType(declarationOwner.getDefaultType(), MapTypeMode.TYPE_PARAMETER).getInternalName();
ownerForDefaultImpl = ownerForDefaultParam ownerForDefaultImpl = ownerForDefaultParam
+ (originalIsInterface ? JvmAbi.TRAIT_IMPL_SUFFIX : ""); + (originalIsInterface ? JvmAbi.TRAIT_IMPL_SUFFIX : "");
@@ -518,10 +549,10 @@ public class JetTypeMapper {
if(kind == OwnerKind.TRAIT_IMPL) { if(kind == OwnerKind.TRAIT_IMPL) {
ClassDescriptor containingDeclaration = (ClassDescriptor) f.getContainingDeclaration(); ClassDescriptor containingDeclaration = (ClassDescriptor) f.getContainingDeclaration();
JetType jetType = TraitImplBodyCodegen.getSuperClass(containingDeclaration, bindingContext); JetType jetType = TraitImplBodyCodegen.getSuperClass(containingDeclaration, bindingContext);
Type type = mapType(jetType); Type type = mapType(jetType, MapTypeMode.VALUE);
if(type.getInternalName().equals("java/lang/Object")) { if(type.getInternalName().equals("java/lang/Object")) {
jetType = containingDeclaration.getDefaultType(); jetType = containingDeclaration.getDefaultType();
type = mapType(jetType); type = mapType(jetType, MapTypeMode.VALUE);
} }
signatureVisitor.writeParameterType(JvmMethodParameterKind.THIS); signatureVisitor.writeParameterType(JvmMethodParameterKind.THIS);
@@ -531,13 +562,13 @@ public class JetTypeMapper {
if (receiverType != null) { if (receiverType != null) {
signatureVisitor.writeParameterType(JvmMethodParameterKind.RECEIVER); signatureVisitor.writeParameterType(JvmMethodParameterKind.RECEIVER);
mapType(receiverType, signatureVisitor); mapType(receiverType, signatureVisitor, MapTypeMode.VALUE);
signatureVisitor.writeParameterTypeEnd(); signatureVisitor.writeParameterTypeEnd();
} }
for (ValueParameterDescriptor parameter : parameters) { for (ValueParameterDescriptor parameter : parameters) {
signatureVisitor.writeParameterType(JvmMethodParameterKind.VALUE); signatureVisitor.writeParameterType(JvmMethodParameterKind.VALUE);
mapType(parameter.getType(), signatureVisitor); mapType(parameter.getType(), signatureVisitor, MapTypeMode.VALUE);
signatureVisitor.writeParameterTypeEnd(); signatureVisitor.writeParameterTypeEnd();
} }
@@ -576,7 +607,7 @@ public class JetTypeMapper {
for (JetType jetType : typeParameterDescriptor.getUpperBounds()) { for (JetType jetType : typeParameterDescriptor.getUpperBounds()) {
if (jetType.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor) { if (jetType.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor) {
if (!CodegenUtil.isInterface(jetType)) { if (!CodegenUtil.isInterface(jetType)) {
mapType(jetType, signatureVisitor); mapType(jetType, signatureVisitor, MapTypeMode.TYPE_PARAMETER);
break classBound; break classBound;
} }
} }
@@ -593,13 +624,13 @@ public class JetTypeMapper {
if (jetType.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor) { if (jetType.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor) {
if (CodegenUtil.isInterface(jetType)) { if (CodegenUtil.isInterface(jetType)) {
signatureVisitor.writeInterfaceBound(); signatureVisitor.writeInterfaceBound();
mapType(jetType, signatureVisitor); mapType(jetType, signatureVisitor, MapTypeMode.TYPE_PARAMETER);
signatureVisitor.writeInterfaceBoundEnd(); signatureVisitor.writeInterfaceBoundEnd();
} }
} }
if (jetType.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor) { if (jetType.getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor) {
signatureVisitor.writeInterfaceBound(); signatureVisitor.writeInterfaceBound();
mapType(jetType, signatureVisitor); mapType(jetType, signatureVisitor, MapTypeMode.TYPE_PARAMETER);
signatureVisitor.writeInterfaceBoundEnd(); signatureVisitor.writeInterfaceBoundEnd();
} }
} }
@@ -620,12 +651,12 @@ public class JetTypeMapper {
final List<ValueParameterDescriptor> parameters = f.getValueParameters(); final List<ValueParameterDescriptor> parameters = f.getValueParameters();
if (receiver.exists()) { if (receiver.exists()) {
signatureWriter.writeParameterType(JvmMethodParameterKind.RECEIVER); signatureWriter.writeParameterType(JvmMethodParameterKind.RECEIVER);
mapType(receiver.getType(), signatureWriter); mapType(receiver.getType(), signatureWriter, MapTypeMode.VALUE);
signatureWriter.writeParameterTypeEnd(); signatureWriter.writeParameterTypeEnd();
} }
for (ValueParameterDescriptor parameter : parameters) { for (ValueParameterDescriptor parameter : parameters) {
signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE); signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE);
mapType(parameter.getType(), signatureWriter); mapType(parameter.getType(), signatureWriter, MapTypeMode.VALUE);
signatureWriter.writeParameterTypeEnd(); signatureWriter.writeParameterTypeEnd();
} }
@@ -653,20 +684,20 @@ public class JetTypeMapper {
ClassDescriptor containingDeclaration = (ClassDescriptor) descriptor.getContainingDeclaration(); ClassDescriptor containingDeclaration = (ClassDescriptor) descriptor.getContainingDeclaration();
assert containingDeclaration != null; assert containingDeclaration != null;
signatureWriter.writeParameterType(JvmMethodParameterKind.THIS); signatureWriter.writeParameterType(JvmMethodParameterKind.THIS);
mapType(containingDeclaration.getDefaultType(), signatureWriter); mapType(containingDeclaration.getDefaultType(), signatureWriter, MapTypeMode.IMPL);
signatureWriter.writeParameterTypeEnd(); signatureWriter.writeParameterTypeEnd();
} }
if(descriptor.getReceiverParameter().exists()) { if(descriptor.getReceiverParameter().exists()) {
signatureWriter.writeParameterType(JvmMethodParameterKind.RECEIVER); signatureWriter.writeParameterType(JvmMethodParameterKind.RECEIVER);
mapType(descriptor.getReceiverParameter().getType(), signatureWriter); mapType(descriptor.getReceiverParameter().getType(), signatureWriter, MapTypeMode.VALUE);
signatureWriter.writeParameterTypeEnd(); signatureWriter.writeParameterTypeEnd();
} }
signatureWriter.writeParametersEnd(); signatureWriter.writeParametersEnd();
signatureWriter.writeReturnType(); signatureWriter.writeReturnType();
mapType(descriptor.getType(), signatureWriter); mapType(descriptor.getType(), signatureWriter, MapTypeMode.VALUE);
signatureWriter.writeReturnTypeEnd(); signatureWriter.writeReturnTypeEnd();
JvmMethodSignature jvmMethodSignature = signatureWriter.makeJvmMethodSignature(name); JvmMethodSignature jvmMethodSignature = signatureWriter.makeJvmMethodSignature(name);
@@ -694,18 +725,18 @@ public class JetTypeMapper {
ClassDescriptor containingDeclaration = (ClassDescriptor) descriptor.getContainingDeclaration(); ClassDescriptor containingDeclaration = (ClassDescriptor) descriptor.getContainingDeclaration();
assert containingDeclaration != null; assert containingDeclaration != null;
signatureWriter.writeParameterType(JvmMethodParameterKind.THIS); signatureWriter.writeParameterType(JvmMethodParameterKind.THIS);
mapType(containingDeclaration.getDefaultType(), signatureWriter); mapType(containingDeclaration.getDefaultType(), signatureWriter, MapTypeMode.VALUE);
signatureWriter.writeParameterTypeEnd(); signatureWriter.writeParameterTypeEnd();
} }
if(descriptor.getReceiverParameter().exists()) { if(descriptor.getReceiverParameter().exists()) {
signatureWriter.writeParameterType(JvmMethodParameterKind.RECEIVER); signatureWriter.writeParameterType(JvmMethodParameterKind.RECEIVER);
mapType(descriptor.getReceiverParameter().getType(), signatureWriter); mapType(descriptor.getReceiverParameter().getType(), signatureWriter, MapTypeMode.VALUE);
signatureWriter.writeParameterTypeEnd(); signatureWriter.writeParameterTypeEnd();
} }
signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE); signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE);
mapType(outType, signatureWriter); mapType(outType, signatureWriter, MapTypeMode.VALUE);
signatureWriter.writeParameterTypeEnd(); signatureWriter.writeParameterTypeEnd();
signatureWriter.writeParametersEnd(); signatureWriter.writeParametersEnd();
@@ -729,13 +760,13 @@ public class JetTypeMapper {
if (hasThis0) { if (hasThis0) {
signatureWriter.writeParameterType(JvmMethodParameterKind.THIS0); signatureWriter.writeParameterType(JvmMethodParameterKind.THIS0);
mapType(closureAnnotator.getEclosingClassDescriptor(descriptor.getContainingDeclaration()).getDefaultType(), OwnerKind.IMPLEMENTATION, signatureWriter); mapType(closureAnnotator.getEclosingClassDescriptor(descriptor.getContainingDeclaration()).getDefaultType(), signatureWriter, MapTypeMode.VALUE);
signatureWriter.writeParameterTypeEnd(); signatureWriter.writeParameterTypeEnd();
} }
for (ValueParameterDescriptor parameter : parameters) { for (ValueParameterDescriptor parameter : parameters) {
signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE); signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE);
mapType(parameter.getType(), signatureWriter); mapType(parameter.getType(), signatureWriter, MapTypeMode.VALUE);
signatureWriter.writeParameterTypeEnd(); signatureWriter.writeParameterTypeEnd();
} }
@@ -748,7 +779,8 @@ public class JetTypeMapper {
public CallableMethod mapToCallableMethod(ConstructorDescriptor descriptor, OwnerKind kind, boolean hasThis0) { public CallableMethod mapToCallableMethod(ConstructorDescriptor descriptor, OwnerKind kind, boolean hasThis0) {
final JvmMethodSignature method = mapConstructorSignature(descriptor, 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); return new CallableMethod(owner, owner, owner, method, INVOKESPECIAL);
} }
@@ -778,7 +810,7 @@ public class JetTypeMapper {
Set<String> result = new HashSet<String>(); Set<String> result = new HashSet<String>();
final ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, jetClass); final ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, jetClass);
if (classDescriptor != null) { if (classDescriptor != null) {
result.add(mapType(classDescriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName()); result.add(mapType(classDescriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName());
} }
return result; return result;
} }
@@ -851,20 +883,20 @@ public class JetTypeMapper {
public Type getSharedVarType(DeclarationDescriptor descriptor) { public Type getSharedVarType(DeclarationDescriptor descriptor) {
if(descriptor instanceof PropertyDescriptor) { 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) { else if (descriptor instanceof SimpleFunctionDescriptor && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) {
PsiElement psiElement = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor); PsiElement psiElement = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor);
return Type.getObjectType(closureAnnotator.classNameForAnonymousClass((JetElement) psiElement)); return Type.getObjectType(closureAnnotator.classNameForAnonymousClass((JetElement) psiElement));
} }
else if (descriptor instanceof FunctionDescriptor) { 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) { else if (descriptor instanceof VariableDescriptor) {
Boolean aBoolean = bindingContext.get(BindingContext.MUST_BE_WRAPPED_IN_A_REF, (VariableDescriptor) descriptor); Boolean aBoolean = bindingContext.get(BindingContext.MUST_BE_WRAPPED_IN_A_REF, (VariableDescriptor) descriptor);
if (aBoolean != null && aBoolean) { if (aBoolean != null && aBoolean) {
JetType outType = ((VariableDescriptor) descriptor).getType(); JetType outType = ((VariableDescriptor) descriptor).getType();
return StackValue.sharedTypeForType(mapType(outType)); return StackValue.sharedTypeForType(mapType(outType, MapTypeMode.VALUE));
} }
else { else {
return null; return null;
@@ -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,
}
@@ -61,7 +61,7 @@ public class ObjectOrClosureCodegen {
if (idx < 0) return null; if (idx < 0) return null;
final Type sharedVarType = state.getInjector().getJetTypeMapper().getSharedVarType(vd); 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; final Type type = sharedVarType != null ? sharedVarType : localType;
StackValue outerValue = StackValue.local(idx, type); StackValue outerValue = StackValue.local(idx, type);
@@ -110,7 +110,7 @@ public class ObjectOrClosureCodegen {
if(fcontext.getReceiverDescriptor() != fd) if(fcontext.getReceiverDescriptor() != fd)
return null; 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; boolean isStatic = fcontext.getContextDescriptor().getContainingDeclaration() instanceof NamespaceDescriptor;
StackValue outerValue = StackValue.local(isStatic ? 0 : 1, type); StackValue outerValue = StackValue.local(isStatic ? 0 : 1, type);
final String fieldName = "receiver$0"; final String fieldName = "receiver$0";
@@ -97,7 +97,8 @@ public class PropertyCodegen {
if(state.getInjector().getJetStandardLibrary().isVolatile(propertyDescriptor)) { if(state.getInjector().getJetStandardLibrary().isVolatile(propertyDescriptor)) {
modifiers |= Opcodes.ACC_VOLATILE; 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); AnnotationCodegen.forField(fieldVisitor, state.getInjector().getJetTypeMapper()).genAnnotations(propertyDescriptor);
} }
} }
@@ -189,7 +190,7 @@ public class PropertyCodegen {
if (kind != OwnerKind.NAMESPACE) { if (kind != OwnerKind.NAMESPACE) {
iv.load(0, JetTypeMapper.TYPE_OBJECT); 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)) { if ((kind instanceof OwnerKind.DelegateKind) != (propertyDescriptor.getKind() == FunctionDescriptor.Kind.DELEGATION)) {
throw new IllegalStateException("mismatching kind in " + propertyDescriptor); throw new IllegalStateException("mismatching kind in " + propertyDescriptor);
@@ -269,7 +270,7 @@ public class PropertyCodegen {
StubCodegen.generateStubThrow(mv); StubCodegen.generateStubThrow(mv);
} else { } else {
InstructionAdapter iv = new InstructionAdapter(mv); 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; int paramCode = 0;
if (kind != OwnerKind.NAMESPACE) { if (kind != OwnerKind.NAMESPACE) {
iv.load(0, JetTypeMapper.TYPE_OBJECT); iv.load(0, JetTypeMapper.TYPE_OBJECT);
@@ -597,7 +597,7 @@ public abstract class StackValue {
List<ValueParameterDescriptor> valueParameters = resolvedGetCall.getResultingDescriptor().getValueParameters(); List<ValueParameterDescriptor> valueParameters = resolvedGetCall.getResultingDescriptor().getValueParameters();
int firstParamIndex = -1; int firstParamIndex = -1;
for(int i = valueParameters.size()-1; i >= 0; --i) { 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(); int sz = type.getSize();
frame.enterTemp(sz); frame.enterTemp(sz);
lastIndex += sz; lastIndex += sz;
@@ -619,7 +619,7 @@ public abstract class StackValue {
ReceiverDescriptor receiverParameter = resolvedGetCall.getReceiverArgument(); ReceiverDescriptor receiverParameter = resolvedGetCall.getReceiverArgument();
int receiverIndex = -1; int receiverIndex = -1;
if(receiverParameter.exists()) { if(receiverParameter.exists()) {
Type type = codegen.typeMapper.mapType(receiverParameter.getType()); Type type = codegen.typeMapper.mapType(receiverParameter.getType(), MapTypeMode.VALUE);
int sz = type.getSize(); int sz = type.getSize();
frame.enterTemp(sz); frame.enterTemp(sz);
lastIndex += sz; lastIndex += sz;
@@ -643,7 +643,7 @@ public abstract class StackValue {
if(thisIndex != -1) { if(thisIndex != -1) {
if(receiverIndex != -1) { if(receiverIndex != -1) {
realReceiverIndex = receiverIndex; realReceiverIndex = receiverIndex;
realReceiverType = codegen.typeMapper.mapType(receiverParameter.getType()); realReceiverType = codegen.typeMapper.mapType(receiverParameter.getType(), MapTypeMode.VALUE);
} }
else { else {
realReceiverIndex = thisIndex; realReceiverIndex = thisIndex;
@@ -652,7 +652,7 @@ public abstract class StackValue {
} }
else { else {
if(receiverIndex != -1) { if(receiverIndex != -1) {
realReceiverType = codegen.typeMapper.mapType(receiverParameter.getType()); realReceiverType = codegen.typeMapper.mapType(receiverParameter.getType(), MapTypeMode.VALUE);
realReceiverIndex = receiverIndex; realReceiverIndex = receiverIndex;
} }
else { else {
@@ -677,7 +677,7 @@ public abstract class StackValue {
int index = firstParamIndex; int index = firstParamIndex;
for(int i = 0; i != valueParameters.size(); ++i) { 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(); int sz = type.getSize();
v.load(index-sz, type); v.load(index-sz, type);
index -= sz; index -= sz;
@@ -689,7 +689,7 @@ public abstract class StackValue {
} }
if(receiverIndex != -1) { 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); v.load(receiverIndex-type.getSize(), type);
} }
@@ -705,7 +705,7 @@ public abstract class StackValue {
index = firstParamIndex; index = firstParamIndex;
for(int i = 0; i != valueParameters.size(); ++i) { 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(); int sz = type.getSize();
v.load(index-sz, type); v.load(index-sz, type);
index -= sz; index -= sz;
@@ -729,7 +729,7 @@ public abstract class StackValue {
return false; return false;
for (ValueParameterDescriptor valueParameter : valueParameters) { for (ValueParameterDescriptor valueParameter : valueParameters) {
if (codegen.typeMapper.mapType(valueParameter.getType()).getSize() != 1) if (codegen.typeMapper.mapType(valueParameter.getType(), MapTypeMode.VALUE).getSize() != 1)
return false; return false;
} }
@@ -738,7 +738,7 @@ public abstract class StackValue {
return false; return false;
} }
else { 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; return false;
} }
@@ -1084,27 +1084,27 @@ public abstract class StackValue {
if (thisObject.exists()) { if (thisObject.exists()) {
if(callableMethod != null) { if(callableMethod != null) {
if(receiverArgument.exists()) { if(receiverArgument.exists()) {
return codegen.typeMapper.mapType(callableMethod.getReceiverClass()); return codegen.typeMapper.mapType(callableMethod.getReceiverClass(), MapTypeMode.VALUE);
} }
else { else {
return codegen.typeMapper.mapType(callableMethod.getThisType()); return codegen.typeMapper.mapType(callableMethod.getThisType(), MapTypeMode.VALUE);
} }
} }
else { else {
if(receiverArgument.exists()) { if(receiverArgument.exists()) {
return codegen.typeMapper.mapType(descriptor.getReceiverParameter().getType()); return codegen.typeMapper.mapType(descriptor.getReceiverParameter().getType(), MapTypeMode.VALUE);
} }
else { else {
return codegen.typeMapper.mapType(descriptor.getExpectedThisObject().getType()); return codegen.typeMapper.mapType(descriptor.getExpectedThisObject().getType(), MapTypeMode.VALUE);
} }
} }
} }
else { else {
if (receiverArgument.exists()) { if (receiverArgument.exists()) {
if(callableMethod != null) if(callableMethod != null)
return codegen.typeMapper.mapType(callableMethod.getReceiverClass()); return codegen.typeMapper.mapType(callableMethod.getReceiverClass(), MapTypeMode.VALUE);
else else
return codegen.typeMapper.mapType(descriptor.getReceiverParameter().getType()); return codegen.typeMapper.mapType(descriptor.getReceiverParameter().getType(), MapTypeMode.VALUE);
} }
else { else {
return Type.VOID_TYPE; return Type.VOID_TYPE;
@@ -1120,7 +1120,12 @@ public abstract class StackValue {
ReceiverDescriptor receiverArgument = resolvedCall.getReceiverArgument(); ReceiverDescriptor receiverArgument = resolvedCall.getReceiverArgument();
if (thisObject.exists()) { if (thisObject.exists()) {
if(receiverArgument.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()); genReceiver(v, receiverArgument, type, descriptor.getReceiverParameter());
} }
else { else {
@@ -1137,7 +1142,7 @@ public abstract class StackValue {
private void genReceiver(InstructionAdapter v, ReceiverDescriptor receiverArgument, Type type, ReceiverDescriptor receiverParameter) { private void genReceiver(InstructionAdapter v, ReceiverDescriptor receiverArgument, Type type, ReceiverDescriptor receiverParameter) {
if(receiver == StackValue.none()) { if(receiver == StackValue.none()) {
if(receiverParameter != null) { if(receiverParameter != null) {
Type receiverType = codegen.typeMapper.mapType(receiverParameter.getType()); Type receiverType = codegen.typeMapper.mapType(receiverParameter.getType(), MapTypeMode.VALUE);
codegen.generateFromResolvedCall(receiverArgument, receiverType); codegen.generateFromResolvedCall(receiverArgument, receiverType);
StackValue.onStack(receiverType).put(type, v); StackValue.onStack(receiverType).put(type, v);
} }
@@ -74,6 +74,6 @@ public class TraitImplBodyCodegen extends ClassBodyCodegen {
} }
private String jvmName() { 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();
} }
} }
@@ -19,10 +19,7 @@ package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.*;
import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.psi.JetCallExpression; import org.jetbrains.jet.lang.psi.JetCallExpression;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
@@ -43,7 +40,8 @@ public class JavaClassFunction implements IntrinsicMethod {
JetCallExpression call = (JetCallExpression) element; JetCallExpression call = (JetCallExpression) element;
ResolvedCall<? extends CallableDescriptor> resolvedCall = codegen.getBindingContext().get(BindingContext.RESOLVED_CALL, call.getCalleeExpression()); ResolvedCall<? extends CallableDescriptor> resolvedCall = codegen.getBindingContext().get(BindingContext.RESOLVED_CALL, call.getCalleeExpression());
CallableDescriptor resultingDescriptor = resolvedCall.getResultingDescriptor(); 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); v.aconst(type);
return StackValue.onStack(JetTypeMapper.JL_CLASS_TYPE); return StackValue.onStack(JetTypeMapper.JL_CLASS_TYPE);
} }
@@ -22,6 +22,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
import java.util.List; import java.util.List;
import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
import org.jetbrains.jet.codegen.ClosureAnnotator; import org.jetbrains.jet.codegen.ClosureAnnotator;
import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; import org.jetbrains.jet.lang.types.lang.JetStandardLibrary;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
@@ -40,10 +41,12 @@ public class InjectorForJetTypeMapper {
@NotNull List<JetFile> listOfJetFile @NotNull List<JetFile> listOfJetFile
) { ) {
this.jetTypeMapper = new JetTypeMapper(); this.jetTypeMapper = new JetTypeMapper();
CompilerSpecialMode compilerSpecialMode = CompilerSpecialMode.REGULAR;
ClosureAnnotator closureAnnotator = new ClosureAnnotator(); ClosureAnnotator closureAnnotator = new ClosureAnnotator();
this.jetTypeMapper.setBindingContext(bindingContext); this.jetTypeMapper.setBindingContext(bindingContext);
this.jetTypeMapper.setClosureAnnotator(closureAnnotator); this.jetTypeMapper.setClosureAnnotator(closureAnnotator);
this.jetTypeMapper.setCompilerSpecialMode(compilerSpecialMode);
this.jetTypeMapper.setStandardLibrary(jetStandardLibrary); this.jetTypeMapper.setStandardLibrary(jetStandardLibrary);
closureAnnotator.setBindingContext(bindingContext); closureAnnotator.setBindingContext(bindingContext);
@@ -22,6 +22,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
import java.util.List; import java.util.List;
import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetFile;
import com.intellij.openapi.project.Project; 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.GenerationState;
import org.jetbrains.jet.codegen.ClassBuilderFactory; import org.jetbrains.jet.codegen.ClassBuilderFactory;
import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.JetTypeMapper;
@@ -33,6 +34,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
import java.util.List; import java.util.List;
import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetFile;
import com.intellij.openapi.project.Project; 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.GenerationState;
import org.jetbrains.jet.codegen.ClassBuilderFactory; import org.jetbrains.jet.codegen.ClassBuilderFactory;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -51,6 +53,7 @@ public class InjectorForJvmCodegen {
@NotNull BindingContext bindingContext, @NotNull BindingContext bindingContext,
@NotNull List<JetFile> listOfJetFile, @NotNull List<JetFile> listOfJetFile,
@NotNull Project project, @NotNull Project project,
@NotNull CompilerSpecialMode compilerSpecialMode,
@NotNull GenerationState generationState, @NotNull GenerationState generationState,
@NotNull ClassBuilderFactory classBuilderFactory @NotNull ClassBuilderFactory classBuilderFactory
) { ) {
@@ -63,6 +66,7 @@ public class InjectorForJvmCodegen {
this.jetTypeMapper.setBindingContext(bindingContext); this.jetTypeMapper.setBindingContext(bindingContext);
this.jetTypeMapper.setClosureAnnotator(closureAnnotator); this.jetTypeMapper.setClosureAnnotator(closureAnnotator);
this.jetTypeMapper.setCompilerSpecialMode(compilerSpecialMode);
this.jetTypeMapper.setStandardLibrary(jetStandardLibrary); this.jetTypeMapper.setStandardLibrary(jetStandardLibrary);
this.intrinsics.setMyProject(project); this.intrinsics.setMyProject(project);
@@ -221,7 +221,7 @@ public class CompileSession {
public GenerationState generate(boolean module) { public GenerationState generate(boolean module) {
Project project = environment.getProject(); Project project = environment.getProject();
GenerationState generationState = new GenerationState(project, ClassBuilderFactories.binaries(stubs), 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); generationState.compileCorrectFiles(CompilationErrorHandler.THROW_EXCEPTION);
List<CompilerPlugin> plugins = environment.getCompilerPlugins(); List<CompilerPlugin> plugins = environment.getCompilerPlugins();
@@ -112,9 +112,9 @@ public class TestlibTest extends CodegenTestCase {
DescriptorUtils.addSuperTypes(descriptor.getDefaultType(), allSuperTypes); DescriptorUtils.addSuperTypes(descriptor.getDefaultType(), allSuperTypes);
for(JetType type : 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")) { 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); System.out.println(name);
Class<TestCase> aClass = (Class<TestCase>) loader.loadClass(name.replace('/', '.')); Class<TestCase> aClass = (Class<TestCase>) loader.loadClass(name.replace('/', '.'));
if((aClass.getModifiers() & Modifier.ABSTRACT) == 0 if((aClass.getModifiers() & Modifier.ABSTRACT) == 0
@@ -146,6 +146,7 @@ public class AllInjectorsGenerator {
generator.addParameter(BindingContext.class); generator.addParameter(BindingContext.class);
generator.addParameter(DiType.listOf(JetFile.class)); generator.addParameter(DiType.listOf(JetFile.class));
generator.addParameter(Project.class); generator.addParameter(Project.class);
generator.addParameter(CompilerSpecialMode.class);
generator.addPublicParameter(GenerationState.class); generator.addPublicParameter(GenerationState.class);
generator.addParameter(ClassBuilderFactory.class); generator.addParameter(ClassBuilderFactory.class);
generator.addPublicField(JetTypeMapper.class); generator.addPublicField(JetTypeMapper.class);
@@ -160,6 +161,7 @@ public class AllInjectorsGenerator {
generator.addParameter(BindingContext.class); generator.addParameter(BindingContext.class);
generator.addParameter(DiType.listOf(JetFile.class)); generator.addParameter(DiType.listOf(JetFile.class));
generator.addPublicField(JetTypeMapper.class); generator.addPublicField(JetTypeMapper.class);
generator.addField(CompilerSpecialMode.REGULAR);
generator.generate("compiler/backend/src", "org.jetbrains.jet.di", "InjectorForJetTypeMapper"); generator.generate("compiler/backend/src", "org.jetbrains.jet.di", "InjectorForJetTypeMapper");
} }