backend refactoring from extension properties and proper naming scheme of inner classes and objects

This commit is contained in:
Alex Tkachman
2011-11-13 21:08:35 +02:00
parent 1927eeef2c
commit 3904b91e4c
25 changed files with 453 additions and 370 deletions
@@ -1,6 +1,7 @@
package org.jetbrains.jet.codegen; package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
@@ -22,7 +23,7 @@ public class CallableMethod implements Callable {
private final List<Type> valueParameterTypes; private final List<Type> valueParameterTypes;
private ClassDescriptor thisClass = null; private ClassDescriptor thisClass = null;
private FunctionDescriptor receiverFunction = null; private CallableDescriptor receiverFunction = null;
private Type generateCalleeType = null; private Type generateCalleeType = null;
public CallableMethod(String owner, Method signature, int invokeOpcode, List<Type> valueParameterTypes) { public CallableMethod(String owner, Method signature, int invokeOpcode, List<Type> valueParameterTypes) {
@@ -48,7 +49,7 @@ public class CallableMethod implements Callable {
return valueParameterTypes; return valueParameterTypes;
} }
public void setNeedsReceiver(@Nullable FunctionDescriptor receiverClass) { public void setNeedsReceiver(@Nullable CallableDescriptor receiverClass) {
this.receiverFunction = receiverClass; this.receiverFunction = receiverClass;
} }
@@ -88,7 +89,7 @@ public class CallableMethod implements Callable {
return thisClass; return thisClass;
} }
public FunctionDescriptor getReceiverFunction() { public CallableDescriptor getReceiverFunction() {
return receiverFunction; return receiverFunction;
} }
} }
@@ -23,7 +23,7 @@ public class ClassCodegen {
ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass); ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass);
final CodegenContext contextForInners = context.intoClass(descriptor, OwnerKind.IMPLEMENTATION); final CodegenContext contextForInners = context.intoClass(descriptor, OwnerKind.IMPLEMENTATION, state.getTypeMapper());
for (JetDeclaration declaration : aClass.getDeclarations()) { for (JetDeclaration declaration : aClass.getDeclarations()) {
if (declaration instanceof JetClass && !(declaration instanceof JetEnumEntry)) { if (declaration instanceof JetClass && !(declaration instanceof JetEnumEntry)) {
generate(contextForInners, (JetClass) declaration); generate(contextForInners, (JetClass) declaration);
@@ -36,12 +36,12 @@ public class ClassCodegen {
private void generateImplementation(CodegenContext context, JetClassOrObject aClass, OwnerKind kind, HashMap<DeclarationDescriptor, DeclarationDescriptor> accessors) { private void generateImplementation(CodegenContext context, JetClassOrObject aClass, OwnerKind kind, HashMap<DeclarationDescriptor, DeclarationDescriptor> accessors) {
ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass); ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass);
ClassBuilder v = state.forClassImplementation(descriptor); ClassBuilder v = state.forClassImplementation(descriptor);
CodegenContext classContext = context.intoClass(descriptor, kind); CodegenContext classContext = context.intoClass(descriptor, kind, state.getTypeMapper());
new ImplementationBodyCodegen(aClass, classContext, v, state).generate(accessors); new ImplementationBodyCodegen(aClass, classContext, v, state).generate(accessors);
if(aClass instanceof JetClass && ((JetClass)aClass).isTrait()) { if(aClass instanceof JetClass && ((JetClass)aClass).isTrait()) {
v = state.forTraitImplementation(descriptor); v = state.forTraitImplementation(descriptor);
new TraitImplBodyCodegen(aClass, context.intoClass(descriptor, OwnerKind.TRAIT_IMPL), v, state).generate(null); new TraitImplBodyCodegen(aClass, context.intoClass(descriptor, OwnerKind.TRAIT_IMPL, state.getTypeMapper()), v, state).generate(null);
} }
} }
} }
@@ -29,8 +29,11 @@ import static org.objectweb.asm.Opcodes.*;
public class ClosureCodegen extends ObjectOrClosureCodegen { public class ClosureCodegen extends ObjectOrClosureCodegen {
private final BindingContext bindingContext;
public ClosureCodegen(GenerationState state, ExpressionCodegen exprContext, CodegenContext context) { public ClosureCodegen(GenerationState state, ExpressionCodegen exprContext, CodegenContext context) {
super(exprContext, context, state); super(exprContext, context, state);
bindingContext = state.getBindingContext();
} }
public static Method erasedInvokeSignature(FunctionDescriptor fd) { public static Method erasedInvokeSignature(FunctionDescriptor fd) {
@@ -63,7 +66,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
public GeneratedAnonymousClassDescriptor gen(JetFunctionLiteralExpression fun) { public GeneratedAnonymousClassDescriptor gen(JetFunctionLiteralExpression fun) {
final Pair<String, ClassBuilder> nameAndVisitor = state.forAnonymousSubclass(fun); final Pair<String, ClassBuilder> nameAndVisitor = state.forAnonymousSubclass(fun);
final FunctionDescriptor funDescriptor = (FunctionDescriptor) state.getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, fun); final FunctionDescriptor funDescriptor = (FunctionDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, fun);
cv = nameAndVisitor.getSecond(); cv = nameAndVisitor.getSecond();
name = nameAndVisitor.getFirst(); name = nameAndVisitor.getFirst();
@@ -5,7 +5,6 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.resolve.DescriptorRenderer;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter; import org.objectweb.asm.commons.InstructionAdapter;
@@ -49,7 +48,7 @@ public abstract class CodegenContext {
protected abstract ClassDescriptor getThisDescriptor (); protected abstract ClassDescriptor getThisDescriptor ();
protected FunctionDescriptor getReceiverDescriptor() { protected CallableDescriptor getReceiverDescriptor() {
return null; return null;
} }
@@ -80,8 +79,8 @@ public abstract class CodegenContext {
return new NamespaceContext(descriptor, this); return new NamespaceContext(descriptor, this);
} }
public CodegenContext intoClass(ClassDescriptor descriptor, OwnerKind kind) { public CodegenContext intoClass(ClassDescriptor descriptor, OwnerKind kind, JetTypeMapper typeMapper) {
return new ClassContext(descriptor, kind, this); return new ClassContext(descriptor, kind, this, typeMapper);
} }
public CodegenContext intoAnonymousClass(@NotNull ObjectOrClosureCodegen closure, ClassDescriptor descriptor, OwnerKind kind) { public CodegenContext intoAnonymousClass(@NotNull ObjectOrClosureCodegen closure, ClassDescriptor descriptor, OwnerKind kind) {
@@ -124,7 +123,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.jvmType((ClassDescriptor) contextType, contextKind); return mapper.mapType(((ClassDescriptor) contextType).getDefaultType(), contextKind);
} }
else if (closure != null) { else if (closure != null) {
return Type.getObjectType(closure.name); return Type.getObjectType(closure.name);
@@ -232,33 +231,23 @@ public abstract class CodegenContext {
return getThisDescriptor() != null ? StackValue.local(1, asmType) : StackValue.local(0, asmType); return getThisDescriptor() != null ? StackValue.local(1, asmType) : StackValue.local(0, asmType);
} }
public abstract static class FunctionContext extends CodegenContext { public abstract static class ReceiverContext extends CodegenContext {
final FunctionDescriptor receiverDescriptor; final CallableDescriptor receiverDescriptor;
public FunctionContext(FunctionDescriptor contextType, OwnerKind contextKind, CodegenContext parentContext, @Nullable ObjectOrClosureCodegen closureCodegen) { public ReceiverContext(CallableDescriptor contextType, OwnerKind contextKind, CodegenContext parentContext, @Nullable ObjectOrClosureCodegen closureCodegen) {
super(contextType, contextKind, parentContext, closureCodegen); super(contextType, contextKind, parentContext, closureCodegen);
receiverDescriptor = contextType.getReceiverParameter().exists() ? contextType : null; receiverDescriptor = contextType.getReceiverParameter().exists() ? contextType : null;
} }
@Override @Override
protected FunctionDescriptor getReceiverDescriptor() { protected CallableDescriptor getReceiverDescriptor() {
return receiverDescriptor; return receiverDescriptor;
} }
public FunctionContext getOuterFunction() {
CodegenContext c = getParentContext();
while(c != null) {
if(c instanceof FunctionContext)
return (FunctionContext) c;
c = c.getParentContext();
}
return null;
}
} }
public static class MethodContext extends FunctionContext { public static class MethodContext extends ReceiverContext {
public MethodContext(FunctionDescriptor contextType, OwnerKind contextKind, CodegenContext parentContext) { public MethodContext(FunctionDescriptor contextType, OwnerKind contextKind, CodegenContext parentContext) {
super(contextType, contextKind, parentContext, null); super(contextType instanceof PropertyAccessorDescriptor ? ((PropertyAccessorDescriptor)contextType).getCorrespondingProperty() : contextType, contextKind, parentContext, null);
} }
@Override @Override
@@ -295,12 +284,12 @@ public abstract class CodegenContext {
} }
public static class ClassContext extends CodegenContext { public static class ClassContext extends CodegenContext {
public ClassContext(ClassDescriptor contextType, OwnerKind contextKind, CodegenContext parentContext) { public ClassContext(ClassDescriptor contextType, OwnerKind contextKind, CodegenContext parentContext, JetTypeMapper typeMapper) {
super(contextType, contextKind, parentContext, null); super(contextType, contextKind, parentContext, null);
final Type type = enclosingClassType(); final Type type = enclosingClassType();
outerExpression = type != null outerExpression = type != null
? StackValue.field(type, DescriptorRenderer.getFQName(contextType).replace('.', '/'), "this$0", false) ? StackValue.field(type, typeMapper.getFQName(contextType), "this$0", false)
: null; : null;
} }
@@ -316,7 +305,7 @@ public abstract class CodegenContext {
final Type type = enclosingClassType(); final Type type = enclosingClassType();
outerExpression = type != null outerExpression = type != null
? StackValue.field(type, closure.state.getTypeMapper().jvmName(contextType, OwnerKind.IMPLEMENTATION), "this$0", false) ? StackValue.field(type, closure.state.getTypeMapper().mapType(contextType.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), "this$0", false)
: null; : null;
} }
@@ -326,7 +315,7 @@ public abstract class CodegenContext {
} }
} }
public static class ClosureContext extends FunctionContext { public static class ClosureContext extends ReceiverContext {
private ClassDescriptor classDescriptor; private ClassDescriptor classDescriptor;
public ClosureContext(FunctionDescriptor contextType, ClassDescriptor classDescriptor, CodegenContext parentContext, @NotNull ObjectOrClosureCodegen closureCodegen, String internalClassName) { public ClosureContext(FunctionDescriptor contextType, ClassDescriptor classDescriptor, CodegenContext parentContext, @NotNull ObjectOrClosureCodegen closureCodegen, String internalClassName) {
@@ -169,4 +169,5 @@ public class CodegenUtil {
addSuperTypes(jetType, set); addSuperTypes(jetType, set);
} }
} }
} }
@@ -3,6 +3,7 @@ package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor; import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
@@ -25,6 +26,19 @@ public class ConstructorFrameMap extends FrameMap {
} }
} }
if (classDescriptor != null) {
List<TypeParameterDescriptor> parameters = classDescriptor.getTypeConstructor().getParameters();
for (TypeParameterDescriptor parameter : parameters) {
if(parameter.isReified()) {
int index = enterTemp();
myTypeParameterCount++;
if(myFirstTypeParameter == -1) {
myFirstTypeParameter = index;
}
}
}
}
List<Type> explicitArgTypes = callableMethod.getValueParameterTypes(); List<Type> explicitArgTypes = callableMethod.getValueParameterTypes();
List<ValueParameterDescriptor> paramDescrs = descriptor != null List<ValueParameterDescriptor> paramDescrs = descriptor != null
@@ -34,18 +48,6 @@ public class ConstructorFrameMap extends FrameMap {
ValueParameterDescriptor parameter = paramDescrs.get(i); ValueParameterDescriptor parameter = paramDescrs.get(i);
enter(parameter, explicitArgTypes.get(i).getSize()); enter(parameter, explicitArgTypes.get(i).getSize());
} }
if (classDescriptor != null) {
myTypeParameterCount = classDescriptor.getTypeConstructor().getParameters().size();
if (kind == OwnerKind.IMPLEMENTATION) {
if (myTypeParameterCount > 0) {
myFirstTypeParameter = enterTemp();
for (int i = 1; i < myTypeParameterCount; i++) {
enterTemp();
}
}
}
}
} }
public int getOuterThisIndex() { public int getOuterThisIndex() {
@@ -79,6 +79,22 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
this.intrinsics = state.getIntrinsics(); this.intrinsics = state.getIntrinsics();
} }
StackValue castToRequiredTypeOfInterfaceIfNeeded(StackValue inner, DeclarationDescriptor provided, ClassDescriptor required) {
if(required == null)
return inner;
if(provided instanceof CallableDescriptor)
provided = ((CallableDescriptor)provided).getReceiverParameter().getType().getConstructor().getDeclarationDescriptor();
assert provided instanceof ClassDescriptor;
if(!CodegenUtil.isInterface(provided) && CodegenUtil.isInterface(required)) {
v.checkcast(typeMapper.mapType(required.getDefaultType()));
}
return inner;
}
public GenerationState getState() { public GenerationState getState() {
return state; return state;
} }
@@ -265,7 +281,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
final JetParameter loopParameter = expression.getLoopParameter(); final JetParameter loopParameter = expression.getLoopParameter();
final VariableDescriptor parameterDescriptor = bindingContext.get(BindingContext.VALUE_PARAMETER, loopParameter); final VariableDescriptor parameterDescriptor = bindingContext.get(BindingContext.VALUE_PARAMETER, loopParameter);
JetType iteratorType = parameterDescriptor.getOutType(); JetType iteratorType = iteratorDescriptor.getReturnType();
Type asmIterType = JetTypeMapper.boxType(typeMapper.mapType(iteratorType)); Type asmIterType = JetTypeMapper.boxType(typeMapper.mapType(iteratorType));
JetType paramType = parameterDescriptor.getOutType(); JetType paramType = parameterDescriptor.getOutType();
@@ -802,8 +818,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
if (declaration instanceof JetObjectDeclarationName) { if (declaration instanceof JetObjectDeclarationName) {
JetObjectDeclaration objectDeclaration = PsiTreeUtil.getParentOfType(declaration, JetObjectDeclaration.class); JetObjectDeclaration objectDeclaration = PsiTreeUtil.getParentOfType(declaration, JetObjectDeclaration.class);
ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, objectDeclaration); ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, objectDeclaration);
return StackValue.field(typeMapper.jvmType(classDescriptor, OwnerKind.IMPLEMENTATION), return StackValue.field(typeMapper.mapType(classDescriptor.getDefaultType(), OwnerKind.IMPLEMENTATION),
typeMapper.jvmName(classDescriptor, OwnerKind.IMPLEMENTATION), typeMapper.mapType(classDescriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(),
"$instance", "$instance",
true); true);
} }
@@ -813,25 +829,59 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
JetExpression r = getReceiverForSelector(expression); JetExpression r = getReceiverForSelector(expression);
final boolean isSuper = r instanceof JetSuperExpression; final boolean isSuper = r instanceof JetSuperExpression;
final StackValue iValue = intermediateValueForProperty(propertyDescriptor, directToField, isSuper ? (JetSuperExpression)r : null); final StackValue iValue = intermediateValueForProperty(propertyDescriptor, directToField, isSuper ? (JetSuperExpression)r : null);
if (!isStatic) { if(!directToField && resolvedCall != null && !isSuper) {
if (receiver == StackValue.none()) { if (resolvedCall.getThisObject().exists()) {
if(resolvedCall == null) if(resolvedCall.getReceiverArgument().exists()) {
receiver = generateThisOrOuter((ClassDescriptor) propertyDescriptor.getContainingDeclaration()); generateFromResolvedCall(resolvedCall.getThisObject());
if(receiver == StackValue.none()) {
generateFromResolvedCall(resolvedCall.getReceiverArgument());
}
else {
receiver.put(typeMapper.mapType(resolvedCall.getReceiverArgument().getType()), v);
}
}
else { else {
if(resolvedCall.getThisObject() instanceof ExtensionReceiver) if (receiver == StackValue.none()) {
receiver = generateReceiver((FunctionDescriptor) ((ExtensionReceiver)resolvedCall.getThisObject()).getDeclarationDescriptor()); generateFromResolvedCall(resolvedCall.getThisObject());
else }
receiver = generateThisOrOuter((ClassDescriptor) propertyDescriptor.getContainingDeclaration()); else {
receiver.put(typeMapper.mapType(((ClassDescriptor)resolvedCall.getResultingDescriptor().getContainingDeclaration()).getDefaultType()), v);
}
} }
} }
JetType receiverType = bindingContext.get(BindingContext.EXPRESSION_TYPE, r); else {
receiver.put(receiverType != null && !isSuper? typeMapper.mapType(receiverType) : JetTypeMapper.TYPE_OBJECT, v); if (resolvedCall.getReceiverArgument().exists()) {
if(receiverType != null) { if (receiver == StackValue.none()) {
ClassDescriptor propReceiverDescriptor = (ClassDescriptor) propertyDescriptor.getContainingDeclaration(); generateFromResolvedCall(resolvedCall.getReceiverArgument());
if(!CodegenUtil.isInterface(propReceiverDescriptor) && CodegenUtil.isInterface(receiverType.getConstructor().getDeclarationDescriptor())) { }
// I hope it happens only in case of required super class for traits else {
assert propReceiverDescriptor != null; receiver.put(typeMapper.mapType(resolvedCall.getReceiverArgument().getType()), v);
v.checkcast(typeMapper.mapType(propReceiverDescriptor.getDefaultType())); }
}
}
pushTypeArguments(resolvedCall);
}
else {
if (!isStatic) {
if (receiver == StackValue.none()) {
if(resolvedCall == null)
receiver = generateThisOrOuter((ClassDescriptor) propertyDescriptor.getContainingDeclaration());
else {
if(resolvedCall.getThisObject() instanceof ExtensionReceiver)
receiver = generateReceiver(((ExtensionReceiver)resolvedCall.getThisObject()).getDeclarationDescriptor(), null);
else
receiver = generateThisOrOuter((ClassDescriptor) propertyDescriptor.getContainingDeclaration());
}
}
JetType receiverType = bindingContext.get(BindingContext.EXPRESSION_TYPE, r);
receiver.put(receiverType != null && !isSuper? typeMapper.mapType(receiverType) : JetTypeMapper.TYPE_OBJECT, v);
if(receiverType != null) {
ClassDescriptor propReceiverDescriptor = (ClassDescriptor) propertyDescriptor.getContainingDeclaration();
if(!CodegenUtil.isInterface(propReceiverDescriptor) && CodegenUtil.isInterface(receiverType.getConstructor().getDeclarationDescriptor())) {
// I hope it happens only in case of required super class for traits
assert propReceiverDescriptor != null;
v.checkcast(typeMapper.mapType(propReceiverDescriptor.getDefaultType()));
}
} }
} }
} }
@@ -844,9 +894,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
if (classObject == null) { if (classObject == null) {
throw new UnsupportedOperationException("trying to reference a class which doesn't have a class object"); throw new UnsupportedOperationException("trying to reference a class which doesn't have a class object");
} }
final String type = typeMapper.jvmName(classObject); final ClassDescriptor descriptor1 = bindingContext.get(BindingContext.CLASS, classObject.getObjectDeclaration());
final String type = typeMapper.mapType(descriptor1.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName();
return StackValue.field(Type.getObjectType(type), return StackValue.field(Type.getObjectType(type),
typeMapper.jvmName((ClassDescriptor) descriptor, OwnerKind.IMPLEMENTATION), typeMapper.mapType(((ClassDescriptor) descriptor).getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(),
"$classobj", "$classobj",
true); true);
} }
@@ -1102,10 +1153,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getCalleeExpression()); ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getCalleeExpression());
assert resolvedCall != null; assert resolvedCall != null;
FunctionDescriptor callableDescriptor = (FunctionDescriptor) resolvedCall.getResultingDescriptor();
boolean hasThis = resolvedCall.getThisObject().exists();
boolean hasReceiver = resolvedCall.getReceiverArgument().exists();
if (callableMethod.isNeedsThis()) { if (callableMethod.isNeedsThis()) {
if(callableMethod.isNeedsReceiver()) { if(callableMethod.isNeedsReceiver()) {
generateFromResolvedCall(resolvedCall.getThisObject()); generateFromResolvedCall(resolvedCall.getThisObject());
@@ -1113,7 +1160,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
generateFromResolvedCall(resolvedCall.getReceiverArgument()); generateFromResolvedCall(resolvedCall.getReceiverArgument());
} }
else { else {
receiver.put(typeMapper.mapType(callableMethod.getReceiverFunction().getReceiverParameter().getType()), v); receiver.put(typeMapper.mapType(resolvedCall.getReceiverArgument().getType()), v);
} }
} }
else { else {
@@ -1135,8 +1182,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
} }
} }
pushTypeArguments(resolvedCall);
int mask = pushMethodArguments(expression, callableMethod.getValueParameterTypes()); int mask = pushMethodArguments(expression, callableMethod.getValueParameterTypes());
pushTypeArguments(expression);
if(mask == 0) if(mask == 0)
callableMethod.invoke(v); callableMethod.invoke(v);
else else
@@ -1150,7 +1197,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
} }
else if(descriptor instanceof ExtensionReceiver) { else if(descriptor instanceof ExtensionReceiver) {
ExtensionReceiver extensionReceiver = (ExtensionReceiver) descriptor; ExtensionReceiver extensionReceiver = (ExtensionReceiver) descriptor;
generateReceiver((FunctionDescriptor) extensionReceiver.getDeclarationDescriptor()).put(typeMapper.mapType(descriptor.getType()), v); generateReceiver(extensionReceiver.getDeclarationDescriptor(), null).put(typeMapper.mapType(descriptor.getType()), v);
} }
else if(descriptor instanceof ExpressionReceiver) { else if(descriptor instanceof ExpressionReceiver) {
ExpressionReceiver expressionReceiver = (ExpressionReceiver) descriptor; ExpressionReceiver expressionReceiver = (ExpressionReceiver) descriptor;
@@ -1169,14 +1216,16 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
return null; return null;
} }
private StackValue generateReceiver(FunctionDescriptor descriptor) { private StackValue generateReceiver(DeclarationDescriptor provided, ClassDescriptor required) {
assert context instanceof CodegenContext.FunctionContext; assert context instanceof CodegenContext.ReceiverContext;
CodegenContext.FunctionContext cur = (CodegenContext.FunctionContext) context; CodegenContext.ReceiverContext cur = (CodegenContext.ReceiverContext) context;
if (cur.getReceiverDescriptor() == descriptor) { if (cur.getReceiverDescriptor() == provided) {
return cur.getReceiverExpression(typeMapper); StackValue result = cur.getReceiverExpression(typeMapper);
return castToRequiredTypeOfInterfaceIfNeeded(result, provided, required);
} }
return context.lookupInContext(descriptor, v, StackValue.local(0, JetTypeMapper.TYPE_OBJECT)); StackValue result = context.lookupInContext(provided, v, StackValue.local(0, JetTypeMapper.TYPE_OBJECT));
return castToRequiredTypeOfInterfaceIfNeeded(result, provided, required);
} }
public StackValue generateThisOrOuter(ClassDescriptor calleeContainingClass) { public StackValue generateThisOrOuter(ClassDescriptor calleeContainingClass) {
@@ -1190,7 +1239,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
if (CodegenUtil.isSubclass(cur.getThisDescriptor(), calleeContainingClass)) { if (CodegenUtil.isSubclass(cur.getThisDescriptor(), calleeContainingClass)) {
Type type = typeMapper.mapType(calleeContainingClass.getDefaultType()); Type type = typeMapper.mapType(calleeContainingClass.getDefaultType());
result.put(JetTypeMapper.TYPE_OBJECT, v); result.put(JetTypeMapper.TYPE_OBJECT, v);
return StackValue.onStack(type); return castToRequiredTypeOfInterfaceIfNeeded(StackValue.onStack(type), cur.getThisDescriptor(), calleeContainingClass);
} }
result = cur.getOuterExpression(result); result = cur.getOuterExpression(result);
@@ -1213,64 +1262,66 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
return false; return false;
} }
private int pushMethodArguments(JetCallElement expression, List<Type> valueParameterTypes) { private int pushMethodArguments(ResolvedCall resolvedCall, List<Type> valueParameterTypes) {
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getCalleeExpression()); Map<ValueParameterDescriptor,ResolvedValueArgument> valueArguments = resolvedCall.getValueArguments();
List<? extends ValueArgument> args = expression.getValueArguments(); CallableDescriptor fd = resolvedCall.getResultingDescriptor();
if(resolvedCall != null) {
Map<ValueParameterDescriptor,ResolvedValueArgument> valueArguments = resolvedCall.getValueArguments();
CallableDescriptor fd = resolvedCall.getResultingDescriptor();
int index = 0; int index = 0;
int mask = 0; int mask = 0;
for (ValueParameterDescriptor valueParameterDescriptor : fd.getValueParameters()) { for (ValueParameterDescriptor valueParameterDescriptor : fd.getValueParameters()) {
ResolvedValueArgument resolvedValueArgument = valueArguments.get(valueParameterDescriptor); ResolvedValueArgument resolvedValueArgument = valueArguments.get(valueParameterDescriptor);
if(resolvedValueArgument instanceof ExpressionValueArgument) { if(resolvedValueArgument instanceof ExpressionValueArgument) {
ExpressionValueArgument valueArgument = (ExpressionValueArgument) resolvedValueArgument; ExpressionValueArgument valueArgument = (ExpressionValueArgument) resolvedValueArgument;
gen(valueArgument.getExpression(), valueParameterTypes.get(index)); gen(valueArgument.getExpression(), valueParameterTypes.get(index));
}
else if(resolvedValueArgument instanceof DefaultValueArgument) {
Type type = valueParameterTypes.get(index);
if(type.getSort() == Type.OBJECT||type.getSort() == Type.ARRAY)
v.aconst(null);
else if(type.getSort() == Type.FLOAT) {
v.aconst(0f);
} }
else if(resolvedValueArgument instanceof DefaultValueArgument) { else if(type.getSort() == Type.DOUBLE) {
Type type = valueParameterTypes.get(index); v.aconst(0d);
if(type.getSort() == Type.OBJECT||type.getSort() == Type.ARRAY)
v.aconst(null);
else if(type.getSort() == Type.FLOAT) {
v.aconst(0f);
}
else if(type.getSort() == Type.DOUBLE) {
v.aconst(0d);
}
else {
v.iconst(0);
}
mask |= (1 << index);
}
else if(resolvedValueArgument instanceof VarargValueArgument) {
VarargValueArgument valueArgument = (VarargValueArgument) resolvedValueArgument;
JetType outType = valueParameterDescriptor.getOutType();
Type type = typeMapper.mapType(outType);
assert type.getSort() == Type.ARRAY;
Type elementType = type.getElementType();
int size = valueArgument.getArgumentExpressions().size();
v.iconst(valueArgument.getArgumentExpressions().size());
v.newarray(elementType);
for(int i = 0; i != size; ++i) {
v.dup();
v.iconst(i);
gen(valueArgument.getArgumentExpressions().get(i), elementType);
StackValue.arrayElement(elementType, false).store(v);
}
// throw new UnsupportedOperationException("Varargs are not supported yet");
} }
else { else {
throw new UnsupportedOperationException(); v.iconst(0);
} }
index++; mask |= (1 << index);
} }
return mask; else if(resolvedValueArgument instanceof VarargValueArgument) {
VarargValueArgument valueArgument = (VarargValueArgument) resolvedValueArgument;
JetType outType = valueParameterDescriptor.getOutType();
Type type = typeMapper.mapType(outType);
assert type.getSort() == Type.ARRAY;
Type elementType = type.getElementType();
int size = valueArgument.getArgumentExpressions().size();
v.iconst(valueArgument.getArgumentExpressions().size());
v.newarray(elementType);
for(int i = 0; i != size; ++i) {
v.dup();
v.iconst(i);
gen(valueArgument.getArgumentExpressions().get(i), elementType);
StackValue.arrayElement(elementType, false).store(v);
}
}
else {
throw new UnsupportedOperationException();
}
index++;
}
return mask;
}
private int pushMethodArguments(JetCallElement expression, List<Type> valueParameterTypes) {
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getCalleeExpression());
if(resolvedCall != null) {
return pushMethodArguments(resolvedCall, valueParameterTypes);
} }
else { else {
List<? extends ValueArgument> args = expression.getValueArguments();
for (int i = 0, argsSize = args.size(); i < argsSize; i++) { for (int i = 0, argsSize = args.size(); i < argsSize; i++) {
ValueArgument arg = args.get(i); ValueArgument arg = args.get(i);
gen(arg.getArgumentExpression(), valueParameterTypes.get(i)); gen(arg.getArgumentExpression(), valueParameterTypes.get(i));
@@ -1898,7 +1949,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
else { else {
// this$0 need to be put on stack // this$0 need to be put on stack
v.dup(); v.dup();
v.load(0, typeMapper.jetImplementationType(classDecl)); v.load(0, typeMapper.mapType(classDecl.getDefaultType(), OwnerKind.IMPLEMENTATION));
} }
} }
else { else {
@@ -1916,9 +1967,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
return StackValue.onStack(type); return StackValue.onStack(type);
} }
private void pushTypeArguments(JetCallElement expression) { private void pushTypeArguments(ResolvedCall<? extends CallableDescriptor> resolvedCall) {
JetExpression calleeExpression = expression.getCalleeExpression();
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, calleeExpression);
if(resolvedCall != null) { if(resolvedCall != null) {
Map<TypeParameterDescriptor, JetType> typeArguments = resolvedCall.getTypeArguments(); Map<TypeParameterDescriptor, JetType> typeArguments = resolvedCall.getTypeArguments();
CallableDescriptor resultingDescriptor = resolvedCall.getCandidateDescriptor(); CallableDescriptor resultingDescriptor = resolvedCall.getCandidateDescriptor();
@@ -2100,7 +2149,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
} }
else { else {
if(descriptor instanceof FunctionDescriptor) { if(descriptor instanceof FunctionDescriptor) {
return generateReceiver((FunctionDescriptor) descriptor); return generateReceiver(descriptor, null);
} }
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@@ -4,6 +4,7 @@ import com.intellij.psi.PsiElement;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.resolve.DescriptorRenderer;
import org.objectweb.asm.AnnotationVisitor; import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Label; import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
@@ -52,7 +53,7 @@ public class FunctionCodegen {
FunctionDescriptor functionDescriptor, JetDeclarationWithBody fun) FunctionDescriptor functionDescriptor, JetDeclarationWithBody fun)
{ {
List<ValueParameterDescriptor> paramDescrs = functionDescriptor.getValueParameters(); List<ValueParameterDescriptor> paramDescrs = functionDescriptor.getValueParameters();
List<TypeParameterDescriptor> typeParameters = functionDescriptor.getTypeParameters(); List<TypeParameterDescriptor> typeParameters = (functionDescriptor instanceof PropertyAccessorDescriptor ? ((PropertyAccessorDescriptor)functionDescriptor).getCorrespondingProperty(): functionDescriptor).getTypeParameters();
int flags = ACC_PUBLIC; // TODO. int flags = ACC_PUBLIC; // TODO.
@@ -83,16 +84,18 @@ public class FunctionCodegen {
Type[] argTypes = jvmSignature.getArgumentTypes(); Type[] argTypes = jvmSignature.getArgumentTypes();
int add = functionDescriptor.getReceiverParameter().exists() ? state.getTypeMapper().mapType(functionDescriptor.getReceiverParameter().getType()).getSize() : 0; int add = functionDescriptor.getReceiverParameter().exists() ? state.getTypeMapper().mapType(functionDescriptor.getReceiverParameter().getType()).getSize() : 0;
for (int i = 0; i < paramDescrs.size(); i++) {
ValueParameterDescriptor parameter = paramDescrs.get(i);
frameMap.enter(parameter, argTypes[i+add].getSize());
}
for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) { for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
int slot = frameMap.enterTemp(); int slot = frameMap.enterTemp();
add++;
codegen.addTypeParameter(typeParameterDescriptor, StackValue.local(slot, JetTypeMapper.TYPE_TYPEINFO)); codegen.addTypeParameter(typeParameterDescriptor, StackValue.local(slot, JetTypeMapper.TYPE_TYPEINFO));
} }
for (int i = 0; i < paramDescrs.size(); i++) {
ValueParameterDescriptor parameter = paramDescrs.get(i);
frameMap.enter(parameter, argTypes[i+add].getSize());
}
if (kind instanceof OwnerKind.DelegateKind) { if (kind instanceof OwnerKind.DelegateKind) {
OwnerKind.DelegateKind dk = (OwnerKind.DelegateKind) kind; OwnerKind.DelegateKind dk = (OwnerKind.DelegateKind) kind;
InstructionAdapter iv = new InstructionAdapter(mv); InstructionAdapter iv = new InstructionAdapter(mv);
@@ -150,7 +153,7 @@ public class FunctionCodegen {
} }
static void generateDefaultIfNeeded(CodegenContext.MethodContext owner, GenerationState state, ClassBuilder v, Method jvmSignature, FunctionDescriptor functionDescriptor, OwnerKind kind) { static void generateDefaultIfNeeded(CodegenContext.MethodContext owner, GenerationState state, ClassBuilder v, Method jvmSignature, FunctionDescriptor functionDescriptor, OwnerKind kind) {
DeclarationDescriptor contextClass = ((FunctionDescriptor)owner.getContextDescriptor()).getContainingDeclaration(); DeclarationDescriptor contextClass = owner.getContextDescriptor().getContainingDeclaration();
if(kind != OwnerKind.TRAIT_IMPL) { if(kind != OwnerKind.TRAIT_IMPL) {
// we don't generate defaults for traits but do for traitImpl // we don't generate defaults for traits but do for traitImpl
@@ -184,8 +187,8 @@ public class FunctionCodegen {
int flags = ACC_PUBLIC; // TODO. int flags = ACC_PUBLIC; // TODO.
String ownerInternalName = contextClass instanceof NamespaceDescriptor ? String ownerInternalName = contextClass instanceof NamespaceDescriptor ?
JetTypeMapper.jvmName((NamespaceDescriptor) contextClass) : NamespaceCodegen.getJVMClassName(DescriptorRenderer.getFQName(contextClass)) :
state.getTypeMapper().jvmName((ClassDescriptor) contextClass, OwnerKind.IMPLEMENTATION); state.getTypeMapper().mapType(((ClassDescriptor) contextClass).getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName();
String descriptor = jvmSignature.getDescriptor().replace(")","I)"); String descriptor = jvmSignature.getDescriptor().replace(")","I)");
if(!isStatic) if(!isStatic)
@@ -210,6 +213,13 @@ public class FunctionCodegen {
var++; var++;
} }
List<TypeParameterDescriptor> typeParameters = functionDescriptor.getTypeParameters();
for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
int slot = frameMap.enterTemp();
codegen.addTypeParameter(typeParameterDescriptor, StackValue.local(slot, JetTypeMapper.TYPE_TYPEINFO));
var++;
}
Type[] argTypes = jvmSignature.getArgumentTypes(); Type[] argTypes = jvmSignature.getArgumentTypes();
List<ValueParameterDescriptor> paramDescrs = functionDescriptor.getValueParameters(); List<ValueParameterDescriptor> paramDescrs = functionDescriptor.getValueParameters();
for (int i = 0; i < paramDescrs.size(); i++) { for (int i = 0; i < paramDescrs.size(); i++) {
@@ -219,13 +229,6 @@ public class FunctionCodegen {
frameMap.enter(parameter, size); frameMap.enter(parameter, size);
} }
List<TypeParameterDescriptor> typeParameters = functionDescriptor.getTypeParameters();
for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
int slot = frameMap.enterTemp();
codegen.addTypeParameter(typeParameterDescriptor, StackValue.local(slot, JetTypeMapper.TYPE_TYPEINFO));
var++;
}
frameMap.enterTemp(); frameMap.enterTemp();
int maskIndex = var; int maskIndex = var;
@@ -236,14 +239,22 @@ public class FunctionCodegen {
} }
if(hasReceiver) { if(hasReceiver) {
mv.visitVarInsn(ALOAD, var++); mv.visitVarInsn(ALOAD, var++); // todo - Long etc.
}
int extra = hasReceiver ? 1 : 0;
for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
if(typeParameterDescriptor.isReified()) {
iv.load(var++, JetTypeMapper.TYPE_OBJECT);
extra++;
}
} }
Type[] argumentTypes = jvmSignature.getArgumentTypes(); Type[] argumentTypes = jvmSignature.getArgumentTypes();
for (int index = 0; index < paramDescrs.size(); index++) { for (int index = 0; index < paramDescrs.size(); index++) {
ValueParameterDescriptor parameterDescriptor = paramDescrs.get(index); ValueParameterDescriptor parameterDescriptor = paramDescrs.get(index);
Type t = argumentTypes[(hasReceiver ? 1 : 0) + index]; Type t = argumentTypes[extra + index];
Label endArg = null; Label endArg = null;
if (parameterDescriptor.hasDefaultValue()) { if (parameterDescriptor.hasDefaultValue()) {
iv.load(maskIndex, Type.INT_TYPE); iv.load(maskIndex, Type.INT_TYPE);
@@ -270,11 +281,6 @@ public class FunctionCodegen {
} }
} }
for (final TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
if(typeParameterDescriptor.isReified())
iv.load(var++, JetTypeMapper.TYPE_OBJECT);
}
if(!isStatic) { if(!isStatic) {
if(kind == OwnerKind.TRAIT_IMPL) { if(kind == OwnerKind.TRAIT_IMPL) {
iv.invokeinterface(ownerInternalName, jvmSignature.getName(), jvmSignature.getDescriptor()); iv.invokeinterface(ownerInternalName, jvmSignature.getName(), jvmSignature.getDescriptor());
@@ -318,7 +324,7 @@ public class FunctionCodegen {
reg += argType.getSize(); reg += argType.getSize();
} }
iv.invokevirtual(state.getTypeMapper().jvmName((ClassDescriptor) owner.getContextDescriptor(), OwnerKind.IMPLEMENTATION), jvmSignature.getName(), jvmSignature.getDescriptor()); iv.invokevirtual(state.getTypeMapper().mapType(((ClassDescriptor) owner.getContextDescriptor()).getDefaultType(), OwnerKind.IMPLEMENTATION).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)
@@ -64,11 +64,11 @@ public class GenerationState {
} }
public ClassBuilder forClassImplementation(ClassDescriptor aClass) { public ClassBuilder forClassImplementation(ClassDescriptor aClass) {
return factory.newVisitor(typeMapper.jvmName(aClass, OwnerKind.IMPLEMENTATION) + ".class"); return factory.newVisitor(typeMapper.mapType(aClass.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName() + ".class");
} }
public ClassBuilder forTraitImplementation(ClassDescriptor aClass) { public ClassBuilder forTraitImplementation(ClassDescriptor aClass) {
return factory.newVisitor(typeMapper.jvmName(aClass, OwnerKind.TRAIT_IMPL) + ".class"); return factory.newVisitor(typeMapper.mapType(aClass.getDefaultType(), OwnerKind.TRAIT_IMPL).getInternalName() + ".class");
} }
public Pair<String, ClassBuilder> forAnonymousSubclass(JetExpression expression) { public Pair<String, ClassBuilder> forAnonymousSubclass(JetExpression expression) {
@@ -28,9 +28,13 @@ import java.util.*;
public class ImplementationBodyCodegen extends ClassBodyCodegen { public class ImplementationBodyCodegen extends ClassBodyCodegen {
private JetDelegationSpecifier superCall; private JetDelegationSpecifier superCall;
private String superClass = "java/lang/Object"; private String superClass = "java/lang/Object";
private final JetTypeMapper typeMapper;
private final BindingContext bindingContext;
public ImplementationBodyCodegen(JetClassOrObject aClass, CodegenContext context, ClassBuilder v, GenerationState state) { public ImplementationBodyCodegen(JetClassOrObject aClass, CodegenContext context, ClassBuilder v, GenerationState state) {
super(aClass, context, v, state); super(aClass, context, v, state);
typeMapper = state.getTypeMapper();
bindingContext = state.getBindingContext();
} }
private Set<String> getSuperInterfaces(JetClassOrObject aClass) { private Set<String> getSuperInterfaces(JetClassOrObject aClass) {
@@ -39,10 +43,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
Set<String> superInterfaces = new LinkedHashSet<String>(); Set<String> superInterfaces = new LinkedHashSet<String>();
for (JetDelegationSpecifier specifier : delegationSpecifiers) { for (JetDelegationSpecifier specifier : delegationSpecifiers) {
JetType superType = state.getBindingContext().get(BindingContext.TYPE, specifier.getTypeReference()); JetType superType = bindingContext.get(BindingContext.TYPE, specifier.getTypeReference());
assert superType != null; assert superType != null;
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
PsiElement superPsi = state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, superClassDescriptor); PsiElement superPsi = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, superClassDescriptor);
if (superPsi instanceof PsiClass) { if (superPsi instanceof PsiClass) {
PsiClass psiClass = (PsiClass) superPsi; PsiClass psiClass = (PsiClass) superPsi;
@@ -71,7 +75,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
} }
else { else {
if(superPsi == null || ((JetClass)superPsi).isTrait()) if(superPsi == null || ((JetClass)superPsi).isTrait())
superInterfaces.add(state.getTypeMapper().jvmNameForImplementation(superClassDescriptor, OwnerKind.IMPLEMENTATION)); superInterfaces.add(typeMapper.mapType(superClassDescriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName());
} }
} }
return superInterfaces; return superInterfaces;
@@ -108,18 +112,18 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
v.visitSource(myClass.getContainingFile().getName(), null); v.visitSource(myClass.getContainingFile().getName(), null);
if(descriptor.getContainingDeclaration() instanceof ClassDescriptor) { if(descriptor.getContainingDeclaration() instanceof ClassDescriptor) {
v.visitOuterClass(state.getTypeMapper().jvmType((ClassDescriptor) descriptor.getContainingDeclaration(), OwnerKind.IMPLEMENTATION).getInternalName(), null, null); v.visitOuterClass(typeMapper.mapType(((ClassDescriptor) descriptor.getContainingDeclaration()).getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), null, null);
} }
if(myClass instanceof JetClass) { if(myClass instanceof JetClass) {
AnnotationVisitor annotationVisitor = v.newAnnotation(myClass, "Ljet/typeinfo/JetSignature;", true); AnnotationVisitor annotationVisitor = v.newAnnotation(myClass, "Ljet/typeinfo/JetSignature;", true);
annotationVisitor.visit("value", SignatureUtil.classToSignature((JetClass)myClass, state.getBindingContext(), state.getTypeMapper())); annotationVisitor.visit("value", SignatureUtil.classToSignature((JetClass)myClass, bindingContext, typeMapper));
annotationVisitor.visitEnd(); annotationVisitor.visitEnd();
} }
} }
private String jvmName() { private String jvmName() {
return state.getTypeMapper().jvmName(descriptor, kind); return typeMapper.mapType(descriptor.getDefaultType(), kind).getInternalName();
} }
protected void getSuperClass() { protected void getSuperClass() {
@@ -130,21 +134,21 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
for (JetDelegationSpecifier specifier : delegationSpecifiers) { for (JetDelegationSpecifier specifier : delegationSpecifiers) {
if (specifier instanceof JetDelegatorToSuperClass || specifier instanceof JetDelegatorToSuperCall) { if (specifier instanceof JetDelegatorToSuperClass || specifier instanceof JetDelegatorToSuperCall) {
JetType superType = state.getBindingContext().get(BindingContext.TYPE, specifier.getTypeReference()); JetType superType = bindingContext.get(BindingContext.TYPE, specifier.getTypeReference());
assert superType != null; assert superType != null;
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
final PsiElement declaration = state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, superClassDescriptor); final PsiElement declaration = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, superClassDescriptor);
if (declaration != null) { if (declaration != null) {
if (declaration instanceof PsiClass) { if (declaration instanceof PsiClass) {
if (!((PsiClass) declaration).isInterface()) { if (!((PsiClass) declaration).isInterface()) {
superClass = state.getTypeMapper().jvmName(superClassDescriptor, kind); superClass = typeMapper.mapType(superClassDescriptor.getDefaultType(), kind).getInternalName();
superCall = specifier; superCall = specifier;
return; return;
} }
} }
else if(declaration instanceof JetClass) { else if(declaration instanceof JetClass) {
if(!((JetClass) declaration).isTrait()) { if(!((JetClass) declaration).isTrait()) {
superClass = state.getTypeMapper().jvmName(superClassDescriptor, kind); superClass = typeMapper.mapType(superClassDescriptor.getDefaultType(), kind).getInternalName();
superCall = specifier; superCall = specifier;
} }
} }
@@ -176,8 +180,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
FunctionDescriptor bridge = (FunctionDescriptor) entry.getValue(); FunctionDescriptor bridge = (FunctionDescriptor) entry.getValue();
FunctionDescriptor original = (FunctionDescriptor) entry.getKey(); FunctionDescriptor original = (FunctionDescriptor) entry.getKey();
Method method = state.getTypeMapper().mapSignature(bridge.getName(), bridge); Method method = typeMapper.mapSignature(bridge.getName(), bridge);
Method originalMethod = state.getTypeMapper().mapSignature(original.getName(), original); Method originalMethod = typeMapper.mapSignature(original.getName(), original);
Type[] argTypes = method.getArgumentTypes(); Type[] argTypes = method.getArgumentTypes();
MethodVisitor mv = v.newMethod(null, Opcodes.ACC_PUBLIC|Opcodes.ACC_BRIDGE|Opcodes.ACC_FINAL, bridge.getName(), method.getDescriptor(), null, null); MethodVisitor mv = v.newMethod(null, Opcodes.ACC_PUBLIC|Opcodes.ACC_BRIDGE|Opcodes.ACC_FINAL, bridge.getName(), method.getDescriptor(), null, null);
@@ -193,7 +197,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
//noinspection AssignmentToForLoopParameter //noinspection AssignmentToForLoopParameter
reg += argType.getSize(); reg += argType.getSize();
} }
iv.invokespecial(state.getTypeMapper().getOwner(original, OwnerKind.IMPLEMENTATION), originalMethod.getName(), originalMethod.getDescriptor()); iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), originalMethod.getName(), originalMethod.getDescriptor());
iv.areturn(method.getReturnType()); iv.areturn(method.getReturnType());
mv.visitMaxs(0,0); mv.visitMaxs(0,0);
@@ -204,8 +208,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
PropertyDescriptor bridge = (PropertyDescriptor) entry.getValue(); PropertyDescriptor bridge = (PropertyDescriptor) entry.getValue();
PropertyDescriptor original = (PropertyDescriptor) entry.getKey(); PropertyDescriptor original = (PropertyDescriptor) entry.getKey();
Method method = state.getTypeMapper().mapGetterSignature(bridge, OwnerKind.IMPLEMENTATION); Method method = typeMapper.mapGetterSignature(bridge, OwnerKind.IMPLEMENTATION);
Method originalMethod = state.getTypeMapper().mapGetterSignature(original, OwnerKind.IMPLEMENTATION); Method originalMethod = typeMapper.mapGetterSignature(original, OwnerKind.IMPLEMENTATION);
MethodVisitor mv = v.newMethod(null, Opcodes.ACC_PUBLIC|Opcodes.ACC_BRIDGE|Opcodes.ACC_FINAL, method.getName(), method.getDescriptor(), null, null); MethodVisitor mv = v.newMethod(null, Opcodes.ACC_PUBLIC|Opcodes.ACC_BRIDGE|Opcodes.ACC_FINAL, method.getName(), method.getDescriptor(), null, null);
InstructionAdapter iv = null; InstructionAdapter iv = null;
if (v.generateCode()) { if (v.generateCode()) {
@@ -214,15 +218,15 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
iv = new InstructionAdapter(mv); iv = new InstructionAdapter(mv);
iv.load(0, JetTypeMapper.TYPE_OBJECT); iv.load(0, JetTypeMapper.TYPE_OBJECT);
iv.invokespecial(state.getTypeMapper().getOwner(original, OwnerKind.IMPLEMENTATION), originalMethod.getName(), originalMethod.getDescriptor()); iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), originalMethod.getName(), originalMethod.getDescriptor());
iv.areturn(method.getReturnType()); iv.areturn(method.getReturnType());
mv.visitMaxs(0,0); mv.visitMaxs(0,0);
mv.visitEnd(); mv.visitEnd();
} }
method = state.getTypeMapper().mapSetterSignature(bridge, OwnerKind.IMPLEMENTATION); method = typeMapper.mapSetterSignature(bridge, OwnerKind.IMPLEMENTATION);
originalMethod = state.getTypeMapper().mapSetterSignature(original, OwnerKind.IMPLEMENTATION); originalMethod = typeMapper.mapSetterSignature(original, OwnerKind.IMPLEMENTATION);
mv = v.newMethod(null, Opcodes.ACC_PUBLIC|Opcodes.ACC_BRIDGE|Opcodes.ACC_FINAL, method.getName(), method.getDescriptor(), null, null); mv = v.newMethod(null, Opcodes.ACC_PUBLIC|Opcodes.ACC_BRIDGE|Opcodes.ACC_FINAL, method.getName(), method.getDescriptor(), null, null);
if (v.generateCode()) { if (v.generateCode()) {
mv.visitCode(); mv.visitCode();
@@ -237,7 +241,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
//noinspection AssignmentToForLoopParameter //noinspection AssignmentToForLoopParameter
reg += argType.getSize(); reg += argType.getSize();
} }
iv.invokespecial(state.getTypeMapper().getOwner(original, OwnerKind.IMPLEMENTATION), originalMethod.getName(), originalMethod.getDescriptor()); iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), originalMethod.getName(), originalMethod.getDescriptor());
iv.areturn(method.getReturnType()); iv.areturn(method.getReturnType());
mv.visitMaxs(0,0); mv.visitMaxs(0,0);
@@ -253,7 +257,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
private void generateFieldForObjectInstance() { private void generateFieldForObjectInstance() {
if (isNonLiteralObject()) { if (isNonLiteralObject()) {
Type type = state.getTypeMapper().jetImplementationType(descriptor); Type type = typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION);
v.newField(myClass, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "$instance", type.getDescriptor(), null, null); v.newField(myClass, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "$instance", type.getDescriptor(), null, null);
staticInitializerChunks.add(new CodeChunk() { staticInitializerChunks.add(new CodeChunk() {
@@ -263,7 +267,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", state.getTypeMapper().jetImplementationType(descriptor).getDescriptor()); v.putstatic(name, "$instance", typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getDescriptor());
} }
}); });
@@ -273,18 +277,20 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
private void generateFieldForClassObject() { private void generateFieldForClassObject() {
final JetClassObject classObject = getClassObject(); final JetClassObject classObject = getClassObject();
if (classObject != null) { if (classObject != null) {
Type type = Type.getObjectType(state.getTypeMapper().jvmName(classObject)); final ClassDescriptor descriptor1 = bindingContext.get(BindingContext.CLASS, classObject.getObjectDeclaration());
Type type = Type.getObjectType(typeMapper.mapType(descriptor1.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName());
v.newField(classObject, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "$classobj", type.getDescriptor(), null, null); v.newField(classObject, Opcodes.ACC_PUBLIC | Opcodes.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) {
String name = state.getTypeMapper().jvmName(classObject); final ClassDescriptor descriptor1 = bindingContext.get(BindingContext.CLASS, classObject.getObjectDeclaration());
String name = typeMapper.mapType(descriptor1.getDefaultType(), OwnerKind.IMPLEMENTATION).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(state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION), "$classobj", v.putstatic(typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), "$classobj",
classObjectType.getDescriptor()); classObjectType.getDescriptor());
} }
}); });
@@ -295,7 +301,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
if(myClass instanceof JetClass && ((JetClass) myClass).isTrait()) if(myClass instanceof JetClass && ((JetClass) myClass).isTrait())
return; return;
ConstructorDescriptor constructorDescriptor = state.getBindingContext().get(BindingContext.CONSTRUCTOR, myClass); ConstructorDescriptor constructorDescriptor = bindingContext.get(BindingContext.CONSTRUCTOR, myClass);
CodegenContext.ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor); CodegenContext.ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor);
@@ -304,7 +310,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
if (constructorDescriptor == null) { if (constructorDescriptor == null) {
List<Type> parameterTypes = new ArrayList<Type>(); List<Type> parameterTypes = new ArrayList<Type>();
if (CodegenUtil.hasThis0(descriptor)) { if (CodegenUtil.hasThis0(descriptor)) {
parameterTypes.add(state.getTypeMapper().jvmType(CodegenUtil.getOuterClassDescriptor(descriptor), OwnerKind.IMPLEMENTATION)); parameterTypes.add(typeMapper.mapType(CodegenUtil.getOuterClassDescriptor(descriptor).getDefaultType(), OwnerKind.IMPLEMENTATION));
} }
List<TypeParameterDescriptor> typeParameters = descriptor.getTypeConstructor().getParameters(); List<TypeParameterDescriptor> typeParameters = descriptor.getTypeConstructor().getParameters();
@@ -316,7 +322,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
callableMethod = new CallableMethod("", method, Opcodes.INVOKESPECIAL, Collections.<Type>emptyList()); callableMethod = new CallableMethod("", method, Opcodes.INVOKESPECIAL, Collections.<Type>emptyList());
} }
else { else {
callableMethod = state.getTypeMapper().mapToCallableMethod(constructorDescriptor, kind); callableMethod = typeMapper.mapToCallableMethod(constructorDescriptor, kind);
method = callableMethod.getSignature(); method = callableMethod.getSignature();
} }
@@ -329,7 +335,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
Map<DeclarationDescriptor, EnclosedValueDescriptor> closure = context.closure.closure; Map<DeclarationDescriptor, EnclosedValueDescriptor> closure = context.closure.closure;
for (DeclarationDescriptor descriptor : closure.keySet()) { for (DeclarationDescriptor descriptor : closure.keySet()) {
final Type sharedVarType = context.closure.exprContext.getSharedVarType(descriptor); final Type sharedVarType = context.closure.exprContext.getSharedVarType(descriptor);
consArgTypes.add(sharedVarType != null ? sharedVarType : state.getTypeMapper().mapType(((VariableDescriptor) descriptor).getOutType())); consArgTypes.add(sharedVarType != null ? sharedVarType : typeMapper.mapType(((VariableDescriptor) descriptor).getOutType()));
} }
method = new Method("<init>", Type.VOID_TYPE, consArgTypes.toArray(new Type[consArgTypes.size()])); method = new Method("<init>", Type.VOID_TYPE, consArgTypes.toArray(new Type[consArgTypes.size()]));
@@ -357,13 +363,13 @@ 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 = state.getTypeMapper().jvmName(descriptor, kind); String classname = typeMapper.mapType(descriptor.getDefaultType(), kind).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>();
for (JetDeclaration declaration : myClass.getDeclarations()) { for (JetDeclaration declaration : myClass.getDeclarations()) {
if (declaration instanceof JetFunction) { if (declaration instanceof JetFunction) {
FunctionDescriptor functionDescriptor = state.getBindingContext().get(BindingContext.FUNCTION, declaration); FunctionDescriptor functionDescriptor = bindingContext.get(BindingContext.FUNCTION, declaration);
assert functionDescriptor != null; assert functionDescriptor != null;
overridden.addAll(functionDescriptor.getOverriddenDescriptors()); overridden.addAll(functionDescriptor.getOverriddenDescriptors());
} }
@@ -375,25 +381,25 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
iv.invokespecial(superClass, "<init>", "()V"); iv.invokespecial(superClass, "<init>", "()V");
} }
else { else {
JetType superType = state.getBindingContext().get(BindingContext.TYPE, superCall.getTypeReference()); JetType superType = bindingContext.get(BindingContext.TYPE, superCall.getTypeReference());
List<Type> parameterTypes = new ArrayList<Type>(); List<Type> parameterTypes = new ArrayList<Type>();
assert superType != null; assert superType != null;
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
if (CodegenUtil.hasThis0(superClassDescriptor)) { if (CodegenUtil.hasThis0(superClassDescriptor)) {
iv.load(1, JetTypeMapper.TYPE_OBJECT); iv.load(1, JetTypeMapper.TYPE_OBJECT);
parameterTypes.add(state.getTypeMapper().jvmType(CodegenUtil.getOuterClassDescriptor(descriptor), OwnerKind.IMPLEMENTATION)); parameterTypes.add(typeMapper.mapType(CodegenUtil.getOuterClassDescriptor(descriptor).getDefaultType(), OwnerKind.IMPLEMENTATION));
} }
for(TypeProjection typeParameterDescriptor : superType.getArguments()) { for(TypeProjection typeParameterDescriptor : superType.getArguments()) {
codegen.generateTypeInfo(typeParameterDescriptor.getType()); codegen.generateTypeInfo(typeParameterDescriptor.getType());
parameterTypes.add(JetTypeMapper.TYPE_TYPEINFO); parameterTypes.add(JetTypeMapper.TYPE_TYPEINFO);
} }
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(state.getTypeMapper().jvmName(superClassDescriptor, OwnerKind.IMPLEMENTATION), "<init>", superCallMethod.getDescriptor()); iv.invokespecial(typeMapper.mapType(superClassDescriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), "<init>", superCallMethod.getDescriptor());
} }
} }
else { else {
iv.load(0, classType); iv.load(0, classType);
ConstructorDescriptor constructorDescriptor1 = (ConstructorDescriptor) state.getBindingContext().get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression().getConstructorReferenceExpression()); ConstructorDescriptor constructorDescriptor1 = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression().getConstructorReferenceExpression());
generateDelegatorToConstructorCall(iv, codegen, (JetDelegatorToSuperCall) superCall, constructorDescriptor1, frameMap); generateDelegatorToConstructorCall(iv, codegen, (JetDelegatorToSuperCall) superCall, constructorDescriptor1, frameMap);
} }
@@ -406,26 +412,26 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
iv.load(0, classType); iv.load(0, classType);
codegen.genToJVMStack(((JetDelegatorByExpressionSpecifier) specifier).getDelegateExpression()); codegen.genToJVMStack(((JetDelegatorByExpressionSpecifier) specifier).getDelegateExpression());
JetType superType = state.getBindingContext().get(BindingContext.TYPE, specifier.getTypeReference()); JetType superType = bindingContext.get(BindingContext.TYPE, specifier.getTypeReference());
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 = state.getTypeMapper().jetImplementationType(superClassDescriptor); Type fieldType = typeMapper.mapType(superClassDescriptor.getDefaultType(), OwnerKind.IMPLEMENTATION);
String fieldDesc = fieldType.getDescriptor(); String fieldDesc = fieldType.getDescriptor();
v.newField(specifier, Opcodes.ACC_PRIVATE, delegateField, fieldDesc, /*TODO*/null, null); v.newField(specifier, Opcodes.ACC_PRIVATE, delegateField, fieldDesc, /*TODO*/null, null);
iv.putfield(classname, delegateField, fieldDesc); iv.putfield(classname, delegateField, fieldDesc);
JetClass superClass = (JetClass) state.getBindingContext().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),
state.getTypeMapper().jvmNameForImplementation(superClassDescriptor, OwnerKind.IMPLEMENTATION))); typeMapper.mapType(superClassDescriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName()), state.getTypeMapper());
generateDelegates(superClass, delegateContext, overridden); generateDelegates(superClass, delegateContext, overridden);
} }
} }
final ClassDescriptor outerDescriptor = getOuterClassDescriptor(); final ClassDescriptor outerDescriptor = getOuterClassDescriptor();
if (outerDescriptor != null && outerDescriptor.getKind() != ClassKind.OBJECT) { if (outerDescriptor != null && outerDescriptor.getKind() != ClassKind.OBJECT) {
final Type type = state.getTypeMapper().jetImplementationType(outerDescriptor); final Type type = typeMapper.mapType(outerDescriptor.getDefaultType(), OwnerKind.IMPLEMENTATION);
String interfaceDesc = type.getDescriptor(); String interfaceDesc = type.getDescriptor();
final String fieldName = "this$0"; final String fieldName = "this$0";
v.newField(myClass, Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, fieldName, interfaceDesc, null, null); v.newField(myClass, Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, fieldName, interfaceDesc, null, null);
@@ -444,11 +450,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
for (DeclarationDescriptor varDescr : closure.keySet()) { for (DeclarationDescriptor varDescr : closure.keySet()) {
Type sharedVarType = context.closure.exprContext.getSharedVarType(varDescr); Type sharedVarType = context.closure.exprContext.getSharedVarType(varDescr);
if(sharedVarType == null) { if(sharedVarType == null) {
sharedVarType = state.getTypeMapper().mapType(((VariableDescriptor) varDescr).getOutType()); sharedVarType = typeMapper.mapType(((VariableDescriptor) varDescr).getOutType());
} }
iv.load(0, JetTypeMapper.TYPE_OBJECT); iv.load(0, JetTypeMapper.TYPE_OBJECT);
iv.load(firstClosureIndex + k, StackValue.refType(sharedVarType)); iv.load(firstClosureIndex + k, StackValue.refType(sharedVarType));
iv.putfield(state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION), "$" + (k+1), sharedVarType.getDescriptor()); iv.putfield(typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), "$" + (k+1), sharedVarType.getDescriptor());
} }
} }
@@ -457,7 +463,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 = state.getTypeMapper().mapType(descriptor.getOutType()); Type type = typeMapper.mapType(descriptor.getOutType());
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());
@@ -484,14 +490,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
DeclarationDescriptor containingDeclaration = fun.getContainingDeclaration(); DeclarationDescriptor containingDeclaration = fun.getContainingDeclaration();
if(containingDeclaration instanceof ClassDescriptor) { if(containingDeclaration instanceof ClassDescriptor) {
ClassDescriptor declaration = (ClassDescriptor) containingDeclaration; ClassDescriptor declaration = (ClassDescriptor) containingDeclaration;
PsiElement psiElement = state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, declaration); PsiElement psiElement = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, declaration);
if(psiElement instanceof JetClass) { if(psiElement instanceof JetClass) {
JetClass jetClass = (JetClass) psiElement; JetClass jetClass = (JetClass) psiElement;
if(jetClass.isTrait()) { if(jetClass.isTrait()) {
int flags = Opcodes.ACC_PUBLIC; // TODO. int flags = Opcodes.ACC_PUBLIC; // TODO.
Method function = state.getTypeMapper().mapSignature(fun.getName(), fun); Method function = typeMapper.mapSignature(fun.getName(), fun);
Method functionOriginal = state.getTypeMapper().mapSignature(fun.getName(), fun.getOriginal()); Method functionOriginal = typeMapper.mapSignature(fun.getName(), fun.getOriginal());
final MethodVisitor mv = v.newMethod(myClass, flags, function.getName(), function.getDescriptor(), null, null); final MethodVisitor mv = v.newMethod(myClass, flags, function.getName(), function.getDescriptor(), null, null);
if (v.generateCode()) { if (v.generateCode()) {
@@ -509,15 +515,15 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
reg += argType.getSize(); reg += argType.getSize();
} }
JetType jetType = TraitImplBodyCodegen.getSuperClass(declaration, state.getBindingContext()); JetType jetType = TraitImplBodyCodegen.getSuperClass(declaration, bindingContext);
Type type = state.getTypeMapper().mapType(jetType); Type type = typeMapper.mapType(jetType);
if(type.getInternalName().equals("java/lang/Object")) { if(type.getInternalName().equals("java/lang/Object")) {
jetType = declaration.getDefaultType(); jetType = declaration.getDefaultType();
type = state.getTypeMapper().mapType(jetType); type = typeMapper.mapType(jetType);
} }
String fdescriptor = functionOriginal.getDescriptor().replace("(","(" + type.getDescriptor()); String fdescriptor = functionOriginal.getDescriptor().replace("(","(" + type.getDescriptor());
iv.invokestatic(state.getTypeMapper().jvmName((ClassDescriptor) fun.getContainingDeclaration(), OwnerKind.TRAIT_IMPL), function.getName(), fdescriptor); iv.invokestatic(typeMapper.mapType(((ClassDescriptor) fun.getContainingDeclaration()).getDefaultType(), OwnerKind.TRAIT_IMPL).getInternalName(), function.getName(), fdescriptor);
if(function.getReturnType().getSort() == Type.OBJECT) { if(function.getReturnType().getSort() == Type.OBJECT) {
iv.checkcast(function.getReturnType()); iv.checkcast(function.getReturnType());
} }
@@ -548,15 +554,15 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
ConstructorFrameMap frameMap) { ConstructorFrameMap frameMap) {
ClassDescriptor classDecl = constructorDescriptor.getContainingDeclaration(); ClassDescriptor classDecl = constructorDescriptor.getContainingDeclaration();
Type type; Type type;
type = state.getTypeMapper().jetImplementationType(classDecl); type = typeMapper.mapType(classDecl.getDefaultType(), OwnerKind.IMPLEMENTATION);
iv.load(0, type); iv.load(0, type);
if (classDecl.getContainingDeclaration() instanceof ClassDescriptor) { if (classDecl.getContainingDeclaration() instanceof ClassDescriptor) {
iv.load(frameMap.getOuterThisIndex(), state.getTypeMapper().jvmType((ClassDescriptor) descriptor.getContainingDeclaration(), OwnerKind.IMPLEMENTATION)); iv.load(frameMap.getOuterThisIndex(), typeMapper.mapType(((ClassDescriptor) descriptor.getContainingDeclaration()).getDefaultType(), OwnerKind.IMPLEMENTATION));
} }
CallableMethod method = state.getTypeMapper().mapToCallableMethod(constructorDescriptor, kind); CallableMethod method = typeMapper.mapToCallableMethod(constructorDescriptor, kind);
codegen.invokeMethodWithArguments(method, constructorCall, StackValue.none()); codegen.invokeMethodWithArguments(method, constructorCall, StackValue.none());
} }
@@ -570,7 +576,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" + state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION) + ";"; final String desc = "L" + typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName() + ";";
v.newField(declaration, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL, name, desc, null, null); v.newField(declaration, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL, name, desc, null, null);
if (myEnumConstants.isEmpty()) { if (myEnumConstants.isEmpty()) {
staticInitializerChunks.add(new CodeChunk() { staticInitializerChunks.add(new CodeChunk() {
@@ -593,7 +599,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 = state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION); String implClass = typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName();
final List<JetDelegationSpecifier> delegationSpecifiers = enumConstant.getDelegationSpecifiers(); final List<JetDelegationSpecifier> delegationSpecifiers = enumConstant.getDelegationSpecifiers();
if (delegationSpecifiers.size() > 1) { if (delegationSpecifiers.size() > 1) {
@@ -607,8 +613,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
final JetDelegationSpecifier specifier = delegationSpecifiers.get(0); final JetDelegationSpecifier specifier = delegationSpecifiers.get(0);
if (specifier instanceof JetDelegatorToSuperCall) { if (specifier instanceof JetDelegatorToSuperCall) {
final JetDelegatorToSuperCall superCall = (JetDelegatorToSuperCall) specifier; final JetDelegatorToSuperCall superCall = (JetDelegatorToSuperCall) specifier;
ConstructorDescriptor constructorDescriptor = (ConstructorDescriptor) state.getBindingContext().get(BindingContext.REFERENCE_TARGET, superCall.getCalleeExpression().getConstructorReferenceExpression()); ConstructorDescriptor constructorDescriptor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, superCall.getCalleeExpression().getConstructorReferenceExpression());
CallableMethod method = state.getTypeMapper().mapToCallableMethod(constructorDescriptor, OwnerKind.IMPLEMENTATION); CallableMethod method = typeMapper.mapToCallableMethod(constructorDescriptor, OwnerKind.IMPLEMENTATION);
codegen.invokeMethodWithArguments(method, superCall, StackValue.none()); codegen.invokeMethodWithArguments(method, superCall, StackValue.none());
} }
else { else {
@@ -623,11 +629,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
} }
private void generateSecondaryConstructor(JetSecondaryConstructor constructor) { private void generateSecondaryConstructor(JetSecondaryConstructor constructor) {
ConstructorDescriptor constructorDescriptor = state.getBindingContext().get(BindingContext.CONSTRUCTOR, constructor); ConstructorDescriptor constructorDescriptor = bindingContext.get(BindingContext.CONSTRUCTOR, constructor);
if (constructorDescriptor == null) { if (constructorDescriptor == null) {
throw new UnsupportedOperationException("failed to get descriptor for secondary constructor"); throw new UnsupportedOperationException("failed to get descriptor for secondary constructor");
} }
CallableMethod method = state.getTypeMapper().mapToCallableMethod(constructorDescriptor, kind); CallableMethod method = typeMapper.mapToCallableMethod(constructorDescriptor, kind);
int flags = Opcodes.ACC_PUBLIC; // TODO int flags = Opcodes.ACC_PUBLIC; // TODO
final MethodVisitor mv = v.newMethod(constructor, flags, "<init>", method.getSignature().getDescriptor(), null, null); final MethodVisitor mv = v.newMethod(constructor, flags, "<init>", method.getSignature().getDescriptor(), null, null);
if (v.generateCode()) { if (v.generateCode()) {
@@ -641,7 +647,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
for (JetDelegationSpecifier initializer : constructor.getInitializers()) { for (JetDelegationSpecifier initializer : constructor.getInitializers()) {
if (initializer instanceof JetDelegatorToThisCall) { if (initializer instanceof JetDelegatorToThisCall) {
JetDelegatorToThisCall thisCall = (JetDelegatorToThisCall) initializer; JetDelegatorToThisCall thisCall = (JetDelegatorToThisCall) initializer;
DeclarationDescriptor thisDescriptor = state.getBindingContext().get(BindingContext.REFERENCE_TARGET, thisCall.getThisReference()); DeclarationDescriptor thisDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, thisCall.getThisReference());
if (!(thisDescriptor instanceof ConstructorDescriptor)) { if (!(thisDescriptor instanceof ConstructorDescriptor)) {
throw new UnsupportedOperationException("expected 'this' delegator to resolve to constructor"); throw new UnsupportedOperationException("expected 'this' delegator to resolve to constructor");
} }
@@ -666,7 +672,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
protected void generateTypeInfoInitializer(int firstTypeParameter, int typeParamCount, InstructionAdapter iv) { protected void generateTypeInfoInitializer(int firstTypeParameter, int typeParamCount, InstructionAdapter iv) {
iv.load(0, JetTypeMapper.TYPE_OBJECT); iv.load(0, JetTypeMapper.TYPE_OBJECT);
iv.aconst(state.getTypeMapper().jvmType(descriptor, OwnerKind.IMPLEMENTATION)); iv.aconst(typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION));
iv.iconst(0); iv.iconst(0);
if(CodegenUtil.hasOuterTypeInfo(descriptor)) { if(CodegenUtil.hasOuterTypeInfo(descriptor)) {
@@ -700,21 +706,21 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
iv.invokestatic("jet/typeinfo/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;Z)Ljet/typeinfo/TypeInfo;"); iv.invokestatic("jet/typeinfo/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;Z)Ljet/typeinfo/TypeInfo;");
} }
iv.invokevirtual(state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION), "$setTypeInfo", "(Ljet/typeinfo/TypeInfo;)V"); iv.invokevirtual(typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), "$setTypeInfo", "(Ljet/typeinfo/TypeInfo;)V");
} }
protected void generateInitializers(ExpressionCodegen codegen, InstructionAdapter iv) { protected void generateInitializers(ExpressionCodegen codegen, InstructionAdapter iv) {
for (JetDeclaration declaration : myClass.getDeclarations()) { for (JetDeclaration declaration : myClass.getDeclarations()) {
if (declaration instanceof JetProperty) { if (declaration instanceof JetProperty) {
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, declaration); final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) bindingContext.get(BindingContext.VARIABLE, declaration);
if (state.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) { if (bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) {
final JetExpression initializer = ((JetProperty) declaration).getInitializer(); final JetExpression initializer = ((JetProperty) declaration).getInitializer();
if (initializer != null) { if (initializer != null) {
CompileTimeConstant<?> compileTimeValue = state.getBindingContext().get(BindingContext.COMPILE_TIME_VALUE, initializer); CompileTimeConstant<?> compileTimeValue = bindingContext.get(BindingContext.COMPILE_TIME_VALUE, initializer);
if(compileTimeValue != null) { if(compileTimeValue != null) {
assert compileTimeValue != null; assert compileTimeValue != null;
Object value = compileTimeValue.getValue(); Object value = compileTimeValue.getValue();
Type type = state.getTypeMapper().mapType(propertyDescriptor.getOutType()); Type type = typeMapper.mapType(propertyDescriptor.getOutType());
if(JetTypeMapper.isPrimitive(type)) { if(JetTypeMapper.isPrimitive(type)) {
if( !propertyDescriptor.getOutType().isNullable() && value instanceof Number) { if( !propertyDescriptor.getOutType().isNullable() && value instanceof Number) {
if(type == Type.INT_TYPE && ((Number)value).intValue() == 0) if(type == Type.INT_TYPE && ((Number)value).intValue() == 0)
@@ -765,7 +771,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
propertyCodegen.gen((JetProperty) declaration); propertyCodegen.gen((JetProperty) declaration);
} }
else if (declaration instanceof JetNamedFunction) { else if (declaration instanceof JetNamedFunction) {
if (!overriden.contains(state.getBindingContext().get(BindingContext.FUNCTION, declaration))) { if (!overriden.contains(bindingContext.get(BindingContext.FUNCTION, declaration))) {
functionCodegen.gen((JetNamedFunction) declaration); functionCodegen.gen((JetNamedFunction) declaration);
} }
} }
@@ -773,7 +779,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
for (JetParameter p : toClass.getPrimaryConstructorParameters()) { for (JetParameter p : toClass.getPrimaryConstructorParameters()) {
if (p.getValOrVarNode() != null) { if (p.getValOrVarNode() != null) {
PropertyDescriptor propertyDescriptor = state.getBindingContext().get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, p); PropertyDescriptor propertyDescriptor = bindingContext.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, p);
if (propertyDescriptor != null) { if (propertyDescriptor != null) {
propertyCodegen.generateDefaultGetter(propertyDescriptor, Opcodes.ACC_PUBLIC, p); propertyCodegen.generateDefaultGetter(propertyDescriptor, Opcodes.ACC_PUBLIC, p);
if (propertyDescriptor.isVar()) { if (propertyDescriptor.isVar()) {
@@ -808,7 +814,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
InstructionAdapter iv = null; InstructionAdapter iv = null;
if (v.generateCode()) { if (v.generateCode()) {
iv = new InstructionAdapter(mv); iv = new InstructionAdapter(mv);
String owner = state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION); String owner = typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName();
iv.load(0, JetTypeMapper.TYPE_OBJECT); iv.load(0, JetTypeMapper.TYPE_OBJECT);
iv.getfield(owner, "$typeInfo", "Ljet/typeinfo/TypeInfo;"); iv.getfield(owner, "$typeInfo", "Ljet/typeinfo/TypeInfo;");
iv.areturn(JetTypeMapper.TYPE_TYPEINFO); iv.areturn(JetTypeMapper.TYPE_TYPEINFO);
@@ -820,7 +826,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
if (v.generateCode()) { if (v.generateCode()) {
mv.visitCode(); mv.visitCode();
iv = new InstructionAdapter(mv); iv = new InstructionAdapter(mv);
String owner = state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION); String owner = typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName();
iv.load(0, JetTypeMapper.TYPE_OBJECT); iv.load(0, JetTypeMapper.TYPE_OBJECT);
iv.load(1, JetTypeMapper.TYPE_OBJECT); iv.load(1, JetTypeMapper.TYPE_OBJECT);
iv.putfield(owner, "$typeInfo", "Ljet/typeinfo/TypeInfo;"); iv.putfield(owner, "$typeInfo", "Ljet/typeinfo/TypeInfo;");
@@ -841,7 +847,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
if (v.generateCode()) { if (v.generateCode()) {
mv.visitCode(); mv.visitCode();
InstructionAdapter v = new InstructionAdapter(mv); InstructionAdapter v = new InstructionAdapter(mv);
String owner = state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION); String owner = typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName();
v.getstatic(owner, "$staticTypeInfo", "Ljet/typeinfo/TypeInfo;"); v.getstatic(owner, "$staticTypeInfo", "Ljet/typeinfo/TypeInfo;");
v.areturn(JetTypeMapper.TYPE_TYPEINFO); v.areturn(JetTypeMapper.TYPE_TYPEINFO);
mv.visitMaxs(0, 0); mv.visitMaxs(0, 0);
@@ -854,18 +860,17 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
staticInitializerChunks.add(new CodeChunk() { staticInitializerChunks.add(new CodeChunk() {
@Override @Override
public void generate(InstructionAdapter v) { public void generate(InstructionAdapter v) {
JetTypeMapper typeMapper = state.getTypeMapper(); v.aconst(typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION));
v.aconst(typeMapper.jvmType(descriptor, OwnerKind.IMPLEMENTATION));
v.iconst(0); v.iconst(0);
ClassDescriptor outerClassDescriptor = CodegenUtil.getOuterClassDescriptor(descriptor); ClassDescriptor outerClassDescriptor = CodegenUtil.getOuterClassDescriptor(descriptor);
if(outerClassDescriptor == null) { if(outerClassDescriptor == null) {
v.invokestatic("jet/typeinfo/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;Z)Ljet/typeinfo/TypeInfo;"); v.invokestatic("jet/typeinfo/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;Z)Ljet/typeinfo/TypeInfo;");
} }
else { else {
v.getstatic(state.getTypeMapper().jvmName(outerClassDescriptor, OwnerKind.IMPLEMENTATION), "$staticTypeInfo", "Ljet/typeinfo/TypeInfo;"); v.getstatic(typeMapper.mapType(outerClassDescriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(), "$staticTypeInfo", "Ljet/typeinfo/TypeInfo;");
v.invokestatic("jet/typeinfo/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;ZLjet/typeinfo/TypeInfo;)Ljet/typeinfo/TypeInfo;"); v.invokestatic("jet/typeinfo/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;ZLjet/typeinfo/TypeInfo;)Ljet/typeinfo/TypeInfo;");
} }
v.putstatic(typeMapper.jvmName(descriptor, kind), "$staticTypeInfo", "Ljet/typeinfo/TypeInfo;"); v.putstatic(typeMapper.mapType(descriptor.getDefaultType(), kind).getInternalName(), "$staticTypeInfo", "Ljet/typeinfo/TypeInfo;");
} }
}); });
} }
@@ -1,6 +1,5 @@
package org.jetbrains.jet.codegen; package org.jetbrains.jet.codegen;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiTreeUtil;
import jet.JetObject; import jet.JetObject;
import jet.typeinfo.TypeInfo; import jet.typeinfo.TypeInfo;
@@ -9,6 +8,8 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver;
import org.jetbrains.jet.lang.resolve.java.JavaNamespaceDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.lexer.JetTokens;
@@ -120,73 +121,11 @@ public class JetTypeMapper {
return type; return type;
} }
public String jvmName(ClassDescriptor jetClass, OwnerKind kind) {
PsiElement declaration = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, jetClass);
if (declaration instanceof JetObjectDeclaration && ((JetObjectDeclaration) declaration).isObjectLiteral()) {
final PsiElement parent = declaration.getParent();
if (parent instanceof JetClassObject) {
JetClass containingClass = PsiTreeUtil.getParentOfType(parent, JetClass.class);
final ClassDescriptor containingClassDescriptor = bindingContext.get(BindingContext.CLASS, containingClass);
return jvmName(containingClassDescriptor, OwnerKind.IMPLEMENTATION) + "$$ClassObj";
}
@SuppressWarnings("SuspiciousMethodCalls") String className = classNamesForAnonymousClasses.get(declaration);
if (className == null) {
throw new UnsupportedOperationException("Unexpected forward reference to anonymous class " + declaration);
}
return className;
}
return jetJvmName(jetClass, kind);
}
public String jvmName(JetClassObject classObject) {
final ClassDescriptor descriptor = bindingContext.get(BindingContext.CLASS, classObject.getObjectDeclaration());
return jvmName(descriptor, OwnerKind.IMPLEMENTATION);
}
private String jetJvmName(ClassDescriptor jetClass, OwnerKind kind) {
if (jetClass.getKind() == ClassKind.OBJECT) {
return jvmNameForImplementation(jetClass, OwnerKind.IMPLEMENTATION);
}
else if (kind == OwnerKind.IMPLEMENTATION) {
return jvmNameForImplementation(jetClass, OwnerKind.IMPLEMENTATION);
}
else if (kind == OwnerKind.TRAIT_IMPL) {
return jvmNameForImplementation(jetClass, OwnerKind.IMPLEMENTATION) + "$$TImpl";
}
else {
assert false : "Unsuitable kind";
return "java/lang/Object";
}
}
public Type jvmType(ClassDescriptor jetClass, OwnerKind kind) {
if (jetClass == standardLibrary.getString()) {
return Type.getType(String.class);
}
return Type.getType("L" + jvmName(jetClass, kind) + ";");
}
Type jetImplementationType(ClassDescriptor classDescriptor) {
return Type.getType("L" + jvmNameForImplementation(classDescriptor, OwnerKind.IMPLEMENTATION) + ";");
}
public static String jvmName(JetNamespace namespace) {
return NamespaceCodegen.getJVMClassName(CodegenUtil.getFQName(namespace));
}
static String jvmName(NamespaceDescriptor namespace) {
return NamespaceCodegen.getJVMClassName(DescriptorRenderer.getFQName(namespace));
}
public String jvmNameForImplementation(ClassDescriptor descriptor, OwnerKind kind) {
return mapType(descriptor.getDefaultType(), kind).getInternalName();
}
public String getOwner(DeclarationDescriptor descriptor, OwnerKind kind) { public String getOwner(DeclarationDescriptor descriptor, OwnerKind kind) {
String owner; String owner;
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
if (containingDeclaration instanceof NamespaceDescriptor) { if (containingDeclaration instanceof NamespaceDescriptor) {
owner = jvmName((NamespaceDescriptor) containingDeclaration); owner = NamespaceCodegen.getJVMClassName(DescriptorRenderer.getFQName((NamespaceDescriptor) containingDeclaration));
} }
else if (containingDeclaration instanceof ClassDescriptor) { else if (containingDeclaration instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration; ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
@@ -198,7 +137,7 @@ public class JetTypeMapper {
kind = OwnerKind.IMPLEMENTATION; kind = OwnerKind.IMPLEMENTATION;
} }
} }
owner = jvmName(classDescriptor, kind); owner = mapType(classDescriptor.getDefaultType(), kind).getInternalName();
} }
else { else {
throw new UnsupportedOperationException("don't know how to generate owner for parent " + containingDeclaration); throw new UnsupportedOperationException("don't know how to generate owner for parent " + containingDeclaration);
@@ -216,6 +155,43 @@ public class JetTypeMapper {
return mapType(jetType, OwnerKind.IMPLEMENTATION); return mapType(jetType, OwnerKind.IMPLEMENTATION);
} }
private HashMap<DeclarationDescriptor,Map<DeclarationDescriptor,String>> naming = new HashMap<DeclarationDescriptor, Map<DeclarationDescriptor, String>>();
public String getFQName(DeclarationDescriptor descriptor) {
descriptor = descriptor.getOriginal();
DeclarationDescriptor container = descriptor.getContainingDeclaration();
String name = descriptor.getName();
if(JetPsiUtil.NO_NAME_PROVIDED.equals(name)) {
// create and store name
Map<DeclarationDescriptor, String> map = naming.get(container);
if(map == null) {
map = new HashMap<DeclarationDescriptor, String>();
naming.put(container, map);
}
name = map.get(descriptor);
if(name == null) {
name = getFQName(container) + "$" + (map.size()+1);
map.put(descriptor, name);
}
return name;
}
if (container != null) {
if (container instanceof ModuleDescriptor) {
return name;
}
if(container instanceof JavaNamespaceDescriptor && JavaDescriptorResolver.JAVA_ROOT.equals(container.getName())) {
return name;
}
String baseName = getFQName(container);
if (!baseName.isEmpty()) {
return baseName + (container instanceof JavaNamespaceDescriptor || container instanceof NamespaceDescriptor ? "/" : "$") + name;
}
}
return name;
}
@NotNull public Type mapType(final JetType jetType) { @NotNull public Type mapType(final JetType jetType) {
return mapType(jetType, OwnerKind.IMPLEMENTATION); return mapType(jetType, OwnerKind.IMPLEMENTATION);
} }
@@ -236,14 +212,13 @@ public class JetTypeMapper {
else else
return ARRAY_GENERIC_TYPE; return ARRAY_GENERIC_TYPE;
} }
if (JetStandardClasses.getAny().equals(descriptor)) { if (JetStandardClasses.getAny().equals(descriptor)) {
return Type.getType(Object.class); return TYPE_OBJECT;
} }
if (descriptor instanceof ClassDescriptor) { if (descriptor instanceof ClassDescriptor) {
String name = DescriptorRenderer.getFQName(descriptor).replace('.', '/'); String name = getFQName(descriptor);
if(name.startsWith("<java_root>"))
name = name.substring("<java_root>".length()+1);
return Type.getObjectType(name + (kind == OwnerKind.TRAIT_IMPL ? "$$TImpl" : "")); return Type.getObjectType(name + (kind == OwnerKind.TRAIT_IMPL ? "$$TImpl" : ""));
} }
@@ -327,14 +302,15 @@ 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 = jvmName(containingClass, OwnerKind.IMPLEMENTATION); owner = mapType(containingClass.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName();
invokeOpcode = INVOKESPECIAL; invokeOpcode = INVOKESPECIAL;
thisClass = null; thisClass = null;
} }
else if (functionParent instanceof ClassDescriptor) { else if (functionParent instanceof ClassDescriptor) {
ClassDescriptor containingClass = (ClassDescriptor) functionParent; ClassDescriptor containingClass = (ClassDescriptor) functionParent;
boolean isInterface = CodegenUtil.isInterface(containingClass); boolean isInterface = CodegenUtil.isInterface(containingClass);
owner = jvmName(containingClass, isInterface && superCall ? OwnerKind.TRAIT_IMPL : OwnerKind.IMPLEMENTATION); OwnerKind kind1 = isInterface && superCall ? OwnerKind.TRAIT_IMPL : OwnerKind.IMPLEMENTATION;
owner = mapType(containingClass.getDefaultType(), kind1).getInternalName();
invokeOpcode = isInterface invokeOpcode = isInterface
? (superCall ? Opcodes.INVOKESTATIC : Opcodes.INVOKEINTERFACE) ? (superCall ? Opcodes.INVOKESTATIC : Opcodes.INVOKEINTERFACE)
: (superCall ? Opcodes.INVOKESPECIAL : Opcodes.INVOKEVIRTUAL); : (superCall ? Opcodes.INVOKESPECIAL : Opcodes.INVOKEVIRTUAL);
@@ -375,16 +351,16 @@ public class JetTypeMapper {
valueParameterTypes.add(type); valueParameterTypes.add(type);
parameterTypes.add(type); parameterTypes.add(type);
} }
for (ValueParameterDescriptor parameter : parameters) {
Type type = mapType(parameter.getOutType());
valueParameterTypes.add(type);
parameterTypes.add(type);
}
for (TypeParameterDescriptor parameterDescriptor : f.getTypeParameters()) { for (TypeParameterDescriptor parameterDescriptor : f.getTypeParameters()) {
if(parameterDescriptor.isReified()) { if(parameterDescriptor.isReified()) {
parameterTypes.add(TYPE_TYPEINFO); parameterTypes.add(TYPE_TYPEINFO);
} }
} }
for (ValueParameterDescriptor parameter : parameters) {
Type type = mapType(parameter.getOutType());
valueParameterTypes.add(type);
parameterTypes.add(type);
}
Type returnType = f instanceof ConstructorDescriptor ? Type.VOID_TYPE : mapReturnType(f.getReturnType()); Type returnType = f instanceof ConstructorDescriptor ? Type.VOID_TYPE : mapReturnType(f.getReturnType());
return new Method(f.getName(), returnType, parameterTypes.toArray(new Type[parameterTypes.size()])); return new Method(f.getName(), returnType, parameterTypes.toArray(new Type[parameterTypes.size()]));
} }
@@ -435,29 +411,53 @@ public class JetTypeMapper {
public Method mapGetterSignature(PropertyDescriptor descriptor, OwnerKind kind) { public Method mapGetterSignature(PropertyDescriptor descriptor, OwnerKind kind) {
Type returnType = mapType(descriptor.getOutType()); Type returnType = mapType(descriptor.getOutType());
if(kind != OwnerKind.TRAIT_IMPL) String name = PropertyCodegen.getterName(descriptor.getName());
return new Method(PropertyCodegen.getterName(descriptor.getName()), returnType, new Type[0]); ArrayList<Type> params = new ArrayList<Type>();
else { if(kind == OwnerKind.TRAIT_IMPL) {
ClassDescriptor containingDeclaration = (ClassDescriptor) descriptor.getContainingDeclaration(); ClassDescriptor containingDeclaration = (ClassDescriptor) descriptor.getContainingDeclaration();
assert containingDeclaration != null; assert containingDeclaration != null;
return new Method(PropertyCodegen.getterName(descriptor.getName()), returnType, new Type[] { mapType(containingDeclaration.getDefaultType()) }); params.add(mapType(containingDeclaration.getDefaultType()));
} }
if(descriptor.getReceiverParameter().exists()) {
params.add(mapType(descriptor.getReceiverParameter().getType()));
}
for (TypeParameterDescriptor typeParameterDescriptor : descriptor.getTypeParameters()) {
if(typeParameterDescriptor.isReified()) {
params.add(TYPE_TYPEINFO);
}
}
return new Method(name, returnType, params.toArray(new Type[params.size()]));
} }
public Method mapSetterSignature(PropertyDescriptor descriptor, OwnerKind kind) { public Method mapSetterSignature(PropertyDescriptor descriptor, OwnerKind kind) {
final JetType inType = descriptor.getInType(); JetType inType = descriptor.getInType();
if (inType == null) { if(inType == null)
return null; return null;
}
Type paramType = mapType(inType); String name = PropertyCodegen.setterName(descriptor.getName());
if(kind != OwnerKind.TRAIT_IMPL) { ArrayList<Type> params = new ArrayList<Type>();
return new Method(PropertyCodegen.setterName(descriptor.getName()), Type.VOID_TYPE, new Type[] { paramType }); if(kind == OwnerKind.TRAIT_IMPL) {
}
else {
ClassDescriptor containingDeclaration = (ClassDescriptor) descriptor.getContainingDeclaration(); ClassDescriptor containingDeclaration = (ClassDescriptor) descriptor.getContainingDeclaration();
assert containingDeclaration != null; assert containingDeclaration != null;
return new Method(PropertyCodegen.setterName(descriptor.getName()), Type.VOID_TYPE, new Type[] { mapType(containingDeclaration.getDefaultType()), paramType }); params.add(mapType(containingDeclaration.getDefaultType()));
} }
if(descriptor.getReceiverParameter().exists()) {
params.add(mapType(descriptor.getReceiverParameter().getType()));
}
for (TypeParameterDescriptor typeParameterDescriptor : descriptor.getTypeParameters()) {
if(typeParameterDescriptor.isReified()) {
params.add(TYPE_TYPEINFO);
}
}
params.add(mapType(inType));
return new Method(name, Type.VOID_TYPE, params.toArray(new Type[params.size()]));
} }
private Method mapConstructorSignature(ConstructorDescriptor descriptor, List<Type> valueParameterTypes) { private Method mapConstructorSignature(ConstructorDescriptor descriptor, List<Type> valueParameterTypes) {
@@ -465,29 +465,28 @@ public class JetTypeMapper {
List<Type> parameterTypes = new ArrayList<Type>(); List<Type> parameterTypes = new ArrayList<Type>();
ClassDescriptor classDescriptor = descriptor.getContainingDeclaration(); ClassDescriptor classDescriptor = descriptor.getContainingDeclaration();
if (CodegenUtil.hasThis0(classDescriptor)) { if (CodegenUtil.hasThis0(classDescriptor)) {
parameterTypes.add(jvmType(CodegenUtil.getOuterClassDescriptor(classDescriptor), OwnerKind.IMPLEMENTATION)); parameterTypes.add(mapType(CodegenUtil.getOuterClassDescriptor(classDescriptor).getDefaultType(), OwnerKind.IMPLEMENTATION));
} }
List<TypeParameterDescriptor> typeParameters = classDescriptor.getTypeConstructor().getParameters();
for (TypeParameterDescriptor typeParameter : typeParameters) {
if(typeParameter.isReified())
parameterTypes.add(TYPE_TYPEINFO);
}
for (ValueParameterDescriptor parameter : parameters) { for (ValueParameterDescriptor parameter : parameters) {
final Type type = mapType(parameter.getOutType()); final Type type = mapType(parameter.getOutType());
parameterTypes.add(type); parameterTypes.add(type);
valueParameterTypes.add(type); valueParameterTypes.add(type);
} }
PsiElement psiElement = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, classDescriptor);
if(!(psiElement instanceof PsiClass)) {
List<TypeParameterDescriptor> typeParameters = classDescriptor.getTypeConstructor().getParameters();
for (int n = typeParameters.size(); n > 0; n--) {
parameterTypes.add(TYPE_TYPEINFO);
}
}
return new Method("<init>", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()])); return new Method("<init>", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()]));
} }
public CallableMethod mapToCallableMethod(ConstructorDescriptor descriptor, OwnerKind kind) { public CallableMethod mapToCallableMethod(ConstructorDescriptor descriptor, OwnerKind kind) {
List<Type> valueParameterTypes = new ArrayList<Type>(); List<Type> valueParameterTypes = new ArrayList<Type>();
final Method method = mapConstructorSignature(descriptor, valueParameterTypes); final Method method = mapConstructorSignature(descriptor, valueParameterTypes);
String owner = jvmName(descriptor.getContainingDeclaration(), kind); String owner = mapType(descriptor.getContainingDeclaration().getDefaultType(), kind).getInternalName();
return new CallableMethod(owner, method, INVOKESPECIAL, valueParameterTypes); return new CallableMethod(owner, method, INVOKESPECIAL, valueParameterTypes);
} }
@@ -506,6 +505,15 @@ public class JetTypeMapper {
} }
String classNameForAnonymousClass(JetExpression expression) { String classNameForAnonymousClass(JetExpression expression) {
if(expression instanceof JetObjectLiteralExpression) {
JetObjectLiteralExpression jetObjectLiteralExpression = (JetObjectLiteralExpression) expression;
expression = jetObjectLiteralExpression.getObjectDeclaration();
}
if(expression instanceof JetObjectDeclaration) {
DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, expression);
return getFQName(declarationDescriptor);
}
String name = classNamesForAnonymousClasses.get(expression); String name = classNamesForAnonymousClasses.get(expression);
if (name != null) { if (name != null) {
return name; return name;
@@ -519,7 +527,7 @@ public class JetTypeMapper {
} }
else { else {
ClassDescriptor aClass = bindingContext.get(BindingContext.CLASS, container); ClassDescriptor aClass = bindingContext.get(BindingContext.CLASS, container);
baseName = jvmNameForImplementation(aClass, OwnerKind.IMPLEMENTATION); baseName = mapType(aClass.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName();
} }
Integer count = anonymousSubclassesCount.get(baseName); Integer count = anonymousSubclassesCount.get(baseName);
@@ -536,7 +544,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(jvmName(classDescriptor, OwnerKind.IMPLEMENTATION)); result.add(mapType(classDescriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName());
} }
return result; return result;
} }
@@ -93,6 +93,10 @@ public class NamespaceCodegen {
final JetExpression initializer = ((JetProperty) declaration).getInitializer(); final JetExpression initializer = ((JetProperty) declaration).getInitializer();
if (initializer != null && !(initializer instanceof JetConstantExpression)) { if (initializer != null && !(initializer instanceof JetConstantExpression)) {
final PropertyDescriptor descriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, declaration); final PropertyDescriptor descriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, declaration);
assert descriptor != null;
if(descriptor.getReceiverParameter().exists()) {
continue;
}
codegen.genToJVMStack(initializer); codegen.genToJVMStack(initializer);
codegen.intermediateValueForProperty(descriptor, true, null).store(new InstructionAdapter(mv)); codegen.intermediateValueForProperty(descriptor, true, null).store(new InstructionAdapter(mv));
} }
@@ -1,11 +1,9 @@
package org.jetbrains.jet.codegen; package org.jetbrains.jet.codegen;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
import java.util.Collections;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
@@ -63,9 +61,9 @@ public class ObjectOrClosureCodegen {
FunctionDescriptor fd = (FunctionDescriptor) d; FunctionDescriptor fd = (FunctionDescriptor) d;
// we generate method // we generate method
assert context instanceof CodegenContext.FunctionContext; assert context instanceof CodegenContext.ReceiverContext;
CodegenContext.FunctionContext fcontext = (CodegenContext.FunctionContext) context; CodegenContext.ReceiverContext fcontext = (CodegenContext.ReceiverContext) context;
if(fcontext.getReceiverDescriptor() != fd) if(fcontext.getReceiverDescriptor() != fd)
return null; return null;
@@ -196,7 +196,11 @@ public abstract class StackValue {
v.checkcast(type); v.checkcast(type);
} }
else if (type.getSort() == Type.OBJECT) { else if (type.getSort() == Type.OBJECT) {
box(this.type, type, v); if(this.type.getSort() == Type.OBJECT && !type.equals(JetTypeMapper.TYPE_OBJECT)) {
v.checkcast(type);
}
else
box(this.type, type, v);
} }
else if (this.type.getSort() == Type.OBJECT && type.getSort() <= Type.DOUBLE) { else if (this.type.getSort() == Type.OBJECT && type.getSort() <= Type.DOUBLE) {
if (this.type.equals(JetTypeMapper.TYPE_OBJECT)) { if (this.type.equals(JetTypeMapper.TYPE_OBJECT)) {
@@ -56,6 +56,6 @@ public class TraitImplBodyCodegen extends ClassBodyCodegen {
} }
private String jvmName() { private String jvmName() {
return state.getTypeMapper().jvmName(descriptor, OwnerKind.TRAIT_IMPL); return state.getTypeMapper().mapType(descriptor.getDefaultType(), OwnerKind.TRAIT_IMPL).getInternalName();
} }
} }
@@ -34,6 +34,7 @@ public class IntrinsicMethods {
private static final List<String> PRIMITIVE_NUMBER_TYPES = ImmutableList.of("Boolean", "Byte", "Char", "Short", "Int", "Float", "Long", "Double"); private static final List<String> PRIMITIVE_NUMBER_TYPES = ImmutableList.of("Boolean", "Byte", "Char", "Short", "Int", "Float", "Long", "Double");
public static final IntrinsicMethod ARRAY_SIZE = new ArraySize(); public static final IntrinsicMethod ARRAY_SIZE = new ArraySize();
public static final IntrinsicMethod ARRAY_INDICES = new ArrayIndices(); public static final IntrinsicMethod ARRAY_INDICES = new ArrayIndices();
public static final Equals EQUALS = new Equals();
private final Project myProject; private final Project myProject;
private final JetStandardLibrary myStdLib; private final JetStandardLibrary myStdLib;
@@ -77,7 +78,8 @@ public class IntrinsicMethods {
declareIntrinsicFunction("String", "plus", 1, new Concat()); declareIntrinsicFunction("String", "plus", 1, new Concat());
declareOverload(myStdLib.getLibraryScope().getFunctions("toString"), 0, new ToString()); declareOverload(myStdLib.getLibraryScope().getFunctions("toString"), 0, new ToString());
declareOverload(myStdLib.getLibraryScope().getFunctions("equals"), 1, new Equals()); declareOverload(myStdLib.getLibraryScope().getFunctions("equals"), 1, EQUALS);
declareOverload(myStdLib.getLibraryScope().getFunctions("identityEquals"), 1, EQUALS);
declareOverload(myStdLib.getLibraryScope().getFunctions("plus"), 1, new StringPlus()); declareOverload(myStdLib.getLibraryScope().getFunctions("plus"), 1, new StringPlus());
// declareIntrinsicFunction("Any", "equals", 1, new Equals()); // declareIntrinsicFunction("Any", "equals", 1, new Equals());
+2
View File
@@ -34,6 +34,8 @@ namespace io {
fun readLine() : String? fun readLine() : String?
} }
fun Any?.identityEquals(other : Any?) // = this === other
// Can't write a body due to a bootstrapping problem (see JET-74) // Can't write a body due to a bootstrapping problem (see JET-74)
fun Any?.equals(other : Any?) : Boolean// = this === other fun Any?.equals(other : Any?) : Boolean// = this === other
@@ -13,6 +13,9 @@ import java.util.Set;
* @author abreslav * @author abreslav
*/ */
public class JetPsiUtil { public class JetPsiUtil {
public static final String NO_NAME_PROVIDED = "<no name provided>";
@Nullable @Nullable
public static JetExpression deparenthesize(@NotNull JetExpression expression) { public static JetExpression deparenthesize(@NotNull JetExpression expression) {
if (expression instanceof JetBinaryExpressionWithTypeRHS) { if (expression instanceof JetBinaryExpressionWithTypeRHS) {
@@ -38,7 +41,7 @@ public class JetPsiUtil {
@NotNull @NotNull
public static String safeName(String name) { public static String safeName(String name) {
return name == null ? "<no name provided>" : name; return name == null ? NO_NAME_PROVIDED : name;
} }
@NotNull @NotNull
@@ -1,7 +1,6 @@
namespace x namespace x
class Outer() { class Outer() {
class object { class object {
class Inner() { class Inner() {
} }
+14 -14
View File
@@ -176,21 +176,21 @@ fun t12(x: Int) : Int {
fun box(): String { fun box(): String {
/* /*
if (!s0()) return "fail" if (!s0()) return "s0 fail"
if (!s1()) return "fail" if (!s1()) return "s1 fail"
if (!t1()) return "fail" if (!t1()) return "t1 fail"
if (!t2()) return "fail" if (!t2()) return "t2 fail"
if (!t3()) return "fail" if (!t3()) return "t3 fail"
if (!t4()) return "fail" if (!t4()) return "t4 fail"
if (!t5()) return "fail" if (!t5()) return "t5 fail"
if (!t6()) return "fail" if (!t6()) return "t6 fail"
if (!t7()) return "fail" if (!t7()) return "t7 fail"
if (!t8()) return "fail" if (!t8()) return "t8 fail"
if (!t9(0)) return "fail" if (!t9(0)) return "t9 fail"
if (!t10()) return "fail" if (!t10()) return "t10 fail"
if (t11(1) != 104) return "fail" if (t11(1) != 104) return "t11 fail"
*/ */
if (t12(0) != 100) return "fail" if (t12(0) != 100) return "t12 fail"
return "OK" return "OK"
} }
@@ -1,14 +1,18 @@
import java.math.BigDecimal import java.util.ArrayList
fun box() : String { fun box() : String {
// Easy to make BigDecimals user-friendly val array = ArrayList<String>()
System.out?.println( array.add("0")
"2.00".bd - "1.00" array.add("1")
) array.add("2")
return "OK" array.last = "5"
return if(array.length == 3 && array.last == "5") "OK" else "fail"
} }
val String.bd = BigDecimal(this) var <T> ArrayList<T>.length : Int
get() = size()
set(value: Int) = throw java.lang.Error()
fun BigDecimal.minus(other : BigDecimal) = this.subtract(other) var <T> ArrayList<T>.last : T
fun BigDecimal.minus(other : String) = subtract(other.bd) // this can be omitted get() = get(size()-1)
set(el : T) { set(size()-1, el) }
@@ -1,4 +1,5 @@
import java.util.ArrayList import java.util.ArrayList
trait Tr { trait Tr {
fun extra() : String = "_" fun extra() : String = "_"
} }
@@ -34,6 +34,6 @@ public class ExtensionFunctionsTest extends CodegenTestCase {
} }
public void testKt475() throws Exception { public void testKt475() throws Exception {
// blackBoxFile("regressions/kt475.jet"); blackBoxFile("regressions/kt475.jet");
} }
} }
@@ -501,7 +501,7 @@ public class NamespaceGenTest extends CodegenTestCase {
loadText("fun <E,D> E.foo(extra: java.util.List<D>) = (1, \"foo\", this, extra)"); loadText("fun <E,D> E.foo(extra: java.util.List<D>) = (1, \"foo\", this, extra)");
System.out.println(generateToText()); System.out.println(generateToText());
final Method main = generateFunction(); final Method main = generateFunction();
Tuple4 tuple4 = (Tuple4) main.invoke(null, "aaa", Arrays.asList(10), TypeInfo.STRING_TYPE_INFO, TypeInfo.INT_TYPE_INFO); Tuple4 tuple4 = (Tuple4) main.invoke(null, "aaa", TypeInfo.STRING_TYPE_INFO, TypeInfo.INT_TYPE_INFO, Arrays.asList(10));
assertEquals(1, tuple4._1); assertEquals(1, tuple4._1);
assertEquals("foo", tuple4._2); assertEquals("foo", tuple4._2);
assertEquals("aaa", tuple4._3); assertEquals("aaa", tuple4._3);
@@ -17,8 +17,10 @@ import com.sun.jdi.ReferenceType;
import com.sun.jdi.request.ClassPrepareRequest; import com.sun.jdi.request.ClassPrepareRequest;
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.CodegenUtil;
import org.jetbrains.jet.codegen.GenerationState; import org.jetbrains.jet.codegen.GenerationState;
import org.jetbrains.jet.codegen.JetTypeMapper; import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.NamespaceCodegen;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.types.JetStandardLibrary; import org.jetbrains.jet.lang.types.JetStandardLibrary;
@@ -111,10 +113,10 @@ public class JetPositionManager implements PositionManager {
else { else {
JetNamespace namespace = PsiTreeUtil.getParentOfType(sourcePosition.getElementAt(), JetNamespace.class); JetNamespace namespace = PsiTreeUtil.getParentOfType(sourcePosition.getElementAt(), JetNamespace.class);
if (namespace != null) { if (namespace != null) {
names.add(JetTypeMapper.jvmName(namespace)); names.add(NamespaceCodegen.getJVMClassName(CodegenUtil.getFQName(namespace)));
} }
else { else {
names.add(JetTypeMapper.jvmName(file.getRootNamespace())); names.add(NamespaceCodegen.getJVMClassName(CodegenUtil.getFQName(file.getRootNamespace())));
} }
} }
return names; return names;