diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassCodegen.java index e1f3aec4775..acd8e708d86 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassCodegen.java @@ -17,6 +17,7 @@ package org.jetbrains.jet.codegen; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.descriptors.ClassKind; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; @@ -56,32 +57,44 @@ public class ClassCodegen { // different for the case when we compute closures generateImplementation(context, aClass, OwnerKind.IMPLEMENTATION, contextForInners.accessors, classBuilder); } - + for (JetDeclaration declaration : aClass.getDeclarations()) { - if (declaration instanceof JetClass && !(declaration instanceof JetEnumEntry)) { + if (declaration instanceof JetClass) { + if (declaration instanceof JetEnumEntry && !state.getInjector().getClosureAnnotator().enumEntryNeedSubclass( + (JetEnumEntry) declaration)) { + continue; + } + generate(contextForInners, (JetClass) declaration); } if (declaration instanceof JetClassObject) { - generate(contextForInners, ((JetClassObject)declaration).getObjectDeclaration()); + generate(contextForInners, ((JetClassObject) declaration).getObjectDeclaration()); } } if (state.getClassBuilderMode() != ClassBuilderMode.SIGNATURES) { generateImplementation(context, aClass, OwnerKind.IMPLEMENTATION, contextForInners.accessors, classBuilder); } - + classBuilder.done(); } - private void generateImplementation(CodegenContext context, JetClassOrObject aClass, OwnerKind kind, HashMap accessors, ClassBuilder classBuilder) { + private void generateImplementation( + CodegenContext context, + JetClassOrObject aClass, + OwnerKind kind, + HashMap accessors, + ClassBuilder classBuilder + ) { ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass); CodegenContext classContext = context.intoClass(descriptor, kind, jetTypeMapper); classContext.copyAccessors(accessors); new ImplementationBodyCodegen(aClass, classContext, classBuilder, state).generate(); - if (aClass instanceof JetClass && ((JetClass)aClass).isTrait()) { + if (aClass instanceof JetClass && ((JetClass) aClass).isTrait()) { ClassBuilder traitBuilder = state.forTraitImplementation(descriptor); - new TraitImplBodyCodegen(aClass, context.intoClass(descriptor, OwnerKind.TRAIT_IMPL, jetTypeMapper), traitBuilder, state).generate(); + new TraitImplBodyCodegen(aClass, context.intoClass(descriptor, OwnerKind.TRAIT_IMPL, jetTypeMapper), traitBuilder, state) + .generate(); traitBuilder.done(); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureAnnotator.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureAnnotator.java index 9e1d91500ec..14a7e835b6c 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureAnnotator.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureAnnotator.java @@ -51,6 +51,7 @@ public class ClosureAnnotator { private BindingContext bindingContext; private List files; + private final Map enumEntryNeedSubclass = new HashMap(); @Inject public void setBindingContext(BindingContext bindingContext) { @@ -229,6 +230,16 @@ public class ClosureAnnotator { return other != null; } + public boolean enumEntryNeedSubclass(JetEnumEntry enumEntry) { + ClassDescriptor descriptor = bindingContext.get(BindingContext.CLASS, enumEntry); + return enumEntryNeedSubclass.get(descriptor); + } + + public boolean enumEntryNeedSubclass(ClassDescriptor enumEntry) { + Boolean aBoolean = enumEntryNeedSubclass.get(enumEntry); + return aBoolean != null && aBoolean; + } + private class MyJetVisitorVoid extends JetVisitorVoid { private final LinkedList classStack = new LinkedList(); private final LinkedList nameStack = new LinkedList(); @@ -285,6 +296,13 @@ public class ClosureAnnotator { nameStack.pop(); } + @Override + public void visitEnumEntry(JetEnumEntry enumEntry) { + ClassDescriptor descriptor = bindingContext.get(BindingContext.CLASS, enumEntry); + enumEntryNeedSubclass.put(descriptor, !enumEntry.getDeclarations().isEmpty()); + super.visitEnumEntry(enumEntry); + } + @Override public void visitClassObject(JetClassObject classObject) { JvmClassName name = recordClassObject(classObject); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ConstructorFrameMap.java b/compiler/backend/src/org/jetbrains/jet/codegen/ConstructorFrameMap.java index cb3ffe37da7..1bb7d916fde 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ConstructorFrameMap.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ConstructorFrameMap.java @@ -31,7 +31,7 @@ import java.util.List; */ public class ConstructorFrameMap extends FrameMap { private int myOuterThisIndex = -1; - private int myTypeInfoIndex = -1; + private int myTypeInfoIndex = -1; public ConstructorFrameMap(CallableMethod callableMethod, @Nullable ConstructorDescriptor descriptor, boolean hasThis0) { enterTemp(); // this @@ -43,14 +43,16 @@ public class ConstructorFrameMap extends FrameMap { List explicitArgTypes = callableMethod.getValueParameterTypes(); - if(descriptor != null && descriptor.getContainingDeclaration().getKind() == ClassKind.ENUM_CLASS) { + if (descriptor != null && + (descriptor.getContainingDeclaration().getKind() == ClassKind.ENUM_CLASS || + descriptor.getContainingDeclaration().getKind() == ClassKind.ENUM_ENTRY)) { enterTemp(); // name enterTemp(); // ordinal } List paramDescrs = descriptor != null - ? descriptor.getValueParameters() - : Collections.emptyList(); + ? descriptor.getValueParameters() + : Collections.emptyList(); for (int i = 0; i < paramDescrs.size(); i++) { ValueParameterDescriptor parameter = paramDescrs.get(i); enter(parameter, explicitArgTypes.get(i).getSize()); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 9191951e0c9..c86f9ceb7e4 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -79,7 +79,7 @@ public class ExpressionCodegen extends JetVisitor { static class BlockStackElement { } - + static class LoopBlockStackElement extends BlockStackElement { final Label continueLabel; final Label breakLabel; @@ -101,11 +101,13 @@ public class ExpressionCodegen extends JetVisitor { } - public ExpressionCodegen(MethodVisitor v, - FrameMap myMap, - Type returnType, - CodegenContext context, - GenerationState state) { + public ExpressionCodegen( + MethodVisitor v, + FrameMap myMap, + Type returnType, + CodegenContext context, + GenerationState state + ) { this.myFrameMap = myMap; this.typeMapper = state.getInjector().getJetTypeMapper(); this.returnType = returnType; @@ -123,11 +125,13 @@ public class ExpressionCodegen extends JetVisitor { } StackValue castToRequiredTypeOfInterfaceIfNeeded(StackValue inner, DeclarationDescriptor provided, @Nullable ClassDescriptor required) { - if (required == null) + if (required == null) { return inner; + } - if (provided instanceof CallableDescriptor) - provided = ((CallableDescriptor)provided).getReceiverParameter().getType().getConstructor().getDeclarationDescriptor(); + if (provided instanceof CallableDescriptor) { + provided = ((CallableDescriptor) provided).getReceiverParameter().getType().getConstructor().getDeclarationDescriptor(); + } assert provided instanceof ClassDescriptor; @@ -229,8 +233,9 @@ public class ExpressionCodegen extends JetVisitor { } private static boolean isEmptyExpression(JetElement expr) { - if (expr == null) + if (expr == null) { return true; + } if (expr instanceof JetBlockExpression) { JetBlockExpression blockExpression = (JetBlockExpression) expr; List statements = blockExpression.getStatements(); @@ -310,14 +315,14 @@ public class ExpressionCodegen extends JetVisitor { return StackValue.onStack(Type.VOID_TYPE); } - + @Override public StackValue visitDoWhileExpression(JetDoWhileExpression expression, StackValue receiver) { Label condition = new Label(); v.mark(condition); Label end = new Label(); - + blockStackElements.push(new LoopBlockStackElement(end, condition, targetLabel(expression))); gen(expression.getBody(), Type.VOID_TYPE); @@ -361,12 +366,15 @@ public class ExpressionCodegen extends JetVisitor { FunctionDescriptor nextDescriptor = bindingContext.get(BindingContext.LOOP_RANGE_NEXT, loopRange); DeclarationDescriptor hasNextDescriptor = bindingContext.get(BindingContext.LOOP_RANGE_HAS_NEXT, loopRange); - if (iteratorDescriptor == null) + if (iteratorDescriptor == null) { throw new IllegalStateException("No iterator() method " + DiagnosticUtils.atLocation(loopRange)); - if (nextDescriptor == null) + } + if (nextDescriptor == null) { throw new IllegalStateException("No next() method " + DiagnosticUtils.atLocation(loopRange)); - if (hasNextDescriptor == null) + } + if (hasNextDescriptor == null) { throw new IllegalStateException("No hasNext method or property" + DiagnosticUtils.atLocation(loopRange)); + } final JetParameter loopParameter = expression.getLoopParameter(); final VariableDescriptor parameterDescriptor = bindingContext.get(BindingContext.VALUE_PARAMETER, loopParameter); @@ -381,7 +389,7 @@ public class ExpressionCodegen extends JetVisitor { gen(expression.getLoopRange(), boxType(loopRangeType)); invokeFunctionNoParams(iteratorDescriptor, asmIterType, v); v.store(iteratorVar, asmIterType); - + Label end = new Label(); if (iteratorType.isNullable()) { v.load(iteratorVar, TYPE_OBJECT); @@ -398,11 +406,11 @@ public class ExpressionCodegen extends JetVisitor { invokeFunctionNoParams(hND, Type.BOOLEAN_TYPE, v); } else { -// hND = ((PropertyDescriptor) hasNextDescriptor).getGetter(); -// if (hND != null) -// invokeFunctionNoParams(hND, Type.BOOLEAN_TYPE, v); -// else - intermediateValueForProperty((PropertyDescriptor) hasNextDescriptor, false, null).put(Type.BOOLEAN_TYPE, v); + // hND = ((PropertyDescriptor) hasNextDescriptor).getGetter(); + // if (hND != null) + // invokeFunctionNoParams(hND, Type.BOOLEAN_TYPE, v); + // else + intermediateValueForProperty((PropertyDescriptor) hasNextDescriptor, false, null).put(Type.BOOLEAN_TYPE, v); } v.ifeq(end); @@ -504,7 +512,7 @@ public class ExpressionCodegen extends JetVisitor { StackValue value = gen(expression.getLoopRange()); if (value instanceof StackValue.Local) { - myArrayVar = ((StackValue.Local)value).index; + myArrayVar = ((StackValue.Local) value).index; localArrayVar = true; } else { @@ -580,7 +588,7 @@ public class ExpressionCodegen extends JetVisitor { v.iconst(1); v.add(Type.INT_TYPE); v.store(myCountVar, Type.INT_TYPE); - + v.load(myCountVar, Type.INT_TYPE); v.iflt(end); @@ -636,8 +644,8 @@ public class ExpressionCodegen extends JetVisitor { @Override public StackValue visitBreakExpression(JetBreakExpression expression, StackValue receiver) { JetSimpleNameExpression labelElement = expression.getTargetLabel(); - - for(int i = blockStackElements.size()-1; i >= 0; --i) { + + for (int i = blockStackElements.size() - 1; i >= 0; --i) { BlockStackElement stackElement = blockStackElements.get(i); if (stackElement instanceof FinallyBlockStackElement) { FinallyBlockStackElement finallyBlockStackElement = (FinallyBlockStackElement) stackElement; @@ -647,7 +655,9 @@ public class ExpressionCodegen extends JetVisitor { } else if (stackElement instanceof LoopBlockStackElement) { LoopBlockStackElement loopBlockStackElement = (LoopBlockStackElement) stackElement; - if (labelElement == null || loopBlockStackElement.targetLabel != null && labelElement.getReferencedName().equals(loopBlockStackElement.targetLabel.getReferencedName())) { + if (labelElement == null || + loopBlockStackElement.targetLabel != null && + labelElement.getReferencedName().equals(loopBlockStackElement.targetLabel.getReferencedName())) { v.goTo(loopBlockStackElement.breakLabel); return StackValue.none(); } @@ -656,7 +666,7 @@ public class ExpressionCodegen extends JetVisitor { throw new UnsupportedOperationException(); } } - + throw new UnsupportedOperationException(); } @@ -664,7 +674,7 @@ public class ExpressionCodegen extends JetVisitor { public StackValue visitContinueExpression(JetContinueExpression expression, StackValue receiver) { JetSimpleNameExpression labelElement = expression.getTargetLabel(); - for(int i = blockStackElements.size()-1; i >= 0; --i) { + for (int i = blockStackElements.size() - 1; i >= 0; --i) { BlockStackElement stackElement = blockStackElements.get(i); if (stackElement instanceof FinallyBlockStackElement) { FinallyBlockStackElement finallyBlockStackElement = (FinallyBlockStackElement) stackElement; @@ -673,7 +683,9 @@ public class ExpressionCodegen extends JetVisitor { } else if (stackElement instanceof LoopBlockStackElement) { LoopBlockStackElement loopBlockStackElement = (LoopBlockStackElement) stackElement; - if (labelElement == null || loopBlockStackElement.targetLabel != null && labelElement.getReferencedName().equals(loopBlockStackElement.targetLabel.getReferencedName())) { + if (labelElement == null || + loopBlockStackElement.targetLabel != null && + labelElement.getReferencedName().equals(loopBlockStackElement.targetLabel.getReferencedName())) { v.goTo(loopBlockStackElement.continueLabel); return StackValue.none(); } @@ -743,8 +755,8 @@ public class ExpressionCodegen extends JetVisitor { } else { String text = entry instanceof JetEscapeStringTemplateEntry - ? ((JetEscapeStringTemplateEntry) entry).getUnescapedValue() - : entry.getText(); + ? ((JetEscapeStringTemplateEntry) entry).getUnescapedValue() + : entry.getText(); v.aconst(text); invokeAppendMethod(JL_STRING_TYPE); } @@ -809,12 +821,13 @@ public class ExpressionCodegen extends JetVisitor { if (closure.isCaptureReceiver() != null) { k++; - v.load(context.getContextDescriptor().getContainingDeclaration() instanceof NamespaceDescriptor ? 0: 1, closure.isCaptureReceiver()); + v.load(context.getContextDescriptor().getContainingDeclaration() instanceof NamespaceDescriptor ? 0 : 1, + closure.isCaptureReceiver()); } for (int i = 0; i < closure.getArgs().size(); i++) { StackValue arg = closure.getArgs().get(i); - arg.put(cons.getArgumentTypes()[i+k], v); + arg.put(cons.getArgumentTypes()[i + k], v); } v.invokespecial(closure.getClassname().getInternalName(), "", cons.getDescriptor()); @@ -839,26 +852,32 @@ public class ExpressionCodegen extends JetVisitor { v.load(context.isStatic() ? 0 : 1, closureCodegen.captureReceiver); consArgTypes.add(closureCodegen.captureReceiver); } - + for (Map.Entry entry : closureCodegen.closure.entrySet()) { if (entry.getKey() instanceof VariableDescriptor && !(entry.getKey() instanceof PropertyDescriptor)) { Type sharedVarType = typeMapper.getSharedVarType(entry.getKey()); - if (sharedVarType == null) - sharedVarType = state.getInjector().getJetTypeMapper().mapType(((VariableDescriptor) entry.getKey()).getType(), MapTypeMode.VALUE); + if (sharedVarType == null) { + sharedVarType = state.getInjector().getJetTypeMapper() + .mapType(((VariableDescriptor) entry.getKey()).getType(), MapTypeMode.VALUE); + } consArgTypes.add(sharedVarType); entry.getValue().getOuterValue().put(sharedVarType, v); } } if (closureCodegen.superCall != null) { - ConstructorDescriptor superConstructor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, closureCodegen.superCall.getCalleeExpression().getConstructorReferenceExpression()); - CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION, typeMapper.hasThis0(superConstructor.getContainingDeclaration())); + ConstructorDescriptor superConstructor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, + closureCodegen.superCall + .getCalleeExpression() + .getConstructorReferenceExpression()); + CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION, + typeMapper.hasThis0(superConstructor.getContainingDeclaration())); Type[] argumentTypes = superCallable.getSignature().getAsmMethod().getArgumentTypes(); Collections.addAll(consArgTypes, argumentTypes); ResolvedCall resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, closureCodegen.superCall.getCalleeExpression()); pushMethodArguments(resolvedCall, Arrays.asList(argumentTypes)); } - + Method cons = new Method("", Type.VOID_TYPE, consArgTypes.toArray(new Type[consArgTypes.size()])); v.invokespecial(closure.getClassname().getInternalName(), "", cons.getDescriptor()); return StackValue.onStack(closure.getClassname().getAsmType()); @@ -885,7 +904,7 @@ public class ExpressionCodegen extends JetVisitor { final Type type = sharedVarType != null ? sharedVarType : asmType(variableDescriptor.getType()); myFrameMap.enter(variableDescriptor, type.getSize()); } - + if (statement instanceof JetNamedFunction) { DeclarationDescriptor descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, statement); myFrameMap.enter(descriptor, 1); @@ -895,7 +914,9 @@ public class ExpressionCodegen extends JetVisitor { StackValue answer = StackValue.none(); for (int i = 0, statementsSize = statements.size(); i < statementsSize; i++) { JetElement statement = statements.get(i); - if (i == statements.size() - 1 /*&& statement instanceof JetExpression && !bindingContext.get(BindingContext.STATEMENT, statement)*/) { + if (i == + statements.size() - + 1 /*&& statement instanceof JetExpression && !bindingContext.get(BindingContext.STATEMENT, statement)*/) { answer = gen(statement); } else { @@ -962,7 +983,7 @@ public class ExpressionCodegen extends JetVisitor { } private void doFinallyOnReturn() { - for(int i = blockStackElements.size()-1; i >= 0; --i) { + for (int i = blockStackElements.size() - 1; i >= 0; --i) { BlockStackElement stackElement = blockStackElements.get(i); if (stackElement instanceof FinallyBlockStackElement) { FinallyBlockStackElement finallyBlockStackElement = (FinallyBlockStackElement) stackElement; @@ -976,7 +997,7 @@ public class ExpressionCodegen extends JetVisitor { } } } - + @Override public StackValue visitReturnExpression(JetReturnExpression expression, StackValue receiver) { final JetExpression returnedExpression = expression.getReturnedExpression(); @@ -993,7 +1014,7 @@ public class ExpressionCodegen extends JetVisitor { public void returnExpression(JetExpression expr) { StackValue lastValue = gen(expr); - + if (lastValue.type != Type.VOID_TYPE) { lastValue.put(returnType, v); v.areturn(returnType); @@ -1006,12 +1027,12 @@ public class ExpressionCodegen extends JetVisitor { private static boolean endsWithReturn(JetElement bodyExpression) { if (bodyExpression instanceof JetBlockExpression) { final List statements = ((JetBlockExpression) bodyExpression).getStatements(); - return statements.size() > 0 && statements.get(statements.size()-1) instanceof JetReturnExpression; + return statements.size() > 0 && statements.get(statements.size() - 1) instanceof JetReturnExpression; } - + return bodyExpression instanceof JetReturnExpression; } - + @Override public StackValue visitSimpleNameExpression(JetSimpleNameExpression expression, StackValue receiver) { ResolvedCall resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression); @@ -1036,7 +1057,7 @@ public class ExpressionCodegen extends JetVisitor { IntrinsicMethod intrinsic = null; if (descriptor instanceof CallableMemberDescriptor) { CallableMemberDescriptor memberDescriptor = (CallableMemberDescriptor) descriptor; - while(memberDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { + while (memberDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { memberDescriptor = memberDescriptor.getOverriddenDescriptors().iterator().next(); } intrinsic = state.getInjector().getIntrinsics().getIntrinsic(memberDescriptor); @@ -1056,17 +1077,18 @@ public class ExpressionCodegen extends JetVisitor { if (descriptor instanceof PropertyDescriptor) { PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor; - + if (propertyDescriptor.isObjectDeclaration()) { - ClassDescriptor classDescriptor = (ClassDescriptor) propertyDescriptor.getReturnType().getConstructor().getDeclarationDescriptor(); + ClassDescriptor classDescriptor = + (ClassDescriptor) propertyDescriptor.getReturnType().getConstructor().getDeclarationDescriptor(); + assert classDescriptor != null; if (classDescriptor.getKind() == ClassKind.ENUM_ENTRY) { ClassDescriptor containing = (ClassDescriptor) classDescriptor.getContainingDeclaration().getContainingDeclaration(); + assert containing != null; Type type = typeMapper.mapType(containing.getDefaultType(), MapTypeMode.VALUE); - StackValue.field(type, JvmClassName.byType(type), classDescriptor.getName().getName(), true).put(TYPE_OBJECT, v); - - // todo: for now we don't generate classes for enum entries, so we need this hack - type = typeMapper.mapType(classDescriptor.getDefaultType(), MapTypeMode.VALUE); - return StackValue.onStack(type); + Type entryType = typeMapper.mapType(classDescriptor.getDefaultType(), MapTypeMode.VALUE); + StackValue.field(type, JvmClassName.byType(type), classDescriptor.getName().getName(), true).put(entryType, v); + return StackValue.onStack(entryType); } else { Type type = typeMapper.mapType(classDescriptor.getDefaultType(), MapTypeMode.VALUE); @@ -1075,11 +1097,13 @@ public class ExpressionCodegen extends JetVisitor { } boolean isStatic = container instanceof NamespaceDescriptor; - final boolean directToField = expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER && contextKind() != OwnerKind.TRAIT_IMPL ; + final boolean directToField = + expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER && contextKind() != OwnerKind.TRAIT_IMPL; JetExpression r = getReceiverForSelector(expression); final boolean isSuper = r instanceof JetSuperExpression; propertyDescriptor = accessablePropertyDescriptor(propertyDescriptor); - final StackValue.Property iValue = intermediateValueForProperty(propertyDescriptor, directToField, isSuper ? (JetSuperExpression)r : null); + final StackValue.Property iValue = + intermediateValueForProperty(propertyDescriptor, directToField, isSuper ? (JetSuperExpression) r : null); if (!directToField && resolvedCall != null && !isSuper) { receiver.put(propertyDescriptor.getReceiverParameter().exists() || isStatic ? receiver.type @@ -1088,20 +1112,24 @@ public class ExpressionCodegen extends JetVisitor { else { if (!isStatic) { if (receiver == StackValue.none()) { - if (resolvedCall == null) + if (resolvedCall == null) { receiver = generateThisOrOuter((ClassDescriptor) propertyDescriptor.getContainingDeclaration()); + } else { - if (resolvedCall.getThisObject() instanceof ExtensionReceiver) - receiver = generateReceiver(((ExtensionReceiver)resolvedCall.getThisObject()).getDeclarationDescriptor()); - else + if (resolvedCall.getThisObject() instanceof ExtensionReceiver) { + receiver = generateReceiver(((ExtensionReceiver) resolvedCall.getThisObject()).getDeclarationDescriptor()); + } + else { receiver = generateThisOrOuter((ClassDescriptor) propertyDescriptor.getContainingDeclaration()); + } } } JetType receiverType = bindingContext.get(BindingContext.EXPRESSION_TYPE, r); - receiver.put(receiverType != null && !isSuper? asmType(receiverType) : TYPE_OBJECT, v); + receiver.put(receiverType != null && !isSuper ? asmType(receiverType) : TYPE_OBJECT, v); if (receiverType != null) { ClassDescriptor propReceiverDescriptor = (ClassDescriptor) propertyDescriptor.getContainingDeclaration(); - if (!CodegenUtil.isInterface(propReceiverDescriptor) && CodegenUtil.isInterface(receiverType.getConstructor().getDeclarationDescriptor())) { + 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(asmType(propReceiverDescriptor.getDefaultType())); @@ -1115,13 +1143,14 @@ public class ExpressionCodegen extends JetVisitor { if (descriptor instanceof ClassDescriptor) { PsiElement declaration = BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor); if (declaration instanceof JetClass) { - final ClassDescriptor descriptor1 = ((ClassDescriptor)descriptor).getClassObjectDescriptor(); + final ClassDescriptor descriptor1 = ((ClassDescriptor) descriptor).getClassObjectDescriptor(); assert descriptor1 != null; final Type type = typeMapper.mapType(descriptor1.getDefaultType(), MapTypeMode.VALUE); return StackValue.field(type, - JvmClassName.byType(typeMapper.mapType(((ClassDescriptor) descriptor).getDefaultType(), MapTypeMode.IMPL)), - "$classobj", - true); + JvmClassName.byType(typeMapper.mapType(((ClassDescriptor) descriptor).getDefaultType(), + MapTypeMode.IMPL)), + "$classobj", + true); } else { // todo ? @@ -1149,7 +1178,8 @@ public class ExpressionCodegen extends JetVisitor { if (value instanceof StackValue.FieldForSharedVar) { StackValue.FieldForSharedVar fieldForSharedVar = (StackValue.FieldForSharedVar) value; Type sharedType = StackValue.sharedTypeForType(value.type); - v.visitFieldInsn(Opcodes.GETFIELD, fieldForSharedVar.owner.getInternalName(), fieldForSharedVar.name, sharedType.getDescriptor()); + v.visitFieldInsn(Opcodes.GETFIELD, fieldForSharedVar.owner.getInternalName(), fieldForSharedVar.name, + sharedType.getDescriptor()); } return value; @@ -1215,11 +1245,15 @@ public class ExpressionCodegen extends JetVisitor { int opcode = isStatic ? Opcodes.INVOKESTATIC : isInterface ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL; v.visitMethodInsn(opcode, owner.getInternalName(), functionDescriptor.getName().getName(), - typeMapper.mapSignature(functionDescriptor.getName(),functionDescriptor).getAsmMethod().getDescriptor()); + typeMapper.mapSignature(functionDescriptor.getName(), functionDescriptor).getAsmMethod().getDescriptor()); StackValue.onStack(asmType(functionDescriptor.getReturnType())).coerce(type, v); } - public StackValue.Property intermediateValueForProperty(PropertyDescriptor propertyDescriptor, final boolean forceField, @Nullable JetSuperExpression superExpression) { + public StackValue.Property intermediateValueForProperty( + PropertyDescriptor propertyDescriptor, + final boolean forceField, + @Nullable JetSuperExpression superExpression + ) { boolean isSuper = superExpression != null; DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration(); @@ -1232,23 +1266,27 @@ public class ExpressionCodegen extends JetVisitor { PropertyDescriptor initialDescriptor = propertyDescriptor; propertyDescriptor = initialDescriptor.getOriginal(); boolean isInsideClass = !isFakeOverride && (((containingDeclaration == context.getThisDescriptor()) || - (context.getParentContext() instanceof CodegenContexts.NamespaceContext) && context.getParentContext().getContextDescriptor() == containingDeclaration) - && contextKind() != OwnerKind.TRAIT_IMPL); + (context.getParentContext() instanceof CodegenContexts.NamespaceContext) && + context.getParentContext().getContextDescriptor() == containingDeclaration) + && contextKind() != OwnerKind.TRAIT_IMPL); Method getter = null; Method setter = null; if (!forceField) { //noinspection ConstantConditions - if (isInsideClass && (propertyDescriptor.getGetter() == null || propertyDescriptor.getGetter().isDefault() && propertyDescriptor.getGetter().getModality() == Modality.FINAL)) { + if (isInsideClass && + (propertyDescriptor.getGetter() == null || + propertyDescriptor.getGetter().isDefault() && propertyDescriptor.getGetter().getModality() == Modality.FINAL)) { getter = null; } else { if (isSuper) { PsiElement enclosingElement = bindingContext.get(BindingContext.LABEL_TARGET, superExpression.getTargetLabel()); - ClassDescriptor enclosed = (ClassDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, enclosingElement); + ClassDescriptor enclosed = + (ClassDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, enclosingElement); if (!CodegenUtil.isInterface(containingDeclaration)) { if (enclosed != null && enclosed != context.getThisDescriptor()) { CodegenContext c = context; - while(c.getContextDescriptor() != enclosed) { + while (c.getContextDescriptor() != enclosed) { c = c.getParentContext(); } propertyDescriptor = (PropertyDescriptor) c.getAccessor(propertyDescriptor); @@ -1269,20 +1307,22 @@ public class ExpressionCodegen extends JetVisitor { if (getter == null && propertyDescriptor.getReceiverParameter().exists()) { throw new IllegalStateException(); } - } //noinspection ConstantConditions - if (isInsideClass && (propertyDescriptor.getSetter() == null || propertyDescriptor.getSetter().isDefault() && propertyDescriptor.getSetter().getModality() == Modality.FINAL)) { + if (isInsideClass && + (propertyDescriptor.getSetter() == null || + propertyDescriptor.getSetter().isDefault() && propertyDescriptor.getSetter().getModality() == Modality.FINAL)) { setter = null; } else { - JvmPropertyAccessorSignature jvmMethodSignature = typeMapper.mapSetterSignature(propertyDescriptor, OwnerKind.IMPLEMENTATION); + JvmPropertyAccessorSignature jvmMethodSignature = + typeMapper.mapSetterSignature(propertyDescriptor, OwnerKind.IMPLEMENTATION); setter = jvmMethodSignature != null ? jvmMethodSignature.getJvmMethodSignature().getAsmMethod() : null; if (propertyDescriptor.getSetter() == null) { setter = null; } - + if (setter == null && propertyDescriptor.isVar() && propertyDescriptor.getReceiverParameter().exists()) { throw new IllegalStateException(); } @@ -1306,26 +1346,33 @@ public class ExpressionCodegen extends JetVisitor { // TODO ugly CallableMethod callableMethod = typeMapper.mapToCallableMethod(propertyDescriptor.getGetter(), isSuper, contextKind()); invokeOpcode = callableMethod.getInvokeOpcode(); - owner = isFakeOverride && !overridesTrait && !CodegenUtil.isInterface(initialDescriptor.getContainingDeclaration()) ? JvmClassName.byType(typeMapper.mapType(((ClassDescriptor)initialDescriptor.getContainingDeclaration()).getDefaultType(), MapTypeMode.IMPL)): callableMethod.getOwner(); + owner = isFakeOverride && !overridesTrait && !CodegenUtil.isInterface(initialDescriptor.getContainingDeclaration()) + ? JvmClassName.byType(typeMapper.mapType( + ((ClassDescriptor) initialDescriptor.getContainingDeclaration()).getDefaultType(), MapTypeMode.IMPL)) + : callableMethod.getOwner(); ownerParam = callableMethod.getDefaultImplParam(); } - return StackValue.property(propertyDescriptor.getName().getName(), owner, ownerParam, asmType(propertyDescriptor.getType()), isStatic, isInterface, isSuper, getter, setter, invokeOpcode); + return StackValue + .property(propertyDescriptor.getName().getName(), owner, ownerParam, asmType(propertyDescriptor.getType()), isStatic, + isInterface, isSuper, getter, setter, invokeOpcode); } private PropertyDescriptor accessablePropertyDescriptor(PropertyDescriptor propertyDescriptor) { - if ((propertyDescriptor.getVisibility() == Visibilities.PRIVATE ||(propertyDescriptor.getSetter() != null && propertyDescriptor.getSetter().getVisibility() == Visibilities.PRIVATE)) - && !DescriptorUtils.isClassObject(propertyDescriptor.getContainingDeclaration()) - && propertyDescriptor.getContainingDeclaration() instanceof ClassDescriptor) { + if ((propertyDescriptor.getVisibility() == Visibilities.PRIVATE || + (propertyDescriptor.getSetter() != null && propertyDescriptor.getSetter().getVisibility() == Visibilities.PRIVATE)) + && !DescriptorUtils.isClassObject(propertyDescriptor.getContainingDeclaration()) + && propertyDescriptor.getContainingDeclaration() instanceof ClassDescriptor) { if (context.getClassOrNamespaceDescriptor() != propertyDescriptor.getContainingDeclaration()) { DeclarationDescriptor enclosed = propertyDescriptor.getContainingDeclaration(); if (enclosed != context.getThisDescriptor()) { CodegenContext c = context; - while(c != null && c.getContextDescriptor() != enclosed) { + while (c != null && c.getContextDescriptor() != enclosed) { c = c.getParentContext(); } - if(c != null) + if (c != null) { propertyDescriptor = (PropertyDescriptor) c.getAccessor(propertyDescriptor); + } } } } @@ -1376,10 +1423,12 @@ public class ExpressionCodegen extends JetVisitor { } } - private StackValue invokeFunction(JetCallExpression expression, + private StackValue invokeFunction( + JetCallExpression expression, FunctionDescriptor fd, StackValue receiver, - ResolvedCall resolvedCall) { + ResolvedCall resolvedCall + ) { boolean superCall = false; if (expression.getParent() instanceof JetQualifiedExpression) { final JetExpression receiverExpression = ((JetQualifiedExpression) expression.getParent()).getReceiverExpression(); @@ -1390,12 +1439,13 @@ public class ExpressionCodegen extends JetVisitor { PsiElement enclosingElement = bindingContext.get(BindingContext.LABEL_TARGET, superExpression.getTargetLabel()); ClassDescriptor enclosed = (ClassDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, enclosingElement); if (!CodegenUtil.isInterface(fd.getContainingDeclaration())) { - if(enclosed == null) { + if (enclosed == null) { enclosed = (ClassDescriptor) fd.getContainingDeclaration(); } if (enclosed != context.getThisDescriptor()) { CodegenContext c = context; - while(!(c instanceof CodegenContexts.ClassContext) || !DescriptorUtils.isSubclass(c.getThisDescriptor(), enclosed)) { + while (!(c instanceof CodegenContexts.ClassContext) || + !DescriptorUtils.isSubclass(c.getThisDescriptor(), enclosed)) { c = c.getParentContext(); } fd = (FunctionDescriptor) c.getAccessor(fd); @@ -1407,13 +1457,13 @@ public class ExpressionCodegen extends JetVisitor { } if (fd.getVisibility() == Visibilities.PRIVATE - && !DescriptorUtils.isClassObject(fd.getContainingDeclaration()) - && fd.getContainingDeclaration() instanceof ClassDescriptor) { + && !DescriptorUtils.isClassObject(fd.getContainingDeclaration()) + && fd.getContainingDeclaration() instanceof ClassDescriptor) { if (context.getClassOrNamespaceDescriptor() != fd.getContainingDeclaration()) { DeclarationDescriptor enclosed = fd.getContainingDeclaration(); if (enclosed != context.getThisDescriptor()) { CodegenContext c = context; - while(c.getContextDescriptor() != enclosed) { + while (c.getContextDescriptor() != enclosed) { c = c.getParentContext(); } fd = (FunctionDescriptor) c.getAccessor(fd); @@ -1437,10 +1487,10 @@ public class ExpressionCodegen extends JetVisitor { for (ValueArgument argument : expression.getValueArguments()) { args.add(argument.getArgumentExpression()); } - Type callType = typeMapper.mapType(resolvedCall.getCandidateDescriptor().getReturnType(),MapTypeMode.VALUE); + Type callType = typeMapper.mapType(resolvedCall.getCandidateDescriptor().getReturnType(), MapTypeMode.VALUE); Type exprType = expressionType(expression); StackValue stackValue = intrinsic.generate(this, v, callType, expression, args, receiver, state); - stackValue.put(exprType,v); + stackValue.put(exprType, v); return StackValue.onStack(exprType); } } @@ -1483,7 +1533,9 @@ public class ExpressionCodegen extends JetVisitor { else if (fd instanceof ExpressionAsFunctionDescriptor) { return true; } - else if (fd instanceof SimpleFunctionDescriptor && (fd.getContainingDeclaration() instanceof FunctionDescriptor || fd.getContainingDeclaration() instanceof ScriptDescriptor)) { + else if (fd instanceof SimpleFunctionDescriptor && + (fd.getContainingDeclaration() instanceof FunctionDescriptor || + fd.getContainingDeclaration() instanceof ScriptDescriptor)) { return true; } else { @@ -1498,11 +1550,12 @@ public class ExpressionCodegen extends JetVisitor { gen(expression.getCalleeExpression(), calleeType); } - ResolvedCall resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getCalleeExpression()); + ResolvedCall resolvedCall = + bindingContext.get(BindingContext.RESOLVED_CALL, expression.getCalleeExpression()); assert resolvedCall != null; if (resolvedCall instanceof VariableAsFunctionResolvedCall) { - resolvedCall = ((VariableAsFunctionResolvedCall)resolvedCall).getFunctionCall(); + resolvedCall = ((VariableAsFunctionResolvedCall) resolvedCall).getFunctionCall(); } if (!(resolvedCall.getResultingDescriptor() instanceof ConstructorDescriptor)) { // otherwise already @@ -1514,13 +1567,19 @@ public class ExpressionCodegen extends JetVisitor { } int mask = pushMethodArguments(expression, callableMethod.getValueParameterTypes()); - if (mask == 0) + if (mask == 0) { callableMethod.invoke(v); - else + } + else { callableMethod.invokeWithDefault(v, mask); + } } - private void genThisAndReceiverFromResolvedCall(StackValue receiver, ResolvedCall resolvedCall, CallableMethod callableMethod) { + private void genThisAndReceiverFromResolvedCall( + StackValue receiver, + ResolvedCall resolvedCall, + CallableMethod callableMethod + ) { receiver = StackValue.receiver(resolvedCall, receiver, this, callableMethod, state); receiver.put(receiver.type, v); } @@ -1533,9 +1592,12 @@ public class ExpressionCodegen extends JetVisitor { if (DescriptorUtils.isClassObject(classReceiverDeclarationDescriptor)) { ClassDescriptor containingDeclaration = (ClassDescriptor) classReceiverDeclarationDescriptor.getContainingDeclaration(); Type classObjType = typeMapper.mapType(containingDeclaration.getDefaultType(), MapTypeMode.IMPL); - if (context.getContextDescriptor() instanceof ConstructorDescriptor && classReceiverDeclarationDescriptor.getDefaultType().equals(((ConstructorDescriptor)context.getContextDescriptor()).getReturnType())) { + if (context.getContextDescriptor() instanceof ConstructorDescriptor && + classReceiverDeclarationDescriptor.getDefaultType() + .equals(((ConstructorDescriptor) context.getContextDescriptor()).getReturnType())) { v.load(0, classObjType); - } else { + } + else { v.getstatic(classObjType.getInternalName(), "$classobj", exprType.getDescriptor()); } StackValue.onStack(exprType).put(type, v); @@ -1596,18 +1658,21 @@ public class ExpressionCodegen extends JetVisitor { cur = context; StackValue result = StackValue.local(0, TYPE_OBJECT); while (cur != null) { - if (cur instanceof CodegenContexts.MethodContext && !(cur instanceof CodegenContexts.ConstructorContext)) + if (cur instanceof CodegenContexts.MethodContext && !(cur instanceof CodegenContexts.ConstructorContext)) { cur = cur.getParentContext(); + } if (cur instanceof CodegenContexts.ScriptContext) { CodegenContexts.ScriptContext scriptContext = (CodegenContexts.ScriptContext) cur; - JvmClassName currentScriptClassName = state.getInjector().getClosureAnnotator().classNameForScriptDescriptor(scriptContext.getScriptDescriptor()); + JvmClassName currentScriptClassName = + state.getInjector().getClosureAnnotator().classNameForScriptDescriptor(scriptContext.getScriptDescriptor()); if (scriptContext.getScriptDescriptor() == receiver.getDeclarationDescriptor()) { result.put(currentScriptClassName.getAsmType(), v); } else { - JvmClassName className = state.getInjector().getClosureAnnotator().classNameForScriptDescriptor(receiver.getDeclarationDescriptor()); + JvmClassName className = + state.getInjector().getClosureAnnotator().classNameForScriptDescriptor(receiver.getDeclarationDescriptor()); String fieldName = state.getInjector().getScriptCodegen().getScriptFieldName(receiver.getDeclarationDescriptor()); result.put(currentScriptClassName.getAsmType(), v); StackValue.field(className.getAsmType(), currentScriptClassName, fieldName, false).put(className.getAsmType(), v); @@ -1629,13 +1694,14 @@ public class ExpressionCodegen extends JetVisitor { public StackValue generateThisOrOuter(@NotNull final ClassDescriptor calleeContainingClass) { PsiElement psiElement = BindingContextUtils.classDescriptorToDeclaration(bindingContext, calleeContainingClass); boolean isObject = psiElement instanceof JetClassOrObject && CodegenUtil.isNonLiteralObject((JetClassOrObject) psiElement); - + CodegenContext cur = context; Type type = asmType(calleeContainingClass.getDefaultType()); StackValue result = StackValue.local(0, type); while (cur != null) { - if (cur instanceof CodegenContexts.MethodContext && !(cur instanceof CodegenContexts.ConstructorContext)) + if (cur instanceof CodegenContexts.MethodContext && !(cur instanceof CodegenContexts.ConstructorContext)) { cur = cur.getParentContext(); + } if (DescriptorUtils.isSubclass(cur.getThisDescriptor(), calleeContainingClass)) { if (!isObject || (cur.getThisDescriptor() == calleeContainingClass)) { @@ -1653,7 +1719,7 @@ public class ExpressionCodegen extends JetVisitor { } cur = cur.getParentContext(); } - + throw new UnsupportedOperationException(); } @@ -1676,7 +1742,7 @@ public class ExpressionCodegen extends JetVisitor { } int index = 0; - int mask = 0; + int mask = 0; for (ValueParameterDescriptor valueParameterDescriptor : fd.getValueParameters()) { ResolvedValueArgument resolvedValueArgument = valueArguments.get(valueParameterDescriptor.getIndex()); @@ -1686,8 +1752,9 @@ public class ExpressionCodegen extends JetVisitor { } else if (resolvedValueArgument instanceof DefaultValueArgument) { Type type = valueParameterTypes.get(index); - if (type.getSort() == Type.OBJECT||type.getSort() == Type.ARRAY) + if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) { v.aconst(null); + } else if (type.getSort() == Type.FLOAT) { v.aconst(0f); } @@ -1724,7 +1791,7 @@ public class ExpressionCodegen extends JetVisitor { int size = arguments.size(); boolean hasSpread = false; - for(int i = 0; i != size; ++i) { + for (int i = 0; i != size; ++i) { if (arguments.get(i).getSpreadElement() != null) { hasSpread = true; break; @@ -1740,11 +1807,11 @@ public class ExpressionCodegen extends JetVisitor { v.anew(Type.getObjectType(owner)); v.dup(); v.invokespecial(owner, "", "()V"); - for(int i = 0; i != size; ++i) { + for (int i = 0; i != size; ++i) { v.dup(); ValueArgument argument = arguments.get(i); if (argument.getSpreadElement() != null) { - gen(argument.getArgumentExpression(),JetTypeMapper.TYPE_OBJECT); + gen(argument.getArgumentExpression(), JetTypeMapper.TYPE_OBJECT); v.invokevirtual(owner, "addSpread", "(Ljava/lang/Object;)V"); } else { @@ -1763,7 +1830,7 @@ public class ExpressionCodegen extends JetVisitor { else { v.iconst(arguments.size()); v.newarray(elementType); - for(int i = 0; i != size; ++i) { + for (int i = 0; i != size; ++i) { v.dup(); v.iconst(i); gen(arguments.get(i).getArgumentExpression(), elementType); @@ -1773,7 +1840,8 @@ public class ExpressionCodegen extends JetVisitor { } public int pushMethodArguments(JetCallElement expression, List valueParameterTypes) { - ResolvedCall resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getCalleeExpression()); + ResolvedCall resolvedCall = + bindingContext.get(BindingContext.RESOLVED_CALL, expression.getCalleeExpression()); if (resolvedCall != null) { return pushMethodArguments(resolvedCall, valueParameterTypes); } @@ -1795,11 +1863,11 @@ public class ExpressionCodegen extends JetVisitor { public int indexOfLocal(JetReferenceExpression lhs) { final DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, lhs); if (typeMapper.isVarCapturedInClosure(declarationDescriptor)) { - return -1; + return -1; } return lookupLocal(declarationDescriptor); } - + @Override public StackValue visitDotQualifiedExpression(JetDotQualifiedExpression expression, StackValue receiver) { return genQualified(StackValue.none(), expression.getSelectorExpression()); @@ -1875,7 +1943,7 @@ public class ExpressionCodegen extends JetVisitor { return generateElvis(expression); } else if (opToken == JetTokens.IN_KEYWORD || opToken == JetTokens.NOT_IN) { - return generateIn (expression); + return generateIn(expression); } else { DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference()); @@ -1886,7 +1954,7 @@ public class ExpressionCodegen extends JetVisitor { Arrays.asList(expression.getLeft(), expression.getRight()), receiver, state); } else { - return invokeOperation(expression, (FunctionDescriptor)op, (CallableMethod) callable); + return invokeOperation(expression, (FunctionDescriptor) op, (CallableMethod) callable); } } } @@ -1901,10 +1969,11 @@ public class ExpressionCodegen extends JetVisitor { } else { StackValue leftValue = gen(expr); - FunctionDescriptor op = (FunctionDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference()); + FunctionDescriptor op = + (FunctionDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference()); assert op != null; Type type = asmType(op.getValueParameters().get(0).getType()); - if(type.getSize() == 1) { + if (type.getSize() == 1) { leftValue.put(type, v); genToJVMStack(expression.getRight()); v.swap(); @@ -2015,7 +2084,9 @@ public class ExpressionCodegen extends JetVisitor { } if (isPrimitive(leftType)) // both are primitive + { return generateEqualsForExpressionsOnStack(opToken, leftType, rightType, false, false); + } assert leftJetType != null; assert rightJetType != null; @@ -2038,7 +2109,13 @@ public class ExpressionCodegen extends JetVisitor { return StackValue.onStack(Type.BOOLEAN_TYPE); } - public StackValue generateEqualsForExpressionsOnStack(IElementType opToken, Type leftType, Type rightType, boolean leftNullable, boolean rightNullable) { + public StackValue generateEqualsForExpressionsOnStack( + IElementType opToken, + Type leftType, + Type rightType, + boolean leftNullable, + boolean rightNullable + ) { if ((isNumberPrimitive(leftType) || leftType.getSort() == Type.BOOLEAN) && leftType == rightType) { return compareExpressionsOnStack(opToken, leftType); } @@ -2112,7 +2189,7 @@ public class ExpressionCodegen extends JetVisitor { JetType type = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression.getLeft()); assert type != null; final Type leftType = asmType(type); - if (type.isNullable()) { + if (type.isNullable()) { gen(expression.getLeft(), leftType); v.dup(); Label end = new Label(); @@ -2181,12 +2258,12 @@ public class ExpressionCodegen extends JetVisitor { final Callable callable = resolveToCallable((FunctionDescriptor) op, false); final JetExpression lhs = expression.getLeft(); -// if (lhs instanceof JetArrayAccessExpression) { -// JetArrayAccessExpression arrayAccessExpression = (JetArrayAccessExpression) lhs; -// if (arrayAccessExpression.getIndexExpressions().size() != 1) { -// throw new UnsupportedOperationException("Augmented assignment with multi-index"); -// } -// } + // if (lhs instanceof JetArrayAccessExpression) { + // JetArrayAccessExpression arrayAccessExpression = (JetArrayAccessExpression) lhs; + // if (arrayAccessExpression.getIndexExpressions().size() != 1) { + // throw new UnsupportedOperationException("Augmented assignment with multi-index"); + // } + // } Type lhsType = expressionType(lhs); //noinspection ConstantConditions @@ -2211,12 +2288,13 @@ public class ExpressionCodegen extends JetVisitor { final boolean keepReturnValue = !((FunctionDescriptor) op).getReturnType().equals(JetStandardClasses.getUnitType()); callAugAssignMethod(expression, (CallableMethod) callable, lhsType, keepReturnValue); } - + return StackValue.none(); } private void callAugAssignMethod(JetBinaryExpression expression, CallableMethod callable, Type lhsType, final boolean keepReturnValue) { - ResolvedCall resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference()); + ResolvedCall resolvedCall = + bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference()); assert resolvedCall != null; StackValue value = gen(expression.getLeft()); @@ -2269,7 +2347,7 @@ public class ExpressionCodegen extends JetVisitor { public void invokeAppendMethod(Type exprType) { Method appendDescriptor = new Method("append", JL_STRING_BUILDER, - new Type[] { exprType.getSort() == Type.OBJECT ? TYPE_OBJECT : exprType}); + new Type[] {exprType.getSort() == Type.OBJECT ? TYPE_OBJECT : exprType}); v.invokevirtual("java/lang/StringBuilder", "append", appendDescriptor.getDescriptor()); } @@ -2283,7 +2361,7 @@ public class ExpressionCodegen extends JetVisitor { } return null; } - + @Override public StackValue visitPrefixExpression(JetPrefixExpression expression, StackValue receiver) { JetSimpleNameExpression operationSign = expression.getOperationReference(); @@ -2301,11 +2379,12 @@ public class ExpressionCodegen extends JetVisitor { else { DeclarationDescriptor cls = op.getContainingDeclaration(); CallableMethod callableMethod = (CallableMethod) callable; - if (isNumberPrimitive(cls) || !(op.getName().getName().equals("inc") || op.getName().getName().equals("dec")) ) { + if (isNumberPrimitive(cls) || !(op.getName().getName().equals("inc") || op.getName().getName().equals("dec"))) { return invokeOperation(expression, (FunctionDescriptor) op, callableMethod); } else { - ResolvedCall resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference()); + ResolvedCall resolvedCall = + bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference()); assert resolvedCall != null; StackValue value = gen(expression.getBaseExpression()); @@ -2327,12 +2406,13 @@ public class ExpressionCodegen extends JetVisitor { if (functionLocalIndex >= 0) { stackValueForLocal(op, functionLocalIndex).put(ClosureCodegen.getInternalClassName(op).getAsmType(), v); } - ResolvedCall resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference()); + ResolvedCall resolvedCall = + bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference()); assert resolvedCall != null; genThisAndReceiverFromResolvedCall(StackValue.none(), resolvedCall, callable); pushMethodArguments(resolvedCall, callable.getValueParameterTypes()); callable.invoke(v); - return returnValueAsStackValue(op, callable.getSignature().getAsmMethod().getReturnType()); + return returnValueAsStackValue(op, callable.getSignature().getAsmMethod().getReturnType()); } @Override @@ -2350,8 +2430,9 @@ public class ExpressionCodegen extends JetVisitor { v.mark(ok); return StackValue.onStack(base.type); } - else + else { return base; + } } DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference()); if (op instanceof FunctionDescriptor) { @@ -2373,7 +2454,8 @@ public class ExpressionCodegen extends JetVisitor { return StackValue.onStack(asmType); // old value } else { - ResolvedCall resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference()); + ResolvedCall resolvedCall = + bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference()); assert resolvedCall != null; final Callable callable = resolveToCallable((FunctionDescriptor) op, false); @@ -2384,26 +2466,32 @@ public class ExpressionCodegen extends JetVisitor { Type type = expressionType(expression.getBaseExpression()); value.put(type, v); - switch(value.receiverSize()) { + switch (value.receiverSize()) { case 0: - if (type.getSize() == 2) + if (type.getSize() == 2) { v.dup2(); - else + } + else { v.dup(); - break; + } + break; case 1: - if (type.getSize() == 2) + if (type.getSize() == 2) { v.dup2X1(); - else + } + else { v.dupX1(); - break; + } + break; case 2: - if (type.getSize() == 2) + if (type.getSize() == 2) { v.dup2X2(); - else + } + else { v.dupX2(); + } break; case -1: @@ -2462,7 +2550,8 @@ public class ExpressionCodegen extends JetVisitor { if (property.isScriptDeclaration()) { JetScript scriptPsi = property.getScript(); JvmClassName scriptClassName = state.getInjector().getClosureAnnotator().classNameForScriptPsi(scriptPsi); - StackValue field = StackValue.field(typeMapper.mapType(variableDescriptor.getType(), MapTypeMode.VALUE), scriptClassName, property.getName(), false); + StackValue field = StackValue + .field(typeMapper.mapType(variableDescriptor.getType(), MapTypeMode.VALUE), scriptClassName, property.getName(), false); return StackValue.none(); } else { @@ -2474,7 +2563,6 @@ public class ExpressionCodegen extends JetVisitor { sharedVarType = typeMapper.getSharedVarType(variableDescriptor); assert variableDescriptor != null; - } Type varType = asmType(variableDescriptor.getType()); @@ -2500,13 +2588,18 @@ public class ExpressionCodegen extends JetVisitor { else { v.load(index, TYPE_OBJECT); gen(initializer, varType); - v.putfield(sharedVarType.getInternalName(), "ref", sharedVarType == TYPE_SHARED_VAR ? "Ljava/lang/Object;" : varType.getDescriptor()); + v.putfield(sharedVarType.getInternalName(), "ref", + sharedVarType == TYPE_SHARED_VAR ? "Ljava/lang/Object;" : varType.getDescriptor()); } } return StackValue.none(); } - private StackValue generateConstructorCall(JetCallExpression expression, JetSimpleNameExpression constructorReference, StackValue receiver) { + private StackValue generateConstructorCall( + JetCallExpression expression, + JetSimpleNameExpression constructorReference, + StackValue receiver + ) { DeclarationDescriptor constructorDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, constructorReference); final PsiElement declaration = BindingContextUtils.descriptorToDeclaration(bindingContext, constructorDescriptor); Type type; @@ -2533,7 +2626,9 @@ public class ExpressionCodegen extends JetVisitor { receiver.put(receiver.type, v); } - CallableMethod method = typeMapper.mapToCallableMethod((ConstructorDescriptor) constructorDescriptor, OwnerKind.IMPLEMENTATION, typeMapper.hasThis0(((ConstructorDescriptor) constructorDescriptor).getContainingDeclaration())); + CallableMethod method = typeMapper + .mapToCallableMethod((ConstructorDescriptor) constructorDescriptor, OwnerKind.IMPLEMENTATION, typeMapper + .hasThis0(((ConstructorDescriptor) constructorDescriptor).getContainingDeclaration())); invokeMethodWithArguments(method, expression, StackValue.none()); } } @@ -2563,15 +2658,16 @@ public class ExpressionCodegen extends JetVisitor { public void generateNewArray(JetCallExpression expression, JetType arrayType) { List args = new ArrayList(); - for(ValueArgument va : expression.getValueArguments()) + for (ValueArgument va : expression.getValueArguments()) { args.add(va.getArgumentExpression()); + } args.addAll(expression.getFunctionLiteralArguments()); boolean isArray = JetStandardLibraryNames.ARRAY.is(arrayType); if (isArray) { -// if (args.size() != 2 && !arrayType.getArguments().get(0).getType().isNullable()) { -// throw new CompilationException("array constructor of non-nullable type requires two arguments"); -// } + // if (args.size() != 2 && !arrayType.getArguments().get(0).getType().isNullable()) { + // throw new CompilationException("array constructor of non-nullable type requires two arguments"); + // } } else { if (args.size() != 1) { @@ -2590,8 +2686,8 @@ public class ExpressionCodegen extends JetVisitor { } if (args.size() == 2) { - int sizeIndex = myFrameMap.enterTemp(2); - int indexIndex = sizeIndex+1; + int sizeIndex = myFrameMap.enterTemp(2); + int indexIndex = sizeIndex + 1; v.dup(); v.arraylength(); @@ -2606,7 +2702,7 @@ public class ExpressionCodegen extends JetVisitor { Label end = new Label(); v.visitLabel(begin); v.load(indexIndex, Type.INT_TYPE); - v.load(sizeIndex, Type.INT_TYPE); + v.load(sizeIndex, Type.INT_TYPE); v.ificmpge(end); v.dup2(); @@ -2634,7 +2730,9 @@ public class ExpressionCodegen extends JetVisitor { final List indices = expression.getIndexExpressions(); FunctionDescriptor operationDescriptor = (FunctionDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, expression); assert operationDescriptor != null; - if (arrayType.getSort() == Type.ARRAY && indices.size() == 1 && JetStandardLibraryNames.INT.is(operationDescriptor.getValueParameters().get(0).getType())) { + if (arrayType.getSort() == Type.ARRAY && + indices.size() == 1 && + JetStandardLibraryNames.INT.is(operationDescriptor.getValueParameters().get(0).getType())) { gen(array, arrayType); for (JetExpression index : indices) { gen(index, Type.INT_TYPE); @@ -2665,13 +2763,14 @@ public class ExpressionCodegen extends JetVisitor { int index = 0; if (isGetter) { Callable callable = resolveToCallable(getterDescriptor, false); - if (callable instanceof CallableMethod) + if (callable instanceof CallableMethod) { genThisAndReceiverFromResolvedCall(receiver, resolvedGetCall, (CallableMethod) callable); + } else { assert getterDescriptor != null; - gen(array, asmType(((ClassDescriptor)getterDescriptor.getContainingDeclaration()).getDefaultType())); + gen(array, asmType(((ClassDescriptor) getterDescriptor.getContainingDeclaration()).getDefaultType())); } - + assert getterDescriptor != null; if (getterDescriptor.getReceiverParameter().exists()) { index++; @@ -2684,13 +2783,14 @@ public class ExpressionCodegen extends JetVisitor { if (callable instanceof CallableMethod) { genThisAndReceiverFromResolvedCall(receiver, resolvedSetCall, (CallableMethod) callable); } - else + else { gen(array, arrayType); + } if (setterDescriptor.getReceiverParameter().exists()) { index++; } - asmType = argumentTypes[argumentTypes.length-1]; + asmType = argumentTypes[argumentTypes.length - 1]; } for (JetExpression jetExpression : expression.getIndexExpressions()) { @@ -2877,8 +2977,10 @@ The "returned" value of try expression with no finally is either the last expres } // on entering the function, expressionToMatch is already placed on stack, and we should consume it - private StackValue generatePatternMatch(JetPattern pattern, boolean negated, StackValue expressionToMatch, - boolean expressionToMatchIsNullable, @Nullable Label nextEntry) { + private StackValue generatePatternMatch( + JetPattern pattern, boolean negated, StackValue expressionToMatch, + boolean expressionToMatchIsNullable, @Nullable Label nextEntry + ) { if (pattern instanceof JetTypePattern) { JetTypeReference typeReference = ((JetTypePattern) pattern).getTypeReference(); JetType jetType = bindingContext.get(BindingContext.TYPE, typeReference); @@ -2911,7 +3013,8 @@ The "returned" value of try expression with no finally is either the last expres patternIsNullable = condJetType != null && condJetType.isNullable(); } gen(condExpression, condType); - return generateEqualsForExpressionsOnStack(JetTokens.EQEQ, subjectType, condType, expressionToMatchIsNullable, patternIsNullable); + return generateEqualsForExpressionsOnStack(JetTokens.EQEQ, subjectType, condType, expressionToMatchIsNullable, + patternIsNullable); } else { JetExpression condExpression = ((JetExpressionPattern) pattern).getExpression(); @@ -2938,8 +3041,10 @@ The "returned" value of try expression with no finally is either the last expres } } - private StackValue generateTuplePatternMatch(JetTuplePattern pattern, boolean negated, StackValue expressionToMatch, - @Nullable Label nextEntry) { + private StackValue generateTuplePatternMatch( + JetTuplePattern pattern, boolean negated, StackValue expressionToMatch, + @Nullable Label nextEntry + ) { final List entries = pattern.getEntries(); Label lblFail = new Label(); @@ -2969,7 +3074,7 @@ The "returned" value of try expression with no finally is either the last expres v.goTo(nextEntry); } else { - v.iconst(!negated?1:0); + v.iconst(!negated ? 1 : 0); } v.goTo(lblDone); v.mark(lblFail); @@ -2977,7 +3082,7 @@ The "returned" value of try expression with no finally is either the last expres v.goTo(nextEntry); } else { - v.iconst(negated?1:0); + v.iconst(negated ? 1 : 0); } v.mark(lblDone); return StackValue.onStack(Type.BOOLEAN_TYPE); @@ -3068,24 +3173,27 @@ The "returned" value of try expression with no finally is either the last expres return StackValue.onStack(resultType); } - private StackValue generateWhenCondition(Type subjectType, int subjectLocal, boolean subjectIsNullable, - JetWhenCondition condition, @Nullable Label nextEntry) { + private StackValue generateWhenCondition( + Type subjectType, int subjectLocal, boolean subjectIsNullable, + JetWhenCondition condition, @Nullable Label nextEntry + ) { if (condition instanceof JetWhenConditionInRange) { JetWhenConditionInRange conditionInRange = (JetWhenConditionInRange) condition; JetExpression rangeExpression = conditionInRange.getRangeExpression(); while (rangeExpression instanceof JetParenthesizedExpression) { - rangeExpression = ((JetParenthesizedExpression)rangeExpression).getExpression(); + rangeExpression = ((JetParenthesizedExpression) rangeExpression).getExpression(); } boolean inverted = conditionInRange.getOperationReference().getReferencedNameElementType() == JetTokens.NOT_IN; if (isIntRangeExpr(rangeExpression)) { getInIntRange(new StackValue.Local(subjectLocal, subjectType), (JetBinaryExpression) rangeExpression, inverted); } else { - FunctionDescriptor op = (FunctionDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, conditionInRange.getOperationReference()); + FunctionDescriptor op = + (FunctionDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, conditionInRange.getOperationReference()); genToJVMStack(rangeExpression); new StackValue.Local(subjectLocal, subjectType).put(TYPE_OBJECT, v); invokeFunctionNoParams(op, Type.BOOLEAN_TYPE, v); - if(inverted) { + if (inverted) { invertBoolean(); } } @@ -3131,7 +3239,7 @@ The "returned" value of try expression with no finally is either the last expres } } } - return false ; + return false; } @Override diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 3a4218d912d..7044253cdce 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -84,8 +84,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if (myClass instanceof JetClass) { JetClass jetClass = (JetClass) myClass; - if (jetClass.hasModifier(JetTokens.ABSTRACT_KEYWORD)) - isAbstract = true; + if (jetClass.hasModifier(JetTokens.ABSTRACT_KEYWORD)) { + isAbstract = true; + } if (jetClass.isTrait()) { isAbstract = true; isInterface = true; @@ -132,7 +133,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { access |= ACC_ENUM; } v.defineClass(myClass, V1_6, - access, + access, signature.getName(), signature.getJavaGenericSignature(), signature.getSuperclassName(), @@ -170,7 +171,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if (descriptor.getClassObjectDescriptor() != null) { int innerClassAccess = ACC_PUBLIC | ACC_FINAL | ACC_STATIC; String outerClassInernalName = typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName(); - v.visitInnerClass(outerClassInernalName + JvmAbi.CLASS_OBJECT_SUFFIX, outerClassInernalName, JvmAbi.CLASS_OBJECT_CLASS_NAME, innerClassAccess); + v.visitInnerClass(outerClassInernalName + JvmAbi.CLASS_OBJECT_SUFFIX, outerClassInernalName, JvmAbi.CLASS_OBJECT_CLASS_NAME, + innerClassAccess); } AnnotationCodegen.forClass(v.getVisitor(), typeMapper).genAnnotations(descriptor); @@ -209,7 +211,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { List typeParameters = descriptor.getTypeConstructor().getParameters(); typeMapper.writeFormalTypeParameters(typeParameters, signatureVisitor); } - + signatureVisitor.writeSupersStart(); { // superclass @@ -242,10 +244,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { superInterfaces = new ArrayList(superInterfacesLinkedHashSet); } - + signatureVisitor.writeSupersEnd(); - return new JvmClassSignature(jvmName(), superClass, superInterfaces, signatureVisitor.makeJavaString(), signatureVisitor.makeKotlinClassSignature()); + return new JvmClassSignature(jvmName(), superClass, superInterfaces, signatureVisitor.makeJavaString(), + signatureVisitor.makeKotlinClassSignature()); } private String jvmName() { @@ -261,8 +264,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { List delegationSpecifiers = myClass.getDelegationSpecifiers(); - if (myClass instanceof JetClass && ((JetClass) myClass).isTrait()) + if (myClass instanceof JetClass && ((JetClass) myClass).isTrait()) { return; + } if (kind != OwnerKind.IMPLEMENTATION) { throw new IllegalStateException("must be impl to reach this code: " + kind); @@ -281,10 +285,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } } - if(superClassType == null) { - if (myClass instanceof JetClass && ((JetClass) myClass).hasModifier(JetTokens.ENUM_KEYWORD)) { + if (superClassType == null) { + if (descriptor.getKind() == ClassKind.ENUM_CLASS) { superClassType = JetStandardLibrary.getInstance().getEnumType(descriptor.getDefaultType()); - superClass = typeMapper.mapType(superClassType,MapTypeMode.VALUE).getInternalName(); + superClass = typeMapper.mapType(superClassType, MapTypeMode.VALUE).getInternalName(); + } + if (descriptor.getKind() == ClassKind.ENUM_ENTRY) { + superClassType = descriptor.getTypeConstructor().getSupertypes().iterator().next(); + superClass = typeMapper.mapType(superClassType, MapTypeMode.VALUE).getInternalName(); } } } @@ -300,10 +308,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { catch (CompilationException e) { throw e; } - catch(ProcessCanceledException e) { + catch (ProcessCanceledException e) { throw e; } - catch(RuntimeException e) { + catch (RuntimeException e) { throw new RuntimeException("Error generating primary constructor of class " + myClass.getName() + " with kind " + kind, e); } @@ -315,18 +323,20 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } private void generateEnumMethods() { - if(myEnumConstants.size() > 0) { + if (myEnumConstants.size() > 0) { { - Type type = typeMapper.mapType(JetStandardLibrary.getInstance().getArrayType(descriptor.getDefaultType()), MapTypeMode.IMPL); + Type type = + typeMapper.mapType(JetStandardLibrary.getInstance().getArrayType(descriptor.getDefaultType()), MapTypeMode.IMPL); MethodVisitor mv = v.newMethod(myClass, ACC_PUBLIC | ACC_STATIC, "values", "()" + type.getDescriptor(), null, null); mv.visitCode(); - mv.visitFieldInsn(GETSTATIC, typeMapper.mapType(descriptor.getDefaultType(),MapTypeMode.VALUE).getInternalName(), VALUES, type.getDescriptor()); + mv.visitFieldInsn(GETSTATIC, typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), VALUES, + type.getDescriptor()); mv.visitMethodInsn(INVOKEVIRTUAL, type.getInternalName(), "clone", "()Ljava/lang/Object;"); mv.visitTypeInsn(CHECKCAST, type.getInternalName()); mv.visitInsn(ARETURN); - FunctionCodegen.endVisit(mv,"values()",myClass); + FunctionCodegen.endVisit(mv, "values()", myClass); } { Type type = typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.IMPL); @@ -339,7 +349,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { mv.visitMethodInsn(INVOKESTATIC, "java/lang/Enum", "valueOf", "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;"); mv.visitTypeInsn(CHECKCAST, type.getInternalName()); mv.visitInsn(ARETURN); - FunctionCodegen.endVisit(mv,"values()",myClass); + FunctionCodegen.endVisit(mv, "values()", myClass); } } } @@ -393,10 +403,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { Method method = typeMapper.mapGetterSignature(bridge, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod(); JvmPropertyAccessorSignature originalSignature = typeMapper.mapGetterSignature(original, OwnerKind.IMPLEMENTATION); Method originalMethod = originalSignature.getJvmMethodSignature().getAsmMethod(); - MethodVisitor mv = v.newMethod(null, ACC_BRIDGE | ACC_SYNTHETIC | ACC_STATIC, method.getName(), method.getDescriptor(), null, null); + MethodVisitor mv = + v.newMethod(null, ACC_BRIDGE | ACC_SYNTHETIC | ACC_STATIC, method.getName(), method.getDescriptor(), null, null); PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature.getPropertyTypeKotlinSignature(), originalSignature.getJvmMethodSignature().getKotlinTypeParameter(), - original, ((PropertyDescriptor) entry.getValue()).getGetter().getVisibility()); + original, + ((PropertyDescriptor) entry.getValue()).getGetter().getVisibility()); if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { StubCodegen.generateStubCode(mv); } @@ -406,25 +418,30 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { InstructionAdapter iv = new InstructionAdapter(mv); iv.load(0, JetTypeMapper.TYPE_OBJECT); - if (original.getVisibility() == Visibilities.PRIVATE) - iv.getfield(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), original.getName().getName(), originalMethod.getReturnType().getDescriptor()); - else - iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), originalMethod.getName(), originalMethod.getDescriptor()); + if (original.getVisibility() == Visibilities.PRIVATE) { + iv.getfield(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), original.getName().getName(), + originalMethod.getReturnType().getDescriptor()); + } + else { + iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), + originalMethod.getName(), originalMethod.getDescriptor()); + } iv.areturn(method.getReturnType()); FunctionCodegen.endVisit(iv, "accessor", null); } } - if (bridge.isVar()) - { + if (bridge.isVar()) { Method method = typeMapper.mapSetterSignature(bridge, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod(); JvmPropertyAccessorSignature originalSignature2 = typeMapper.mapSetterSignature(original, OwnerKind.IMPLEMENTATION); Method originalMethod = originalSignature2.getJvmMethodSignature().getAsmMethod(); - MethodVisitor mv = v.newMethod(null, ACC_STATIC | ACC_BRIDGE | ACC_FINAL, method.getName(), method.getDescriptor(), null, null); + MethodVisitor mv = + v.newMethod(null, ACC_STATIC | ACC_BRIDGE | ACC_FINAL, method.getName(), method.getDescriptor(), null, null); PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature2.getPropertyTypeKotlinSignature(), originalSignature2.getJvmMethodSignature().getKotlinTypeParameter(), - original, ((PropertyDescriptor) entry.getValue()).getSetter().getVisibility()); + original, + ((PropertyDescriptor) entry.getValue()).getSetter().getVisibility()); if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { StubCodegen.generateStubCode(mv); } @@ -441,10 +458,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { //noinspection AssignmentToForLoopParameter reg += argType.getSize(); } - if (original.getVisibility() == Visibilities.PRIVATE && original.getModality() == Modality.FINAL) - iv.putfield(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), original.getName().getName(), originalMethod.getArgumentTypes()[0].getDescriptor()); - else - iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), originalMethod.getName(), originalMethod.getDescriptor()); + if (original.getVisibility() == Visibilities.PRIVATE && original.getModality() == Modality.FINAL) { + iv.putfield(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), original.getName().getName(), + originalMethod.getArgumentTypes()[0].getDescriptor()); + } + else { + iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION).getInternalName(), + originalMethod.getName(), originalMethod.getDescriptor()); + } iv.areturn(method.getReturnType()); FunctionCodegen.endVisit(iv, "accessor", null); @@ -471,7 +492,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { v.putstatic(name, "$instance", typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getDescriptor()); } }); - } } @@ -500,9 +520,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { protected void generatePrimaryConstructor() { if (myClass instanceof JetClass) { - JetClass aClass = (JetClass)myClass; - if (aClass.isTrait()) + JetClass aClass = (JetClass) myClass; + if (aClass.isTrait()) { return; + } if (aClass.isAnnotation()) { return; } @@ -521,27 +542,32 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { boolean hasThis0 = typeMapper.hasThis0(descriptor); if (constructorDescriptor == null) { BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, false); - + signatureWriter.writeFormalTypeParametersStart(); signatureWriter.writeFormalTypeParametersEnd(); - + signatureWriter.writeParametersStart(); - + if (hasThis0) { signatureWriter.writeParameterType(JvmMethodParameterKind.THIS0); - typeMapper.mapType(typeMapper.getClosureAnnotator().getEclosingClassDescriptor(descriptor).getDefaultType(), signatureWriter, MapTypeMode.VALUE); + typeMapper + .mapType(typeMapper.getClosureAnnotator().getEclosingClassDescriptor(descriptor).getDefaultType(), signatureWriter, + MapTypeMode.VALUE); signatureWriter.writeParameterTypeEnd(); } signatureWriter.writeParametersEnd(); - + signatureWriter.writeVoidReturn(); constructorMethod = signatureWriter.makeJvmMethodSignature(""); - callableMethod = new CallableMethod(JvmClassName.byInternalName("Ignored"), null, null, constructorMethod, INVOKESPECIAL, null, null, null); + callableMethod = + new CallableMethod(JvmClassName.byInternalName("Ignored"), null, null, constructorMethod, INVOKESPECIAL, null, null, + null); } else { - callableMethod = typeMapper.mapToCallableMethod(constructorDescriptor, kind, typeMapper.hasThis0(constructorDescriptor.getContainingDeclaration())); + callableMethod = typeMapper.mapToCallableMethod(constructorDescriptor, kind, + typeMapper.hasThis0(constructorDescriptor.getContainingDeclaration())); constructorMethod = callableMethod.getSignature(); } @@ -566,22 +592,28 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { ObjectOrClosureCodegen closure = context.closure; int firstSuperArgument = -1; - final LinkedList consArgTypes = new LinkedList(constructorMethod.getKotlinParameterTypes()); + final LinkedList consArgTypes = + new LinkedList(constructorMethod.getKotlinParameterTypes()); int insert = 0; if (closure != null) { if (closure.captureThis != null) { - if (!hasThis0) - consArgTypes.add(insert, new JvmMethodParameterSignature(Type.getObjectType(context.getThisDescriptor().getName().getName()), "", JvmMethodParameterKind.THIS0)); + if (!hasThis0) { + consArgTypes.add(insert, + new JvmMethodParameterSignature(Type.getObjectType(context.getThisDescriptor().getName().getName()), + "", JvmMethodParameterKind.THIS0)); + } insert++; } else { - if (hasThis0) + if (hasThis0) { insert++; + } } - if (closure.captureReceiver != null) + if (closure.captureReceiver != null) { consArgTypes.add(insert++, new JvmMethodParameterSignature(closure.captureReceiver, "", JvmMethodParameterKind.RECEIVER)); + } for (DeclarationDescriptor descriptor : closure.closure.keySet()) { if (descriptor instanceof VariableDescriptor && !(descriptor instanceof PropertyDescriptor)) { @@ -591,7 +623,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { type = sharedVarType; } else { - type = state.getInjector().getJetTypeMapper().mapType(((VariableDescriptor) descriptor).getType(), MapTypeMode.VALUE); + type = state.getInjector().getJetTypeMapper() + .mapType(((VariableDescriptor) descriptor).getType(), MapTypeMode.VALUE); } consArgTypes.add(insert++, new JvmMethodParameterSignature(type, "", JvmMethodParameterKind.SHARED_VAR)); } @@ -603,16 +636,20 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if (myClass instanceof JetObjectDeclaration && ((JetObjectDeclaration) myClass).isObjectLiteral()) { if (superCall instanceof JetDelegatorToSuperCall) { - if (closure != null) + if (closure != null) { closure.superCall = (JetDelegatorToSuperCall) superCall; - DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression().getConstructorReferenceExpression()); + } + DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, + ((JetDelegatorToSuperCall) superCall).getCalleeExpression() + .getConstructorReferenceExpression()); if (declarationDescriptor instanceof ClassDescriptor) { declarationDescriptor = ((ClassDescriptorFromSource) declarationDescriptor).getUnsubstitutedPrimaryConstructor(); } ConstructorDescriptor superConstructor = (ConstructorDescriptor) declarationDescriptor; - CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION, typeMapper.hasThis0(superConstructor.getContainingDeclaration())); + CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION, typeMapper + .hasThis0(superConstructor.getContainingDeclaration())); firstSuperArgument = insert; - for(Type t : superCallable.getSignature().getAsmMethod().getArgumentTypes()) { + for (Type t : superCallable.getSignature().getAsmMethod().getArgumentTypes()) { consArgTypes.add(insert++, new JvmMethodParameterSignature(t, "", JvmMethodParameterKind.SHARED_VAR)); } } @@ -621,7 +658,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } int flags = JetTypeMapper.getAccessModifiers(constructorDescriptor, 0); - final MethodVisitor mv = v.newMethod(myClass, flags, constructorMethod.getName(), constructorMethod.getAsmMethod().getDescriptor(), constructorMethod.getGenericsSignature(), null); + final MethodVisitor mv = v.newMethod(myClass, flags, constructorMethod.getName(), constructorMethod.getAsmMethod().getDescriptor(), + constructorMethod.getGenericsSignature(), null); if (state.getClassBuilderMode() == ClassBuilderMode.SIGNATURES) return; AnnotationVisitor jetConstructorVisitor = mv.visitAnnotation(JvmStdlibNames.JET_CONSTRUCTOR.getDescriptor(), true); @@ -632,7 +670,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } jetConstructorVisitor.visitEnd(); - + AnnotationCodegen.forMethod(mv, typeMapper).genAnnotations(constructorDescriptor); if (constructorDescriptor != null) { @@ -642,13 +680,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { i++; } - if(myClass instanceof JetClass && ((JetClass)myClass).hasModifier(JetTokens.ENUM_KEYWORD)) { + if (descriptor.getKind() == ClassKind.ENUM_CLASS || descriptor.getKind() == ClassKind.ENUM_ENTRY) { i += 2; } for (ValueParameterDescriptor valueParameter : constructorDescriptor.getValueParameters()) { AnnotationCodegen.forParameter(i, mv, state.getInjector().getJetTypeMapper()).genAnnotations(valueParameter); - JetValueParameterAnnotationWriter jetValueParameterAnnotation = JetValueParameterAnnotationWriter.visitParameterAnnotation(mv, i); + JetValueParameterAnnotationWriter jetValueParameterAnnotation = + JetValueParameterAnnotationWriter.visitParameterAnnotation(mv, i); jetValueParameterAnnotation.writeName(valueParameter.getName().getName()); jetValueParameterAnnotation.writeHasDefaultValue(valueParameter.declaresDefaultValue()); jetValueParameterAnnotation.writeType(constructorMethod.getKotlinParameterType(i)); @@ -665,20 +704,20 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { mv.visitCode(); List paramDescrs = constructorDescriptor != null - ? constructorDescriptor.getValueParameters() - : Collections.emptyList(); + ? constructorDescriptor.getValueParameters() + : Collections.emptyList(); ConstructorFrameMap frameMap = new ConstructorFrameMap(callableMethod, constructorDescriptor, hasThis0); final InstructionAdapter iv = new InstructionAdapter(mv); ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, constructorContext, state); -// for(int slot = 0; slot != frameMap.getTypeParameterCount(); ++slot) { -// if (constructorDescriptor != null) -// codegen.addTypeParameter(constructorDescriptor.getTypeParameters().get(slot), StackValue.local(frameMap.getFirstTypeParameter() + slot, JetTypeMapper.TYPE_TYPEINFO)); -// else -// codegen.addTypeParameter(descriptor.getTypeConstructor().getParameters().get(slot), StackValue.local(frameMap.getFirstTypeParameter() + slot, JetTypeMapper.TYPE_TYPEINFO)); -// } + // for(int slot = 0; slot != frameMap.getTypeParameterCount(); ++slot) { + // if (constructorDescriptor != null) + // codegen.addTypeParameter(constructorDescriptor.getTypeParameters().get(slot), StackValue.local(frameMap.getFirstTypeParameter() + slot, JetTypeMapper.TYPE_TYPEINFO)); + // else + // codegen.addTypeParameter(descriptor.getTypeConstructor().getParameters().get(slot), StackValue.local(frameMap.getFirstTypeParameter() + slot, JetTypeMapper.TYPE_TYPEINFO)); + // } Type classType = typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.IMPL); JvmClassName classname = JvmClassName.byType(classType); @@ -694,7 +733,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if (superCall == null) { iv.load(0, Type.getType("L" + superClass + ";")); - if(descriptor.getKind() == ClassKind.ENUM_CLASS) { + if (descriptor.getKind() == ClassKind.ENUM_CLASS || descriptor.getKind() == ClassKind.ENUM_ENTRY) { iv.load(1, JetTypeMapper.JL_STRING_TYPE); iv.load(2, Type.INT_TYPE); iv.invokespecial(superClass, "", "(Ljava/lang/String;I)V"); @@ -711,14 +750,20 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); if (typeMapper.hasThis0(superClassDescriptor)) { iv.load(1, JetTypeMapper.TYPE_OBJECT); - parameterTypes.add(typeMapper.mapType(typeMapper.getClosureAnnotator().getEclosingClassDescriptor(descriptor).getDefaultType(), MapTypeMode.VALUE)); + parameterTypes.add(typeMapper.mapType( + typeMapper.getClosureAnnotator().getEclosingClassDescriptor(descriptor).getDefaultType(), MapTypeMode.VALUE)); } Method superCallMethod = new Method("", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()])); - iv.invokespecial(typeMapper.mapType(superClassDescriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), "", superCallMethod.getDescriptor()); + iv.invokespecial(typeMapper.mapType(superClassDescriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), "", + superCallMethod.getDescriptor()); } else { - ConstructorDescriptor constructorDescriptor1 = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression().getConstructorReferenceExpression()); - generateDelegatorToConstructorCall(iv, codegen, (JetDelegatorToSuperCall) superCall, constructorDescriptor1, frameMap, firstSuperArgument); + ConstructorDescriptor constructorDescriptor1 = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, + ((JetDelegatorToSuperCall) superCall) + .getCalleeExpression() + .getConstructorReferenceExpression()); + generateDelegatorToConstructorCall(iv, codegen, (JetDelegatorToSuperCall) superCall, constructorDescriptor1, frameMap, + firstSuperArgument); } final ClassDescriptor outerDescriptor = typeMapper.getClosureAnnotator().getEclosingClassDescriptor(descriptor); @@ -738,7 +783,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if (closure.captureReceiver != null) { iv.load(0, JetTypeMapper.TYPE_OBJECT); iv.load(1, closure.captureReceiver); - iv.putfield(typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), "receiver$0", closure.captureReceiver.getDescriptor()); + iv.putfield(typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), "receiver$0", + closure.captureReceiver.getDescriptor()); k += closure.captureReceiver.getSize(); } @@ -752,7 +798,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { iv.load(0, JetTypeMapper.TYPE_OBJECT); iv.load(k, StackValue.refType(sharedVarType)); k += StackValue.refType(sharedVarType).getSize(); - iv.putfield(typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), "$" + varDescr.getName(), sharedVarType.getDescriptor()); + iv.putfield(typeMapper.mapType(descriptor.getDefaultType(), MapTypeMode.VALUE).getInternalName(), + "$" + varDescr.getName(), sharedVarType.getDescriptor()); l++; } } @@ -760,8 +807,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { int n = 0; for (JetDelegationSpecifier specifier : myClass.getDelegationSpecifiers()) { - if (specifier == superCall) + if (specifier == superCall) { continue; + } if (specifier instanceof JetDelegatorByExpressionSpecifier) { iv.load(0, classType); @@ -779,8 +827,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { JetClass superClass = (JetClass) BindingContextUtils.classDescriptorToDeclaration(bindingContext, superClassDescriptor); final CodegenContext delegateContext = context.intoClass(superClassDescriptor, - new OwnerKind.DelegateKind(StackValue.field(fieldType, classname, delegateField, false), - typeMapper.mapType(superClassDescriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName()), state.getInjector().getJetTypeMapper()); + new OwnerKind.DelegateKind(StackValue.field(fieldType, classname, + delegateField, false), + typeMapper.mapType(superClassDescriptor + .getDefaultType(), + MapTypeMode.IMPL) + .getInternalName()), + state.getInjector().getJetTypeMapper()); generateDelegates(superClass, delegateContext, field); } } @@ -803,13 +856,16 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { mv.visitInsn(RETURN); FunctionCodegen.endVisit(mv, "constructor", myClass); - FunctionCodegen.generateDefaultIfNeeded(constructorContext, state, v, constructorMethod.getAsmMethod(), constructorDescriptor, OwnerKind.IMPLEMENTATION); + FunctionCodegen.generateDefaultIfNeeded(constructorContext, state, v, constructorMethod.getAsmMethod(), constructorDescriptor, + OwnerKind.IMPLEMENTATION); } private void generateTraitMethods() { - if (myClass instanceof JetClass && (((JetClass)myClass).isTrait() || ((JetClass)myClass).hasModifier(JetTokens.ABSTRACT_KEYWORD))) + if (myClass instanceof JetClass && + (((JetClass) myClass).isTrait() || ((JetClass) myClass).hasModifier(JetTokens.ABSTRACT_KEYWORD))) { return; - + } + for (Pair needDelegates : getTraitImplementations(descriptor)) { CallableMemberDescriptor callableDescriptor = needDelegates.first; if (needDelegates.second instanceof SimpleFunctionDescriptor) { @@ -843,11 +899,15 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { PropertyDescriptor property = ((PropertyAccessorDescriptor) fun).getCorrespondingProperty(); if (fun instanceof PropertyGetterDescriptor) { function = typeMapper.mapGetterSignature(property, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod(); - functionOriginal = typeMapper.mapGetterSignature(property.getOriginal(), OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod(); + functionOriginal = + typeMapper.mapGetterSignature(property.getOriginal(), OwnerKind.IMPLEMENTATION).getJvmMethodSignature() + .getAsmMethod(); } else if (fun instanceof PropertySetterDescriptor) { function = typeMapper.mapSetterSignature(property, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod(); - functionOriginal = typeMapper.mapSetterSignature(property.getOriginal(), OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod(); + functionOriginal = + typeMapper.mapSetterSignature(property.getOriginal(), OwnerKind.IMPLEMENTATION).getJvmMethodSignature() + .getAsmMethod(); } else { throw new IllegalStateException("Accessor is neither getter, nor setter, what is it?"); @@ -861,14 +921,16 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { final MethodVisitor mv = v.newMethod(myClass, flags, function.getName(), function.getDescriptor(), null, null); AnnotationCodegen.forMethod(mv, state.getInjector().getJetTypeMapper()).genAnnotations(fun); - JvmMethodSignature jvmSignature = typeMapper.mapToCallableMethod(inheritedFun, false, OwnerKind.IMPLEMENTATION).getSignature(); + JvmMethodSignature jvmSignature = + typeMapper.mapToCallableMethod(inheritedFun, false, OwnerKind.IMPLEMENTATION).getSignature(); JetMethodAnnotationWriter aw = JetMethodAnnotationWriter.visitAnnotation(mv); BitSet kotlinFlags = CodegenUtil.getFlagsForVisibility(fun.getVisibility()); if (fun instanceof PropertyAccessorDescriptor) { kotlinFlags.set(JvmStdlibNames.FLAG_PROPERTY_BIT); aw.writeTypeParameters(jvmSignature.getKotlinTypeParameter()); aw.writePropertyType(jvmSignature.getKotlinReturnType()); - } else { + } + else { aw.writeNullableReturnType(fun.getReturnType().isNullable()); aw.writeTypeParameters(jvmSignature.getKotlinTypeParameter()); aw.writeReturnType(jvmSignature.getKotlinReturnType()); @@ -882,7 +944,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { else if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { mv.visitCode(); FrameMap frameMap = context.prepareFrame(state.getInjector().getJetTypeMapper()); - ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, jvmSignature.getAsmMethod().getReturnType(), context, state); + ExpressionCodegen codegen = + new ExpressionCodegen(mv, frameMap, jvmSignature.getAsmMethod().getReturnType(), context, state); codegen.generateThisOrOuter(descriptor); // ??? wouldn't it be a good idea to put it? Type[] argTypes = function.getArgumentTypes(); @@ -904,10 +967,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { type = typeMapper.mapType(jetType, MapTypeMode.IMPL); } - String fdescriptor = functionOriginal.getDescriptor().replace("(","(" + type.getDescriptor()); - Type type1 = typeMapper.mapType(((ClassDescriptor) fun.getContainingDeclaration()).getDefaultType(), MapTypeMode.TRAIT_IMPL); + String fdescriptor = functionOriginal.getDescriptor().replace("(", "(" + type.getDescriptor()); + Type type1 = + typeMapper.mapType(((ClassDescriptor) fun.getContainingDeclaration()).getDefaultType(), MapTypeMode.TRAIT_IMPL); iv.invokestatic(type1.getInternalName(), function.getName(), fdescriptor); - if (function.getReturnType().getSort() == Type.OBJECT && !function.getReturnType().equals(functionOriginal.getReturnType())) { + if (function.getReturnType().getSort() == Type.OBJECT && + !function.getReturnType().equals(functionOriginal.getReturnType())) { iv.checkcast(function.getReturnType()); } iv.areturn(function.getReturnType()); @@ -919,28 +984,38 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } } - private void generateDelegatorToConstructorCall(InstructionAdapter iv, ExpressionCodegen codegen, JetCallElement constructorCall, - ConstructorDescriptor constructorDescriptor, - ConstructorFrameMap frameMap, int firstSuperArgument) { + private void generateDelegatorToConstructorCall( + InstructionAdapter iv, ExpressionCodegen codegen, JetCallElement constructorCall, + ConstructorDescriptor constructorDescriptor, + ConstructorFrameMap frameMap, int firstSuperArgument + ) { ClassDescriptor classDecl = constructorDescriptor.getContainingDeclaration(); iv.load(0, TYPE_OBJECT); - if(classDecl.getKind() == ClassKind.ENUM_CLASS) { + if (classDecl.getKind() == ClassKind.ENUM_CLASS || classDecl.getKind() == ClassKind.ENUM_ENTRY) { iv.load(1, JetTypeMapper.TYPE_OBJECT); iv.load(2, Type.INT_TYPE); } if (classDecl.getContainingDeclaration() instanceof ClassDescriptor) { - iv.load(frameMap.getOuterThisIndex(), typeMapper.mapType(((ClassDescriptor) descriptor.getContainingDeclaration()).getDefaultType(), MapTypeMode.IMPL)); + iv.load(frameMap.getOuterThisIndex(), + typeMapper.mapType(((ClassDescriptor) descriptor.getContainingDeclaration()).getDefaultType(), MapTypeMode.IMPL)); } - CallableMethod method = typeMapper.mapToCallableMethod(constructorDescriptor, kind, typeMapper.hasThis0(constructorDescriptor.getContainingDeclaration())); + CallableMethod method = typeMapper + .mapToCallableMethod(constructorDescriptor, kind, typeMapper.hasThis0(constructorDescriptor.getContainingDeclaration())); - if (myClass instanceof JetObjectDeclaration && superCall instanceof JetDelegatorToSuperCall && ((JetObjectDeclaration) myClass).isObjectLiteral()) { - ConstructorDescriptor superConstructor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, ((JetDelegatorToSuperCall) superCall).getCalleeExpression().getConstructorReferenceExpression()); - CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION, typeMapper.hasThis0(superConstructor.getContainingDeclaration())); - int nextVar = firstSuperArgument+1; - for(Type t : superCallable.getSignature().getAsmMethod().getArgumentTypes()) { + if (myClass instanceof JetObjectDeclaration && + superCall instanceof JetDelegatorToSuperCall && + ((JetObjectDeclaration) myClass).isObjectLiteral()) { + ConstructorDescriptor superConstructor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, + ((JetDelegatorToSuperCall) superCall) + .getCalleeExpression() + .getConstructorReferenceExpression()); + CallableMethod superCallable = typeMapper.mapToCallableMethod(superConstructor, OwnerKind.IMPLEMENTATION, + typeMapper.hasThis0(superConstructor.getContainingDeclaration())); + int nextVar = firstSuperArgument + 1; + for (Type t : superCallable.getSignature().getAsmMethod().getArgumentTypes()) { iv.load(nextVar, t); nextVar += t.getSize(); } @@ -999,7 +1074,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { iv.iconst(ordinal); // TODO type and constructor parameters - String implClass = typeMapper.mapType(myType, MapTypeMode.IMPL).getInternalName(); + ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, enumConstant); + String implClass = typeMapper.mapType(classDescriptor.getDefaultType(), MapTypeMode.IMPL).getInternalName(); final List delegationSpecifiers = enumConstant.getDelegationSpecifiers(); if (delegationSpecifiers.size() > 1) { @@ -1016,8 +1092,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { final JetDelegationSpecifier specifier = delegationSpecifiers.get(0); if (specifier instanceof JetDelegatorToSuperCall) { final JetDelegatorToSuperCall superCall = (JetDelegatorToSuperCall) specifier; - ConstructorDescriptor constructorDescriptor = (ConstructorDescriptor) bindingContext.get(BindingContext.REFERENCE_TARGET, superCall.getCalleeExpression().getConstructorReferenceExpression()); - CallableMethod method = typeMapper.mapToCallableMethod(constructorDescriptor, OwnerKind.IMPLEMENTATION, typeMapper.hasThis0(constructorDescriptor.getContainingDeclaration())); + ConstructorDescriptor constructorDescriptor = (ConstructorDescriptor) bindingContext + .get(BindingContext.REFERENCE_TARGET, superCall.getCalleeExpression().getConstructorReferenceExpression()); + CallableMethod method = typeMapper.mapToCallableMethod(constructorDescriptor, OwnerKind.IMPLEMENTATION, typeMapper + .hasThis0(constructorDescriptor.getContainingDeclaration())); codegen.invokeMethodWithArguments(method, superCall, StackValue.none()); } else { @@ -1028,14 +1106,16 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { iv.invokespecial(implClass, "", "(Ljava/lang/String;I)V"); } iv.dup(); - iv.putstatic(implClass, enumConstant.getName(), "L" + implClass + ";"); + iv.putstatic(myAsmType.getInternalName(), enumConstant.getName(), "L" + myAsmType.getInternalName() + ";"); iv.astore(TYPE_OBJECT); } iv.putstatic(myAsmType.getInternalName(), "$VALUES", arrayAsmType.getDescriptor()); } - public static void generateInitializers(@NotNull ExpressionCodegen codegen, @NotNull InstructionAdapter iv, @NotNull List declarations, - @NotNull BindingContext bindingContext, @NotNull JetTypeMapper typeMapper) { + public static void generateInitializers( + @NotNull ExpressionCodegen codegen, @NotNull InstructionAdapter iv, @NotNull List declarations, + @NotNull BindingContext bindingContext, @NotNull JetTypeMapper typeMapper + ) { for (JetDeclaration declaration : declarations) { if (declaration instanceof JetProperty) { final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) bindingContext.get(BindingContext.VARIABLE, declaration); @@ -1048,34 +1128,44 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { Object value = compileTimeValue.getValue(); Type type = typeMapper.mapType(propertyDescriptor.getType(), MapTypeMode.VALUE); if (JetTypeMapper.isPrimitive(type)) { - if ( !propertyDescriptor.getType().isNullable() && value instanceof Number) { - if (type == Type.INT_TYPE && ((Number)value).intValue() == 0) + if (!propertyDescriptor.getType().isNullable() && value instanceof Number) { + if (type == Type.INT_TYPE && ((Number) value).intValue() == 0) { continue; - if (type == Type.BYTE_TYPE && ((Number)value).byteValue() == 0) + } + if (type == Type.BYTE_TYPE && ((Number) value).byteValue() == 0) { continue; - if (type == Type.LONG_TYPE && ((Number)value).longValue() == 0L) + } + if (type == Type.LONG_TYPE && ((Number) value).longValue() == 0L) { continue; - if (type == Type.SHORT_TYPE && ((Number)value).shortValue() == 0) + } + if (type == Type.SHORT_TYPE && ((Number) value).shortValue() == 0) { continue; - if (type == Type.DOUBLE_TYPE && ((Number)value).doubleValue() == 0d) + } + if (type == Type.DOUBLE_TYPE && ((Number) value).doubleValue() == 0d) { continue; - if (type == Type.FLOAT_TYPE && ((Number)value).byteValue() == 0f) + } + if (type == Type.FLOAT_TYPE && ((Number) value).byteValue() == 0f) { continue; + } } - if (type == Type.BOOLEAN_TYPE && value instanceof Boolean && !((Boolean)value)) + if (type == Type.BOOLEAN_TYPE && value instanceof Boolean && !((Boolean) value)) { continue; - if (type == Type.CHAR_TYPE && value instanceof Character && ((Character)value) == 0) + } + if (type == Type.CHAR_TYPE && value instanceof Character && ((Character) value) == 0) { continue; + } } else { - if (value == null) + if (value == null) { continue; + } } } iv.load(0, JetTypeMapper.TYPE_OBJECT); Type type = codegen.expressionType(initializer); - if (propertyDescriptor.getType().isNullable()) + if (propertyDescriptor.getType().isNullable()) { type = JetTypeMapper.boxType(type); + } codegen.gen(initializer, type); // @todo write directly to the field. Fix test excloset.jet::test6 JvmClassName owner = typeMapper.getOwner(propertyDescriptor, OwnerKind.IMPLEMENTATION); @@ -1083,7 +1173,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { StackValue.property(propertyDescriptor.getName().getName(), owner, owner, propType, false, false, false, null, null, 0).store(propType, iv); } - } } else if (declaration instanceof JetClassInitializer) { @@ -1105,7 +1194,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { for (CallableMemberDescriptor overriddenDescriptor : overriddenDescriptors) { if (overriddenDescriptor.getContainingDeclaration() == classDescriptor) { if (declaration instanceof PropertyDescriptor) { - propertyCodegen.genDelegate((PropertyDescriptor) declaration, (PropertyDescriptor) overriddenDescriptor, field); + propertyCodegen + .genDelegate((PropertyDescriptor) declaration, (PropertyDescriptor) overriddenDescriptor, field); } else if (declaration instanceof SimpleFunctionDescriptor) { functionCodegen.genDelegate((SimpleFunctionDescriptor) declaration, overriddenDescriptor, field); @@ -1129,7 +1219,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { */ public static List> getTraitImplementations(@NotNull ClassDescriptor classDescriptor) { List> r = Lists.newArrayList(); - + root: for (DeclarationDescriptor decl : classDescriptor.getDefaultType().getMemberScope().getAllDescriptors()) { if (!(decl instanceof CallableMemberDescriptor)) { @@ -1141,7 +1231,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { continue; } - Collection overriddenDeclarations = OverridingUtil.getOverriddenDeclarations(callableMemberDescriptor); + Collection overriddenDeclarations = + OverridingUtil.getOverriddenDeclarations(callableMemberDescriptor); for (CallableMemberDescriptor overriddenDeclaration : overriddenDeclarations) { if (overriddenDeclaration.getModality() != Modality.ABSTRACT) { if (!CodegenUtil.isInterface(overriddenDeclaration.getContainingDeclaration())) { @@ -1149,7 +1240,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } } } - + for (CallableMemberDescriptor overriddenDeclaration : overriddenDeclarations) { if (overriddenDeclaration.getModality() != Modality.ABSTRACT) { r.add(Pair.create(callableMemberDescriptor, overriddenDeclaration)); @@ -1159,5 +1250,4 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { return r; } - } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index a86ab093492..b41adfb3fb7 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -306,11 +306,13 @@ public class JetTypeMapper { return JvmClassName.byInternalName(r.toString()); } - @NotNull public Type mapReturnType(@NotNull final JetType jetType) { + @NotNull + public Type mapReturnType(@NotNull final JetType jetType) { return mapReturnType(jetType, null); } - @NotNull private Type mapReturnType(@NotNull final JetType jetType, @Nullable BothSignatureWriter signatureVisitor) { + @NotNull + private Type mapReturnType(@NotNull final JetType jetType, @Nullable BothSignatureWriter signatureVisitor) { if (jetType.equals(JetStandardClasses.getUnitType())) { if (signatureVisitor != null) { signatureVisitor.writeAsmType(Type.VOID_TYPE, false); @@ -375,7 +377,12 @@ public class JetTypeMapper { } } else if (klass.getKind() == ClassKind.ENUM_ENTRY) { - return getJvmInternalFQName(klass.getContainingDeclaration()); + if (closureAnnotator.enumEntryNeedSubclass(klass)) { + return getJvmInternalFQName(klass.getContainingDeclaration()) + "$" + klass.getName().getName(); + } + else { + return getJvmInternalFQName(klass.getContainingDeclaration()); + } } } @@ -462,13 +469,13 @@ public class JetTypeMapper { } if (descriptor instanceof ClassDescriptor - && JetStandardLibraryNames.ARRAY.is((ClassDescriptor) descriptor) - && mapBuiltinsToJava) { + && JetStandardLibraryNames.ARRAY.is((ClassDescriptor) descriptor) + && mapBuiltinsToJava) { if (jetType.getArguments().size() != 1) { throw new UnsupportedOperationException("arrays must have one type argument"); } JetType memberType = jetType.getArguments().get(0).getType(); - + if (signatureVisitor != null) { signatureVisitor.writeArrayType(jetType.isNullable()); mapType(memberType, signatureVisitor, MapTypeMode.TYPE_PARAMETER); @@ -511,7 +518,8 @@ public class JetTypeMapper { Type type = mapType(((TypeParameterDescriptor) descriptor).getUpperBoundsAsType(), kind); if (signatureVisitor != null) { - TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) jetType.getConstructor().getDeclarationDescriptor(); + TypeParameterDescriptor typeParameterDescriptor = + (TypeParameterDescriptor) jetType.getConstructor().getDeclarationDescriptor(); assert typeParameterDescriptor != null; signatureVisitor.writeTypeVariable(typeParameterDescriptor.getName(), jetType.isNullable(), type); } @@ -584,11 +592,13 @@ public class JetTypeMapper { } public CallableMethod mapToCallableMethod(FunctionDescriptor functionDescriptor, boolean superCall, OwnerKind kind) { - if (functionDescriptor == null) { return null; } + if (functionDescriptor == null) { + return null; + } final DeclarationDescriptor functionParent = functionDescriptor.getOriginal().getContainingDeclaration(); - while(functionDescriptor.getKind()==CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { + while (functionDescriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { functionDescriptor = functionDescriptor.getOverriddenDescriptors().iterator().next(); } @@ -614,11 +624,12 @@ public class JetTypeMapper { thisClass = null; } else if (functionParent instanceof ScriptDescriptor) { - thisClass = owner = ownerForDefaultParam = ownerForDefaultImpl = closureAnnotator.classNameForScriptDescriptor((ScriptDescriptor) functionParent); + thisClass = owner = + ownerForDefaultParam = ownerForDefaultImpl = closureAnnotator.classNameForScriptDescriptor((ScriptDescriptor) functionParent); invokeOpcode = INVOKEVIRTUAL; } else if (functionParent instanceof ClassDescriptor) { - + FunctionDescriptor declarationFunctionDescriptor = findAnyDeclaration(functionDescriptor); ClassDescriptor currentOwner = (ClassDescriptor) functionParent; @@ -647,8 +658,8 @@ public class JetTypeMapper { ownerForDefaultParam.getInternalName() + (originalIsInterface ? JvmAbi.TRAIT_IMPL_SUFFIX : "")); invokeOpcode = isInterface - ? (superCall ? Opcodes.INVOKESTATIC : Opcodes.INVOKEINTERFACE) - : (isAccessor ? Opcodes.INVOKESTATIC : (superCall ? Opcodes.INVOKESPECIAL : Opcodes.INVOKEVIRTUAL)); + ? (superCall ? Opcodes.INVOKESTATIC : Opcodes.INVOKEINTERFACE) + : (isAccessor ? Opcodes.INVOKESTATIC : (superCall ? Opcodes.INVOKESPECIAL : Opcodes.INVOKEVIRTUAL)); if (isInterface && superCall) { descriptor = mapSignature(functionDescriptor, false, OwnerKind.TRAIT_IMPL); owner = JvmClassName.byInternalName(owner.getInternalName() + JvmAbi.TRAIT_IMPL_SUFFIX); @@ -673,7 +684,9 @@ public class JetTypeMapper { } private static boolean isAccessor(FunctionDescriptor functionDescriptor) { - return functionDescriptor instanceof AccessorForFunctionDescriptor || functionDescriptor instanceof AccessorForPropertyDescriptor.Getter || functionDescriptor instanceof AccessorForPropertyDescriptor.Setter; + return functionDescriptor instanceof AccessorForFunctionDescriptor || + functionDescriptor instanceof AccessorForPropertyDescriptor.Getter || + functionDescriptor instanceof AccessorForPropertyDescriptor.Setter; } @NotNull @@ -689,11 +702,11 @@ public class JetTypeMapper { } private JvmMethodSignature mapSignature(FunctionDescriptor f, boolean needGenericSignature, OwnerKind kind) { - + if (kind == OwnerKind.TRAIT_IMPL) { needGenericSignature = false; } - + BothSignatureWriter signatureVisitor = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, needGenericSignature); writeFormalTypeParameters(f.getTypeParameters(), signatureVisitor); @@ -704,9 +717,9 @@ public class JetTypeMapper { signatureVisitor.writeParametersStart(); - if(isAccessor(f)) { + if (isAccessor(f)) { signatureVisitor.writeParameterType(JvmMethodParameterKind.THIS); - mapType(((ClassifierDescriptor)f.getContainingDeclaration()).getDefaultType(), signatureVisitor, MapTypeMode.VALUE); + mapType(((ClassifierDescriptor) f.getContainingDeclaration()).getDefaultType(), signatureVisitor, MapTypeMode.VALUE); signatureVisitor.writeParameterTypeEnd(); } @@ -714,11 +727,11 @@ public class JetTypeMapper { ClassDescriptor containingDeclaration = (ClassDescriptor) f.getContainingDeclaration(); JetType jetType = TraitImplBodyCodegen.getSuperClass(containingDeclaration); Type type = mapType(jetType, MapTypeMode.VALUE); - if(type.getInternalName().equals("java/lang/Object")) { + if (type.getInternalName().equals("java/lang/Object")) { jetType = containingDeclaration.getDefaultType(); type = mapType(jetType, MapTypeMode.VALUE); } - + signatureVisitor.writeParameterType(JvmMethodParameterKind.THIS); signatureVisitor.writeAsmType(type, jetType.isNullable()); signatureVisitor.writeParameterTypeEnd(); @@ -763,7 +776,8 @@ public class JetTypeMapper { } private void writeFormalTypeParameter(TypeParameterDescriptor typeParameterDescriptor, BothSignatureWriter signatureVisitor) { - signatureVisitor.writeFormalTypeParameter(typeParameterDescriptor.getName().getName(), typeParameterDescriptor.getVariance(), typeParameterDescriptor.isReified()); + signatureVisitor.writeFormalTypeParameter(typeParameterDescriptor.getName().getName(), typeParameterDescriptor.getVariance(), + typeParameterDescriptor.isReified()); classBound: { @@ -799,23 +813,22 @@ public class JetTypeMapper { signatureVisitor.writeInterfaceBoundEnd(); } } - - signatureVisitor.writeFormalTypeParameterEnd(); + signatureVisitor.writeFormalTypeParameterEnd(); } public JvmMethodSignature mapSignature(Name name, FunctionDescriptor f) { final ReceiverDescriptor receiver = f.getReceiverParameter(); - + BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, false); - + writeFormalTypeParameters(f.getTypeParameters(), signatureWriter); signatureWriter.writeParametersStart(); - if(isAccessor(f)) { + if (isAccessor(f)) { signatureWriter.writeParameterType(JvmMethodParameterKind.THIS); - mapType(((ClassifierDescriptor)f.getContainingDeclaration()).getDefaultType(), signatureWriter, MapTypeMode.VALUE); + mapType(((ClassifierDescriptor) f.getContainingDeclaration()).getDefaultType(), signatureWriter, MapTypeMode.VALUE); signatureWriter.writeParameterTypeEnd(); } @@ -832,15 +845,15 @@ public class JetTypeMapper { } signatureWriter.writeParametersEnd(); - + signatureWriter.writeReturnType(); mapReturnType(f.getReturnType(), signatureWriter); signatureWriter.writeReturnTypeEnd(); - + return signatureWriter.makeJvmMethodSignature(name.getName()); } - + public JvmPropertyAccessorSignature mapGetterSignature(PropertyDescriptor descriptor, OwnerKind kind) { final DeclarationDescriptor parentDescriptor = descriptor.getContainingDeclaration(); boolean isAnnotation = parentDescriptor instanceof ClassDescriptor && @@ -854,16 +867,17 @@ public class JetTypeMapper { signatureWriter.writeParametersStart(); - if(kind == OwnerKind.TRAIT_IMPL) { + if (kind == OwnerKind.TRAIT_IMPL) { ClassDescriptor containingDeclaration = (ClassDescriptor) parentDescriptor; signatureWriter.writeParameterType(JvmMethodParameterKind.THIS); mapType(containingDeclaration.getDefaultType(), signatureWriter, MapTypeMode.IMPL); signatureWriter.writeParameterTypeEnd(); } else { - if(descriptor instanceof AccessorForPropertyDescriptor) { + if (descriptor instanceof AccessorForPropertyDescriptor) { signatureWriter.writeParameterType(JvmMethodParameterKind.THIS); - mapType(((ClassifierDescriptor)descriptor.getContainingDeclaration()).getDefaultType(), signatureWriter, MapTypeMode.VALUE); + mapType(((ClassifierDescriptor) descriptor.getContainingDeclaration()).getDefaultType(), signatureWriter, + MapTypeMode.VALUE); signatureWriter.writeParameterTypeEnd(); } } @@ -893,7 +907,7 @@ public class JetTypeMapper { // TODO: generics signature is not always needed BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, true); - + writeFormalTypeParameters(descriptor.getTypeParameters(), signatureWriter); JetType outType = descriptor.getType(); @@ -908,9 +922,10 @@ public class JetTypeMapper { signatureWriter.writeParameterTypeEnd(); } else { - if(descriptor instanceof AccessorForPropertyDescriptor) { + if (descriptor instanceof AccessorForPropertyDescriptor) { signatureWriter.writeParameterType(JvmMethodParameterKind.THIS); - mapType(((ClassifierDescriptor)descriptor.getContainingDeclaration()).getDefaultType(), signatureWriter, MapTypeMode.VALUE); + mapType(((ClassifierDescriptor) descriptor.getContainingDeclaration()).getDefaultType(), signatureWriter, + MapTypeMode.VALUE); signatureWriter.writeParameterTypeEnd(); } } @@ -924,19 +939,20 @@ public class JetTypeMapper { signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE); mapType(outType, signatureWriter, MapTypeMode.VALUE); signatureWriter.writeParameterTypeEnd(); - + signatureWriter.writeParametersEnd(); - + signatureWriter.writeVoidReturn(); JvmMethodSignature jvmMethodSignature = signatureWriter.makeJvmMethodSignature(name); - return new JvmPropertyAccessorSignature(jvmMethodSignature, jvmMethodSignature.getKotlinParameterType(jvmMethodSignature.getParameterCount() - 1)); + return new JvmPropertyAccessorSignature(jvmMethodSignature, + jvmMethodSignature.getKotlinParameterType(jvmMethodSignature.getParameterCount() - 1)); } private JvmMethodSignature mapConstructorSignature(ConstructorDescriptor descriptor, boolean hasThis0) { - + BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, true); - + List parameters = descriptor.getOriginal().getValueParameters(); // constructor type parmeters are fake @@ -947,11 +963,12 @@ public class JetTypeMapper { ClassDescriptor containingDeclaration = descriptor.getContainingDeclaration(); if (hasThis0) { signatureWriter.writeParameterType(JvmMethodParameterKind.THIS0); - mapType(closureAnnotator.getEclosingClassDescriptor(containingDeclaration).getDefaultType(), signatureWriter, MapTypeMode.VALUE); + mapType(closureAnnotator.getEclosingClassDescriptor(containingDeclaration).getDefaultType(), signatureWriter, + MapTypeMode.VALUE); signatureWriter.writeParameterTypeEnd(); } - if(containingDeclaration.getKind() == ClassKind.ENUM_CLASS) { + if (containingDeclaration.getKind() == ClassKind.ENUM_CLASS || containingDeclaration.getKind() == ClassKind.ENUM_ENTRY) { signatureWriter.writeParameterType(JvmMethodParameterKind.ENUM_NAME); mapType(JetStandardLibrary.getInstance().getStringType(), signatureWriter, MapTypeMode.VALUE); signatureWriter.writeParameterTypeEnd(); @@ -965,9 +982,9 @@ public class JetTypeMapper { mapType(parameter.getType(), signatureWriter, MapTypeMode.VALUE); signatureWriter.writeParameterTypeEnd(); } - + signatureWriter.writeParametersEnd(); - + signatureWriter.writeVoidReturn(); return signatureWriter.makeJvmMethodSignature(""); @@ -983,7 +1000,8 @@ public class JetTypeMapper { for (ScriptDescriptor importedScript : importedScripts) { signatureWriter.writeParameterType(JvmMethodParameterKind.VALUE); - mapType(closureAnnotator.classDescriptorForScriptDescriptor(importedScript).getDefaultType(), signatureWriter, MapTypeMode.VALUE); + mapType(closureAnnotator.classDescriptorForScriptDescriptor(importedScript).getDefaultType(), signatureWriter, + MapTypeMode.VALUE); signatureWriter.writeParameterTypeEnd(); } @@ -1055,28 +1073,31 @@ public class JetTypeMapper { private static boolean isForceReal(JvmClassName className) { return JvmPrimitiveType.getByWrapperClass(className) != null - || className.getFqName().getFqName().equals("java.lang.String") - || className.getFqName().getFqName().equals("java.lang.CharSequence") - || className.getFqName().getFqName().equals("java.lang.Object") - || className.getFqName().getFqName().equals("java.lang.Number") - || className.getFqName().getFqName().equals("java.lang.Enum") - || className.getFqName().getFqName().equals("java.lang.Comparable"); + || className.getFqName().getFqName().equals("java.lang.String") + || className.getFqName().getFqName().equals("java.lang.CharSequence") + || className.getFqName().getFqName().equals("java.lang.Object") + || className.getFqName().getFqName().equals("java.lang.Number") + || className.getFqName().getFqName().equals("java.lang.Enum") + || className.getFqName().getFqName().equals("java.lang.Comparable"); } public static boolean isGenericsArray(JetType type) { - return JetStandardLibraryNames.ARRAY.is(type) && type.getArguments().get(0).getType().getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor; + return JetStandardLibraryNames.ARRAY.is(type) && + type.getArguments().get(0).getType().getConstructor().getDeclarationDescriptor() instanceof TypeParameterDescriptor; } public Type getSharedVarType(DeclarationDescriptor descriptor) { if (descriptor instanceof PropertyDescriptor) { - return StackValue.sharedTypeForType(mapType(((PropertyDescriptor) descriptor).getReceiverParameter().getType(), MapTypeMode.VALUE)); + return StackValue + .sharedTypeForType(mapType(((PropertyDescriptor) descriptor).getReceiverParameter().getType(), MapTypeMode.VALUE)); } else if (descriptor instanceof SimpleFunctionDescriptor && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) { PsiElement psiElement = BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor); return closureAnnotator.classNameForAnonymousClass((JetElement) psiElement).getAsmType(); } else if (descriptor instanceof FunctionDescriptor) { - return StackValue.sharedTypeForType(mapType(((FunctionDescriptor) descriptor).getReceiverParameter().getType(), MapTypeMode.VALUE)); + return StackValue + .sharedTypeForType(mapType(((FunctionDescriptor) descriptor).getReceiverParameter().getType(), MapTypeMode.VALUE)); } else if (descriptor instanceof VariableDescriptor && isVarCapturedInClosure(descriptor)) { JetType outType = ((VariableDescriptor) descriptor).getType(); diff --git a/compiler/testData/codegen/enum/abstractmethod.kt b/compiler/testData/codegen/enum/abstractmethod.kt new file mode 100644 index 00000000000..8c00de1fae6 --- /dev/null +++ b/compiler/testData/codegen/enum/abstractmethod.kt @@ -0,0 +1,10 @@ +fun box() = IssueState.DEFAULT.ToString() + IssueState.FIXED.ToString() + +open enum class IssueState { + DEFAULT + FIXED { + override fun ToString() = "K" + } + + open fun ToString() : String = "O" +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/EnumGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/EnumGenTest.java index be46d8de8cd..516195f6664 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/EnumGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/EnumGenTest.java @@ -100,4 +100,35 @@ public class EnumGenTest extends CodegenTestCase { public void testInClassObj() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { blackBoxFile("enum/inclassobj.kt"); } + + public void testAbstractMethod() + throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { + blackBoxFile("enum/abstractmethod.kt"); + } + + public void testNoClassForSimpleEnum() + throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException { + loadFile("enum/name.kt"); + Class cls = loadImplementationClass(generateClassesInFile(), "State"); + Field field = cls.getField("O"); + assertEquals("State", field.get(null).getClass().getName()); + } + + public void testYesClassForComplexEnum() + throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, NoSuchFieldException { + loadFile("enum/abstractmethod.kt"); + Class cls = loadImplementationClass(generateClassesInFile(), "IssueState"); + Field field = cls.getField("DEFAULT"); + assertEquals("IssueState", field.get(null).getClass().getName()); + field = cls.getField("FIXED"); + assertEquals("IssueState", field.getType().getName()); + assertEquals("IssueState$FIXED", field.get(null).getClass().getName()); + assertNotNull(cls.getClassLoader().loadClass("IssueState$FIXED")); + try { + cls.getClassLoader().loadClass("IssueState$DEFAULT"); + fail(); + } + catch (ClassNotFoundException e) { + } + } }