Wrap ASM class generation so we can attribute generated classes with PSI origins when building kotlin-as-seen-from-java model
This commit is contained in:
@@ -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<CodeChunk> staticInitializerChunks = new ArrayList<CodeChunk>();
|
||||
|
||||
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,
|
||||
"<clinit>", "()V", null, null);
|
||||
final MethodVisitor mv = v.newMethod(null, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,
|
||||
"<clinit>", "()V", null, null);
|
||||
mv.visitCode();
|
||||
|
||||
InstructionAdapter v = new InstructionAdapter(mv);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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()) {
|
||||
|
||||
@@ -17,7 +17,7 @@ public class ClassFileFactory {
|
||||
private final Project project;
|
||||
private final boolean isText;
|
||||
private final Map<String, NamespaceCodegen> ns2codegen = new HashMap<String, NamespaceCodegen>();
|
||||
private final Map<String, ClassVisitor> generators = new LinkedHashMap<String, ClassVisitor>();
|
||||
private final Map<String, ClassBuilder> generators = new LinkedHashMap<String, ClassBuilder>();
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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<String, ClassVisitor> nameAndVisitor = state.forAnonymousSubclass(fun);
|
||||
final Pair<String, ClassBuilder> 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("<init>", Type.VOID_TYPE, argTypes);
|
||||
final MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "<init>", constructor.getDescriptor(), null, new String[0]);
|
||||
final MethodVisitor mv = cv.newMethod(fun, ACC_PUBLIC, "<init>", constructor.getDescriptor(), null, new String[0]);
|
||||
mv.visitCode();
|
||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||
ExpressionCodegen expressionCodegen = new ExpressionCodegen(mv, null, Type.VOID_TYPE, context, state);
|
||||
|
||||
@@ -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<ValueParameterDescriptor> paramDescrs = functionDescriptor.getValueParameters();
|
||||
List<TypeParameterDescriptor> 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<? extends FunctionDescriptor> 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();
|
||||
|
||||
@@ -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<DeclarationDescriptor, EnclosedValueDescriptor> closure = new LinkedHashMap<DeclarationDescriptor, EnclosedValueDescriptor>();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<String, ClassVisitor> forAnonymousSubclass(JetExpression expression) {
|
||||
public Pair<String, ClassBuilder> 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<String, ClassVisitor> nameAndVisitor = forAnonymousSubclass(objectDeclaration);
|
||||
Pair<String, ClassBuilder> nameAndVisitor = forAnonymousSubclass(objectDeclaration);
|
||||
|
||||
closure.cv = nameAndVisitor.getSecond();
|
||||
closure.name = nameAndVisitor.getFirst();
|
||||
|
||||
@@ -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, "<init>", method.getDescriptor(), null, null);
|
||||
final MethodVisitor mv = v.newMethod(myClass, flags, "<init>", method.getDescriptor(), null, null);
|
||||
mv.visitCode();
|
||||
|
||||
List<ValueParameterDescriptor> 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, "<init>", method.getSignature().getDescriptor(), null, null);
|
||||
final MethodVisitor mv = v.newMethod(constructor, flags, "<init>", 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);
|
||||
|
||||
|
||||
@@ -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,
|
||||
"<clinit>", "()V", null, null);
|
||||
MethodVisitor mv = v.newMethod(namespace, ACC_PUBLIC | ACC_STATIC,
|
||||
"<clinit>", "()V", null, null);
|
||||
mv.visitCode();
|
||||
|
||||
FrameMap frameMap = new FrameMap();
|
||||
@@ -104,9 +108,9 @@ public class NamespaceCodegen {
|
||||
String jvmClassName = getJVMClassName(namespace.getName());
|
||||
for(Map.Entry<JetType,Integer> e : (context.typeInfoConstants != null ? context.typeInfoConstants : Collections.<JetType,Integer>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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user