From 20233da7cf785e3d2a267a69f08148241cd69be1 Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Wed, 2 Nov 2011 18:24:53 +0300 Subject: [PATCH] Wrap ASM class generation so we can attribute generated classes with PSI origins when building kotlin-as-seen-from-java model --- .../jet/codegen/ClassBodyCodegen.java | 22 +++---- .../jetbrains/jet/codegen/ClassBuilder.java | 59 +++++++++++++++++ .../jetbrains/jet/codegen/ClassCodegen.java | 3 +- .../jet/codegen/ClassFileFactory.java | 19 +++--- .../jetbrains/jet/codegen/ClosureCodegen.java | 49 +++++++------- .../jet/codegen/FunctionCodegen.java | 25 +++---- .../jet/codegen/FunctionOrClosureCodegen.java | 5 +- .../jet/codegen/GenerationState.java | 17 ++--- .../codegen/ImplementationBodyCodegen.java | 65 ++++++++++--------- .../jet/codegen/NamespaceCodegen.java | 36 +++++----- .../jet/codegen/PropertyCodegen.java | 28 ++++---- .../jet/codegen/TraitImplBodyCodegen.java | 17 ++--- 12 files changed, 206 insertions(+), 139 deletions(-) create mode 100644 compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilder.java diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java index 4ab6dfeb815..7a9ff954f9c 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java @@ -1,10 +1,10 @@ package org.jetbrains.jet.codegen; +import com.intellij.psi.PsiElement; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; -import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.commons.InstructionAdapter; @@ -23,12 +23,12 @@ public abstract class ClassBodyCodegen { protected final JetClassOrObject myClass; protected final OwnerKind kind; protected final ClassDescriptor descriptor; - protected final ClassVisitor v; + protected final ClassBuilder v; protected final ClassContext context; protected final List staticInitializerChunks = new ArrayList(); - public ClassBodyCodegen(JetClassOrObject aClass, ClassContext context, ClassVisitor v, GenerationState state) { + public ClassBodyCodegen(JetClassOrObject aClass, ClassContext context, ClassBuilder v, GenerationState state) { this.state = state; descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass); myClass = aClass; @@ -46,7 +46,7 @@ public abstract class ClassBodyCodegen { generateStaticInitializer(); - v.visitEnd(); + v.done(); } protected abstract void generateDeclaration(); @@ -62,7 +62,7 @@ public abstract class ClassBodyCodegen { generateDeclaration(propertyCodegen, declaration, functionCodegen); } - generatePrimaryConstructorProperties(propertyCodegen); + generatePrimaryConstructorProperties(propertyCodegen, myClass); } protected void generateDeclaration(PropertyCodegen propertyCodegen, JetDeclaration declaration, FunctionCodegen functionCodegen) { @@ -82,20 +82,20 @@ public abstract class ClassBodyCodegen { functionCodegen.gen(declaration); } - private void generatePrimaryConstructorProperties(PropertyCodegen propertyCodegen) { + private void generatePrimaryConstructorProperties(PropertyCodegen propertyCodegen, PsiElement origin) { OwnerKind kind = context.getContextKind(); for (JetParameter p : getPrimaryConstructorParameters()) { if (p.getValOrVarNode() != null) { PropertyDescriptor propertyDescriptor = state.getBindingContext().get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, p); if (propertyDescriptor != null) { - propertyCodegen.generateDefaultGetter(propertyDescriptor, Opcodes.ACC_PUBLIC); + propertyCodegen.generateDefaultGetter(propertyDescriptor, Opcodes.ACC_PUBLIC, p); if (propertyDescriptor.isVar()) { - propertyCodegen.generateDefaultSetter(propertyDescriptor, Opcodes.ACC_PUBLIC); + propertyCodegen.generateDefaultSetter(propertyDescriptor, Opcodes.ACC_PUBLIC, origin); } //noinspection ConstantConditions if (!(kind instanceof OwnerKind.DelegateKind) && state.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) { - v.visitField(Opcodes.ACC_PRIVATE, p.getName(), state.getTypeMapper().mapType(propertyDescriptor.getOutType()).getDescriptor(), null, null); + v.newField(p, Opcodes.ACC_PRIVATE, p.getName(), state.getTypeMapper().mapType(propertyDescriptor.getOutType()).getDescriptor(), null, null); } } } @@ -111,8 +111,8 @@ public abstract class ClassBodyCodegen { private void generateStaticInitializer() { if (staticInitializerChunks.size() > 0) { - final MethodVisitor mv = v.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, - "", "()V", null, null); + final MethodVisitor mv = v.newMethod(null, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, + "", "()V", null, null); mv.visitCode(); InstructionAdapter v = new InstructionAdapter(mv); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilder.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilder.java new file mode 100644 index 00000000000..ad49c8c56ce --- /dev/null +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBuilder.java @@ -0,0 +1,59 @@ +/* + * @author max + */ +package org.jetbrains.jet.codegen; + +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.Nullable; +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.ClassVisitor; +import org.objectweb.asm.FieldVisitor; +import org.objectweb.asm.MethodVisitor; + +public class ClassBuilder { + private final ClassVisitor v; + + public ClassBuilder(ClassVisitor v) { + this.v = v; + } + + public FieldVisitor newField(@Nullable PsiElement origin, + int access, + String name, + String desc, + String signature, + Object value) { + return v.visitField(access, name, desc, signature, value); + } + + public MethodVisitor newMethod(@Nullable PsiElement origin, + int access, + String name, + String desc, + @Nullable String signature, + @Nullable String[] exceptions) { + return v.visitMethod(access, name, desc, signature, exceptions); + } + + public AnnotationVisitor newAnnotation(PsiElement origin, + String desc, + boolean visible) { + return v.visitAnnotation(desc, visible); + } + + public void done() { + v.visitEnd(); + } + + public ClassVisitor getVisitor() { + return v; + } + + public void defineClass(int version, int access, String name, String signature, String superName, String[] interfaces) { + v.visit(version, access, name, signature, superName, interfaces); + } + + public void visitSource(String name, String debug) { + v.visitSource(name, debug); + } +} diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassCodegen.java index 86ebc6554ad..434fa8cf5f2 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassCodegen.java @@ -3,7 +3,6 @@ package org.jetbrains.jet.codegen; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; -import org.objectweb.asm.ClassVisitor; /** * @author max @@ -33,7 +32,7 @@ public class ClassCodegen { private void generateImplementation(ClassContext parentContext, JetClassOrObject aClass, OwnerKind kind) { ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass); - ClassVisitor v = state.forClassImplementation(descriptor); + ClassBuilder v = state.forClassImplementation(descriptor); new ImplementationBodyCodegen(aClass, parentContext.intoClass(null, descriptor, kind), v, state).generate(); if(aClass instanceof JetClass && ((JetClass)aClass).isTrait()) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassFileFactory.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassFileFactory.java index bc00c386c08..0fadb452d83 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassFileFactory.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassFileFactory.java @@ -17,7 +17,7 @@ public class ClassFileFactory { private final Project project; private final boolean isText; private final Map ns2codegen = new HashMap(); - private final Map generators = new LinkedHashMap(); + private final Map generators = new LinkedHashMap(); private boolean isDone = false; public final GenerationState state; @@ -27,7 +27,7 @@ public class ClassFileFactory { this.state = state; } - ClassVisitor newVisitor(String filePath) { + ClassBuilder newVisitor(String filePath) { ClassVisitor visitor; if (isText) { visitor = new TraceClassVisitor(new PrintWriter(new StringWriter())); @@ -36,11 +36,12 @@ public class ClassFileFactory { visitor = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); } - generators.put(filePath, visitor); - return visitor; + final ClassBuilder answer = new ClassBuilder(visitor); + generators.put(filePath, answer); + return answer; } - ClassVisitor forAnonymousSubclass(String className) { + ClassBuilder forAnonymousSubclass(String className) { return newVisitor(className + ".class"); } @@ -49,8 +50,8 @@ public class ClassFileFactory { String fqName = namespace.getFQName(); NamespaceCodegen codegen = ns2codegen.get(fqName); if (codegen == null) { - final ClassVisitor classVisitor = newVisitor(NamespaceCodegen.getJVMClassName(fqName) + ".class"); - codegen = new NamespaceCodegen(classVisitor, fqName, state, namespace.getContainingFile()); + final ClassBuilder builder = newVisitor(NamespaceCodegen.getJVMClassName(fqName) + ".class"); + codegen = new NamespaceCodegen(builder, fqName, state, namespace.getContainingFile()); ns2codegen.put(fqName, codegen); } @@ -71,7 +72,7 @@ public class ClassFileFactory { done(); - TraceClassVisitor visitor = (TraceClassVisitor) generators.get(file); + TraceClassVisitor visitor = (TraceClassVisitor) generators.get(file).getVisitor(); StringWriter writer = new StringWriter(); visitor.print(new PrintWriter(writer)); @@ -84,7 +85,7 @@ public class ClassFileFactory { done(); - ClassWriter visitor = (ClassWriter) generators.get(file); + ClassWriter visitor = (ClassWriter) generators.get(file).getVisitor(); return visitor.toByteArray(); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java index 3aa68b5b5ed..fa277df481e 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java @@ -5,13 +5,18 @@ package org.jetbrains.jet.codegen; import com.intellij.openapi.util.Pair; -import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; +import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; +import org.jetbrains.jet.lang.descriptors.VariableDescriptor; import org.jetbrains.jet.lang.psi.JetFunctionLiteral; import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.types.JetType; -import org.objectweb.asm.*; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Type; import org.objectweb.asm.commons.InstructionAdapter; import org.objectweb.asm.commons.Method; import org.objectweb.asm.signature.SignatureWriter; @@ -44,7 +49,7 @@ public class ClosureCodegen extends FunctionOrClosureCodegen { } public GeneratedAnonymousClassDescriptor gen(JetFunctionLiteralExpression fun) { - final Pair nameAndVisitor = state.forAnonymousSubclass(fun); + final Pair nameAndVisitor = state.forAnonymousSubclass(fun); final FunctionDescriptor funDescriptor = (FunctionDescriptor) state.getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, fun); @@ -63,32 +68,32 @@ public class ClosureCodegen extends FunctionOrClosureCodegen { appendType(signatureWriter, funDescriptor.getReturnType(), '='); signatureWriter.visitEnd(); - cv.visit(V1_6, - ACC_PUBLIC, - name, - null, - funClass, - new String[0] + cv.defineClass(V1_6, + ACC_PUBLIC, + name, + null, + funClass, + new String[0] ); cv.visitSource(fun.getContainingFile().getName(), null); - generateBridge(name, funDescriptor, cv); + generateBridge(name, funDescriptor, fun, cv); captureThis = generateBody(funDescriptor, cv, fun.getFunctionLiteral()); final Type enclosingType = context.enclosingClassType(state.getTypeMapper()); if (enclosingType == null) captureThis = false; - final Method constructor = generateConstructor(funClass, captureThis, funDescriptor.getReturnType()); + final Method constructor = generateConstructor(funClass, captureThis, fun, funDescriptor.getReturnType()); if (captureThis) { - cv.visitField(0, "this$0", enclosingType.getDescriptor(), null, null); + cv.newField(fun, 0, "this$0", enclosingType.getDescriptor(), null, null); } if(isConst()) { - generateConstInstance(); + generateConstInstance(fun); } - cv.visitEnd(); + cv.done(); final GeneratedAnonymousClassDescriptor answer = new GeneratedAnonymousClassDescriptor(name, constructor, captureThis); for (DeclarationDescriptor descriptor : closure.keySet()) { @@ -98,10 +103,10 @@ public class ClosureCodegen extends FunctionOrClosureCodegen { return answer; } - private void generateConstInstance() { - cv.visitField(ACC_PRIVATE| ACC_STATIC, "$instance", "Ljava/lang/ref/SoftReference;", null, null); + private void generateConstInstance(JetFunctionLiteralExpression fun) { + cv.newField(fun, ACC_PRIVATE | ACC_STATIC, "$instance", "Ljava/lang/ref/SoftReference;", null, null); - MethodVisitor mv = cv.visitMethod(ACC_PUBLIC | ACC_STATIC, "$getInstance", "()L" + name + ";", null, new String[0]); + MethodVisitor mv = cv.newMethod(fun, ACC_PUBLIC | ACC_STATIC, "$getInstance", "()L" + name + ";", null, new String[0]); mv.visitCode(); mv.visitFieldInsn(GETSTATIC, name, "$instance", "Ljava/lang/ref/SoftReference;"); mv.visitInsn(DUP); @@ -140,21 +145,21 @@ public class ClosureCodegen extends FunctionOrClosureCodegen { mv.visitEnd(); } - private boolean generateBody(FunctionDescriptor funDescriptor, ClassVisitor cv, JetFunctionLiteral body) { + private boolean generateBody(FunctionDescriptor funDescriptor, ClassBuilder cv, JetFunctionLiteral body) { final ClassContext closureContext = context.intoClosure(name, this); FunctionCodegen fc = new FunctionCodegen(closureContext, cv, state); fc.generateMethod(body, invokeSignature(funDescriptor), funDescriptor); return closureContext.isThisWasUsed(); } - private void generateBridge(String className, FunctionDescriptor funDescriptor, ClassVisitor cv) { + private void generateBridge(String className, FunctionDescriptor funDescriptor, JetFunctionLiteralExpression fun, ClassBuilder cv) { final Method bridge = erasedInvokeSignature(funDescriptor); final Method delegate = invokeSignature(funDescriptor); if(bridge.getDescriptor().equals(delegate.getDescriptor())) return; - final MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "invoke", bridge.getDescriptor(), state.getTypeMapper().genericSignature(funDescriptor), new String[0]); + final MethodVisitor mv = cv.newMethod(fun, ACC_PUBLIC, "invoke", bridge.getDescriptor(), state.getTypeMapper().genericSignature(funDescriptor), new String[0]); mv.visitCode(); InstructionAdapter iv = new InstructionAdapter(mv); @@ -185,7 +190,7 @@ public class ClosureCodegen extends FunctionOrClosureCodegen { mv.visitEnd(); } - private Method generateConstructor(String funClass, boolean captureThis, JetType returnType) { + private Method generateConstructor(String funClass, boolean captureThis, JetFunctionLiteralExpression fun, JetType returnType) { int argCount = closure.size(); if (captureThis) { @@ -208,7 +213,7 @@ public class ClosureCodegen extends FunctionOrClosureCodegen { } final Method constructor = new Method("", Type.VOID_TYPE, argTypes); - final MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "", constructor.getDescriptor(), null, new String[0]); + final MethodVisitor mv = cv.newMethod(fun, ACC_PUBLIC, "", constructor.getDescriptor(), null, new String[0]); mv.visitCode(); InstructionAdapter iv = new InstructionAdapter(mv); ExpressionCodegen expressionCodegen = new ExpressionCodegen(mv, null, Type.VOID_TYPE, context, state); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index a7724378b36..cd05790af27 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -4,7 +4,10 @@ import com.intellij.psi.PsiElement; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; -import org.objectweb.asm.*; +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Type; import org.objectweb.asm.commons.InstructionAdapter; import org.objectweb.asm.commons.Method; @@ -20,10 +23,10 @@ import static org.objectweb.asm.Opcodes.*; */ public class FunctionCodegen { private final ClassContext owner; - private final ClassVisitor v; + private final ClassBuilder v; private final GenerationState state; - public FunctionCodegen(ClassContext owner, ClassVisitor v, GenerationState state) { + public FunctionCodegen(ClassContext owner, ClassBuilder v, GenerationState state) { this.owner = owner; this.v = v; this.state = state; @@ -39,13 +42,13 @@ public class FunctionCodegen { ClassContext funContext = owner.intoFunction(functionDescriptor); final JetExpression bodyExpression = f.getBodyExpression(); - generatedMethod(bodyExpression, jvmMethod, funContext, functionDescriptor); + generatedMethod(bodyExpression, jvmMethod, funContext, functionDescriptor, f); } private void generatedMethod(JetExpression bodyExpressions, Method jvmSignature, ClassContext context, - FunctionDescriptor functionDescriptor) + FunctionDescriptor functionDescriptor, JetDeclarationWithBody fun) { List paramDescrs = functionDescriptor.getValueParameters(); List typeParameters = functionDescriptor.getTypeParameters(); @@ -62,7 +65,7 @@ public class FunctionCodegen { boolean isAbstract = !isStatic && (bodyExpressions == null || CodegenUtil.isInterface(functionDescriptor.getContainingDeclaration())); if (isAbstract) flags |= ACC_ABSTRACT; - final MethodVisitor mv = v.visitMethod(flags, jvmSignature.getName(), jvmSignature.getDescriptor(), null, null); + final MethodVisitor mv = v.newMethod(fun, flags, jvmSignature.getName(), jvmSignature.getDescriptor(), null, null); if(kind != OwnerKind.TRAIT_IMPL) { int start = functionDescriptor.getReceiverParameter().exists() ? 1 : 0; for(int i = 0; i != paramDescrs.size(); ++i) { @@ -135,7 +138,7 @@ public class FunctionCodegen { generateDefaultIfNeeded(context, state, v, jvmSignature, functionDescriptor, kind); } - static void generateBridgeIfNeeded(ClassContext owner, GenerationState state, ClassVisitor v, Method jvmSignature, FunctionDescriptor functionDescriptor, OwnerKind kind) { + static void generateBridgeIfNeeded(ClassContext owner, GenerationState state, ClassBuilder v, Method jvmSignature, FunctionDescriptor functionDescriptor, OwnerKind kind) { Set overriddenFunctions = functionDescriptor.getOverriddenDescriptors(); if(kind != OwnerKind.TRAIT_IMPL) { for (FunctionDescriptor overriddenFunction : overriddenFunctions) { @@ -146,7 +149,7 @@ public class FunctionCodegen { } } - static void generateDefaultIfNeeded(ClassContext owner, GenerationState state, ClassVisitor v, Method jvmSignature, FunctionDescriptor functionDescriptor, OwnerKind kind) { + static void generateDefaultIfNeeded(ClassContext owner, GenerationState state, ClassBuilder v, Method jvmSignature, FunctionDescriptor functionDescriptor, OwnerKind kind) { DeclarationDescriptor contextClass = owner.getContextClass(); if(kind != OwnerKind.TRAIT_IMPL) { @@ -187,7 +190,7 @@ public class FunctionCodegen { String descriptor = jvmSignature.getDescriptor().replace(")","I)"); if(!isStatic) descriptor = descriptor.replace("(","(L" + ownerInternalName + ";"); - final MethodVisitor mv = v.visitMethod(flags| ACC_STATIC, jvmSignature.getName() + "$default", descriptor, null, null); + final MethodVisitor mv = v.newMethod(null, flags | ACC_STATIC, jvmSignature.getName() + "$default", descriptor, null, null); InstructionAdapter iv = new InstructionAdapter(mv); mv.visitCode(); @@ -287,14 +290,14 @@ public class FunctionCodegen { } } - private static void checkOverride(ClassContext owner, GenerationState state, ClassVisitor v, Method jvmSignature, FunctionDescriptor functionDescriptor, FunctionDescriptor overriddenFunction) { + private static void checkOverride(ClassContext owner, GenerationState state, ClassBuilder v, Method jvmSignature, FunctionDescriptor functionDescriptor, FunctionDescriptor overriddenFunction) { Type type1 = state.getTypeMapper().mapType(overriddenFunction.getOriginal().getReturnType()); Type type2 = state.getTypeMapper().mapType(functionDescriptor.getReturnType()); if(!type1.equals(type2)) { Method overriden = state.getTypeMapper().mapSignature(overriddenFunction.getName(), overriddenFunction.getOriginal()); int flags = ACC_PUBLIC; // TODO. - final MethodVisitor mv = v.visitMethod(flags, jvmSignature.getName(), overriden.getDescriptor(), null, null); + final MethodVisitor mv = v.newMethod(null, flags, jvmSignature.getName(), overriden.getDescriptor(), null, null); mv.visitCode(); Type[] argTypes = jvmSignature.getArgumentTypes(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionOrClosureCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionOrClosureCodegen.java index a9834ed153d..2a0bd3be23f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionOrClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionOrClosureCodegen.java @@ -2,7 +2,6 @@ package org.jetbrains.jet.codegen; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.VariableDescriptor; -import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; @@ -18,7 +17,7 @@ public class FunctionOrClosureCodegen { public final GenerationState state; protected final ExpressionCodegen exprContext; protected final ClassContext context; - protected ClassVisitor cv = null; + protected ClassBuilder cv = null; public String name = null; protected Map closure = new LinkedHashMap(); @@ -46,7 +45,7 @@ public class FunctionOrClosureCodegen { final String fieldName = "$" + (closure.size() + 1); // + "$" + vd.getName(); StackValue innerValue = sharedVarType != null ? StackValue.fieldForSharedVar(localType, name, fieldName) : StackValue.field(type, name, fieldName, false); - cv.visitField(Opcodes.ACC_PUBLIC, fieldName, type.getDescriptor(), null, null); + cv.newField(null, Opcodes.ACC_PUBLIC, fieldName, type.getDescriptor(), null, null); answer = new EnclosedValueDescriptor(d, innerValue, outerValue); closure.put(d, answer); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java b/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java index 51713dc8fb4..8a4ec90771a 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java @@ -15,8 +15,6 @@ import org.jetbrains.jet.lang.resolve.AnalyzingUtils; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.java.JavaDefaultImports; import org.jetbrains.jet.lang.types.JetStandardLibrary; -import org.objectweb.asm.ClassVisitor; -import org.objectweb.asm.commons.Method; import java.util.Collections; import java.util.List; @@ -61,26 +59,21 @@ public class GenerationState { return intrinsics; } - public ClassVisitor forClassInterface(ClassDescriptor aClass) { - return factory.newVisitor(JetTypeMapper.jvmNameForInterface(aClass) + ".class"); - } - public ClassCodegen forClass() { return new ClassCodegen(this); } - public ClassVisitor forClassImplementation(ClassDescriptor aClass) { + public ClassBuilder forClassImplementation(ClassDescriptor aClass) { return factory.newVisitor(typeMapper.jvmName(aClass, OwnerKind.IMPLEMENTATION) + ".class"); } - public ClassVisitor forTraitImplementation(ClassDescriptor aClass) { + public ClassBuilder forTraitImplementation(ClassDescriptor aClass) { return factory.newVisitor(typeMapper.jvmName(aClass, OwnerKind.TRAIT_IMPL) + ".class"); } - public Pair forAnonymousSubclass(JetExpression expression) { + public Pair forAnonymousSubclass(JetExpression expression) { String className = typeMapper.classNameForAnonymousClass(expression); - ClassVisitor visitor = factory.forAnonymousSubclass(className); - return Pair.create(className, visitor); + return Pair.create(className, factory.forAnonymousSubclass(className)); } public NamespaceCodegen forNamespace(JetNamespace namespace) { @@ -123,7 +116,7 @@ public class GenerationState { public GeneratedAnonymousClassDescriptor generateObjectLiteral(JetObjectLiteralExpression literal, FunctionOrClosureCodegen closure) { JetObjectDeclaration objectDeclaration = literal.getObjectDeclaration(); - Pair nameAndVisitor = forAnonymousSubclass(objectDeclaration); + Pair nameAndVisitor = forAnonymousSubclass(objectDeclaration); closure.cv = nameAndVisitor.getSecond(); closure.name = nameAndVisitor.getFirst(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 69df0081b91..6834d94c79c 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -11,7 +11,10 @@ import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeProjection; import org.jetbrains.jet.lexer.JetTokens; -import org.objectweb.asm.*; +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; import org.objectweb.asm.commons.InstructionAdapter; import org.objectweb.asm.commons.Method; @@ -26,7 +29,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { private JetDelegationSpecifier superCall; private String superClass = "java/lang/Object"; - public ImplementationBodyCodegen(JetClassOrObject aClass, ClassContext context, ClassVisitor v, GenerationState state) { + public ImplementationBodyCodegen(JetClassOrObject aClass, ClassContext context, ClassBuilder v, GenerationState state) { super(aClass, context, v, state); } @@ -89,21 +92,23 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } } - v.visit(Opcodes.V1_6, - Opcodes.ACC_PUBLIC | (isAbstract ? Opcodes.ACC_ABSTRACT : 0) | (isInterface ? Opcodes.ACC_INTERFACE : 0), - jvmName(), - null, - superClass, - interfaces.toArray(new String[interfaces.size()]) + v.defineClass(Opcodes.V1_6, + Opcodes.ACC_PUBLIC | (isAbstract ? Opcodes.ACC_ABSTRACT : 0) | (isInterface + ? Opcodes.ACC_INTERFACE + : 0), + jvmName(), + null, + superClass, + interfaces.toArray(new String[interfaces.size()]) ); v.visitSource(myClass.getContainingFile().getName(), null); if(descriptor.getContainingDeclaration() instanceof ClassDescriptor) { - v.visitOuterClass(state.getTypeMapper().jvmType((ClassDescriptor) descriptor.getContainingDeclaration(), OwnerKind.IMPLEMENTATION).getInternalName(), null, null); + v.getVisitor().visitOuterClass(state.getTypeMapper().jvmType((ClassDescriptor) descriptor.getContainingDeclaration(), OwnerKind.IMPLEMENTATION).getInternalName(), null, null); } if(myClass instanceof JetClass) { - AnnotationVisitor annotationVisitor = v.visitAnnotation("Ljet/typeinfo/JetSignature;", true); + AnnotationVisitor annotationVisitor = v.newAnnotation(myClass, "Ljet/typeinfo/JetSignature;", true); annotationVisitor.visit("value", SignatureUtil.classToSignature((JetClass)myClass, state.getBindingContext(), state.getTypeMapper())); annotationVisitor.visitEnd(); } @@ -162,7 +167,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { private void generateFieldForObjectInstance() { if (isNonLiteralObject()) { Type type = JetTypeMapper.jetImplementationType(descriptor); - v.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "$instance", type.getDescriptor(), null, null); + v.newField(myClass, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "$instance", type.getDescriptor(), null, null); staticInitializerChunks.add(new CodeChunk() { @Override @@ -182,7 +187,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { final JetClassObject classObject = getClassObject(); if (classObject != null) { Type type = Type.getObjectType(state.getTypeMapper().jvmName(classObject)); - v.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "$classobj", type.getDescriptor(), null, null); + v.newField(classObject, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "$classobj", type.getDescriptor(), null, null); staticInitializerChunks.add(new CodeChunk() { @Override @@ -242,7 +247,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } int flags = Opcodes.ACC_PUBLIC; // TODO - final MethodVisitor mv = v.visitMethod(flags, "", method.getDescriptor(), null, null); + final MethodVisitor mv = v.newMethod(myClass, flags, "", method.getDescriptor(), null, null); mv.visitCode(); List paramDescrs = constructorDescriptor != null @@ -312,7 +317,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { String delegateField = "$delegate_" + n; Type fieldType = JetTypeMapper.jetInterfaceType(superClassDescriptor); String fieldDesc = fieldType.getDescriptor(); - v.visitField(Opcodes.ACC_PRIVATE, delegateField, fieldDesc, /*TODO*/null, null); + v.newField(specifier, Opcodes.ACC_PRIVATE, delegateField, fieldDesc, /*TODO*/null, null); iv.putfield(classname, delegateField, fieldDesc); JetClass superClass = (JetClass) state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, superClassDescriptor); @@ -328,7 +333,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { final Type type = JetTypeMapper.jetImplementationType(outerDescriptor); String interfaceDesc = type.getDescriptor(); final String fieldName = "this$0"; - v.visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, fieldName, interfaceDesc, null, null); + v.newField(myClass, Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, fieldName, interfaceDesc, null, null); iv.load(0, classType); iv.load(frameMap.getOuterThisIndex(), type); iv.putfield(classname, fieldName, interfaceDesc); @@ -393,7 +398,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { Method function = state.getTypeMapper().mapSignature(fun.getName(), fun); Method functionOriginal = state.getTypeMapper().mapSignature(fun.getName(), fun.getOriginal()); - final MethodVisitor mv = v.visitMethod(flags, function.getName(), function.getDescriptor(), null, null); + final MethodVisitor mv = v.newMethod(myClass, flags, function.getName(), function.getDescriptor(), null, null); mv.visitCode(); codegen.generateThisOrOuter(descriptor); @@ -475,7 +480,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { else if (declaration instanceof JetEnumEntry && !((JetEnumEntry) declaration).hasPrimaryConstructor()) { String name = declaration.getName(); final String desc = "L" + state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION) + ";"; - v.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL, name, desc, null, null); + v.newField(declaration, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC | Opcodes.ACC_FINAL, name, desc, null, null); if (myEnumConstants.isEmpty()) { staticInitializerChunks.add(new CodeChunk() { @Override @@ -533,7 +538,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } CallableMethod method = state.getTypeMapper().mapToCallableMethod(constructorDescriptor, kind); int flags = Opcodes.ACC_PUBLIC; // TODO - final MethodVisitor mv = v.visitMethod(flags, "", method.getSignature().getDescriptor(), null, null); + final MethodVisitor mv = v.newMethod(constructor, flags, "", method.getSignature().getDescriptor(), null, null); mv.visitCode(); ConstructorFrameMap frameMap = new ConstructorFrameMap(method, constructorDescriptor, descriptor, kind); @@ -677,9 +682,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if (p.getValOrVarNode() != null) { PropertyDescriptor propertyDescriptor = state.getBindingContext().get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, p); if (propertyDescriptor != null) { - propertyCodegen.generateDefaultGetter(propertyDescriptor, Opcodes.ACC_PUBLIC); + propertyCodegen.generateDefaultGetter(propertyDescriptor, Opcodes.ACC_PUBLIC, p); if (propertyDescriptor.isVar()) { - propertyCodegen.generateDefaultSetter(propertyDescriptor, Opcodes.ACC_PUBLIC); + propertyCodegen.generateDefaultSetter(propertyDescriptor, Opcodes.ACC_PUBLIC, p); } } } @@ -703,9 +708,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { JetType defaultType = descriptor.getDefaultType(); if(CodegenUtil.hasTypeInfoField(defaultType)) { if(!CodegenUtil.hasDerivedTypeInfoField(defaultType, true)) { - v.visitField(Opcodes.ACC_PRIVATE, "$typeInfo", "Ljet/typeinfo/TypeInfo;", null, null); + v.newField(myClass, Opcodes.ACC_PRIVATE, "$typeInfo", "Ljet/typeinfo/TypeInfo;", null, null); - MethodVisitor mv = v.visitMethod(Opcodes.ACC_PUBLIC, "getTypeInfo", "()Ljet/typeinfo/TypeInfo;", null, null); + MethodVisitor mv = v.newMethod(myClass, Opcodes.ACC_PUBLIC, "getTypeInfo", "()Ljet/typeinfo/TypeInfo;", null, null); mv.visitCode(); InstructionAdapter iv = new InstructionAdapter(mv); String owner = state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION); @@ -715,7 +720,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { mv.visitMaxs(0, 0); mv.visitEnd(); - mv = v.visitMethod(Opcodes.ACC_PROTECTED|Opcodes.ACC_FINAL, "$setTypeInfo", "(Ljet/typeinfo/TypeInfo;)V", null, null); + mv = v.newMethod(myClass, Opcodes.ACC_PROTECTED | Opcodes.ACC_FINAL, "$setTypeInfo", "(Ljet/typeinfo/TypeInfo;)V", null, null); mv.visitCode(); iv = new InstructionAdapter(mv); owner = state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION); @@ -734,7 +739,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } private void genGetStaticGetTypeInfoMethod() { - final MethodVisitor mv = v.visitMethod(Opcodes.ACC_PUBLIC, "getTypeInfo", "()Ljet/typeinfo/TypeInfo;", null, null); + final MethodVisitor mv = v.newMethod(myClass, Opcodes.ACC_PUBLIC, "getTypeInfo", "()Ljet/typeinfo/TypeInfo;", null, null); mv.visitCode(); InstructionAdapter v = new InstructionAdapter(mv); String owner = state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION); @@ -745,7 +750,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } private void staticTypeInfoField() { - v.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_STATIC, "$staticTypeInfo", "Ljet/typeinfo/TypeInfo;", null, null); + v.newField(myClass, Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_STATIC, "$staticTypeInfo", "Ljet/typeinfo/TypeInfo;", null, null); staticInitializerChunks.add(new CodeChunk() { @Override public void generate(InstructionAdapter v) { @@ -776,11 +781,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { String sig = getGetSuperTypesTypeInfoSignature(descriptor.getDefaultType()); - final MethodVisitor mv = v.visitMethod(Opcodes.ACC_PUBLIC|Opcodes.ACC_STATIC, - "$$getSuperTypesTypeInfo", - sig, - null /* TODO */, - null); + final MethodVisitor mv = v.newMethod(myClass, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, + "$$getSuperTypesTypeInfo", + sig, + null /* TODO */, + null); mv.visitCode(); InstructionAdapter v = new InstructionAdapter(mv); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java index 4974917fb30..a456c64b74a 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java @@ -9,10 +9,14 @@ import org.jetbrains.jet.lang.resolve.java.JavaClassDescriptor; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeProjection; import org.jetbrains.jet.lang.types.TypeUtils; -import org.objectweb.asm.*; +import org.objectweb.asm.Label; +import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Type; import org.objectweb.asm.commons.InstructionAdapter; -import java.util.*; +import java.util.Collections; +import java.util.List; +import java.util.Map; import static org.objectweb.asm.Opcodes.*; @@ -20,20 +24,20 @@ import static org.objectweb.asm.Opcodes.*; * @author max */ public class NamespaceCodegen { - private final ClassVisitor v; + private final ClassBuilder v; private final GenerationState state; - public NamespaceCodegen(ClassVisitor v, String fqName, GenerationState state, PsiFile sourceFile) { + public NamespaceCodegen(ClassBuilder v, String fqName, GenerationState state, PsiFile sourceFile) { this.v = v; this.state = state; - v.visit(V1_6, - ACC_PUBLIC, - getJVMClassName(fqName), - null, - //"jet/lang/Namespace", - "java/lang/Object", - new String[0] + v.defineClass(V1_6, + ACC_PUBLIC, + getJVMClassName(fqName), + null, + //"jet/lang/Namespace", + "java/lang/Object", + new String[0] ); // TODO figure something out for a namespace that spans multiple files v.visitSource(sourceFile.getName(), null); @@ -76,8 +80,8 @@ public class NamespaceCodegen { } private void generateStaticInitializers(JetNamespace namespace) { - MethodVisitor mv = v.visitMethod(ACC_PUBLIC | ACC_STATIC, - "", "()V", null, null); + MethodVisitor mv = v.newMethod(namespace, ACC_PUBLIC | ACC_STATIC, + "", "()V", null, null); mv.visitCode(); FrameMap frameMap = new FrameMap(); @@ -104,9 +108,9 @@ public class NamespaceCodegen { String jvmClassName = getJVMClassName(namespace.getName()); for(Map.Entry e : (context.typeInfoConstants != null ? context.typeInfoConstants : Collections.emptyMap()).entrySet()) { String fieldName = "$typeInfoCache$" + e.getValue(); - v.visitField(ACC_PRIVATE|ACC_STATIC|ACC_SYNTHETIC, fieldName, "Ljet/typeinfo/TypeInfo;", null, null); + v.newField(null, ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC, fieldName, "Ljet/typeinfo/TypeInfo;", null, null); - MethodVisitor mmv = v.visitMethod(ACC_PUBLIC|ACC_STATIC|ACC_SYNTHETIC, "$getCachedTypeInfo$" + e.getValue(), "()Ljet/typeinfo/TypeInfo;", null, null); + MethodVisitor mmv = v.newMethod(null, ACC_PUBLIC | ACC_STATIC | ACC_SYNTHETIC, "$getCachedTypeInfo$" + e.getValue(), "()Ljet/typeinfo/TypeInfo;", null, null); InstructionAdapter v = new InstructionAdapter(mmv); v.visitFieldInsn(GETSTATIC, jvmClassName, fieldName, "Ljet/typeinfo/TypeInfo;"); v.visitInsn(DUP); @@ -185,7 +189,7 @@ public class NamespaceCodegen { } public void done() { - v.visitEnd(); + v.done(); } public static String getJVMClassName(String fqName) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java index 6dc17c82643..be9733fac27 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java @@ -2,12 +2,14 @@ package org.jetbrains.jet.codegen; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; -import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; +import org.jetbrains.jet.lang.descriptors.PropertySetterDescriptor; +import org.jetbrains.jet.lang.descriptors.VariableDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lexer.JetTokens; -import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; @@ -19,10 +21,10 @@ import org.objectweb.asm.commons.InstructionAdapter; public class PropertyCodegen { private final GenerationState state; private final FunctionCodegen functionCodegen; - private final ClassVisitor v; + private final ClassBuilder v; private final OwnerKind kind; - public PropertyCodegen(ClassContext context, ClassVisitor v, FunctionCodegen functionCodegen, GenerationState state) { + public PropertyCodegen(ClassContext context, ClassBuilder v, FunctionCodegen functionCodegen, GenerationState state) { this.v = v; this.functionCodegen = functionCodegen; this.state = state; @@ -41,9 +43,9 @@ public class PropertyCodegen { generateSetter(p, propertyDescriptor); } else if (kind instanceof OwnerKind.DelegateKind) { - generateDefaultGetter(propertyDescriptor, Opcodes.ACC_PUBLIC); + generateDefaultGetter(propertyDescriptor, Opcodes.ACC_PUBLIC, p); if (propertyDescriptor.isVar()) { - generateDefaultSetter(propertyDescriptor, Opcodes.ACC_PUBLIC); + generateDefaultSetter(propertyDescriptor, Opcodes.ACC_PUBLIC, p); } } } @@ -71,7 +73,7 @@ public class PropertyCodegen { else { modifiers = Opcodes.ACC_PRIVATE; } - v.visitField(modifiers, p.getName(), state.getTypeMapper().mapType(propertyDescriptor.getOutType()).getDescriptor(), null, value); + v.newField(p, modifiers, p.getName(), state.getTypeMapper().mapType(propertyDescriptor.getOutType()).getDescriptor(), null, value); } } @@ -114,10 +116,10 @@ public class PropertyCodegen { private void generateDefaultGetter(JetProperty p, JetDeclaration declaration) { final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, p); int flags = JetTypeMapper.getAccessModifiers(declaration, Opcodes.ACC_PUBLIC); - generateDefaultGetter(propertyDescriptor, flags); + generateDefaultGetter(propertyDescriptor, flags, p); } - public void generateDefaultGetter(PropertyDescriptor propertyDescriptor, int flags) { + public void generateDefaultGetter(PropertyDescriptor propertyDescriptor, int flags, PsiElement origin) { if (kind == OwnerKind.NAMESPACE) { flags |= Opcodes.ACC_STATIC; } @@ -129,7 +131,7 @@ public class PropertyCodegen { final String signature = state.getTypeMapper().mapGetterSignature(propertyDescriptor).getDescriptor(); String getterName = getterName(propertyDescriptor.getName()); - MethodVisitor mv = v.visitMethod(flags, getterName, signature, null, null); + MethodVisitor mv = v.newMethod(origin, flags, getterName, signature, null, null); if (!isTrait || kind instanceof OwnerKind.DelegateKind) { mv.visitCode(); InstructionAdapter iv = new InstructionAdapter(mv); @@ -156,10 +158,10 @@ public class PropertyCodegen { private void generateDefaultSetter(JetProperty p, JetDeclaration declaration) { final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, p); int flags = JetTypeMapper.getAccessModifiers(declaration, Opcodes.ACC_PUBLIC); - generateDefaultSetter(propertyDescriptor, flags); + generateDefaultSetter(propertyDescriptor, flags, p); } - public void generateDefaultSetter(PropertyDescriptor propertyDescriptor, int flags) { + public void generateDefaultSetter(PropertyDescriptor propertyDescriptor, int flags, PsiElement origin) { if (kind == OwnerKind.NAMESPACE) { flags |= Opcodes.ACC_STATIC; } @@ -170,7 +172,7 @@ public class PropertyCodegen { flags |= Opcodes.ACC_ABSTRACT; final String signature = state.getTypeMapper().mapSetterSignature(propertyDescriptor).getDescriptor(); - MethodVisitor mv = v.visitMethod(flags, setterName(propertyDescriptor.getName()), signature, null, null); + MethodVisitor mv = v.newMethod(origin, flags, setterName(propertyDescriptor.getName()), signature, null, null); if (!isTrait || kind instanceof OwnerKind.DelegateKind) { mv.visitCode(); InstructionAdapter iv = new InstructionAdapter(mv); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/TraitImplBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/TraitImplBodyCodegen.java index 86a07215e04..1f084b731dc 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/TraitImplBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/TraitImplBodyCodegen.java @@ -7,15 +7,12 @@ import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.types.JetStandardClasses; import org.jetbrains.jet.lang.types.JetType; -import org.jetbrains.jet.lexer.JetTokens; -import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.Opcodes; -import java.util.ArrayList; import java.util.List; public class TraitImplBodyCodegen extends ClassBodyCodegen { - public TraitImplBodyCodegen(JetClassOrObject aClass, ClassContext context, ClassVisitor v, GenerationState state) { + public TraitImplBodyCodegen(JetClassOrObject aClass, ClassContext context, ClassBuilder v, GenerationState state) { super(aClass, context, v, state); } @@ -48,12 +45,12 @@ public class TraitImplBodyCodegen extends ClassBodyCodegen { @Override protected void generateDeclaration() { - v.visit(Opcodes.V1_6, - Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, - jvmName(), - null, - "java/lang/Object", - new String[0] + v.defineClass(Opcodes.V1_6, + Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, + jvmName(), + null, + "java/lang/Object", + new String[0] ); v.visitSource(myClass.getContainingFile().getName(), null); }