backend refactoring from extension properties and proper naming scheme of inner classes and objects
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
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.DeclarationDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||
@@ -22,7 +23,7 @@ public class CallableMethod implements Callable {
|
||||
private final List<Type> valueParameterTypes;
|
||||
private ClassDescriptor thisClass = null;
|
||||
|
||||
private FunctionDescriptor receiverFunction = null;
|
||||
private CallableDescriptor receiverFunction = null;
|
||||
private Type generateCalleeType = null;
|
||||
|
||||
public CallableMethod(String owner, Method signature, int invokeOpcode, List<Type> valueParameterTypes) {
|
||||
@@ -48,7 +49,7 @@ public class CallableMethod implements Callable {
|
||||
return valueParameterTypes;
|
||||
}
|
||||
|
||||
public void setNeedsReceiver(@Nullable FunctionDescriptor receiverClass) {
|
||||
public void setNeedsReceiver(@Nullable CallableDescriptor receiverClass) {
|
||||
this.receiverFunction = receiverClass;
|
||||
}
|
||||
|
||||
@@ -88,7 +89,7 @@ public class CallableMethod implements Callable {
|
||||
return thisClass;
|
||||
}
|
||||
|
||||
public FunctionDescriptor getReceiverFunction() {
|
||||
public CallableDescriptor getReceiverFunction() {
|
||||
return receiverFunction;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ public class ClassCodegen {
|
||||
|
||||
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()) {
|
||||
if (declaration instanceof JetClass && !(declaration instanceof JetEnumEntry)) {
|
||||
generate(contextForInners, (JetClass) declaration);
|
||||
@@ -36,12 +36,12 @@ public class ClassCodegen {
|
||||
private void generateImplementation(CodegenContext context, JetClassOrObject aClass, OwnerKind kind, HashMap<DeclarationDescriptor, DeclarationDescriptor> accessors) {
|
||||
ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass);
|
||||
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);
|
||||
|
||||
if(aClass instanceof JetClass && ((JetClass)aClass).isTrait()) {
|
||||
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 {
|
||||
|
||||
private final BindingContext bindingContext;
|
||||
|
||||
public ClosureCodegen(GenerationState state, ExpressionCodegen exprContext, CodegenContext context) {
|
||||
super(exprContext, context, state);
|
||||
bindingContext = state.getBindingContext();
|
||||
}
|
||||
|
||||
public static Method erasedInvokeSignature(FunctionDescriptor fd) {
|
||||
@@ -63,7 +66,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
||||
public GeneratedAnonymousClassDescriptor gen(JetFunctionLiteralExpression 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();
|
||||
name = nameAndVisitor.getFirst();
|
||||
|
||||
@@ -5,7 +5,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.commons.InstructionAdapter;
|
||||
|
||||
@@ -49,7 +48,7 @@ public abstract class CodegenContext {
|
||||
|
||||
protected abstract ClassDescriptor getThisDescriptor ();
|
||||
|
||||
protected FunctionDescriptor getReceiverDescriptor() {
|
||||
protected CallableDescriptor getReceiverDescriptor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -80,8 +79,8 @@ public abstract class CodegenContext {
|
||||
return new NamespaceContext(descriptor, this);
|
||||
}
|
||||
|
||||
public CodegenContext intoClass(ClassDescriptor descriptor, OwnerKind kind) {
|
||||
return new ClassContext(descriptor, kind, this);
|
||||
public CodegenContext intoClass(ClassDescriptor descriptor, OwnerKind kind, JetTypeMapper typeMapper) {
|
||||
return new ClassContext(descriptor, kind, this, typeMapper);
|
||||
}
|
||||
|
||||
public CodegenContext intoAnonymousClass(@NotNull ObjectOrClosureCodegen closure, ClassDescriptor descriptor, OwnerKind kind) {
|
||||
@@ -124,7 +123,7 @@ public abstract class CodegenContext {
|
||||
|
||||
public Type jvmType(JetTypeMapper mapper) {
|
||||
if (contextType instanceof ClassDescriptor) {
|
||||
return mapper.jvmType((ClassDescriptor) contextType, contextKind);
|
||||
return mapper.mapType(((ClassDescriptor) contextType).getDefaultType(), contextKind);
|
||||
}
|
||||
else if (closure != null) {
|
||||
return Type.getObjectType(closure.name);
|
||||
@@ -232,33 +231,23 @@ public abstract class CodegenContext {
|
||||
return getThisDescriptor() != null ? StackValue.local(1, asmType) : StackValue.local(0, asmType);
|
||||
}
|
||||
|
||||
public abstract static class FunctionContext extends CodegenContext {
|
||||
final FunctionDescriptor receiverDescriptor;
|
||||
public abstract static class ReceiverContext extends CodegenContext {
|
||||
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);
|
||||
receiverDescriptor = contextType.getReceiverParameter().exists() ? contextType : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FunctionDescriptor getReceiverDescriptor() {
|
||||
protected CallableDescriptor getReceiverDescriptor() {
|
||||
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) {
|
||||
super(contextType, contextKind, parentContext, null);
|
||||
super(contextType instanceof PropertyAccessorDescriptor ? ((PropertyAccessorDescriptor)contextType).getCorrespondingProperty() : contextType, contextKind, parentContext, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -295,12 +284,12 @@ public abstract class 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);
|
||||
|
||||
final Type type = enclosingClassType();
|
||||
outerExpression = type != null
|
||||
? StackValue.field(type, DescriptorRenderer.getFQName(contextType).replace('.', '/'), "this$0", false)
|
||||
? StackValue.field(type, typeMapper.getFQName(contextType), "this$0", false)
|
||||
: null;
|
||||
}
|
||||
|
||||
@@ -316,7 +305,7 @@ public abstract class CodegenContext {
|
||||
|
||||
final Type type = enclosingClassType();
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -326,7 +315,7 @@ public abstract class CodegenContext {
|
||||
}
|
||||
}
|
||||
|
||||
public static class ClosureContext extends FunctionContext {
|
||||
public static class ClosureContext extends ReceiverContext {
|
||||
private ClassDescriptor classDescriptor;
|
||||
|
||||
public ClosureContext(FunctionDescriptor contextType, ClassDescriptor classDescriptor, CodegenContext parentContext, @NotNull ObjectOrClosureCodegen closureCodegen, String internalClassName) {
|
||||
|
||||
@@ -169,4 +169,5 @@ public class CodegenUtil {
|
||||
addSuperTypes(jetType, set);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.jetbrains.jet.codegen;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||
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<ValueParameterDescriptor> paramDescrs = descriptor != null
|
||||
@@ -34,18 +48,6 @@ public class ConstructorFrameMap extends FrameMap {
|
||||
ValueParameterDescriptor parameter = paramDescrs.get(i);
|
||||
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() {
|
||||
|
||||
@@ -79,6 +79,22 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
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() {
|
||||
return state;
|
||||
}
|
||||
@@ -265,7 +281,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
final JetParameter loopParameter = expression.getLoopParameter();
|
||||
final VariableDescriptor parameterDescriptor = bindingContext.get(BindingContext.VALUE_PARAMETER, loopParameter);
|
||||
|
||||
JetType iteratorType = parameterDescriptor.getOutType();
|
||||
JetType iteratorType = iteratorDescriptor.getReturnType();
|
||||
Type asmIterType = JetTypeMapper.boxType(typeMapper.mapType(iteratorType));
|
||||
|
||||
JetType paramType = parameterDescriptor.getOutType();
|
||||
@@ -802,8 +818,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
if (declaration instanceof JetObjectDeclarationName) {
|
||||
JetObjectDeclaration objectDeclaration = PsiTreeUtil.getParentOfType(declaration, JetObjectDeclaration.class);
|
||||
ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, objectDeclaration);
|
||||
return StackValue.field(typeMapper.jvmType(classDescriptor, OwnerKind.IMPLEMENTATION),
|
||||
typeMapper.jvmName(classDescriptor, OwnerKind.IMPLEMENTATION),
|
||||
return StackValue.field(typeMapper.mapType(classDescriptor.getDefaultType(), OwnerKind.IMPLEMENTATION),
|
||||
typeMapper.mapType(classDescriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(),
|
||||
"$instance",
|
||||
true);
|
||||
}
|
||||
@@ -813,25 +829,59 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
JetExpression r = getReceiverForSelector(expression);
|
||||
final boolean isSuper = r instanceof JetSuperExpression;
|
||||
final StackValue iValue = intermediateValueForProperty(propertyDescriptor, directToField, isSuper ? (JetSuperExpression)r : null);
|
||||
if (!isStatic) {
|
||||
if (receiver == StackValue.none()) {
|
||||
if(resolvedCall == null)
|
||||
receiver = generateThisOrOuter((ClassDescriptor) propertyDescriptor.getContainingDeclaration());
|
||||
if(!directToField && resolvedCall != null && !isSuper) {
|
||||
if (resolvedCall.getThisObject().exists()) {
|
||||
if(resolvedCall.getReceiverArgument().exists()) {
|
||||
generateFromResolvedCall(resolvedCall.getThisObject());
|
||||
if(receiver == StackValue.none()) {
|
||||
generateFromResolvedCall(resolvedCall.getReceiverArgument());
|
||||
}
|
||||
else {
|
||||
receiver.put(typeMapper.mapType(resolvedCall.getReceiverArgument().getType()), v);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(resolvedCall.getThisObject() instanceof ExtensionReceiver)
|
||||
receiver = generateReceiver((FunctionDescriptor) ((ExtensionReceiver)resolvedCall.getThisObject()).getDeclarationDescriptor());
|
||||
else
|
||||
receiver = generateThisOrOuter((ClassDescriptor) propertyDescriptor.getContainingDeclaration());
|
||||
if (receiver == StackValue.none()) {
|
||||
generateFromResolvedCall(resolvedCall.getThisObject());
|
||||
}
|
||||
else {
|
||||
receiver.put(typeMapper.mapType(((ClassDescriptor)resolvedCall.getResultingDescriptor().getContainingDeclaration()).getDefaultType()), v);
|
||||
}
|
||||
}
|
||||
}
|
||||
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()));
|
||||
else {
|
||||
if (resolvedCall.getReceiverArgument().exists()) {
|
||||
if (receiver == StackValue.none()) {
|
||||
generateFromResolvedCall(resolvedCall.getReceiverArgument());
|
||||
}
|
||||
else {
|
||||
receiver.put(typeMapper.mapType(resolvedCall.getReceiverArgument().getType()), v);
|
||||
}
|
||||
}
|
||||
}
|
||||
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) {
|
||||
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),
|
||||
typeMapper.jvmName((ClassDescriptor) descriptor, OwnerKind.IMPLEMENTATION),
|
||||
typeMapper.mapType(((ClassDescriptor) descriptor).getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName(),
|
||||
"$classobj",
|
||||
true);
|
||||
}
|
||||
@@ -1102,10 +1153,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getCalleeExpression());
|
||||
assert resolvedCall != null;
|
||||
|
||||
FunctionDescriptor callableDescriptor = (FunctionDescriptor) resolvedCall.getResultingDescriptor();
|
||||
boolean hasThis = resolvedCall.getThisObject().exists();
|
||||
boolean hasReceiver = resolvedCall.getReceiverArgument().exists();
|
||||
|
||||
if (callableMethod.isNeedsThis()) {
|
||||
if(callableMethod.isNeedsReceiver()) {
|
||||
generateFromResolvedCall(resolvedCall.getThisObject());
|
||||
@@ -1113,7 +1160,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
generateFromResolvedCall(resolvedCall.getReceiverArgument());
|
||||
}
|
||||
else {
|
||||
receiver.put(typeMapper.mapType(callableMethod.getReceiverFunction().getReceiverParameter().getType()), v);
|
||||
receiver.put(typeMapper.mapType(resolvedCall.getReceiverArgument().getType()), v);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1135,8 +1182,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
}
|
||||
}
|
||||
|
||||
pushTypeArguments(resolvedCall);
|
||||
int mask = pushMethodArguments(expression, callableMethod.getValueParameterTypes());
|
||||
pushTypeArguments(expression);
|
||||
if(mask == 0)
|
||||
callableMethod.invoke(v);
|
||||
else
|
||||
@@ -1150,7 +1197,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
}
|
||||
else if(descriptor instanceof ExtensionReceiver) {
|
||||
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) {
|
||||
ExpressionReceiver expressionReceiver = (ExpressionReceiver) descriptor;
|
||||
@@ -1169,14 +1216,16 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
return null;
|
||||
}
|
||||
|
||||
private StackValue generateReceiver(FunctionDescriptor descriptor) {
|
||||
assert context instanceof CodegenContext.FunctionContext;
|
||||
CodegenContext.FunctionContext cur = (CodegenContext.FunctionContext) context;
|
||||
if (cur.getReceiverDescriptor() == descriptor) {
|
||||
return cur.getReceiverExpression(typeMapper);
|
||||
private StackValue generateReceiver(DeclarationDescriptor provided, ClassDescriptor required) {
|
||||
assert context instanceof CodegenContext.ReceiverContext;
|
||||
CodegenContext.ReceiverContext cur = (CodegenContext.ReceiverContext) context;
|
||||
if (cur.getReceiverDescriptor() == provided) {
|
||||
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) {
|
||||
@@ -1190,7 +1239,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
if (CodegenUtil.isSubclass(cur.getThisDescriptor(), calleeContainingClass)) {
|
||||
Type type = typeMapper.mapType(calleeContainingClass.getDefaultType());
|
||||
result.put(JetTypeMapper.TYPE_OBJECT, v);
|
||||
return StackValue.onStack(type);
|
||||
return castToRequiredTypeOfInterfaceIfNeeded(StackValue.onStack(type), cur.getThisDescriptor(), calleeContainingClass);
|
||||
}
|
||||
|
||||
result = cur.getOuterExpression(result);
|
||||
@@ -1213,64 +1262,66 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
return false;
|
||||
}
|
||||
|
||||
private int pushMethodArguments(JetCallElement expression, List<Type> valueParameterTypes) {
|
||||
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getCalleeExpression());
|
||||
List<? extends ValueArgument> args = expression.getValueArguments();
|
||||
if(resolvedCall != null) {
|
||||
Map<ValueParameterDescriptor,ResolvedValueArgument> valueArguments = resolvedCall.getValueArguments();
|
||||
CallableDescriptor fd = resolvedCall.getResultingDescriptor();
|
||||
private int pushMethodArguments(ResolvedCall resolvedCall, List<Type> valueParameterTypes) {
|
||||
Map<ValueParameterDescriptor,ResolvedValueArgument> valueArguments = resolvedCall.getValueArguments();
|
||||
CallableDescriptor fd = resolvedCall.getResultingDescriptor();
|
||||
|
||||
int index = 0;
|
||||
int mask = 0;
|
||||
for (ValueParameterDescriptor valueParameterDescriptor : fd.getValueParameters()) {
|
||||
ResolvedValueArgument resolvedValueArgument = valueArguments.get(valueParameterDescriptor);
|
||||
if(resolvedValueArgument instanceof ExpressionValueArgument) {
|
||||
ExpressionValueArgument valueArgument = (ExpressionValueArgument) resolvedValueArgument;
|
||||
gen(valueArgument.getExpression(), valueParameterTypes.get(index));
|
||||
int index = 0;
|
||||
int mask = 0;
|
||||
for (ValueParameterDescriptor valueParameterDescriptor : fd.getValueParameters()) {
|
||||
ResolvedValueArgument resolvedValueArgument = valueArguments.get(valueParameterDescriptor);
|
||||
if(resolvedValueArgument instanceof ExpressionValueArgument) {
|
||||
ExpressionValueArgument valueArgument = (ExpressionValueArgument) resolvedValueArgument;
|
||||
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) {
|
||||
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(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 if(type.getSort() == Type.DOUBLE) {
|
||||
v.aconst(0d);
|
||||
}
|
||||
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 {
|
||||
List<? extends ValueArgument> args = expression.getValueArguments();
|
||||
for (int i = 0, argsSize = args.size(); i < argsSize; i++) {
|
||||
ValueArgument arg = args.get(i);
|
||||
gen(arg.getArgumentExpression(), valueParameterTypes.get(i));
|
||||
@@ -1898,7 +1949,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
else {
|
||||
// this$0 need to be put on stack
|
||||
v.dup();
|
||||
v.load(0, typeMapper.jetImplementationType(classDecl));
|
||||
v.load(0, typeMapper.mapType(classDecl.getDefaultType(), OwnerKind.IMPLEMENTATION));
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1916,9 +1967,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
return StackValue.onStack(type);
|
||||
}
|
||||
|
||||
private void pushTypeArguments(JetCallElement expression) {
|
||||
JetExpression calleeExpression = expression.getCalleeExpression();
|
||||
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, calleeExpression);
|
||||
private void pushTypeArguments(ResolvedCall<? extends CallableDescriptor> resolvedCall) {
|
||||
if(resolvedCall != null) {
|
||||
Map<TypeParameterDescriptor, JetType> typeArguments = resolvedCall.getTypeArguments();
|
||||
CallableDescriptor resultingDescriptor = resolvedCall.getCandidateDescriptor();
|
||||
@@ -2100,7 +2149,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
||||
}
|
||||
else {
|
||||
if(descriptor instanceof FunctionDescriptor) {
|
||||
return generateReceiver((FunctionDescriptor) descriptor);
|
||||
return generateReceiver(descriptor, null);
|
||||
}
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
import org.objectweb.asm.Label;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
@@ -52,7 +53,7 @@ public class FunctionCodegen {
|
||||
FunctionDescriptor functionDescriptor, JetDeclarationWithBody fun)
|
||||
{
|
||||
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.
|
||||
|
||||
@@ -83,16 +84,18 @@ public class FunctionCodegen {
|
||||
|
||||
Type[] argTypes = jvmSignature.getArgumentTypes();
|
||||
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) {
|
||||
int slot = frameMap.enterTemp();
|
||||
add++;
|
||||
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) {
|
||||
OwnerKind.DelegateKind dk = (OwnerKind.DelegateKind) kind;
|
||||
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) {
|
||||
DeclarationDescriptor contextClass = ((FunctionDescriptor)owner.getContextDescriptor()).getContainingDeclaration();
|
||||
DeclarationDescriptor contextClass = owner.getContextDescriptor().getContainingDeclaration();
|
||||
|
||||
if(kind != OwnerKind.TRAIT_IMPL) {
|
||||
// we don't generate defaults for traits but do for traitImpl
|
||||
@@ -184,8 +187,8 @@ public class FunctionCodegen {
|
||||
int flags = ACC_PUBLIC; // TODO.
|
||||
|
||||
String ownerInternalName = contextClass instanceof NamespaceDescriptor ?
|
||||
JetTypeMapper.jvmName((NamespaceDescriptor) contextClass) :
|
||||
state.getTypeMapper().jvmName((ClassDescriptor) contextClass, OwnerKind.IMPLEMENTATION);
|
||||
NamespaceCodegen.getJVMClassName(DescriptorRenderer.getFQName(contextClass)) :
|
||||
state.getTypeMapper().mapType(((ClassDescriptor) contextClass).getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName();
|
||||
|
||||
String descriptor = jvmSignature.getDescriptor().replace(")","I)");
|
||||
if(!isStatic)
|
||||
@@ -210,6 +213,13 @@ public class FunctionCodegen {
|
||||
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();
|
||||
List<ValueParameterDescriptor> paramDescrs = functionDescriptor.getValueParameters();
|
||||
for (int i = 0; i < paramDescrs.size(); i++) {
|
||||
@@ -219,13 +229,6 @@ public class FunctionCodegen {
|
||||
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();
|
||||
|
||||
int maskIndex = var;
|
||||
@@ -236,14 +239,22 @@ public class FunctionCodegen {
|
||||
}
|
||||
|
||||
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();
|
||||
for (int index = 0; index < paramDescrs.size(); index++) {
|
||||
ValueParameterDescriptor parameterDescriptor = paramDescrs.get(index);
|
||||
|
||||
Type t = argumentTypes[(hasReceiver ? 1 : 0) + index];
|
||||
Type t = argumentTypes[extra + index];
|
||||
Label endArg = null;
|
||||
if (parameterDescriptor.hasDefaultValue()) {
|
||||
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(kind == OwnerKind.TRAIT_IMPL) {
|
||||
iv.invokeinterface(ownerInternalName, jvmSignature.getName(), jvmSignature.getDescriptor());
|
||||
@@ -318,7 +324,7 @@ public class FunctionCodegen {
|
||||
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()))
|
||||
StackValue.valueOf(iv, jvmSignature.getReturnType());
|
||||
if(jvmSignature.getReturnType() == Type.VOID_TYPE)
|
||||
|
||||
@@ -64,11 +64,11 @@ public class GenerationState {
|
||||
}
|
||||
|
||||
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) {
|
||||
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) {
|
||||
|
||||
@@ -28,9 +28,13 @@ import java.util.*;
|
||||
public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
private JetDelegationSpecifier superCall;
|
||||
private String superClass = "java/lang/Object";
|
||||
private final JetTypeMapper typeMapper;
|
||||
private final BindingContext bindingContext;
|
||||
|
||||
public ImplementationBodyCodegen(JetClassOrObject aClass, CodegenContext context, ClassBuilder v, GenerationState state) {
|
||||
super(aClass, context, v, state);
|
||||
typeMapper = state.getTypeMapper();
|
||||
bindingContext = state.getBindingContext();
|
||||
}
|
||||
|
||||
private Set<String> getSuperInterfaces(JetClassOrObject aClass) {
|
||||
@@ -39,10 +43,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
Set<String> superInterfaces = new LinkedHashSet<String>();
|
||||
|
||||
for (JetDelegationSpecifier specifier : delegationSpecifiers) {
|
||||
JetType superType = state.getBindingContext().get(BindingContext.TYPE, specifier.getTypeReference());
|
||||
JetType superType = bindingContext.get(BindingContext.TYPE, specifier.getTypeReference());
|
||||
assert superType != null;
|
||||
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) {
|
||||
PsiClass psiClass = (PsiClass) superPsi;
|
||||
@@ -71,7 +75,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
else {
|
||||
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;
|
||||
@@ -108,18 +112,18 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
v.visitSource(myClass.getContainingFile().getName(), null);
|
||||
|
||||
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) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
private String jvmName() {
|
||||
return state.getTypeMapper().jvmName(descriptor, kind);
|
||||
return typeMapper.mapType(descriptor.getDefaultType(), kind).getInternalName();
|
||||
}
|
||||
|
||||
protected void getSuperClass() {
|
||||
@@ -130,21 +134,21 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
for (JetDelegationSpecifier specifier : delegationSpecifiers) {
|
||||
if (specifier instanceof JetDelegatorToSuperClass || specifier instanceof JetDelegatorToSuperCall) {
|
||||
JetType superType = state.getBindingContext().get(BindingContext.TYPE, specifier.getTypeReference());
|
||||
JetType superType = bindingContext.get(BindingContext.TYPE, specifier.getTypeReference());
|
||||
assert superType != null;
|
||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
||||
final PsiElement declaration = state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, superClassDescriptor);
|
||||
final PsiElement declaration = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, superClassDescriptor);
|
||||
if (declaration != null) {
|
||||
if (declaration instanceof PsiClass) {
|
||||
if (!((PsiClass) declaration).isInterface()) {
|
||||
superClass = state.getTypeMapper().jvmName(superClassDescriptor, kind);
|
||||
superClass = typeMapper.mapType(superClassDescriptor.getDefaultType(), kind).getInternalName();
|
||||
superCall = specifier;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(declaration instanceof JetClass) {
|
||||
if(!((JetClass) declaration).isTrait()) {
|
||||
superClass = state.getTypeMapper().jvmName(superClassDescriptor, kind);
|
||||
superClass = typeMapper.mapType(superClassDescriptor.getDefaultType(), kind).getInternalName();
|
||||
superCall = specifier;
|
||||
}
|
||||
}
|
||||
@@ -176,8 +180,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
FunctionDescriptor bridge = (FunctionDescriptor) entry.getValue();
|
||||
FunctionDescriptor original = (FunctionDescriptor) entry.getKey();
|
||||
|
||||
Method method = state.getTypeMapper().mapSignature(bridge.getName(), bridge);
|
||||
Method originalMethod = state.getTypeMapper().mapSignature(original.getName(), original);
|
||||
Method method = typeMapper.mapSignature(bridge.getName(), bridge);
|
||||
Method originalMethod = typeMapper.mapSignature(original.getName(), original);
|
||||
Type[] argTypes = method.getArgumentTypes();
|
||||
|
||||
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
|
||||
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());
|
||||
mv.visitMaxs(0,0);
|
||||
@@ -204,8 +208,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
PropertyDescriptor bridge = (PropertyDescriptor) entry.getValue();
|
||||
PropertyDescriptor original = (PropertyDescriptor) entry.getKey();
|
||||
|
||||
Method method = state.getTypeMapper().mapGetterSignature(bridge, OwnerKind.IMPLEMENTATION);
|
||||
Method originalMethod = state.getTypeMapper().mapGetterSignature(original, OwnerKind.IMPLEMENTATION);
|
||||
Method method = typeMapper.mapGetterSignature(bridge, 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);
|
||||
InstructionAdapter iv = null;
|
||||
if (v.generateCode()) {
|
||||
@@ -214,15 +218,15 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
iv = new InstructionAdapter(mv);
|
||||
|
||||
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());
|
||||
mv.visitMaxs(0,0);
|
||||
mv.visitEnd();
|
||||
}
|
||||
|
||||
method = state.getTypeMapper().mapSetterSignature(bridge, OwnerKind.IMPLEMENTATION);
|
||||
originalMethod = state.getTypeMapper().mapSetterSignature(original, OwnerKind.IMPLEMENTATION);
|
||||
method = typeMapper.mapSetterSignature(bridge, 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);
|
||||
if (v.generateCode()) {
|
||||
mv.visitCode();
|
||||
@@ -237,7 +241,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
//noinspection AssignmentToForLoopParameter
|
||||
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());
|
||||
mv.visitMaxs(0,0);
|
||||
@@ -253,7 +257,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
private void generateFieldForObjectInstance() {
|
||||
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);
|
||||
|
||||
staticInitializerChunks.add(new CodeChunk() {
|
||||
@@ -263,7 +267,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
v.anew(Type.getObjectType(name));
|
||||
v.dup();
|
||||
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() {
|
||||
final JetClassObject classObject = getClassObject();
|
||||
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);
|
||||
|
||||
staticInitializerChunks.add(new CodeChunk() {
|
||||
@Override
|
||||
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);
|
||||
v.anew(classObjectType);
|
||||
v.dup();
|
||||
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());
|
||||
}
|
||||
});
|
||||
@@ -295,7 +301,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
if(myClass instanceof JetClass && ((JetClass) myClass).isTrait())
|
||||
return;
|
||||
|
||||
ConstructorDescriptor constructorDescriptor = state.getBindingContext().get(BindingContext.CONSTRUCTOR, myClass);
|
||||
ConstructorDescriptor constructorDescriptor = bindingContext.get(BindingContext.CONSTRUCTOR, myClass);
|
||||
|
||||
CodegenContext.ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor);
|
||||
|
||||
@@ -304,7 +310,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
if (constructorDescriptor == null) {
|
||||
List<Type> parameterTypes = new ArrayList<Type>();
|
||||
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();
|
||||
@@ -316,7 +322,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
callableMethod = new CallableMethod("", method, Opcodes.INVOKESPECIAL, Collections.<Type>emptyList());
|
||||
}
|
||||
else {
|
||||
callableMethod = state.getTypeMapper().mapToCallableMethod(constructorDescriptor, kind);
|
||||
callableMethod = typeMapper.mapToCallableMethod(constructorDescriptor, kind);
|
||||
method = callableMethod.getSignature();
|
||||
}
|
||||
|
||||
@@ -329,7 +335,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
Map<DeclarationDescriptor, EnclosedValueDescriptor> closure = context.closure.closure;
|
||||
for (DeclarationDescriptor descriptor : closure.keySet()) {
|
||||
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()]));
|
||||
@@ -357,13 +363,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
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 + ";");
|
||||
|
||||
HashSet<FunctionDescriptor> overridden = new HashSet<FunctionDescriptor>();
|
||||
for (JetDeclaration declaration : myClass.getDeclarations()) {
|
||||
if (declaration instanceof JetFunction) {
|
||||
FunctionDescriptor functionDescriptor = state.getBindingContext().get(BindingContext.FUNCTION, declaration);
|
||||
FunctionDescriptor functionDescriptor = bindingContext.get(BindingContext.FUNCTION, declaration);
|
||||
assert functionDescriptor != null;
|
||||
overridden.addAll(functionDescriptor.getOverriddenDescriptors());
|
||||
}
|
||||
@@ -375,25 +381,25 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
iv.invokespecial(superClass, "<init>", "()V");
|
||||
}
|
||||
else {
|
||||
JetType superType = state.getBindingContext().get(BindingContext.TYPE, superCall.getTypeReference());
|
||||
JetType superType = bindingContext.get(BindingContext.TYPE, superCall.getTypeReference());
|
||||
List<Type> parameterTypes = new ArrayList<Type>();
|
||||
assert superType != null;
|
||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
||||
if (CodegenUtil.hasThis0(superClassDescriptor)) {
|
||||
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()) {
|
||||
codegen.generateTypeInfo(typeParameterDescriptor.getType());
|
||||
parameterTypes.add(JetTypeMapper.TYPE_TYPEINFO);
|
||||
}
|
||||
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 {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -406,26 +412,26 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
iv.load(0, classType);
|
||||
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;
|
||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
||||
String delegateField = "$delegate_" + n;
|
||||
Type fieldType = state.getTypeMapper().jetImplementationType(superClassDescriptor);
|
||||
Type fieldType = typeMapper.mapType(superClassDescriptor.getDefaultType(), OwnerKind.IMPLEMENTATION);
|
||||
String fieldDesc = fieldType.getDescriptor();
|
||||
v.newField(specifier, Opcodes.ACC_PRIVATE, delegateField, fieldDesc, /*TODO*/null, null);
|
||||
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,
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
final ClassDescriptor outerDescriptor = getOuterClassDescriptor();
|
||||
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();
|
||||
final String fieldName = "this$0";
|
||||
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()) {
|
||||
Type sharedVarType = context.closure.exprContext.getSharedVarType(varDescr);
|
||||
if(sharedVarType == null) {
|
||||
sharedVarType = state.getTypeMapper().mapType(((VariableDescriptor) varDescr).getOutType());
|
||||
sharedVarType = typeMapper.mapType(((VariableDescriptor) varDescr).getOutType());
|
||||
}
|
||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||
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) {
|
||||
if (parameter.getValOrVarNode() != null) {
|
||||
VariableDescriptor descriptor = paramDescrs.get(curParam);
|
||||
Type type = state.getTypeMapper().mapType(descriptor.getOutType());
|
||||
Type type = typeMapper.mapType(descriptor.getOutType());
|
||||
iv.load(0, classType);
|
||||
iv.load(frameMap.getIndex(descriptor), type);
|
||||
iv.putfield(classname, descriptor.getName(), type.getDescriptor());
|
||||
@@ -484,14 +490,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
DeclarationDescriptor containingDeclaration = fun.getContainingDeclaration();
|
||||
if(containingDeclaration instanceof ClassDescriptor) {
|
||||
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) {
|
||||
JetClass jetClass = (JetClass) psiElement;
|
||||
if(jetClass.isTrait()) {
|
||||
int flags = Opcodes.ACC_PUBLIC; // TODO.
|
||||
|
||||
Method function = state.getTypeMapper().mapSignature(fun.getName(), fun);
|
||||
Method functionOriginal = state.getTypeMapper().mapSignature(fun.getName(), fun.getOriginal());
|
||||
Method function = typeMapper.mapSignature(fun.getName(), fun);
|
||||
Method functionOriginal = typeMapper.mapSignature(fun.getName(), fun.getOriginal());
|
||||
|
||||
final MethodVisitor mv = v.newMethod(myClass, flags, function.getName(), function.getDescriptor(), null, null);
|
||||
if (v.generateCode()) {
|
||||
@@ -509,15 +515,15 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
reg += argType.getSize();
|
||||
}
|
||||
|
||||
JetType jetType = TraitImplBodyCodegen.getSuperClass(declaration, state.getBindingContext());
|
||||
Type type = state.getTypeMapper().mapType(jetType);
|
||||
JetType jetType = TraitImplBodyCodegen.getSuperClass(declaration, bindingContext);
|
||||
Type type = typeMapper.mapType(jetType);
|
||||
if(type.getInternalName().equals("java/lang/Object")) {
|
||||
jetType = declaration.getDefaultType();
|
||||
type = state.getTypeMapper().mapType(jetType);
|
||||
type = typeMapper.mapType(jetType);
|
||||
}
|
||||
|
||||
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) {
|
||||
iv.checkcast(function.getReturnType());
|
||||
}
|
||||
@@ -548,15 +554,15 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
ConstructorFrameMap frameMap) {
|
||||
ClassDescriptor classDecl = constructorDescriptor.getContainingDeclaration();
|
||||
Type type;
|
||||
type = state.getTypeMapper().jetImplementationType(classDecl);
|
||||
type = typeMapper.mapType(classDecl.getDefaultType(), OwnerKind.IMPLEMENTATION);
|
||||
|
||||
iv.load(0, type);
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
@@ -570,7 +576,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
else if (declaration instanceof JetEnumEntry && !((JetEnumEntry) declaration).hasPrimaryConstructor()) {
|
||||
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);
|
||||
if (myEnumConstants.isEmpty()) {
|
||||
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);
|
||||
for (JetEnumEntry enumConstant : myEnumConstants) {
|
||||
// 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();
|
||||
if (delegationSpecifiers.size() > 1) {
|
||||
@@ -607,8 +613,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
final JetDelegationSpecifier specifier = delegationSpecifiers.get(0);
|
||||
if (specifier instanceof JetDelegatorToSuperCall) {
|
||||
final JetDelegatorToSuperCall superCall = (JetDelegatorToSuperCall) specifier;
|
||||
ConstructorDescriptor constructorDescriptor = (ConstructorDescriptor) state.getBindingContext().get(BindingContext.REFERENCE_TARGET, superCall.getCalleeExpression().getConstructorReferenceExpression());
|
||||
CallableMethod method = state.getTypeMapper().mapToCallableMethod(constructorDescriptor, OwnerKind.IMPLEMENTATION);
|
||||
ConstructorDescriptor constructorDescriptor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, superCall.getCalleeExpression().getConstructorReferenceExpression());
|
||||
CallableMethod method = typeMapper.mapToCallableMethod(constructorDescriptor, OwnerKind.IMPLEMENTATION);
|
||||
codegen.invokeMethodWithArguments(method, superCall, StackValue.none());
|
||||
}
|
||||
else {
|
||||
@@ -623,11 +629,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
private void generateSecondaryConstructor(JetSecondaryConstructor constructor) {
|
||||
ConstructorDescriptor constructorDescriptor = state.getBindingContext().get(BindingContext.CONSTRUCTOR, constructor);
|
||||
ConstructorDescriptor constructorDescriptor = bindingContext.get(BindingContext.CONSTRUCTOR, constructor);
|
||||
if (constructorDescriptor == null) {
|
||||
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
|
||||
final MethodVisitor mv = v.newMethod(constructor, flags, "<init>", method.getSignature().getDescriptor(), null, null);
|
||||
if (v.generateCode()) {
|
||||
@@ -641,7 +647,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
for (JetDelegationSpecifier initializer : constructor.getInitializers()) {
|
||||
if (initializer instanceof JetDelegatorToThisCall) {
|
||||
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)) {
|
||||
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) {
|
||||
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);
|
||||
|
||||
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.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) {
|
||||
for (JetDeclaration declaration : myClass.getDeclarations()) {
|
||||
if (declaration instanceof JetProperty) {
|
||||
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, declaration);
|
||||
if (state.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) {
|
||||
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) bindingContext.get(BindingContext.VARIABLE, declaration);
|
||||
if (bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) {
|
||||
final JetExpression initializer = ((JetProperty) declaration).getInitializer();
|
||||
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) {
|
||||
assert compileTimeValue != null;
|
||||
Object value = compileTimeValue.getValue();
|
||||
Type type = state.getTypeMapper().mapType(propertyDescriptor.getOutType());
|
||||
Type type = typeMapper.mapType(propertyDescriptor.getOutType());
|
||||
if(JetTypeMapper.isPrimitive(type)) {
|
||||
if( !propertyDescriptor.getOutType().isNullable() && value instanceof Number) {
|
||||
if(type == Type.INT_TYPE && ((Number)value).intValue() == 0)
|
||||
@@ -765,7 +771,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
propertyCodegen.gen((JetProperty) declaration);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -773,7 +779,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
for (JetParameter p : toClass.getPrimaryConstructorParameters()) {
|
||||
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) {
|
||||
propertyCodegen.generateDefaultGetter(propertyDescriptor, Opcodes.ACC_PUBLIC, p);
|
||||
if (propertyDescriptor.isVar()) {
|
||||
@@ -808,7 +814,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
InstructionAdapter iv = null;
|
||||
if (v.generateCode()) {
|
||||
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.getfield(owner, "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
iv.areturn(JetTypeMapper.TYPE_TYPEINFO);
|
||||
@@ -820,7 +826,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
if (v.generateCode()) {
|
||||
mv.visitCode();
|
||||
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(1, JetTypeMapper.TYPE_OBJECT);
|
||||
iv.putfield(owner, "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||
@@ -841,7 +847,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
if (v.generateCode()) {
|
||||
mv.visitCode();
|
||||
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.areturn(JetTypeMapper.TYPE_TYPEINFO);
|
||||
mv.visitMaxs(0, 0);
|
||||
@@ -854,18 +860,17 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
staticInitializerChunks.add(new CodeChunk() {
|
||||
@Override
|
||||
public void generate(InstructionAdapter v) {
|
||||
JetTypeMapper typeMapper = state.getTypeMapper();
|
||||
v.aconst(typeMapper.jvmType(descriptor, OwnerKind.IMPLEMENTATION));
|
||||
v.aconst(typeMapper.mapType(descriptor.getDefaultType(), OwnerKind.IMPLEMENTATION));
|
||||
v.iconst(0);
|
||||
ClassDescriptor outerClassDescriptor = CodegenUtil.getOuterClassDescriptor(descriptor);
|
||||
if(outerClassDescriptor == null) {
|
||||
v.invokestatic("jet/typeinfo/TypeInfo", "getTypeInfo", "(Ljava/lang/Class;Z)Ljet/typeinfo/TypeInfo;");
|
||||
}
|
||||
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.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;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import jet.JetObject;
|
||||
import jet.typeinfo.TypeInfo;
|
||||
@@ -9,6 +8,8 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
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.types.*;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
@@ -120,73 +121,11 @@ public class JetTypeMapper {
|
||||
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) {
|
||||
String owner;
|
||||
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
||||
if (containingDeclaration instanceof NamespaceDescriptor) {
|
||||
owner = jvmName((NamespaceDescriptor) containingDeclaration);
|
||||
owner = NamespaceCodegen.getJVMClassName(DescriptorRenderer.getFQName((NamespaceDescriptor) containingDeclaration));
|
||||
}
|
||||
else if (containingDeclaration instanceof ClassDescriptor) {
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
|
||||
@@ -198,7 +137,7 @@ public class JetTypeMapper {
|
||||
kind = OwnerKind.IMPLEMENTATION;
|
||||
}
|
||||
}
|
||||
owner = jvmName(classDescriptor, kind);
|
||||
owner = mapType(classDescriptor.getDefaultType(), kind).getInternalName();
|
||||
}
|
||||
else {
|
||||
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);
|
||||
}
|
||||
|
||||
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) {
|
||||
return mapType(jetType, OwnerKind.IMPLEMENTATION);
|
||||
}
|
||||
@@ -236,14 +212,13 @@ public class JetTypeMapper {
|
||||
else
|
||||
return ARRAY_GENERIC_TYPE;
|
||||
}
|
||||
|
||||
if (JetStandardClasses.getAny().equals(descriptor)) {
|
||||
return Type.getType(Object.class);
|
||||
return TYPE_OBJECT;
|
||||
}
|
||||
|
||||
if (descriptor instanceof ClassDescriptor) {
|
||||
String name = DescriptorRenderer.getFQName(descriptor).replace('.', '/');
|
||||
if(name.startsWith("<java_root>"))
|
||||
name = name.substring("<java_root>".length()+1);
|
||||
String name = getFQName(descriptor);
|
||||
return Type.getObjectType(name + (kind == OwnerKind.TRAIT_IMPL ? "$$TImpl" : ""));
|
||||
}
|
||||
|
||||
@@ -327,14 +302,15 @@ public class JetTypeMapper {
|
||||
else if (functionDescriptor instanceof ConstructorDescriptor) {
|
||||
assert !superCall;
|
||||
ClassDescriptor containingClass = (ClassDescriptor) functionParent;
|
||||
owner = jvmName(containingClass, OwnerKind.IMPLEMENTATION);
|
||||
owner = mapType(containingClass.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName();
|
||||
invokeOpcode = INVOKESPECIAL;
|
||||
thisClass = null;
|
||||
}
|
||||
else if (functionParent instanceof ClassDescriptor) {
|
||||
ClassDescriptor containingClass = (ClassDescriptor) functionParent;
|
||||
boolean isInterface = CodegenUtil.isInterface(containingClass);
|
||||
owner = jvmName(containingClass, isInterface && superCall ? OwnerKind.TRAIT_IMPL : OwnerKind.IMPLEMENTATION);
|
||||
OwnerKind kind1 = isInterface && superCall ? OwnerKind.TRAIT_IMPL : OwnerKind.IMPLEMENTATION;
|
||||
owner = mapType(containingClass.getDefaultType(), kind1).getInternalName();
|
||||
invokeOpcode = isInterface
|
||||
? (superCall ? Opcodes.INVOKESTATIC : Opcodes.INVOKEINTERFACE)
|
||||
: (superCall ? Opcodes.INVOKESPECIAL : Opcodes.INVOKEVIRTUAL);
|
||||
@@ -375,16 +351,16 @@ public class JetTypeMapper {
|
||||
valueParameterTypes.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()) {
|
||||
if(parameterDescriptor.isReified()) {
|
||||
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());
|
||||
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) {
|
||||
Type returnType = mapType(descriptor.getOutType());
|
||||
if(kind != OwnerKind.TRAIT_IMPL)
|
||||
return new Method(PropertyCodegen.getterName(descriptor.getName()), returnType, new Type[0]);
|
||||
else {
|
||||
String name = PropertyCodegen.getterName(descriptor.getName());
|
||||
ArrayList<Type> params = new ArrayList<Type>();
|
||||
if(kind == OwnerKind.TRAIT_IMPL) {
|
||||
ClassDescriptor containingDeclaration = (ClassDescriptor) descriptor.getContainingDeclaration();
|
||||
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) {
|
||||
final JetType inType = descriptor.getInType();
|
||||
if (inType == null) {
|
||||
JetType inType = descriptor.getInType();
|
||||
if(inType == null)
|
||||
return null;
|
||||
}
|
||||
Type paramType = mapType(inType);
|
||||
if(kind != OwnerKind.TRAIT_IMPL) {
|
||||
return new Method(PropertyCodegen.setterName(descriptor.getName()), Type.VOID_TYPE, new Type[] { paramType });
|
||||
}
|
||||
else {
|
||||
|
||||
String name = PropertyCodegen.setterName(descriptor.getName());
|
||||
ArrayList<Type> params = new ArrayList<Type>();
|
||||
if(kind == OwnerKind.TRAIT_IMPL) {
|
||||
ClassDescriptor containingDeclaration = (ClassDescriptor) descriptor.getContainingDeclaration();
|
||||
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) {
|
||||
@@ -465,29 +465,28 @@ public class JetTypeMapper {
|
||||
List<Type> parameterTypes = new ArrayList<Type>();
|
||||
ClassDescriptor classDescriptor = descriptor.getContainingDeclaration();
|
||||
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) {
|
||||
final Type type = mapType(parameter.getOutType());
|
||||
parameterTypes.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()]));
|
||||
}
|
||||
|
||||
public CallableMethod mapToCallableMethod(ConstructorDescriptor descriptor, OwnerKind kind) {
|
||||
List<Type> valueParameterTypes = new ArrayList<Type>();
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -506,6 +505,15 @@ public class JetTypeMapper {
|
||||
}
|
||||
|
||||
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);
|
||||
if (name != null) {
|
||||
return name;
|
||||
@@ -519,7 +527,7 @@ public class JetTypeMapper {
|
||||
}
|
||||
else {
|
||||
ClassDescriptor aClass = bindingContext.get(BindingContext.CLASS, container);
|
||||
baseName = jvmNameForImplementation(aClass, OwnerKind.IMPLEMENTATION);
|
||||
baseName = mapType(aClass.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName();
|
||||
}
|
||||
|
||||
Integer count = anonymousSubclassesCount.get(baseName);
|
||||
@@ -536,7 +544,7 @@ public class JetTypeMapper {
|
||||
Set<String> result = new HashSet<String>();
|
||||
final ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, jetClass);
|
||||
if (classDescriptor != null) {
|
||||
result.add(jvmName(classDescriptor, OwnerKind.IMPLEMENTATION));
|
||||
result.add(mapType(classDescriptor.getDefaultType(), OwnerKind.IMPLEMENTATION).getInternalName());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -93,6 +93,10 @@ public class NamespaceCodegen {
|
||||
final JetExpression initializer = ((JetProperty) declaration).getInitializer();
|
||||
if (initializer != null && !(initializer instanceof JetConstantExpression)) {
|
||||
final PropertyDescriptor descriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, declaration);
|
||||
assert descriptor != null;
|
||||
if(descriptor.getReceiverParameter().exists()) {
|
||||
continue;
|
||||
}
|
||||
codegen.genToJVMStack(initializer);
|
||||
codegen.intermediateValueForProperty(descriptor, true, null).store(new InstructionAdapter(mv));
|
||||
}
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -63,9 +61,9 @@ public class ObjectOrClosureCodegen {
|
||||
FunctionDescriptor fd = (FunctionDescriptor) d;
|
||||
|
||||
// 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)
|
||||
return null;
|
||||
|
||||
@@ -196,7 +196,11 @@ public abstract class StackValue {
|
||||
v.checkcast(type);
|
||||
}
|
||||
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) {
|
||||
if (this.type.equals(JetTypeMapper.TYPE_OBJECT)) {
|
||||
|
||||
@@ -56,6 +56,6 @@ public class TraitImplBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
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");
|
||||
public static final IntrinsicMethod ARRAY_SIZE = new ArraySize();
|
||||
public static final IntrinsicMethod ARRAY_INDICES = new ArrayIndices();
|
||||
public static final Equals EQUALS = new Equals();
|
||||
|
||||
private final Project myProject;
|
||||
private final JetStandardLibrary myStdLib;
|
||||
@@ -77,7 +78,8 @@ public class IntrinsicMethods {
|
||||
declareIntrinsicFunction("String", "plus", 1, new Concat());
|
||||
|
||||
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());
|
||||
|
||||
// declareIntrinsicFunction("Any", "equals", 1, new Equals());
|
||||
|
||||
@@ -34,6 +34,8 @@ namespace io {
|
||||
fun readLine() : String?
|
||||
}
|
||||
|
||||
fun Any?.identityEquals(other : Any?) // = this === other
|
||||
|
||||
// Can't write a body due to a bootstrapping problem (see JET-74)
|
||||
fun Any?.equals(other : Any?) : Boolean// = this === other
|
||||
|
||||
|
||||
@@ -13,6 +13,9 @@ import java.util.Set;
|
||||
* @author abreslav
|
||||
*/
|
||||
public class JetPsiUtil {
|
||||
|
||||
public static final String NO_NAME_PROVIDED = "<no name provided>";
|
||||
|
||||
@Nullable
|
||||
public static JetExpression deparenthesize(@NotNull JetExpression expression) {
|
||||
if (expression instanceof JetBinaryExpressionWithTypeRHS) {
|
||||
@@ -38,7 +41,7 @@ public class JetPsiUtil {
|
||||
|
||||
@NotNull
|
||||
public static String safeName(String name) {
|
||||
return name == null ? "<no name provided>" : name;
|
||||
return name == null ? NO_NAME_PROVIDED : name;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
namespace x
|
||||
|
||||
class Outer() {
|
||||
|
||||
class object {
|
||||
class Inner() {
|
||||
}
|
||||
|
||||
@@ -176,21 +176,21 @@ fun t12(x: Int) : Int {
|
||||
|
||||
fun box(): String {
|
||||
/*
|
||||
if (!s0()) return "fail"
|
||||
if (!s1()) return "fail"
|
||||
if (!t1()) return "fail"
|
||||
if (!t2()) return "fail"
|
||||
if (!t3()) return "fail"
|
||||
if (!t4()) return "fail"
|
||||
if (!t5()) return "fail"
|
||||
if (!t6()) return "fail"
|
||||
if (!t7()) return "fail"
|
||||
if (!t8()) return "fail"
|
||||
if (!t9(0)) return "fail"
|
||||
if (!t10()) return "fail"
|
||||
if (t11(1) != 104) return "fail"
|
||||
if (!s0()) return "s0 fail"
|
||||
if (!s1()) return "s1 fail"
|
||||
if (!t1()) return "t1 fail"
|
||||
if (!t2()) return "t2 fail"
|
||||
if (!t3()) return "t3 fail"
|
||||
if (!t4()) return "t4 fail"
|
||||
if (!t5()) return "t5 fail"
|
||||
if (!t6()) return "t6 fail"
|
||||
if (!t7()) return "t7 fail"
|
||||
if (!t8()) return "t8 fail"
|
||||
if (!t9(0)) return "t9 fail"
|
||||
if (!t10()) return "t10 fail"
|
||||
if (t11(1) != 104) return "t11 fail"
|
||||
*/
|
||||
if (t12(0) != 100) return "fail"
|
||||
if (t12(0) != 100) return "t12 fail"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -1,14 +1,18 @@
|
||||
import java.math.BigDecimal
|
||||
import java.util.ArrayList
|
||||
|
||||
fun box() : String {
|
||||
// Easy to make BigDecimals user-friendly
|
||||
System.out?.println(
|
||||
"2.00".bd - "1.00"
|
||||
)
|
||||
return "OK"
|
||||
val array = ArrayList<String>()
|
||||
array.add("0")
|
||||
array.add("1")
|
||||
array.add("2")
|
||||
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)
|
||||
fun BigDecimal.minus(other : String) = subtract(other.bd) // this can be omitted
|
||||
var <T> ArrayList<T>.last : T
|
||||
get() = get(size()-1)
|
||||
set(el : T) { set(size()-1, el) }
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import java.util.ArrayList
|
||||
|
||||
trait Tr {
|
||||
fun extra() : String = "_"
|
||||
}
|
||||
|
||||
@@ -34,6 +34,6 @@ public class ExtensionFunctionsTest extends CodegenTestCase {
|
||||
}
|
||||
|
||||
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)");
|
||||
System.out.println(generateToText());
|
||||
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("foo", tuple4._2);
|
||||
assertEquals("aaa", tuple4._3);
|
||||
|
||||
@@ -17,8 +17,10 @@ import com.sun.jdi.ReferenceType;
|
||||
import com.sun.jdi.request.ClassPrepareRequest;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.codegen.CodegenUtil;
|
||||
import org.jetbrains.jet.codegen.GenerationState;
|
||||
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||
import org.jetbrains.jet.codegen.NamespaceCodegen;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
||||
@@ -111,10 +113,10 @@ public class JetPositionManager implements PositionManager {
|
||||
else {
|
||||
JetNamespace namespace = PsiTreeUtil.getParentOfType(sourcePosition.getElementAt(), JetNamespace.class);
|
||||
if (namespace != null) {
|
||||
names.add(JetTypeMapper.jvmName(namespace));
|
||||
names.add(NamespaceCodegen.getJVMClassName(CodegenUtil.getFQName(namespace)));
|
||||
}
|
||||
else {
|
||||
names.add(JetTypeMapper.jvmName(file.getRootNamespace()));
|
||||
names.add(NamespaceCodegen.getJVMClassName(CodegenUtil.getFQName(file.getRootNamespace())));
|
||||
}
|
||||
}
|
||||
return names;
|
||||
|
||||
Reference in New Issue
Block a user