diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java new file mode 100644 index 00000000000..412fd4b21ee --- /dev/null +++ b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java @@ -0,0 +1,420 @@ +/* + * Copyright 2010-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.codegen; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Sets; +import com.intellij.openapi.util.Pair; +import com.intellij.psi.tree.IElementType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.asm4.Label; +import org.jetbrains.asm4.MethodVisitor; +import org.jetbrains.asm4.Type; +import org.jetbrains.asm4.commons.InstructionAdapter; +import org.jetbrains.jet.codegen.binding.CalculatedClosure; +import org.jetbrains.jet.codegen.state.JetTypeMapper; +import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants; +import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver; +import org.jetbrains.jet.lang.resolve.java.JvmAbi; +import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType; +import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; +import org.jetbrains.jet.lexer.JetTokens; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.jetbrains.asm4.Opcodes.*; +import static org.jetbrains.jet.codegen.CodegenUtil.isInterface; +import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isClassObject; +import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.JAVA_STRING_TYPE; + +/** + * @author alex.tkachman + */ +public class AsmUtil { + private static final Set PRIMITIVE_NUMBER_CLASSES = Sets.newHashSet( + JetStandardLibrary.getInstance().getByte(), + JetStandardLibrary.getInstance().getShort(), + JetStandardLibrary.getInstance().getInt(), + JetStandardLibrary.getInstance().getLong(), + JetStandardLibrary.getInstance().getFloat(), + JetStandardLibrary.getInstance().getDouble(), + JetStandardLibrary.getInstance().getChar() + ); + + private static final int NO_FLAG_LOCAL = 0; + private static final int NO_FLAG_PACKAGE_PRIVATE = 0; + + @NotNull + private static final Map visibilityToAccessFlag = ImmutableMap.builder() + .put(Visibilities.PRIVATE, ACC_PRIVATE) + .put(Visibilities.PROTECTED, ACC_PROTECTED) + .put(Visibilities.PUBLIC, ACC_PUBLIC) + .put(Visibilities.INTERNAL, ACC_PUBLIC) + .put(Visibilities.LOCAL, NO_FLAG_LOCAL) + .put(JavaDescriptorResolver.PACKAGE_VISIBILITY, NO_FLAG_PACKAGE_PRIVATE) + .build(); + + public static final String RECEIVER$0 = "receiver$0"; + public static final String THIS$0 = "this$0"; + + private static final String STUB_EXCEPTION = "java/lang/RuntimeException"; + private static final String STUB_EXCEPTION_MESSAGE = "Stubs are for compiler only, do not add them to runtime classpath"; + + private AsmUtil() { + } + + public static Type boxType(Type asmType) { + JvmPrimitiveType jvmPrimitiveType = JvmPrimitiveType.getByAsmType(asmType); + if (jvmPrimitiveType != null) { + return jvmPrimitiveType.getWrapper().getAsmType(); + } + else { + return asmType; + } + } + + public static boolean isIntPrimitive(Type type) { + return type == Type.INT_TYPE || type == Type.SHORT_TYPE || type == Type.BYTE_TYPE || type == Type.CHAR_TYPE; + } + + public static boolean isNumberPrimitive(Type type) { + return isIntPrimitive(type) || type == Type.FLOAT_TYPE || type == Type.DOUBLE_TYPE || type == Type.LONG_TYPE; + } + + public static boolean isPrimitive(Type type) { + return type.getSort() != Type.OBJECT && type.getSort() != Type.ARRAY; + } + + public static boolean isPrimitiveNumberClassDescriptor(DeclarationDescriptor descriptor) { + if (!(descriptor instanceof ClassDescriptor)) { + return false; + } + return PRIMITIVE_NUMBER_CLASSES.contains(descriptor); + } + + public static Type correctElementType(Type type) { + String internalName = type.getInternalName(); + assert internalName.charAt(0) == '['; + return Type.getType(internalName.substring(1)); + } + + public static Type unboxType(final Type type) { + JvmPrimitiveType jvmPrimitiveType = JvmPrimitiveType.getByWrapperAsmType(type); + if (jvmPrimitiveType != null) { + return jvmPrimitiveType.getAsmType(); + } + else { + throw new UnsupportedOperationException("Unboxing: " + type); + } + } + + //TODO: move mapping logic to front-end java + public static int getVisibilityAccessFlag(@NotNull MemberDescriptor descriptor) { + Integer specialCase = specialCaseVisibility(descriptor); + if (specialCase != null) { + return specialCase; + } + Integer defaultMapping = visibilityToAccessFlag.get(descriptor.getVisibility()); + if (defaultMapping == null) { + throw new IllegalStateException(descriptor.getVisibility() + " is not a valid visibility in backend."); + } + return defaultMapping; + } + + @Nullable + private static Integer specialCaseVisibility(@NotNull MemberDescriptor memberDescriptor) { + DeclarationDescriptor containingDeclaration = memberDescriptor.getContainingDeclaration(); + if (isInterface(containingDeclaration)) { + return ACC_PUBLIC; + } + Visibility memberVisibility = memberDescriptor.getVisibility(); + if (memberVisibility != Visibilities.PRIVATE) { + return null; + } + if (isClassObject(containingDeclaration)) { + return NO_FLAG_PACKAGE_PRIVATE; + } + if (memberDescriptor instanceof ConstructorDescriptor) { + ClassKind kind = ((ClassDescriptor) containingDeclaration).getKind(); + if (kind == ClassKind.OBJECT) { + //TODO: should be NO_FLAG_PACKAGE_PRIVATE + // see http://youtrack.jetbrains.com/issue/KT-2700 + return ACC_PUBLIC; + } + else if (kind == ClassKind.ENUM_ENTRY) { + return NO_FLAG_PACKAGE_PRIVATE; + } + else if (kind == ClassKind.ENUM_CLASS) { + //TODO: should be ACC_PRIVATE + // see http://youtrack.jetbrains.com/issue/KT-2680 + return ACC_PROTECTED; + } + } + if (containingDeclaration instanceof NamespaceDescriptor) { + return ACC_PUBLIC; + } + return null; + } + + private static Type stringValueOfOrStringBuilderAppendType(Type type) { + final int sort = type.getSort(); + return sort == Type.OBJECT || sort == Type.ARRAY + ? AsmTypeConstants.OBJECT_TYPE + : sort == Type.BYTE || sort == Type.SHORT ? Type.INT_TYPE : type; + } + + public static void genThrow(MethodVisitor mv, String exception, String message) { + InstructionAdapter iv = new InstructionAdapter(mv); + iv.anew(Type.getObjectType(exception)); + iv.dup(); + iv.aconst(message); + iv.invokespecial(exception, "", "(Ljava/lang/String;)V"); + iv.athrow(); + } + + public static void genMethodThrow(MethodVisitor mv, String exception, String message) { + mv.visitCode(); + genThrow(mv, exception, message); + mv.visitMaxs(-1, -1); + mv.visitEnd(); + } + + public static void genClosureFields(CalculatedClosure closure, ClassBuilder v, JetTypeMapper typeMapper) { + final ClassifierDescriptor captureThis = closure.getCaptureThis(); + final int access = ACC_PUBLIC | ACC_SYNTHETIC | ACC_FINAL; + if (captureThis != null) { + v.newField(null, access, THIS$0, typeMapper.mapType(captureThis).getDescriptor(), null, + null); + } + + final ClassifierDescriptor captureReceiver = closure.getCaptureReceiver(); + if (captureReceiver != null) { + v.newField(null, access, RECEIVER$0, typeMapper.mapType(captureReceiver).getDescriptor(), + null, null); + } + + final List> fields = closure.getRecordedFields(); + for (Pair field : fields) { + v.newField(null, access, field.first, field.second.getDescriptor(), null, null); + } + } + + public static void genInitSingletonField(Type classAsmType, InstructionAdapter iv) { + iv.anew(classAsmType); + iv.dup(); + iv.invokespecial(classAsmType.getInternalName(), "", "()V"); + iv.putstatic(classAsmType.getInternalName(), JvmAbi.INSTANCE_FIELD, classAsmType.getDescriptor()); + } + + public static void genStringBuilderConstructor(InstructionAdapter v) { + v.visitTypeInsn(NEW, "java/lang/StringBuilder"); + v.dup(); + v.invokespecial("java/lang/StringBuilder", "", "()V"); + } + + public static void genInvokeAppendMethod(InstructionAdapter v, Type type) { + type = stringValueOfOrStringBuilderAppendType(type); + v.invokevirtual("java/lang/StringBuilder", "append", "(" + type.getDescriptor() + ")Ljava/lang/StringBuilder;"); + } + + public static StackValue genToString(InstructionAdapter v, StackValue receiver) { + final Type type = stringValueOfOrStringBuilderAppendType(receiver.type); + receiver.put(type, v); + v.invokestatic("java/lang/String", "valueOf", "(" + type.getDescriptor() + ")Ljava/lang/String;"); + return StackValue.onStack(JAVA_STRING_TYPE); + } + + static void genHashCode(MethodVisitor mv, InstructionAdapter iv, Type type) { + if (type.getSort() == Type.ARRAY) { + final Type elementType = correctElementType(type); + if (elementType.getSort() == Type.OBJECT || elementType.getSort() == Type.ARRAY) { + iv.invokestatic("java/util/Arrays", "hashCode", "([Ljava/lang/Object;)I"); + } + else { + iv.invokestatic("java/util/Arrays", "hashCode", "(" + type.getDescriptor() + ")I"); + } + } + else if (type.getSort() == Type.OBJECT) { + iv.invokevirtual("java/lang/Object", "hashCode", "()I"); + } + else if (type.getSort() == Type.LONG) { + genLongHashCode(mv, iv); + } + else if (type.getSort() == Type.DOUBLE) { + iv.invokestatic("java/lang/Double", "doubleToLongBits", "(D)J"); + genLongHashCode(mv, iv); + } + else if (type.getSort() == Type.FLOAT) { + iv.invokestatic("java/lang/Float", "floatToIntBits", "(F)I"); + } + else if (type.getSort() == Type.BOOLEAN) { + Label end = new Label(); + iv.dup(); + iv.ifeq(end); + iv.pop(); + iv.iconst(1); + iv.mark(end); + } + else { // byte short char int + // do nothing + } + } + + private static void genLongHashCode(MethodVisitor mv, InstructionAdapter iv) { + iv.dup2(); + iv.iconst(32); + iv.ushr(Type.LONG_TYPE); + iv.xor(Type.LONG_TYPE); + mv.visitInsn(L2I); + } + + static StackValue compareExpressionsOnStack(InstructionAdapter v, IElementType opToken, Type operandType) { + if (operandType.getSort() == Type.OBJECT) { + v.invokeinterface("java/lang/Comparable", "compareTo", "(Ljava/lang/Object;)I"); + v.iconst(0); + operandType = Type.INT_TYPE; + } + return StackValue.cmp(opToken, operandType); + } + + static StackValue genNullSafeEquals( + InstructionAdapter v, + IElementType opToken, + boolean leftNullable, + boolean rightNullable + ) { + if (!leftNullable) { + v.invokevirtual("java/lang/Object", "equals", "(Ljava/lang/Object;)Z"); + if (opToken == JetTokens.EXCLEQ) { + genInvertBoolean(v); + } + } + else { + if (rightNullable) { + v.dup2(); // left right left right + Label rightNull = new Label(); + v.ifnull(rightNull); + Label leftNull = new Label(); + v.ifnull(leftNull); + v.invokevirtual("java/lang/Object", "equals", "(Ljava/lang/Object;)Z"); + if (opToken == JetTokens.EXCLEQ || opToken == JetTokens.EXCLEQEQEQ) { + genInvertBoolean(v); + } + Label end = new Label(); + v.goTo(end); + v.mark(rightNull); + // left right left + Label bothNull = new Label(); + v.ifnull(bothNull); + v.mark(leftNull); + v.pop2(); + v.iconst(opToken == JetTokens.EXCLEQ || opToken == JetTokens.EXCLEQEQEQ ? 1 : 0); + v.goTo(end); + v.mark(bothNull); + v.pop2(); + v.iconst(opToken == JetTokens.EXCLEQ || opToken == JetTokens.EXCLEQEQEQ ? 0 : 1); + v.mark(end); + } + else { + v.dup2(); // left right left right + v.pop(); + Label leftNull = new Label(); + v.ifnull(leftNull); + v.invokevirtual("java/lang/Object", "equals", "(Ljava/lang/Object;)Z"); + if (opToken == JetTokens.EXCLEQ || opToken == JetTokens.EXCLEQEQEQ) { + genInvertBoolean(v); + } + Label end = new Label(); + v.goTo(end); + // left right + v.mark(leftNull); + v.pop2(); + v.iconst(opToken == JetTokens.EXCLEQ ? 1 : 0); + v.mark(end); + } + } + + return StackValue.onStack(Type.BOOLEAN_TYPE); + } + + static void genInvertBoolean(InstructionAdapter v) { + v.iconst(1); + v.xor(Type.INT_TYPE); + } + + public static StackValue genEqualsForExpressionsOnStack( + InstructionAdapter v, + IElementType opToken, + Type leftType, + Type rightType, + boolean leftNullable, + boolean rightNullable + ) { + if ((isNumberPrimitive(leftType) || leftType.getSort() == Type.BOOLEAN) && leftType == rightType) { + return compareExpressionsOnStack(v, opToken, leftType); + } + else { + if (opToken == JetTokens.EQEQEQ || opToken == JetTokens.EXCLEQEQEQ) { + return StackValue.cmp(opToken, leftType); + } + else { + return genNullSafeEquals(v, opToken, leftNullable, rightNullable); + } + } + } + + public static Type genIncrement(Type expectedType, int myDelta, InstructionAdapter v) { + if (expectedType == Type.LONG_TYPE) { + //noinspection UnnecessaryBoxing + v.lconst(myDelta); + } + else if (expectedType == Type.FLOAT_TYPE) { + //noinspection UnnecessaryBoxing + v.fconst(myDelta); + } + else if (expectedType == Type.DOUBLE_TYPE) { + //noinspection UnnecessaryBoxing + v.dconst(myDelta); + } + else { + v.iconst(myDelta); + expectedType = Type.INT_TYPE; + } + v.add(expectedType); + return expectedType; + } + + public static Type genNegate(Type expectedType, InstructionAdapter v) { + if (expectedType == Type.BYTE_TYPE || expectedType == Type.SHORT_TYPE || expectedType == Type.CHAR_TYPE) { + expectedType = Type.INT_TYPE; + } + v.neg(expectedType); + return expectedType; + } + + public static void genStubThrow(MethodVisitor mv) { + genThrow(mv, STUB_EXCEPTION, STUB_EXCEPTION_MESSAGE); + } + + public static void genStubCode(MethodVisitor mv) { + genMethodThrow(mv, STUB_EXCEPTION, STUB_EXCEPTION_MESSAGE); + } +} diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java index e189693e34e..5a7d4effef0 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java @@ -34,8 +34,8 @@ import java.util.Collections; import java.util.List; import static org.jetbrains.asm4.Opcodes.*; -import static org.jetbrains.jet.codegen.CodegenUtil.generateMethodThrow; -import static org.jetbrains.jet.codegen.CodegenUtil.getVisibilityAccessFlag; +import static org.jetbrains.jet.codegen.AsmUtil.genMethodThrow; +import static org.jetbrains.jet.codegen.AsmUtil.getVisibilityAccessFlag; /** * @author max @@ -89,7 +89,7 @@ public abstract class ClassBodyCodegen extends GenerationStateAware { protected void generateDeclaration(PropertyCodegen propertyCodegen, JetDeclaration declaration, FunctionCodegen functionCodegen) { if (declaration instanceof JetProperty || declaration instanceof JetNamedFunction) { - CodegenUtil.generateFunctionOrProperty(state, (JetTypeParameterListOwner) declaration, context, v); + context.genFunctionOrProperty(state, (JetTypeParameterListOwner) declaration, v); } } @@ -146,7 +146,7 @@ public abstract class ClassBodyCodegen extends GenerationStateAware { // generates stub 'remove' function for subclasses of Iterator to be compatible with java.util.Iterator if (DescriptorUtils.isIteratorWithoutRemoveImpl(descriptor)) { final MethodVisitor mv = v.getVisitor().visitMethod(ACC_PUBLIC, "remove", "()V", null, null); - generateMethodThrow(mv, "java/lang/UnsupportedOperationException", "Mutating method called on a Kotlin Iterator"); + genMethodThrow(mv, "java/lang/UnsupportedOperationException", "Mutating method called on a Kotlin Iterator"); } } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassFileFactory.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassFileFactory.java index 820959a410e..f73de6bcd3c 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassFileFactory.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassFileFactory.java @@ -28,6 +28,8 @@ import org.jetbrains.jet.lang.resolve.name.FqName; import javax.inject.Inject; import java.util.*; +import static org.jetbrains.jet.codegen.AsmUtil.isPrimitive; + /** * @author max * @author alex.tkachman @@ -114,7 +116,7 @@ public final class ClassFileFactory extends GenerationStateAware { public ClassBuilder forClassImplementation(ClassDescriptor aClass) { Type type = state.getTypeMapper().mapType(aClass.getDefaultType(), JetTypeMapperMode.IMPL); - if (CodegenUtil.isPrimitive(type)) { + if (isPrimitive(type)) { throw new IllegalStateException("Codegen for primitive type is not possible: " + aClass); } return newVisitor(type.getInternalName() + ".class"); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java index 21b81e62255..f98e6661b1e 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java @@ -49,6 +49,7 @@ import java.util.ArrayList; import java.util.List; import static org.jetbrains.asm4.Opcodes.*; +import static org.jetbrains.jet.codegen.AsmUtil.*; import static org.jetbrains.jet.codegen.CodegenUtil.*; import static org.jetbrains.jet.codegen.binding.CodegenBinding.classNameForAnonymousClass; import static org.jetbrains.jet.codegen.binding.CodegenBinding.isLocalNamedFun; @@ -108,7 +109,7 @@ public class ClosureCodegen extends GenerationStateAware { generateConstInstance(fun, cv); } - generateClosureFields(closure, cv, state.getTypeMapper()); + genClosureFields(closure, cv, state.getTypeMapper()); cv.done(); @@ -122,11 +123,11 @@ public class ClosureCodegen extends GenerationStateAware { cv.newField(fun, ACC_PUBLIC | ACC_STATIC | ACC_FINAL, JvmAbi.INSTANCE_FIELD, name.getDescriptor(), null, null); if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { - StubCodegen.generateStubCode(mv); + genStubCode(mv); } else if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { mv.visitCode(); - initSingletonField(name.getAsmType(), iv); + genInitSingletonField(name.getAsmType(), iv); mv.visitInsn(RETURN); FunctionCodegen.endVisit(mv, "", fun); } @@ -164,7 +165,7 @@ public class ClosureCodegen extends GenerationStateAware { cv.newMethod(fun, ACC_PUBLIC | ACC_BRIDGE | ACC_VOLATILE, "invoke", bridge.getAsmMethod().getDescriptor(), null, new String[0]); if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { - StubCodegen.generateStubCode(mv); + genStubCode(mv); } if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { mv.visitCode(); @@ -212,7 +213,7 @@ public class ClosureCodegen extends GenerationStateAware { final Method constructor = new Method("", Type.VOID_TYPE, argTypes); final MethodVisitor mv = cv.newMethod(fun, ACC_PUBLIC, "", constructor.getDescriptor(), null, new String[0]); if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { - StubCodegen.generateStubCode(mv); + genStubCode(mv); } else if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { mv.visitCode(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java index 3cc89f3a442..64c1fc491b9 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java @@ -16,44 +16,29 @@ package org.jetbrains.jet.codegen; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Sets; -import com.intellij.openapi.util.Pair; import com.intellij.psi.PsiElement; -import com.intellij.psi.tree.IElementType; import com.intellij.util.containers.Stack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.asm4.Label; -import org.jetbrains.asm4.MethodVisitor; -import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.binding.CalculatedClosure; -import org.jetbrains.jet.codegen.context.CodegenContext; import org.jetbrains.jet.codegen.signature.BothSignatureWriter; import org.jetbrains.jet.codegen.signature.JvmMethodParameterKind; import org.jetbrains.jet.codegen.signature.JvmMethodSignature; -import org.jetbrains.jet.codegen.state.GenerationState; -import org.jetbrains.jet.codegen.state.JetTypeMapper; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; -import org.jetbrains.jet.lang.psi.*; -import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.psi.JetClassObject; +import org.jetbrains.jet.lang.psi.JetClassOrObject; +import org.jetbrains.jet.lang.psi.JetObjectDeclaration; import org.jetbrains.jet.lang.resolve.DescriptorUtils; -import org.jetbrains.jet.lang.resolve.java.*; +import org.jetbrains.jet.lang.resolve.java.JvmAbi; +import org.jetbrains.jet.lang.resolve.java.JvmClassName; +import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; import org.jetbrains.jet.lang.resolve.name.Name; -import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.lang.JetStandardClasses; -import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; -import org.jetbrains.jet.lexer.JetTokens; import java.util.*; -import static org.jetbrains.asm4.Opcodes.*; -import static org.jetbrains.jet.codegen.binding.CodegenBinding.enumEntryNeedSubclass; -import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isClassObject; -import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.JAVA_STRING_TYPE; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE; /** @@ -61,31 +46,6 @@ import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE; * @author alex.tkachman */ public class CodegenUtil { - public static final String RECEIVER$0 = "receiver$0"; - public static final String THIS$0 = "this$0"; - - private static final int NO_FLAG_LOCAL = 0; - private static final int NO_FLAG_PACKAGE_PRIVATE = 0; - - @NotNull - private static final Map visibilityToAccessFlag = ImmutableMap.builder() - .put(Visibilities.PRIVATE, ACC_PRIVATE) - .put(Visibilities.PROTECTED, ACC_PROTECTED) - .put(Visibilities.PUBLIC, ACC_PUBLIC) - .put(Visibilities.INTERNAL, ACC_PUBLIC) - .put(Visibilities.LOCAL, NO_FLAG_LOCAL) - .put(JavaDescriptorResolver.PACKAGE_VISIBILITY, NO_FLAG_PACKAGE_PRIVATE) - .build(); - - private static final Set PRIMITIVE_NUMBER_CLASSES = Sets.newHashSet( - JetStandardLibrary.getInstance().getByte(), - JetStandardLibrary.getInstance().getShort(), - JetStandardLibrary.getInstance().getInt(), - JetStandardLibrary.getInstance().getLong(), - JetStandardLibrary.getInstance().getFloat(), - JetStandardLibrary.getInstance().getDouble(), - JetStandardLibrary.getInstance().getChar() - ); private CodegenUtil() { } @@ -130,7 +90,7 @@ public class CodegenUtil { } - public static String generateTmpVariableName(Collection existingNames) { + public static String createTmpVariableName(Collection existingNames) { String prefix = "tmp"; int i = RANDOM.nextInt(Integer.MAX_VALUE); String name = prefix + i; @@ -142,9 +102,8 @@ public class CodegenUtil { } - public static @NotNull - BitSet getFlagsForVisibility(@NotNull Visibility visibility) { + public static BitSet getFlagsForVisibility(@NotNull Visibility visibility) { BitSet flags = new BitSet(); if (visibility == Visibilities.INTERNAL) { flags.set(JvmStdlibNames.FLAG_INTERNAL_BIT); @@ -155,22 +114,6 @@ public class CodegenUtil { return flags; } - public static void generateThrow(MethodVisitor mv, String exception, String message) { - InstructionAdapter iv = new InstructionAdapter(mv); - iv.anew(Type.getObjectType(exception)); - iv.dup(); - iv.aconst(message); - iv.invokespecial(exception, "", "(Ljava/lang/String;)V"); - iv.athrow(); - } - - public static void generateMethodThrow(MethodVisitor mv, String exception, String message) { - mv.visitCode(); - generateThrow(mv, exception, message); - mv.visitMaxs(-1, -1); - mv.visitEnd(); - } - @NotNull public static JvmClassName getInternalClassName(FunctionDescriptor descriptor) { final int paramCount = descriptor.getValueParameters().size(); @@ -216,123 +159,10 @@ public class CodegenUtil { return closure.getCaptureThis() == null && closure.getCaptureReceiver() == null && closure.getCaptureVariables().isEmpty(); } - public static void generateClosureFields(CalculatedClosure closure, ClassBuilder v, JetTypeMapper typeMapper) { - final ClassifierDescriptor captureThis = closure.getCaptureThis(); - final int access = ACC_PUBLIC | ACC_SYNTHETIC | ACC_FINAL; - if (captureThis != null) { - v.newField(null, access, THIS$0, typeMapper.mapType(captureThis).getDescriptor(), null, - null); - } - - final ClassifierDescriptor captureReceiver = closure.getCaptureReceiver(); - if (captureReceiver != null) { - v.newField(null, access, RECEIVER$0, typeMapper.mapType(captureReceiver).getDescriptor(), - null, null); - } - - final List> fields = closure.getRecordedFields(); - for (Pair field : fields) { - v.newField(null, access, field.first, field.second.getDescriptor(), null, null); - } - } - public static T peekFromStack(Stack stack) { return stack.empty() ? null : stack.peek(); } - //TODO: move mapping logic to front-end java - public static int getVisibilityAccessFlag(@NotNull MemberDescriptor descriptor) { - Integer specialCase = specialCaseVisibility(descriptor); - if (specialCase != null) { - return specialCase; - } - Integer defaultMapping = visibilityToAccessFlag.get(descriptor.getVisibility()); - if (defaultMapping == null) { - throw new IllegalStateException(descriptor.getVisibility() + " is not a valid visibility in backend."); - } - return defaultMapping; - } - - @Nullable - private static Integer specialCaseVisibility(@NotNull MemberDescriptor memberDescriptor) { - DeclarationDescriptor containingDeclaration = memberDescriptor.getContainingDeclaration(); - if (isInterface(containingDeclaration)) { - return ACC_PUBLIC; - } - Visibility memberVisibility = memberDescriptor.getVisibility(); - if (memberVisibility != Visibilities.PRIVATE) { - return null; - } - if (isClassObject(containingDeclaration)) { - return NO_FLAG_PACKAGE_PRIVATE; - } - if (memberDescriptor instanceof ConstructorDescriptor) { - ClassKind kind = ((ClassDescriptor) containingDeclaration).getKind(); - if (kind == ClassKind.OBJECT) { - //TODO: should be NO_FLAG_PACKAGE_PRIVATE - // see http://youtrack.jetbrains.com/issue/KT-2700 - return ACC_PUBLIC; - } - else if (kind == ClassKind.ENUM_ENTRY) { - return NO_FLAG_PACKAGE_PRIVATE; - } - else if (kind == ClassKind.ENUM_CLASS) { - //TODO: should be ACC_PRIVATE - // see http://youtrack.jetbrains.com/issue/KT-2680 - return ACC_PROTECTED; - } - } - if (containingDeclaration instanceof NamespaceDescriptor) { - return ACC_PUBLIC; - } - return null; - } - - public static Type unboxType(final Type type) { - JvmPrimitiveType jvmPrimitiveType = JvmPrimitiveType.getByWrapperAsmType(type); - if (jvmPrimitiveType != null) { - return jvmPrimitiveType.getAsmType(); - } - else { - throw new UnsupportedOperationException("Unboxing: " + type); - } - } - - public static Type boxType(Type asmType) { - JvmPrimitiveType jvmPrimitiveType = JvmPrimitiveType.getByAsmType(asmType); - if (jvmPrimitiveType != null) { - return jvmPrimitiveType.getWrapper().getAsmType(); - } - else { - return asmType; - } - } - - public static boolean isIntPrimitive(Type type) { - return type == Type.INT_TYPE || type == Type.SHORT_TYPE || type == Type.BYTE_TYPE || type == Type.CHAR_TYPE; - } - - public static boolean isNumberPrimitive(Type type) { - return isIntPrimitive(type) || type == Type.FLOAT_TYPE || type == Type.DOUBLE_TYPE || type == Type.LONG_TYPE; - } - - public static boolean isPrimitive(Type type) { - return type.getSort() != Type.OBJECT && type.getSort() != Type.ARRAY; - } - - public static boolean isPrimitiveNumberClassDescriptor(DeclarationDescriptor descriptor) { - if (!(descriptor instanceof ClassDescriptor)) { - return false; - } - return PRIMITIVE_NUMBER_CLASSES.contains(descriptor); - } - - public static Type correctElementType(Type type) { - String internalName = type.getInternalName(); - assert internalName.charAt(0) == '['; - return Type.getType(internalName.substring(1)); - } - @Nullable public static String getLocalNameForObject(JetObjectDeclaration object) { PsiElement parent = object.getParent(); @@ -369,309 +199,4 @@ public class CodegenUtil { throw new IllegalStateException("code generation for synthesized members should be handled separately"); } } - - public static void initSingletonField(Type classAsmType, InstructionAdapter iv) { - iv.anew(classAsmType); - iv.dup(); - iv.invokespecial(classAsmType.getInternalName(), "", "()V"); - iv.putstatic(classAsmType.getInternalName(), JvmAbi.INSTANCE_FIELD, classAsmType.getDescriptor()); - } - - public static void generateStringBuilderConstructor(InstructionAdapter v) { - v.visitTypeInsn(NEW, "java/lang/StringBuilder"); - v.dup(); - v.invokespecial("java/lang/StringBuilder", "", "()V"); - } - - public static void invokeAppendMethod(InstructionAdapter v, Type type) { - type = getStringValueOfOrStringBuilderAppendType(type); - v.invokevirtual("java/lang/StringBuilder", "append", "(" + type.getDescriptor() + ")Ljava/lang/StringBuilder;"); - } - - public static StackValue genToString(InstructionAdapter v, StackValue receiver) { - final Type type = getStringValueOfOrStringBuilderAppendType(receiver.type); - receiver.put(type, v); - v.invokestatic("java/lang/String", "valueOf", "(" + type.getDescriptor() + ")Ljava/lang/String;"); - return StackValue.onStack(JAVA_STRING_TYPE); - } - - private static Type getStringValueOfOrStringBuilderAppendType(Type type) { - final int sort = type.getSort(); - return sort == Type.OBJECT || sort == Type.ARRAY - ? AsmTypeConstants.OBJECT_TYPE - : sort == Type.BYTE || sort == Type.SHORT ? Type.INT_TYPE : type; - } - - static void genHashCode(MethodVisitor mv, InstructionAdapter iv, Type type) { - if (type.getSort() == Type.ARRAY) { - final Type elementType = correctElementType(type); - if (elementType.getSort() == Type.OBJECT || elementType.getSort() == Type.ARRAY) { - iv.invokestatic("java/util/Arrays", "hashCode", "([Ljava/lang/Object;)I"); - } - else { - iv.invokestatic("java/util/Arrays", "hashCode", "(" + type.getDescriptor() + ")I"); - } - } - else if (type.getSort() == Type.OBJECT) { - iv.invokevirtual("java/lang/Object", "hashCode", "()I"); - } - else if (type.getSort() == Type.LONG) { - genLongHashCode(mv, iv); - } - else if (type.getSort() == Type.DOUBLE) { - iv.invokestatic("java/lang/Double", "doubleToLongBits", "(D)J"); - genLongHashCode(mv, iv); - } - else if (type.getSort() == Type.FLOAT) { - iv.invokestatic("java/lang/Float", "floatToIntBits", "(F)I"); - } - else if (type.getSort() == Type.BOOLEAN) { - Label end = new Label(); - iv.dup(); - iv.ifeq(end); - iv.pop(); - iv.iconst(1); - iv.mark(end); - } - else { // byte short char int - // do nothing - } - } - - private static void genLongHashCode(MethodVisitor mv, InstructionAdapter iv) { - iv.dup2(); - iv.iconst(32); - iv.ushr(Type.LONG_TYPE); - iv.xor(Type.LONG_TYPE); - mv.visitInsn(L2I); - } - - static StackValue compareExpressionsOnStack(InstructionAdapter v, IElementType opToken, Type operandType) { - if (operandType.getSort() == Type.OBJECT) { - v.invokeinterface("java/lang/Comparable", "compareTo", "(Ljava/lang/Object;)I"); - v.iconst(0); - operandType = Type.INT_TYPE; - } - return StackValue.cmp(opToken, operandType); - } - - static StackValue generateNullSafeEquals( - InstructionAdapter v, - IElementType opToken, - boolean leftNullable, - boolean rightNullable - ) { - if (!leftNullable) { - v.invokevirtual("java/lang/Object", "equals", "(Ljava/lang/Object;)Z"); - if (opToken == JetTokens.EXCLEQ) { - invertBoolean(v); - } - } - else { - if (rightNullable) { - v.dup2(); // left right left right - Label rightNull = new Label(); - v.ifnull(rightNull); - Label leftNull = new Label(); - v.ifnull(leftNull); - v.invokevirtual("java/lang/Object", "equals", "(Ljava/lang/Object;)Z"); - if (opToken == JetTokens.EXCLEQ || opToken == JetTokens.EXCLEQEQEQ) { - invertBoolean(v); - } - Label end = new Label(); - v.goTo(end); - v.mark(rightNull); - // left right left - Label bothNull = new Label(); - v.ifnull(bothNull); - v.mark(leftNull); - v.pop2(); - v.iconst(opToken == JetTokens.EXCLEQ || opToken == JetTokens.EXCLEQEQEQ ? 1 : 0); - v.goTo(end); - v.mark(bothNull); - v.pop2(); - v.iconst(opToken == JetTokens.EXCLEQ || opToken == JetTokens.EXCLEQEQEQ ? 0 : 1); - v.mark(end); - } - else { - v.dup2(); // left right left right - v.pop(); - Label leftNull = new Label(); - v.ifnull(leftNull); - v.invokevirtual("java/lang/Object", "equals", "(Ljava/lang/Object;)Z"); - if (opToken == JetTokens.EXCLEQ || opToken == JetTokens.EXCLEQEQEQ) { - invertBoolean(v); - } - Label end = new Label(); - v.goTo(end); - // left right - v.mark(leftNull); - v.pop2(); - v.iconst(opToken == JetTokens.EXCLEQ ? 1 : 0); - v.mark(end); - } - } - - return StackValue.onStack(Type.BOOLEAN_TYPE); - } - - static void invertBoolean(InstructionAdapter v) { - v.iconst(1); - v.xor(Type.INT_TYPE); - } - - public static StackValue generateEqualsForExpressionsOnStack( - InstructionAdapter v, - IElementType opToken, - Type leftType, - Type rightType, - boolean leftNullable, - boolean rightNullable - ) { - if ((isNumberPrimitive(leftType) || leftType.getSort() == Type.BOOLEAN) && leftType == rightType) { - return compareExpressionsOnStack(v, opToken, leftType); - } - else { - if (opToken == JetTokens.EQEQEQ || opToken == JetTokens.EXCLEQEQEQ) { - return StackValue.cmp(opToken, leftType); - } - else { - return generateNullSafeEquals(v, opToken, leftNullable, rightNullable); - } - } - } - - public static Type genIncrement(Type expectedType, int myDelta, InstructionAdapter v) { - if (expectedType == Type.LONG_TYPE) { - //noinspection UnnecessaryBoxing - v.lconst(myDelta); - } - else if (expectedType == Type.FLOAT_TYPE) { - //noinspection UnnecessaryBoxing - v.fconst(myDelta); - } - else if (expectedType == Type.DOUBLE_TYPE) { - //noinspection UnnecessaryBoxing - v.dconst(myDelta); - } - else { - v.iconst(myDelta); - expectedType = Type.INT_TYPE; - } - v.add(expectedType); - return expectedType; - } - - public static Type genNegate(Type expectedType, InstructionAdapter v) { - if (expectedType == Type.BYTE_TYPE || expectedType == Type.SHORT_TYPE || expectedType == Type.CHAR_TYPE) { - expectedType = Type.INT_TYPE; - } - v.neg(expectedType); - return expectedType; - } - - public static void generate(GenerationState state, CodegenContext context, JetClassOrObject aClass) { - ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass); - - if (descriptor == null || ErrorUtils.isError(descriptor) || descriptor.getName().equals(JetPsiUtil.NO_NAME_PROVIDED)) { - if (state.getClassBuilderMode() != ClassBuilderMode.SIGNATURES) { - throw new IllegalStateException( - "Generating bad descriptor in ClassBuilderMode = " + state.getClassBuilderMode() + ": " + descriptor); - } - return; - } - - ClassBuilder classBuilder = state.getFactory().forClassImplementation(descriptor); - - final CodegenContext contextForInners = context.intoClass(descriptor, OwnerKind.IMPLEMENTATION, state); - - if (state.getClassBuilderMode() == ClassBuilderMode.SIGNATURES) { - // Outer class implementation must happen prior inner classes so we get proper scoping tree in JetLightClass's delegate - // The same code is present below for the case when we generate real bytecode. This is because the order should be - // different for the case when we compute closures - generateImplementation(state, context, aClass, OwnerKind.IMPLEMENTATION, contextForInners.getAccessors(), classBuilder); - } - - genInners(state, aClass, contextForInners); - - if (state.getClassBuilderMode() != ClassBuilderMode.SIGNATURES) { - generateImplementation(state, context, aClass, OwnerKind.IMPLEMENTATION, contextForInners.getAccessors(), classBuilder); - } - - classBuilder.done(); - } - - public static void genInners(GenerationState state, JetClassOrObject aClass, CodegenContext contextForInners) { - for (JetDeclaration declaration : aClass.getDeclarations()) { - if (declaration instanceof JetClass) { - if (declaration instanceof JetEnumEntry && !enumEntryNeedSubclass( - state.getBindingContext(), (JetEnumEntry) declaration)) { - continue; - } - - generate(state, contextForInners, (JetClass) declaration); - } - else if (declaration instanceof JetClassObject) { - generate(state, contextForInners, ((JetClassObject) declaration).getObjectDeclaration()); - } - else if (declaration instanceof JetObjectDeclaration) { - generate(state, contextForInners, (JetObjectDeclaration) declaration); - } - } - } - - private static void generateImplementation( - GenerationState state, - CodegenContext context, - JetClassOrObject aClass, - OwnerKind kind, - Map accessors, - ClassBuilder classBuilder - ) { - ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass); - CodegenContext classContext = context.intoClass(descriptor, kind, state); - classContext.copyAccessors(accessors); - - new ImplementationBodyCodegen(aClass, classContext, classBuilder, state).generate(); - - if (aClass instanceof JetClass && ((JetClass) aClass).isTrait()) { - ClassBuilder traitBuilder = state.getFactory().forTraitImplementation(descriptor, state); - new TraitImplBodyCodegen(aClass, context.intoClass(descriptor, OwnerKind.TRAIT_IMPL, state), traitBuilder, state) - .generate(); - traitBuilder.done(); - } - } - - public static void generateFunctionOrProperty( - GenerationState state, - @NotNull JetTypeParameterListOwner functionOrProperty, - @NotNull CodegenContext context, @NotNull ClassBuilder classBuilder - ) { - FunctionCodegen functionCodegen = new FunctionCodegen(context, classBuilder, state); - if (functionOrProperty instanceof JetNamedFunction) { - try { - functionCodegen.gen((JetNamedFunction) functionOrProperty); - } - catch (CompilationException e) { - throw e; - } - catch (Exception e) { - throw new CompilationException("Failed to generate function " + functionOrProperty.getName(), e, functionOrProperty); - } - } - else if (functionOrProperty instanceof JetProperty) { - try { - new PropertyCodegen(context, classBuilder, functionCodegen).gen((JetProperty) functionOrProperty); - } - catch (CompilationException e) { - throw e; - } - catch (Exception e) { - throw new CompilationException("Failed to generate property " + functionOrProperty.getName(), e, functionOrProperty); - } - } - else { - throw new IllegalArgumentException("Unknown parameter: " + functionOrProperty); - } - } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CompilationException.java b/compiler/backend/src/org/jetbrains/jet/codegen/CompilationException.java index f48a303a0f7..2f9f8e2fbbc 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CompilationException.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CompilationException.java @@ -30,7 +30,7 @@ import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils; public class CompilationException extends RuntimeException { private final PsiElement element; - CompilationException(@NotNull String message, @Nullable Throwable cause, @NotNull PsiElement element) { + public CompilationException(@NotNull String message, @Nullable Throwable cause, @NotNull PsiElement element) { super(message, cause); this.element = element; } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 2b6cbae0b8a..6d4c30a6522 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -61,6 +61,7 @@ import org.jetbrains.jet.lexer.JetTokens; import java.util.*; import static org.jetbrains.asm4.Opcodes.*; +import static org.jetbrains.jet.codegen.AsmUtil.*; import static org.jetbrains.jet.codegen.CodegenUtil.*; import static org.jetbrains.jet.codegen.binding.CodegenBinding.*; import static org.jetbrains.jet.lang.resolve.BindingContext.*; @@ -117,7 +118,7 @@ public class ExpressionCodegen extends JetVisitor implem final CalculatedClosure closure = bindingContext.get(CLOSURE, classDescriptor); final CodegenContext contextForInners = context.intoClass(classDescriptor, OwnerKind.IMPLEMENTATION, state); - genInners(state, objectDeclaration, contextForInners); + contextForInners.genInners(state, objectDeclaration); final CodegenContext objectContext = context.intoAnonymousClass(classDescriptor, this); objectContext.copyAccessors(contextForInners.getAccessors()); @@ -994,7 +995,7 @@ public class ExpressionCodegen extends JetVisitor implem return StackValue.constant(constantValue.toString(), type); } else { - generateStringBuilderConstructor(v); + genStringBuilderConstructor(v); for (JetStringTemplateEntry entry : entries) { if (entry instanceof JetStringTemplateEntryWithExpression) { invokeAppend(entry.getExpression()); @@ -1004,7 +1005,7 @@ public class ExpressionCodegen extends JetVisitor implem ? ((JetEscapeStringTemplateEntry) entry).getUnescapedValue() : entry.getText(); v.aconst(text); - invokeAppendMethod(v, JAVA_STRING_TYPE); + genInvokeAppendMethod(v, JAVA_STRING_TYPE); } } v.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;"); @@ -1665,9 +1666,9 @@ public class ExpressionCodegen extends JetVisitor implem PropertySetterDescriptor setter = propertyDescriptor.getSetter(); PropertyGetterDescriptor getter = propertyDescriptor.getGetter(); - final int flag = CodegenUtil.getVisibilityAccessFlag(propertyDescriptor) | - (getter == null ? 0 : CodegenUtil.getVisibilityAccessFlag(getter)) | - (setter == null ? 0 : CodegenUtil.getVisibilityAccessFlag(setter)); + final int flag = getVisibilityAccessFlag(propertyDescriptor) | + (getter == null ? 0 : getVisibilityAccessFlag(getter)) | + (setter == null ? 0 : getVisibilityAccessFlag(setter)); if ((flag & ACC_PRIVATE) == 0) { return propertyDescriptor; @@ -1677,7 +1678,7 @@ public class ExpressionCodegen extends JetVisitor implem } private FunctionDescriptor accessableFunctionDescriptor(FunctionDescriptor fd) { - final int flag = CodegenUtil.getVisibilityAccessFlag(fd); + final int flag = getVisibilityAccessFlag(fd); if ((flag & ACC_PRIVATE) == 0) { return fd; } @@ -2261,7 +2262,7 @@ public class ExpressionCodegen extends JetVisitor implem else { invokeFunctionByReference(expression.getOperationReference()); if (inverted) { - invertBoolean(v); + genInvertBoolean(v); } } return StackValue.onStack(Type.BOOLEAN_TYPE); @@ -2302,7 +2303,7 @@ public class ExpressionCodegen extends JetVisitor implem v.and(Type.INT_TYPE); if (inverted) { - invertBoolean(v); + genInvertBoolean(v); } } @@ -2362,10 +2363,11 @@ public class ExpressionCodegen extends JetVisitor implem if (isPrimitive(leftType)) // both are primitive { - return generateEqualsForExpressionsOnStack(v, opToken, leftType, rightType, false, false); + return genEqualsForExpressionsOnStack(v, opToken, leftType, rightType, false, false); } - return generateEqualsForExpressionsOnStack(v, opToken, leftType, rightType, leftJetType.isNullable(), rightJetType.isNullable()); + return + genEqualsForExpressionsOnStack(v, opToken, leftType, rightType, leftJetType.isNullable(), rightJetType.isNullable()); } private StackValue genCmpWithNull(JetExpression exp, Type expType, IElementType opToken) { @@ -2514,7 +2516,7 @@ public class ExpressionCodegen extends JetVisitor implem } Type exprType = expressionType(expr); gen(expr, exprType); - invokeAppendMethod(v, exprType.getSort() == Type.ARRAY ? OBJECT_TYPE : exprType); + genInvokeAppendMethod(v, exprType.getSort() == Type.ARRAY ? OBJECT_TYPE : exprType); } @Nullable @@ -3187,10 +3189,10 @@ The "returned" value of try expression with no finally is either the last expres boolean patternIsNullable = false; JetType condJetType = bindingContext.get(BindingContext.EXPRESSION_TYPE, patternExpression); Type condType; - if (CodegenUtil.isNumberPrimitive(subjectType) || subjectType.getSort() == Type.BOOLEAN) { + if (isNumberPrimitive(subjectType) || subjectType.getSort() == Type.BOOLEAN) { assert condJetType != null; condType = asmType(condJetType); - if (!(CodegenUtil.isNumberPrimitive(condType) || condType.getSort() == Type.BOOLEAN)) { + if (!(isNumberPrimitive(condType) || condType.getSort() == Type.BOOLEAN)) { subjectType = boxType(subjectType); expressionToMatch.coerceTo(subjectType, v); } @@ -3200,8 +3202,8 @@ The "returned" value of try expression with no finally is either the last expres patternIsNullable = condJetType != null && condJetType.isNullable(); } gen(patternExpression, condType); - return generateEqualsForExpressionsOnStack(v, JetTokens.EQEQ, subjectType, condType, expressionToMatchIsNullable, - patternIsNullable); + return genEqualsForExpressionsOnStack(v, JetTokens.EQEQ, subjectType, condType, expressionToMatchIsNullable, + patternIsNullable); } else { return gen(patternExpression); @@ -3326,7 +3328,7 @@ The "returned" value of try expression with no finally is either the last expres //invokeFunctionNoParams(op, Type.BOOLEAN_TYPE, v); invokeFunctionByReference(operationReference); if (inverted) { - invertBoolean(v); + genInvertBoolean(v); } } return StackValue.onStack(Type.BOOLEAN_TYPE); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index d7cae2f6e1c..9a653f4a9d0 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -48,6 +48,7 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import java.util.*; import static org.jetbrains.asm4.Opcodes.*; +import static org.jetbrains.jet.codegen.AsmUtil.*; import static org.jetbrains.jet.codegen.CodegenUtil.*; import static org.jetbrains.jet.codegen.binding.CodegenBinding.isLocalFun; import static org.jetbrains.jet.lang.resolve.BindingContextUtils.callableDescriptorToDeclaration; @@ -130,7 +131,7 @@ public class FunctionCodegen extends GenerationStateAware { } if (!isAbstract && state.getClassBuilderMode() == ClassBuilderMode.STUBS) { - StubCodegen.generateStubCode(mv); + genStubCode(mv); } @@ -258,7 +259,7 @@ public class FunctionCodegen extends GenerationStateAware { Type sharedVarType = state.getTypeMapper().getSharedVarType(parameter); mv.visitLocalVariable(parameterName, type.getDescriptor(), null, methodBegin, divideLabel, k); - String nameForSharedVar = generateTmpVariableName(localVariableNames); + String nameForSharedVar = createTmpVariableName(localVariableNames); localVariableNames.add(nameForSharedVar); mv.visitLocalVariable(nameForSharedVar, sharedVarType.getDescriptor(), null, divideLabel, methodEnd, k); @@ -516,7 +517,7 @@ public class FunctionCodegen extends GenerationStateAware { descriptor, null, null); InstructionAdapter iv = new InstructionAdapter(mv); if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { - StubCodegen.generateStubCode(mv); + genStubCode(mv); } else if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { generateDefaultImpl(owner, state, jvmSignature, functionDescriptor, kind, receiverParameter, hasReceiver, isStatic, @@ -684,7 +685,7 @@ public class FunctionCodegen extends GenerationStateAware { final MethodVisitor mv = v.newMethod(null, flags, jvmSignature.getName(), overridden.getDescriptor(), null, null); if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { - StubCodegen.generateStubCode(mv); + genStubCode(mv); } else if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { mv.visitCode(); @@ -738,7 +739,7 @@ public class FunctionCodegen extends GenerationStateAware { final MethodVisitor mv = v.newMethod(null, flags, method.getName(), method.getDescriptor(), null, null); if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { - StubCodegen.generateStubCode(mv); + genStubCode(mv); } else if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { mv.visitCode(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 6cdd0a70688..4c6812f8118 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -19,8 +19,6 @@ package org.jetbrains.jet.codegen; import com.google.common.collect.Lists; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.util.Pair; -import com.intellij.psi.PsiElement; -import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.asm4.AnnotationVisitor; @@ -43,7 +41,6 @@ import org.jetbrains.jet.codegen.state.JetTypeMapperMode; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.OverridingUtil; import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; @@ -61,6 +58,7 @@ import org.jetbrains.jet.utils.BitSetUtils; import java.util.*; import static org.jetbrains.asm4.Opcodes.*; +import static org.jetbrains.jet.codegen.AsmUtil.*; import static org.jetbrains.jet.codegen.CodegenUtil.*; import static org.jetbrains.jet.codegen.binding.CodegenBinding.*; import static org.jetbrains.jet.lang.resolve.BindingContextUtils.callableDescriptorToDeclaration; @@ -394,7 +392,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { generateFunctionsForDataClasses(); - generateClosureFields(context.closure, v, state.getTypeMapper()); + genClosureFields(context.closure, v, state.getTypeMapper()); } private List getDataProperties() { @@ -451,7 +449,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { genPropertyOnStack(iv, propertyDescriptor, 2); if (asmType.getSort() == Type.ARRAY) { - final Type elementType = CodegenUtil.correctElementType(asmType); + final Type elementType = correctElementType(asmType); if (elementType.getSort() == Type.OBJECT || elementType.getSort() == Type.ARRAY) { iv.invokestatic("java/util/Arrays", "equals", "([Ljava/lang/Object;[Ljava/lang/Object;)Z"); } @@ -461,7 +459,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } else { final StackValue value = - generateEqualsForExpressionsOnStack(iv, JetTokens.EQEQ, asmType, asmType, type.isNullable(), type.isNullable()); + genEqualsForExpressionsOnStack(iv, JetTokens.EQEQ, asmType, asmType, type.isNullable(), type.isNullable()); value.put(Type.BOOLEAN_TYPE, iv); } @@ -530,7 +528,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { final InstructionAdapter iv = new InstructionAdapter(mv); mv.visitCode(); - generateStringBuilderConstructor(iv); + genStringBuilderConstructor(iv); boolean first = true; for (PropertyDescriptor propertyDescriptor : properties) { @@ -541,7 +539,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { else { iv.aconst(", " + propertyDescriptor.getName().getName()+"="); } - invokeAppendMethod(iv, JAVA_STRING_TYPE); + genInvokeAppendMethod(iv, JAVA_STRING_TYPE); Type type = genPropertyOnStack(iv, propertyDescriptor, 0); @@ -558,11 +556,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } } } - invokeAppendMethod(iv, type); + genInvokeAppendMethod(iv, type); } iv.aconst(")"); - invokeAppendMethod(iv, JAVA_STRING_TYPE); + genInvokeAppendMethod(iv, JAVA_STRING_TYPE); iv.invokevirtual("java/lang/StringBuilder", "toString", "()Ljava/lang/String;"); iv.areturn(JAVA_STRING_TYPE); @@ -673,7 +671,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { MethodVisitor mv = v.newMethod(null, ACC_BRIDGE | ACC_SYNTHETIC | ACC_STATIC, bridge.getName().getName(), method.getDescriptor(), null, null); if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { - StubCodegen.generateStubCode(mv); + genStubCode(mv); } else if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { mv.visitCode(); @@ -718,7 +716,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { original, getter.getVisibility()); if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { - StubCodegen.generateStubCode(mv); + genStubCode(mv); } else if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { mv.visitCode(); @@ -753,7 +751,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { original, setter.getVisibility()); if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { - StubCodegen.generateStubCode(mv); + genStubCode(mv); } else if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { mv.visitCode(); @@ -795,7 +793,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { staticInitializerChunks.add(new CodeChunk() { @Override public void generate(InstructionAdapter iv) { - initSingletonField(classAsmType, iv); + genInitSingletonField(classAsmType, iv); } }); } @@ -841,7 +839,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { writeParameterAnnotations(constructorDescriptor, constructorMethod, hasThis0, mv); if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { - StubCodegen.generateStubCode(mv); + genStubCode(mv); return; } @@ -1238,7 +1236,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { aw.visitEnd(); if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { - StubCodegen.generateStubCode(mv); + genStubCode(mv); } else if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { mv.visitCode(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java index 864ddaf5a0f..d5ecb65cb2c 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java @@ -128,19 +128,17 @@ public class NamespaceCodegen extends GenerationStateAware { for (JetDeclaration declaration : file.getDeclarations()) { if (declaration instanceof JetProperty) { final CodegenContext context = CodegenContext.STATIC.intoNamespace(descriptor); - CodegenUtil.generateFunctionOrProperty( - state, (JetTypeParameterListOwner) declaration, context, v.getClassBuilder()); + context.genFunctionOrProperty(state, (JetTypeParameterListOwner) declaration, v.getClassBuilder()); } else if (declaration instanceof JetNamedFunction) { if (!multiFile) { final CodegenContext context = CodegenContext.STATIC.intoNamespace(descriptor); - CodegenUtil.generateFunctionOrProperty( - state, (JetTypeParameterListOwner) declaration, context, v.getClassBuilder()); + context.genFunctionOrProperty(state, (JetTypeParameterListOwner) declaration, v.getClassBuilder()); } } else if (declaration instanceof JetClassOrObject) { final CodegenContext context = CodegenContext.STATIC.intoNamespace(descriptor); - CodegenUtil.generate(state, context, (JetClassOrObject) declaration); + context.genClassOrObject(state, (JetClassOrObject) declaration); } else if (declaration instanceof JetScript) { state.getScriptCodegen().generate((JetScript) declaration); @@ -176,16 +174,12 @@ public class NamespaceCodegen extends GenerationStateAware { { final CodegenContext context = CodegenContext.STATIC.intoNamespace(descriptor); - CodegenUtil - .generateFunctionOrProperty(state, (JetTypeParameterListOwner) declaration, - context, builder); + context.genFunctionOrProperty(state, (JetTypeParameterListOwner) declaration, builder); } { final CodegenContext context = CodegenContext.STATIC.intoNamespacePart(className, descriptor); - CodegenUtil - .generateFunctionOrProperty(state, (JetTypeParameterListOwner) declaration, - context, v.getClassBuilder()); + context.genFunctionOrProperty(state, (JetTypeParameterListOwner) declaration, v.getClassBuilder()); } } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java index f7326a533dd..d58c281f40a 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java @@ -42,6 +42,8 @@ import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; import java.util.BitSet; import static org.jetbrains.asm4.Opcodes.*; +import static org.jetbrains.jet.codegen.AsmUtil.genStubThrow; +import static org.jetbrains.jet.codegen.AsmUtil.getVisibilityAccessFlag; import static org.jetbrains.jet.codegen.CodegenUtil.*; import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE; @@ -214,7 +216,7 @@ public class PropertyCodegen extends GenerationStateAware { if (propertyDescriptor.getModality() != Modality.ABSTRACT) { mv.visitCode(); if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { - StubCodegen.generateStubThrow(mv); + genStubThrow(mv); } else { InstructionAdapter iv = new InstructionAdapter(mv); @@ -316,7 +318,7 @@ public class PropertyCodegen extends GenerationStateAware { if (propertyDescriptor.getModality() != Modality.ABSTRACT) { mv.visitCode(); if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { - StubCodegen.generateStubThrow(mv); + genStubThrow(mv); } else { InstructionAdapter iv = new InstructionAdapter(mv); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/RangeCodegenUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/RangeCodegenUtil.java index 503e47984cc..ac18e591bff 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/RangeCodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/RangeCodegenUtil.java @@ -27,6 +27,8 @@ import org.jetbrains.jet.lang.types.lang.JetStandardLibrary; import java.util.List; +import static org.jetbrains.jet.codegen.AsmUtil.isPrimitiveNumberClassDescriptor; + /** * @author abreslav */ @@ -91,7 +93,7 @@ public class RangeCodegenUtil { public static boolean isOptimizableRangeTo(CallableDescriptor rangeTo) { if ("rangeTo".equals(rangeTo.getName().getName())) { - if (CodegenUtil.isPrimitiveNumberClassDescriptor(rangeTo.getContainingDeclaration())) { + if (isPrimitiveNumberClassDescriptor(rangeTo.getContainingDeclaration())) { return true; } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java index c2b8416bcfc..6ba72c11122 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java @@ -202,7 +202,7 @@ public class ScriptCodegen extends GenerationStateAware { private void genMembers(@NotNull JetScript scriptDeclaration, @NotNull CodegenContext context, @NotNull ClassBuilder classBuilder) { for (JetDeclaration decl : scriptDeclaration.getDeclarations()) { - CodegenUtil.generateFunctionOrProperty(state, (JetTypeParameterListOwner) decl, context, classBuilder); + context.genFunctionOrProperty(state, (JetTypeParameterListOwner) decl, classBuilder); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java index bef134fd345..6e0307c9145 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java @@ -39,6 +39,8 @@ import org.jetbrains.jet.lexer.JetTokens; import java.util.List; import static org.jetbrains.asm4.Opcodes.*; +import static org.jetbrains.jet.codegen.AsmUtil.boxType; +import static org.jetbrains.jet.codegen.AsmUtil.isIntPrimitive; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.*; /** @@ -61,7 +63,7 @@ public abstract class StackValue { instructionAdapter.aconst(null); } else { - Type boxed = CodegenUtil.boxType(type); + Type boxed = boxType(type); instructionAdapter.invokestatic(boxed.getInternalName(), "valueOf", "(" + type.getDescriptor() + ")" + boxed.getDescriptor()); } } @@ -76,7 +78,7 @@ public abstract class StackValue { * JVM stack after this value was generated. * * @param type the type as which the value should be put - * @param v the visitor used to generate the instructions + * @param v the visitor used to genClassOrObject the instructions * @param depth the number of new values put onto the stack */ protected void moveToTopOfStack(Type type, InstructionAdapter v, int depth) { @@ -171,7 +173,7 @@ public abstract class StackValue { private static void box(final Type type, final Type toType, InstructionAdapter v) { // TODO handle toType correctly - if (type == Type.INT_TYPE || (CodegenUtil.isIntPrimitive(type) && toType.getInternalName().equals("java/lang/Integer"))) { + if (type == Type.INT_TYPE || (isIntPrimitive(type) && toType.getInternalName().equals("java/lang/Integer"))) { v.invokestatic("java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;"); } else if (type == Type.BOOLEAN_TYPE) { @@ -614,7 +616,7 @@ public abstract class StackValue { public ArrayElement(Type type, boolean unbox) { super(type); - this.boxed = unbox ? CodegenUtil.boxType(type) : type; + this.boxed = unbox ? boxType(type) : type; } @Override diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/StubCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/StubCodegen.java deleted file mode 100644 index 7647dd34b4e..00000000000 --- a/compiler/backend/src/org/jetbrains/jet/codegen/StubCodegen.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2010-2012 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.codegen; - -import org.jetbrains.asm4.MethodVisitor; - -import static org.jetbrains.jet.codegen.CodegenUtil.generateMethodThrow; -import static org.jetbrains.jet.codegen.CodegenUtil.generateThrow; - -/** - * @author Stepan Koltsov - */ -public class StubCodegen { - private static final String STUB_EXCEPTION = "java/lang/RuntimeException"; - private static final String STUB_EXCEPTION_MESSAGE = "Stubs are for compiler only, do not add them to runtime classpath"; - - private StubCodegen() { - } - - public static void generateStubThrow(MethodVisitor mv) { - generateThrow(mv, STUB_EXCEPTION, STUB_EXCEPTION_MESSAGE); - } - - public static void generateStubCode(MethodVisitor mv) { - generateMethodThrow(mv, STUB_EXCEPTION, STUB_EXCEPTION_MESSAGE); - } -} diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenBinding.java b/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenBinding.java index b3e59571d47..d040c981f77 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenBinding.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenBinding.java @@ -19,7 +19,6 @@ package org.jetbrains.jet.codegen.binding; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.codegen.CodegenUtil; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.psi.*; @@ -39,6 +38,7 @@ import java.util.Collection; import java.util.Collections; import java.util.HashSet; +import static org.jetbrains.jet.codegen.CodegenUtil.isInterface; import static org.jetbrains.jet.lang.resolve.BindingContext.*; import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration; @@ -365,7 +365,7 @@ public class CodegenBinding { assert superType != null; ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); assert superClassDescriptor != null; - if (!CodegenUtil.isInterface(superClassDescriptor)) { + if (!isInterface(superClassDescriptor)) { return (JetDelegatorToSuperCall) specifier; } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java index d208e444554..4fec60bf7f0 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java @@ -26,13 +26,16 @@ import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.codegen.state.JetTypeMapper; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.types.ErrorUtils; import java.util.Collections; import java.util.HashMap; import java.util.Map; -import static org.jetbrains.jet.codegen.binding.CodegenBinding.CLASS_FOR_FUNCTION; -import static org.jetbrains.jet.codegen.binding.CodegenBinding.FQN; +import static org.jetbrains.jet.codegen.AsmUtil.THIS$0; +import static org.jetbrains.jet.codegen.binding.CodegenBinding.*; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE; /* @@ -261,7 +264,7 @@ public abstract class CodegenContext { final ClassDescriptor enclosingClass = getEnclosingClass(); outerExpression = enclosingClass != null ? StackValue - .field(typeMapper.mapType(enclosingClass), CodegenBinding.getJvmInternalName(typeMapper.getBindingTrace(), classDescriptor), CodegenUtil.THIS$0, + .field(typeMapper.mapType(enclosingClass), CodegenBinding.getJvmInternalName(typeMapper.getBindingTrace(), classDescriptor), THIS$0, false) : null; } @@ -298,4 +301,108 @@ public abstract class CodegenContext { public Map getAccessors() { return accessors == null ? Collections.emptyMap() : accessors; } + + public void genFunctionOrProperty( + GenerationState state, + @NotNull JetTypeParameterListOwner functionOrProperty, + @NotNull ClassBuilder classBuilder + ) { + FunctionCodegen functionCodegen = new FunctionCodegen(this, classBuilder, state); + if (functionOrProperty instanceof JetNamedFunction) { + try { + functionCodegen.gen((JetNamedFunction) functionOrProperty); + } + catch (CompilationException e) { + throw e; + } + catch (Exception e) { + throw new CompilationException("Failed to generate function " + functionOrProperty.getName(), e, functionOrProperty); + } + } + else if (functionOrProperty instanceof JetProperty) { + try { + new PropertyCodegen(this, classBuilder, functionCodegen).gen((JetProperty) functionOrProperty); + } + catch (CompilationException e) { + throw e; + } + catch (Exception e) { + throw new CompilationException("Failed to generate property " + functionOrProperty.getName(), e, functionOrProperty); + } + } + else { + throw new IllegalArgumentException("Unknown parameter: " + functionOrProperty); + } + } + + public void genImplementation( + GenerationState state, + JetClassOrObject aClass, + OwnerKind kind, + Map accessors, + ClassBuilder classBuilder + ) { + ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass); + CodegenContext classContext = intoClass(descriptor, kind, state); + classContext.copyAccessors(accessors); + + new ImplementationBodyCodegen(aClass, classContext, classBuilder, state).generate(); + + if (aClass instanceof JetClass && ((JetClass) aClass).isTrait()) { + ClassBuilder traitBuilder = state.getFactory().forTraitImplementation(descriptor, state); + new TraitImplBodyCodegen(aClass, intoClass(descriptor, OwnerKind.TRAIT_IMPL, state), traitBuilder, state) + .generate(); + traitBuilder.done(); + } + } + + public void genInners(GenerationState state, JetClassOrObject aClass) { + for (JetDeclaration declaration : aClass.getDeclarations()) { + if (declaration instanceof JetClass) { + if (declaration instanceof JetEnumEntry && !enumEntryNeedSubclass( + state.getBindingContext(), (JetEnumEntry) declaration)) { + continue; + } + + genClassOrObject(state, (JetClass) declaration); + } + else if (declaration instanceof JetClassObject) { + genClassOrObject(state, ((JetClassObject) declaration).getObjectDeclaration()); + } + else if (declaration instanceof JetObjectDeclaration) { + genClassOrObject(state, (JetObjectDeclaration) declaration); + } + } + } + + public void genClassOrObject(GenerationState state, JetClassOrObject aClass) { + ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass); + + if (descriptor == null || ErrorUtils.isError(descriptor) || descriptor.getName().equals(JetPsiUtil.NO_NAME_PROVIDED)) { + if (state.getClassBuilderMode() != ClassBuilderMode.SIGNATURES) { + throw new IllegalStateException( + "Generating bad descriptor in ClassBuilderMode = " + state.getClassBuilderMode() + ": " + descriptor); + } + return; + } + + ClassBuilder classBuilder = state.getFactory().forClassImplementation(descriptor); + + final CodegenContext contextForInners = intoClass(descriptor, OwnerKind.IMPLEMENTATION, state); + + if (state.getClassBuilderMode() == ClassBuilderMode.SIGNATURES) { + // Outer class implementation must happen prior inner classes so we get proper scoping tree in JetLightClass's delegate + // The same code is present below for the case when we genClassOrObject real bytecode. This is because the order should be + // different for the case when we compute closures + genImplementation(state, aClass, OwnerKind.IMPLEMENTATION, contextForInners.getAccessors(), classBuilder); + } + + contextForInners.genInners(state, aClass); + + if (state.getClassBuilderMode() != ClassBuilderMode.SIGNATURES) { + genImplementation(state, aClass, OwnerKind.IMPLEMENTATION, contextForInners.getAccessors(), classBuilder); + } + + classBuilder.done(); + } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/LocalLookup.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/LocalLookup.java index 8722a0fd971..ff175602566 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/LocalLookup.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/LocalLookup.java @@ -17,7 +17,6 @@ package org.jetbrains.jet.codegen.context; import org.jetbrains.asm4.Type; -import org.jetbrains.jet.codegen.CodegenUtil; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.binding.MutableClosure; @@ -27,6 +26,7 @@ import org.jetbrains.jet.lang.psi.JetElement; import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.types.JetType; +import static org.jetbrains.jet.codegen.AsmUtil.RECEIVER$0; import static org.jetbrains.jet.codegen.binding.CodegenBinding.classNameForAnonymousClass; import static org.jetbrains.jet.codegen.binding.CodegenBinding.isLocalNamedFun; import static org.jetbrains.jet.lang.resolve.BindingContextUtils.callableDescriptorToDeclaration; @@ -122,7 +122,7 @@ public interface LocalLookup { final JetType receiverType = ((CallableDescriptor) d).getReceiverParameter().getType(); Type type = state.getTypeMapper().mapType(receiverType); - StackValue innerValue = StackValue.field(type, className, CodegenUtil.RECEIVER$0, false); + StackValue innerValue = StackValue.field(type, className, RECEIVER$0, false); closure.setCaptureReceiver(); return innerValue; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArrayGet.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArrayGet.java index 68c154e04e7..1e1afa1c699 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArrayGet.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArrayGet.java @@ -20,15 +20,16 @@ import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.asm4.Type; import org.jetbrains.asm4.commons.InstructionAdapter; -import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants; -import org.jetbrains.jet.codegen.CodegenUtil; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.lang.psi.JetExpression; +import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants; import java.util.List; +import static org.jetbrains.jet.codegen.AsmUtil.correctElementType; + /** * @author alex.tkachman */ @@ -44,7 +45,7 @@ public class ArrayGet implements IntrinsicMethod { @NotNull GenerationState state ) { receiver.put(AsmTypeConstants.OBJECT_TYPE, v); - Type type = CodegenUtil.correctElementType(receiver.type); + Type type = correctElementType(receiver.type); codegen.gen(arguments.get(0), Type.INT_TYPE); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArraySet.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArraySet.java index 082c54ca469..b6d55db6c64 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArraySet.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArraySet.java @@ -20,15 +20,16 @@ import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.asm4.Type; import org.jetbrains.asm4.commons.InstructionAdapter; -import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants; -import org.jetbrains.jet.codegen.CodegenUtil; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.lang.psi.JetExpression; +import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants; import java.util.List; +import static org.jetbrains.jet.codegen.AsmUtil.correctElementType; + /** * @author alex.tkachman */ @@ -44,7 +45,7 @@ public class ArraySet implements IntrinsicMethod { @NotNull GenerationState state ) { receiver.put(AsmTypeConstants.OBJECT_TYPE, v); - Type type = CodegenUtil.correctElementType(receiver.type); + Type type = correctElementType(receiver.type); codegen.gen(arguments.get(0), Type.INT_TYPE); codegen.gen(arguments.get(1), type); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/BinaryOp.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/BinaryOp.java index 8d334a137e3..e71753f5d86 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/BinaryOp.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/BinaryOp.java @@ -20,7 +20,6 @@ import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.asm4.Type; import org.jetbrains.asm4.commons.InstructionAdapter; -import org.jetbrains.jet.codegen.CodegenUtil; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.state.GenerationState; @@ -29,6 +28,8 @@ import org.jetbrains.jet.lang.psi.JetExpression; import java.util.List; import static org.jetbrains.asm4.Opcodes.*; +import static org.jetbrains.jet.codegen.AsmUtil.boxType; +import static org.jetbrains.jet.codegen.AsmUtil.unboxType; /** * @author yole @@ -52,7 +53,7 @@ public class BinaryOp implements IntrinsicMethod { ) { boolean nullable = expectedType.getSort() == Type.OBJECT; if (nullable) { - expectedType = CodegenUtil.unboxType(expectedType); + expectedType = unboxType(expectedType); } if (arguments.size() == 1) { // Intrinsic is called as an ordinary function @@ -68,7 +69,7 @@ public class BinaryOp implements IntrinsicMethod { v.visitInsn(expectedType.getOpcode(opcode)); if (nullable) { - StackValue.onStack(expectedType).put(expectedType = CodegenUtil.boxType(expectedType), v); + StackValue.onStack(expectedType).put(expectedType = boxType(expectedType), v); } return StackValue.onStack(expectedType); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Concat.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Concat.java index f488a74cb3a..753f8ff037b 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Concat.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Concat.java @@ -20,7 +20,6 @@ import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.asm4.Type; import org.jetbrains.asm4.commons.InstructionAdapter; -import org.jetbrains.jet.codegen.CodegenUtil; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.state.GenerationState; @@ -29,6 +28,9 @@ import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants; import java.util.List; +import static org.jetbrains.jet.codegen.AsmUtil.genInvokeAppendMethod; +import static org.jetbrains.jet.codegen.AsmUtil.genStringBuilderConstructor; + /** * @author yole */ @@ -44,15 +46,15 @@ public class Concat implements IntrinsicMethod { @NotNull GenerationState state ) { if (receiver == null || receiver == StackValue.none()) { // LHS + RHS - CodegenUtil.generateStringBuilderConstructor(v); + genStringBuilderConstructor(v); codegen.invokeAppend(arguments.get(0)); // StringBuilder(LHS) codegen.invokeAppend(arguments.get(1)); } else { // LHS.plus(RHS) receiver.put(AsmTypeConstants.OBJECT_TYPE, v); - CodegenUtil.generateStringBuilderConstructor(v); + genStringBuilderConstructor(v); v.swap(); // StringBuilder LHS - CodegenUtil.invokeAppendMethod(v, expectedType); // StringBuilder(LHS) + genInvokeAppendMethod(v, expectedType); // StringBuilder(LHS) codegen.invokeAppend(arguments.get(0)); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Equals.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Equals.java index 29aeb822834..94908a802d8 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Equals.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Equals.java @@ -20,7 +20,6 @@ import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.asm4.Type; import org.jetbrains.asm4.commons.InstructionAdapter; -import org.jetbrains.jet.codegen.CodegenUtil; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.state.GenerationState; @@ -33,6 +32,8 @@ import org.jetbrains.jet.lexer.JetTokens; import java.util.List; +import static org.jetbrains.jet.codegen.AsmUtil.genEqualsForExpressionsOnStack; + /** * @author alex.tkachman */ @@ -75,9 +76,8 @@ public class Equals implements IntrinsicMethod { codegen.gen(rightExpr).put(AsmTypeConstants.OBJECT_TYPE, v); assert rightType != null; - return CodegenUtil - .generateEqualsForExpressionsOnStack(v, JetTokens.EQEQ, AsmTypeConstants.OBJECT_TYPE, AsmTypeConstants.OBJECT_TYPE, - leftNullable, - rightType.isNullable()); + return genEqualsForExpressionsOnStack(v, JetTokens.EQEQ, AsmTypeConstants.OBJECT_TYPE, AsmTypeConstants.OBJECT_TYPE, + leftNullable, + rightType.isNullable()); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Increment.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Increment.java index 607947502f5..d20ef90ee3c 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Increment.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Increment.java @@ -20,7 +20,6 @@ import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.asm4.Type; import org.jetbrains.asm4.commons.InstructionAdapter; -import org.jetbrains.jet.codegen.CodegenUtil; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.state.GenerationState; @@ -30,6 +29,8 @@ import org.jetbrains.jet.lang.psi.JetReferenceExpression; import java.util.List; +import static org.jetbrains.jet.codegen.AsmUtil.*; + /** * @author yole */ @@ -52,7 +53,7 @@ public class Increment implements IntrinsicMethod { ) { boolean nullable = expectedType.getSort() == Type.OBJECT; if (nullable) { - expectedType = CodegenUtil.unboxType(expectedType); + expectedType = unboxType(expectedType); } if (arguments.size() > 0) { JetExpression operand = arguments.get(0); @@ -61,7 +62,7 @@ public class Increment implements IntrinsicMethod { } if (operand instanceof JetReferenceExpression) { final int index = codegen.indexOfLocal((JetReferenceExpression) operand); - if (index >= 0 && CodegenUtil.isIntPrimitive(expectedType)) { + if (index >= 0 && isIntPrimitive(expectedType)) { return StackValue.preIncrement(index, myDelta); } } @@ -70,12 +71,12 @@ public class Increment implements IntrinsicMethod { value.dupReceiver(v); value.put(expectedType, v); - value.store(CodegenUtil.genIncrement(expectedType, myDelta, v), v); + value.store(genIncrement(expectedType, myDelta, v), v); value.put(expectedType, v); } else { receiver.put(expectedType, v); - StackValue.coerce(CodegenUtil.genIncrement(expectedType, myDelta, v), expectedType, v); + StackValue.coerce(genIncrement(expectedType, myDelta, v), expectedType, v); } return StackValue.onStack(expectedType); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Inv.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Inv.java index 9e55d256b00..5a5a02c6cf0 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Inv.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Inv.java @@ -20,7 +20,6 @@ import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.asm4.Type; import org.jetbrains.asm4.commons.InstructionAdapter; -import org.jetbrains.jet.codegen.CodegenUtil; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.state.GenerationState; @@ -28,6 +27,8 @@ import org.jetbrains.jet.lang.psi.JetExpression; import java.util.List; +import static org.jetbrains.jet.codegen.AsmUtil.unboxType; + /** * @author yole * @author alex.tkachman @@ -45,7 +46,7 @@ public class Inv implements IntrinsicMethod { ) { boolean nullable = expectedType.getSort() == Type.OBJECT; if (nullable) { - expectedType = CodegenUtil.unboxType(expectedType); + expectedType = unboxType(expectedType); } receiver.put(expectedType, v); if (expectedType == Type.LONG_TYPE) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ToString.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ToString.java index 32add939d89..87419ad3a33 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ToString.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ToString.java @@ -20,7 +20,6 @@ import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.asm4.Type; import org.jetbrains.asm4.commons.InstructionAdapter; -import org.jetbrains.jet.codegen.CodegenUtil; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.state.GenerationState; @@ -28,6 +27,8 @@ import org.jetbrains.jet.lang.psi.JetExpression; import java.util.List; +import static org.jetbrains.jet.codegen.AsmUtil.genToString; + /** * @author alex.tkachman */ @@ -42,6 +43,6 @@ public class ToString implements IntrinsicMethod { StackValue receiver, @NotNull GenerationState state ) { - return CodegenUtil.genToString(v, receiver); + return genToString(v, receiver); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UnaryMinus.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UnaryMinus.java index f56354f38a6..6efdc40f120 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UnaryMinus.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UnaryMinus.java @@ -20,7 +20,6 @@ import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.asm4.Type; import org.jetbrains.asm4.commons.InstructionAdapter; -import org.jetbrains.jet.codegen.CodegenUtil; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.state.GenerationState; @@ -28,6 +27,9 @@ import org.jetbrains.jet.lang.psi.JetExpression; import java.util.List; +import static org.jetbrains.jet.codegen.AsmUtil.genNegate; +import static org.jetbrains.jet.codegen.AsmUtil.unboxType; + /** * @author yole */ @@ -44,7 +46,7 @@ public class UnaryMinus implements IntrinsicMethod { ) { boolean nullable = expectedType.getSort() == Type.OBJECT; if (nullable) { - expectedType = CodegenUtil.unboxType(expectedType); + expectedType = unboxType(expectedType); } if (arguments.size() == 1) { codegen.gen(arguments.get(0), expectedType); @@ -52,7 +54,7 @@ public class UnaryMinus implements IntrinsicMethod { else { receiver.put(expectedType, v); } - StackValue.coerce(CodegenUtil.genNegate(expectedType, v), expectedType, v); + StackValue.coerce(genNegate(expectedType, v), expectedType, v); return StackValue.onStack(expectedType); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UnaryPlus.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UnaryPlus.java index 362df6fa695..e2f0350bea3 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UnaryPlus.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/UnaryPlus.java @@ -21,7 +21,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.asm4.Type; import org.jetbrains.asm4.commons.InstructionAdapter; -import org.jetbrains.jet.codegen.CodegenUtil; import org.jetbrains.jet.codegen.ExpressionCodegen; import org.jetbrains.jet.codegen.StackValue; import org.jetbrains.jet.codegen.state.GenerationState; @@ -29,6 +28,8 @@ import org.jetbrains.jet.lang.psi.JetExpression; import java.util.List; +import static org.jetbrains.jet.codegen.AsmUtil.unboxType; + /** * @author alex.tkachman */ @@ -45,7 +46,7 @@ public class UnaryPlus implements IntrinsicMethod { ) { boolean nullable = expectedType.getSort() == Type.OBJECT; if (nullable) { - expectedType = CodegenUtil.unboxType(expectedType); + expectedType = unboxType(expectedType); } if (receiver != null && receiver != StackValue.none()) { receiver.put(expectedType, v); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java index 54f4917eac8..61489afacaa 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java @@ -46,6 +46,7 @@ import java.util.List; import java.util.Map; import static org.jetbrains.asm4.Opcodes.*; +import static org.jetbrains.jet.codegen.AsmUtil.boxType; import static org.jetbrains.jet.codegen.CodegenUtil.*; import static org.jetbrains.jet.codegen.binding.CodegenBinding.*; import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration; @@ -658,7 +659,7 @@ public class JetTypeMapper extends BindingTraceAware { ((ClassDescriptor) parentDescriptor).getKind() == ClassKind.ANNOTATION_CLASS; String name = isAnnotation ? descriptor.getName().getName() : PropertyCodegen.getterName(descriptor.getName()); - // TODO: do not generate generics if not needed + // TODO: do not genClassOrObject generics if not needed BothSignatureWriter signatureWriter = new BothSignatureWriter(BothSignatureWriter.Mode.METHOD, true); writeFormalTypeParameters(descriptor.getTypeParameters(), signatureWriter); diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JavaElementFinder.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JavaElementFinder.java index d678a28e9d1..72d9ee34e19 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JavaElementFinder.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JavaElementFinder.java @@ -29,7 +29,6 @@ import com.intellij.psi.search.GlobalSearchScope; import com.intellij.util.SmartList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.codegen.CodegenUtil; import org.jetbrains.jet.codegen.NamespaceCodegen; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.java.JavaPsiFacadeKotlinHacks; @@ -41,6 +40,8 @@ import org.jetbrains.jet.util.QualifiedNamesUtil; import java.util.*; +import static org.jetbrains.jet.codegen.CodegenUtil.getLocalNameForObject; + public class JavaElementFinder extends PsiElementFinder implements JavaPsiFacadeKotlinHacks.KotlinFinderMarker { private final Project project; private final PsiManager psiManager; @@ -166,7 +167,7 @@ public class JavaElementFinder extends PsiElementFinder implements JavaPsiFacade if (given != null) return given; if (declaration instanceof JetObjectDeclaration) { - return CodegenUtil.getLocalNameForObject((JetObjectDeclaration) declaration); + return getLocalNameForObject((JetObjectDeclaration) declaration); } return null; diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightClass.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightClass.java index 3876582fd74..a8ee19d1825 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightClass.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightClass.java @@ -266,7 +266,7 @@ public class JetLightClass extends AbstractLightClass implements JetJavaMirrorMa public static PsiMethod wrapMethod(@NotNull JetNamedFunction function) { //noinspection unchecked if (PsiTreeUtil.getParentOfType(function, JetFunction.class, JetProperty.class) != null) { - // Don't generate method wrappers for internal declarations. Their classes are not generated during calcStub + // Don't genClassOrObject method wrappers for internal declarations. Their classes are not generated during calcStub // with ClassBuilderMode.SIGNATURES mode, and this produces "Class not found exception" in getDelegate() return null; }