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;
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
import org.jetbrains.jet.lang.descriptors.PropertyDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.objectweb.asm.ClassVisitor;
|
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
import org.objectweb.asm.commons.InstructionAdapter;
|
||||||
@@ -23,12 +23,12 @@ public abstract class ClassBodyCodegen {
|
|||||||
protected final JetClassOrObject myClass;
|
protected final JetClassOrObject myClass;
|
||||||
protected final OwnerKind kind;
|
protected final OwnerKind kind;
|
||||||
protected final ClassDescriptor descriptor;
|
protected final ClassDescriptor descriptor;
|
||||||
protected final ClassVisitor v;
|
protected final ClassBuilder v;
|
||||||
protected final ClassContext context;
|
protected final ClassContext context;
|
||||||
|
|
||||||
protected final List<CodeChunk> staticInitializerChunks = new ArrayList<CodeChunk>();
|
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;
|
this.state = state;
|
||||||
descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass);
|
descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass);
|
||||||
myClass = aClass;
|
myClass = aClass;
|
||||||
@@ -46,7 +46,7 @@ public abstract class ClassBodyCodegen {
|
|||||||
|
|
||||||
generateStaticInitializer();
|
generateStaticInitializer();
|
||||||
|
|
||||||
v.visitEnd();
|
v.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void generateDeclaration();
|
protected abstract void generateDeclaration();
|
||||||
@@ -62,7 +62,7 @@ public abstract class ClassBodyCodegen {
|
|||||||
generateDeclaration(propertyCodegen, declaration, functionCodegen);
|
generateDeclaration(propertyCodegen, declaration, functionCodegen);
|
||||||
}
|
}
|
||||||
|
|
||||||
generatePrimaryConstructorProperties(propertyCodegen);
|
generatePrimaryConstructorProperties(propertyCodegen, myClass);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void generateDeclaration(PropertyCodegen propertyCodegen, JetDeclaration declaration, FunctionCodegen functionCodegen) {
|
protected void generateDeclaration(PropertyCodegen propertyCodegen, JetDeclaration declaration, FunctionCodegen functionCodegen) {
|
||||||
@@ -82,20 +82,20 @@ public abstract class ClassBodyCodegen {
|
|||||||
functionCodegen.gen(declaration);
|
functionCodegen.gen(declaration);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generatePrimaryConstructorProperties(PropertyCodegen propertyCodegen) {
|
private void generatePrimaryConstructorProperties(PropertyCodegen propertyCodegen, PsiElement origin) {
|
||||||
OwnerKind kind = context.getContextKind();
|
OwnerKind kind = context.getContextKind();
|
||||||
for (JetParameter p : getPrimaryConstructorParameters()) {
|
for (JetParameter p : getPrimaryConstructorParameters()) {
|
||||||
if (p.getValOrVarNode() != null) {
|
if (p.getValOrVarNode() != null) {
|
||||||
PropertyDescriptor propertyDescriptor = state.getBindingContext().get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, p);
|
PropertyDescriptor propertyDescriptor = state.getBindingContext().get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, p);
|
||||||
if (propertyDescriptor != null) {
|
if (propertyDescriptor != null) {
|
||||||
propertyCodegen.generateDefaultGetter(propertyDescriptor, Opcodes.ACC_PUBLIC);
|
propertyCodegen.generateDefaultGetter(propertyDescriptor, Opcodes.ACC_PUBLIC, p);
|
||||||
if (propertyDescriptor.isVar()) {
|
if (propertyDescriptor.isVar()) {
|
||||||
propertyCodegen.generateDefaultSetter(propertyDescriptor, Opcodes.ACC_PUBLIC);
|
propertyCodegen.generateDefaultSetter(propertyDescriptor, Opcodes.ACC_PUBLIC, origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
if (!(kind instanceof OwnerKind.DelegateKind) && state.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor)) {
|
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() {
|
private void generateStaticInitializer() {
|
||||||
if (staticInitializerChunks.size() > 0) {
|
if (staticInitializerChunks.size() > 0) {
|
||||||
final MethodVisitor mv = v.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,
|
final MethodVisitor mv = v.newMethod(null, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,
|
||||||
"<clinit>", "()V", null, null);
|
"<clinit>", "()V", null, null);
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
|
|
||||||
InstructionAdapter v = new InstructionAdapter(mv);
|
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.descriptors.ClassDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.objectweb.asm.ClassVisitor;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author max
|
* @author max
|
||||||
@@ -33,7 +32,7 @@ public class ClassCodegen {
|
|||||||
|
|
||||||
private void generateImplementation(ClassContext parentContext, JetClassOrObject aClass, OwnerKind kind) {
|
private void generateImplementation(ClassContext parentContext, JetClassOrObject aClass, OwnerKind kind) {
|
||||||
ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass);
|
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();
|
new ImplementationBodyCodegen(aClass, parentContext.intoClass(null, descriptor, kind), v, state).generate();
|
||||||
|
|
||||||
if(aClass instanceof JetClass && ((JetClass)aClass).isTrait()) {
|
if(aClass instanceof JetClass && ((JetClass)aClass).isTrait()) {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ public class ClassFileFactory {
|
|||||||
private final Project project;
|
private final Project project;
|
||||||
private final boolean isText;
|
private final boolean isText;
|
||||||
private final Map<String, NamespaceCodegen> ns2codegen = new HashMap<String, NamespaceCodegen>();
|
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;
|
private boolean isDone = false;
|
||||||
public final GenerationState state;
|
public final GenerationState state;
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@ public class ClassFileFactory {
|
|||||||
this.state = state;
|
this.state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClassVisitor newVisitor(String filePath) {
|
ClassBuilder newVisitor(String filePath) {
|
||||||
ClassVisitor visitor;
|
ClassVisitor visitor;
|
||||||
if (isText) {
|
if (isText) {
|
||||||
visitor = new TraceClassVisitor(new PrintWriter(new StringWriter()));
|
visitor = new TraceClassVisitor(new PrintWriter(new StringWriter()));
|
||||||
@@ -36,11 +36,12 @@ public class ClassFileFactory {
|
|||||||
visitor = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
visitor = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
||||||
}
|
}
|
||||||
|
|
||||||
generators.put(filePath, visitor);
|
final ClassBuilder answer = new ClassBuilder(visitor);
|
||||||
return visitor;
|
generators.put(filePath, answer);
|
||||||
|
return answer;
|
||||||
}
|
}
|
||||||
|
|
||||||
ClassVisitor forAnonymousSubclass(String className) {
|
ClassBuilder forAnonymousSubclass(String className) {
|
||||||
return newVisitor(className + ".class");
|
return newVisitor(className + ".class");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,8 +50,8 @@ public class ClassFileFactory {
|
|||||||
String fqName = namespace.getFQName();
|
String fqName = namespace.getFQName();
|
||||||
NamespaceCodegen codegen = ns2codegen.get(fqName);
|
NamespaceCodegen codegen = ns2codegen.get(fqName);
|
||||||
if (codegen == null) {
|
if (codegen == null) {
|
||||||
final ClassVisitor classVisitor = newVisitor(NamespaceCodegen.getJVMClassName(fqName) + ".class");
|
final ClassBuilder builder = newVisitor(NamespaceCodegen.getJVMClassName(fqName) + ".class");
|
||||||
codegen = new NamespaceCodegen(classVisitor, fqName, state, namespace.getContainingFile());
|
codegen = new NamespaceCodegen(builder, fqName, state, namespace.getContainingFile());
|
||||||
ns2codegen.put(fqName, codegen);
|
ns2codegen.put(fqName, codegen);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,7 +72,7 @@ public class ClassFileFactory {
|
|||||||
|
|
||||||
done();
|
done();
|
||||||
|
|
||||||
TraceClassVisitor visitor = (TraceClassVisitor) generators.get(file);
|
TraceClassVisitor visitor = (TraceClassVisitor) generators.get(file).getVisitor();
|
||||||
|
|
||||||
StringWriter writer = new StringWriter();
|
StringWriter writer = new StringWriter();
|
||||||
visitor.print(new PrintWriter(writer));
|
visitor.print(new PrintWriter(writer));
|
||||||
@@ -84,7 +85,7 @@ public class ClassFileFactory {
|
|||||||
|
|
||||||
done();
|
done();
|
||||||
|
|
||||||
ClassWriter visitor = (ClassWriter) generators.get(file);
|
ClassWriter visitor = (ClassWriter) generators.get(file).getVisitor();
|
||||||
return visitor.toByteArray();
|
return visitor.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,13 +5,18 @@
|
|||||||
package org.jetbrains.jet.codegen;
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
import com.intellij.openapi.util.Pair;
|
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.JetFunctionLiteral;
|
||||||
import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression;
|
import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
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.InstructionAdapter;
|
||||||
import org.objectweb.asm.commons.Method;
|
import org.objectweb.asm.commons.Method;
|
||||||
import org.objectweb.asm.signature.SignatureWriter;
|
import org.objectweb.asm.signature.SignatureWriter;
|
||||||
@@ -44,7 +49,7 @@ public class ClosureCodegen extends FunctionOrClosureCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public GeneratedAnonymousClassDescriptor gen(JetFunctionLiteralExpression fun) {
|
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);
|
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(), '=');
|
appendType(signatureWriter, funDescriptor.getReturnType(), '=');
|
||||||
signatureWriter.visitEnd();
|
signatureWriter.visitEnd();
|
||||||
|
|
||||||
cv.visit(V1_6,
|
cv.defineClass(V1_6,
|
||||||
ACC_PUBLIC,
|
ACC_PUBLIC,
|
||||||
name,
|
name,
|
||||||
null,
|
null,
|
||||||
funClass,
|
funClass,
|
||||||
new String[0]
|
new String[0]
|
||||||
);
|
);
|
||||||
cv.visitSource(fun.getContainingFile().getName(), null);
|
cv.visitSource(fun.getContainingFile().getName(), null);
|
||||||
|
|
||||||
|
|
||||||
generateBridge(name, funDescriptor, cv);
|
generateBridge(name, funDescriptor, fun, cv);
|
||||||
captureThis = generateBody(funDescriptor, cv, fun.getFunctionLiteral());
|
captureThis = generateBody(funDescriptor, cv, fun.getFunctionLiteral());
|
||||||
final Type enclosingType = context.enclosingClassType(state.getTypeMapper());
|
final Type enclosingType = context.enclosingClassType(state.getTypeMapper());
|
||||||
if (enclosingType == null) captureThis = false;
|
if (enclosingType == null) captureThis = false;
|
||||||
|
|
||||||
final Method constructor = generateConstructor(funClass, captureThis, funDescriptor.getReturnType());
|
final Method constructor = generateConstructor(funClass, captureThis, fun, funDescriptor.getReturnType());
|
||||||
|
|
||||||
if (captureThis) {
|
if (captureThis) {
|
||||||
cv.visitField(0, "this$0", enclosingType.getDescriptor(), null, null);
|
cv.newField(fun, 0, "this$0", enclosingType.getDescriptor(), null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isConst()) {
|
if(isConst()) {
|
||||||
generateConstInstance();
|
generateConstInstance(fun);
|
||||||
}
|
}
|
||||||
|
|
||||||
cv.visitEnd();
|
cv.done();
|
||||||
|
|
||||||
final GeneratedAnonymousClassDescriptor answer = new GeneratedAnonymousClassDescriptor(name, constructor, captureThis);
|
final GeneratedAnonymousClassDescriptor answer = new GeneratedAnonymousClassDescriptor(name, constructor, captureThis);
|
||||||
for (DeclarationDescriptor descriptor : closure.keySet()) {
|
for (DeclarationDescriptor descriptor : closure.keySet()) {
|
||||||
@@ -98,10 +103,10 @@ public class ClosureCodegen extends FunctionOrClosureCodegen {
|
|||||||
return answer;
|
return answer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateConstInstance() {
|
private void generateConstInstance(JetFunctionLiteralExpression fun) {
|
||||||
cv.visitField(ACC_PRIVATE| ACC_STATIC, "$instance", "Ljava/lang/ref/SoftReference;", null, null);
|
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.visitCode();
|
||||||
mv.visitFieldInsn(GETSTATIC, name, "$instance", "Ljava/lang/ref/SoftReference;");
|
mv.visitFieldInsn(GETSTATIC, name, "$instance", "Ljava/lang/ref/SoftReference;");
|
||||||
mv.visitInsn(DUP);
|
mv.visitInsn(DUP);
|
||||||
@@ -140,21 +145,21 @@ public class ClosureCodegen extends FunctionOrClosureCodegen {
|
|||||||
mv.visitEnd();
|
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);
|
final ClassContext closureContext = context.intoClosure(name, this);
|
||||||
FunctionCodegen fc = new FunctionCodegen(closureContext, cv, state);
|
FunctionCodegen fc = new FunctionCodegen(closureContext, cv, state);
|
||||||
fc.generateMethod(body, invokeSignature(funDescriptor), funDescriptor);
|
fc.generateMethod(body, invokeSignature(funDescriptor), funDescriptor);
|
||||||
return closureContext.isThisWasUsed();
|
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 bridge = erasedInvokeSignature(funDescriptor);
|
||||||
final Method delegate = invokeSignature(funDescriptor);
|
final Method delegate = invokeSignature(funDescriptor);
|
||||||
|
|
||||||
if(bridge.getDescriptor().equals(delegate.getDescriptor()))
|
if(bridge.getDescriptor().equals(delegate.getDescriptor()))
|
||||||
return;
|
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();
|
mv.visitCode();
|
||||||
|
|
||||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||||
@@ -185,7 +190,7 @@ public class ClosureCodegen extends FunctionOrClosureCodegen {
|
|||||||
mv.visitEnd();
|
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();
|
int argCount = closure.size();
|
||||||
|
|
||||||
if (captureThis) {
|
if (captureThis) {
|
||||||
@@ -208,7 +213,7 @@ public class ClosureCodegen extends FunctionOrClosureCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final Method constructor = new Method("<init>", Type.VOID_TYPE, argTypes);
|
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();
|
mv.visitCode();
|
||||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||||
ExpressionCodegen expressionCodegen = new ExpressionCodegen(mv, null, Type.VOID_TYPE, context, state);
|
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.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
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.InstructionAdapter;
|
||||||
import org.objectweb.asm.commons.Method;
|
import org.objectweb.asm.commons.Method;
|
||||||
|
|
||||||
@@ -20,10 +23,10 @@ import static org.objectweb.asm.Opcodes.*;
|
|||||||
*/
|
*/
|
||||||
public class FunctionCodegen {
|
public class FunctionCodegen {
|
||||||
private final ClassContext owner;
|
private final ClassContext owner;
|
||||||
private final ClassVisitor v;
|
private final ClassBuilder v;
|
||||||
private final GenerationState state;
|
private final GenerationState state;
|
||||||
|
|
||||||
public FunctionCodegen(ClassContext owner, ClassVisitor v, GenerationState state) {
|
public FunctionCodegen(ClassContext owner, ClassBuilder v, GenerationState state) {
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
this.v = v;
|
this.v = v;
|
||||||
this.state = state;
|
this.state = state;
|
||||||
@@ -39,13 +42,13 @@ public class FunctionCodegen {
|
|||||||
ClassContext funContext = owner.intoFunction(functionDescriptor);
|
ClassContext funContext = owner.intoFunction(functionDescriptor);
|
||||||
|
|
||||||
final JetExpression bodyExpression = f.getBodyExpression();
|
final JetExpression bodyExpression = f.getBodyExpression();
|
||||||
generatedMethod(bodyExpression, jvmMethod, funContext, functionDescriptor);
|
generatedMethod(bodyExpression, jvmMethod, funContext, functionDescriptor, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generatedMethod(JetExpression bodyExpressions,
|
private void generatedMethod(JetExpression bodyExpressions,
|
||||||
Method jvmSignature,
|
Method jvmSignature,
|
||||||
ClassContext context,
|
ClassContext context,
|
||||||
FunctionDescriptor functionDescriptor)
|
FunctionDescriptor functionDescriptor, JetDeclarationWithBody fun)
|
||||||
{
|
{
|
||||||
List<ValueParameterDescriptor> paramDescrs = functionDescriptor.getValueParameters();
|
List<ValueParameterDescriptor> paramDescrs = functionDescriptor.getValueParameters();
|
||||||
List<TypeParameterDescriptor> typeParameters = functionDescriptor.getTypeParameters();
|
List<TypeParameterDescriptor> typeParameters = functionDescriptor.getTypeParameters();
|
||||||
@@ -62,7 +65,7 @@ public class FunctionCodegen {
|
|||||||
boolean isAbstract = !isStatic && (bodyExpressions == null || CodegenUtil.isInterface(functionDescriptor.getContainingDeclaration()));
|
boolean isAbstract = !isStatic && (bodyExpressions == null || CodegenUtil.isInterface(functionDescriptor.getContainingDeclaration()));
|
||||||
if (isAbstract) flags |= ACC_ABSTRACT;
|
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) {
|
if(kind != OwnerKind.TRAIT_IMPL) {
|
||||||
int start = functionDescriptor.getReceiverParameter().exists() ? 1 : 0;
|
int start = functionDescriptor.getReceiverParameter().exists() ? 1 : 0;
|
||||||
for(int i = 0; i != paramDescrs.size(); ++i) {
|
for(int i = 0; i != paramDescrs.size(); ++i) {
|
||||||
@@ -135,7 +138,7 @@ public class FunctionCodegen {
|
|||||||
generateDefaultIfNeeded(context, state, v, jvmSignature, functionDescriptor, kind);
|
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();
|
Set<? extends FunctionDescriptor> overriddenFunctions = functionDescriptor.getOverriddenDescriptors();
|
||||||
if(kind != OwnerKind.TRAIT_IMPL) {
|
if(kind != OwnerKind.TRAIT_IMPL) {
|
||||||
for (FunctionDescriptor overriddenFunction : overriddenFunctions) {
|
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();
|
DeclarationDescriptor contextClass = owner.getContextClass();
|
||||||
|
|
||||||
if(kind != OwnerKind.TRAIT_IMPL) {
|
if(kind != OwnerKind.TRAIT_IMPL) {
|
||||||
@@ -187,7 +190,7 @@ public class FunctionCodegen {
|
|||||||
String descriptor = jvmSignature.getDescriptor().replace(")","I)");
|
String descriptor = jvmSignature.getDescriptor().replace(")","I)");
|
||||||
if(!isStatic)
|
if(!isStatic)
|
||||||
descriptor = descriptor.replace("(","(L" + ownerInternalName + ";");
|
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);
|
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||||
mv.visitCode();
|
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 type1 = state.getTypeMapper().mapType(overriddenFunction.getOriginal().getReturnType());
|
||||||
Type type2 = state.getTypeMapper().mapType(functionDescriptor.getReturnType());
|
Type type2 = state.getTypeMapper().mapType(functionDescriptor.getReturnType());
|
||||||
if(!type1.equals(type2)) {
|
if(!type1.equals(type2)) {
|
||||||
Method overriden = state.getTypeMapper().mapSignature(overriddenFunction.getName(), overriddenFunction.getOriginal());
|
Method overriden = state.getTypeMapper().mapSignature(overriddenFunction.getName(), overriddenFunction.getOriginal());
|
||||||
int flags = ACC_PUBLIC; // TODO.
|
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();
|
mv.visitCode();
|
||||||
|
|
||||||
Type[] argTypes = jvmSignature.getArgumentTypes();
|
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.DeclarationDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
||||||
import org.objectweb.asm.ClassVisitor;
|
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
@@ -18,7 +17,7 @@ public class FunctionOrClosureCodegen {
|
|||||||
public final GenerationState state;
|
public final GenerationState state;
|
||||||
protected final ExpressionCodegen exprContext;
|
protected final ExpressionCodegen exprContext;
|
||||||
protected final ClassContext context;
|
protected final ClassContext context;
|
||||||
protected ClassVisitor cv = null;
|
protected ClassBuilder cv = null;
|
||||||
public String name = null;
|
public String name = null;
|
||||||
protected Map<DeclarationDescriptor, EnclosedValueDescriptor> closure = new LinkedHashMap<DeclarationDescriptor, EnclosedValueDescriptor>();
|
protected Map<DeclarationDescriptor, EnclosedValueDescriptor> closure = new LinkedHashMap<DeclarationDescriptor, EnclosedValueDescriptor>();
|
||||||
|
|
||||||
@@ -46,7 +45,7 @@ public class FunctionOrClosureCodegen {
|
|||||||
final String fieldName = "$" + (closure.size() + 1); // + "$" + vd.getName();
|
final String fieldName = "$" + (closure.size() + 1); // + "$" + vd.getName();
|
||||||
StackValue innerValue = sharedVarType != null ? StackValue.fieldForSharedVar(localType, name, fieldName) : StackValue.field(type, name, fieldName, false);
|
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);
|
answer = new EnclosedValueDescriptor(d, innerValue, outerValue);
|
||||||
closure.put(d, answer);
|
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.BindingContext;
|
||||||
import org.jetbrains.jet.lang.resolve.java.JavaDefaultImports;
|
import org.jetbrains.jet.lang.resolve.java.JavaDefaultImports;
|
||||||
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
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.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -61,26 +59,21 @@ public class GenerationState {
|
|||||||
return intrinsics;
|
return intrinsics;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassVisitor forClassInterface(ClassDescriptor aClass) {
|
|
||||||
return factory.newVisitor(JetTypeMapper.jvmNameForInterface(aClass) + ".class");
|
|
||||||
}
|
|
||||||
|
|
||||||
public ClassCodegen forClass() {
|
public ClassCodegen forClass() {
|
||||||
return new ClassCodegen(this);
|
return new ClassCodegen(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassVisitor forClassImplementation(ClassDescriptor aClass) {
|
public ClassBuilder forClassImplementation(ClassDescriptor aClass) {
|
||||||
return factory.newVisitor(typeMapper.jvmName(aClass, OwnerKind.IMPLEMENTATION) + ".class");
|
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");
|
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);
|
String className = typeMapper.classNameForAnonymousClass(expression);
|
||||||
ClassVisitor visitor = factory.forAnonymousSubclass(className);
|
return Pair.create(className, factory.forAnonymousSubclass(className));
|
||||||
return Pair.create(className, visitor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public NamespaceCodegen forNamespace(JetNamespace namespace) {
|
public NamespaceCodegen forNamespace(JetNamespace namespace) {
|
||||||
@@ -123,7 +116,7 @@ public class GenerationState {
|
|||||||
|
|
||||||
public GeneratedAnonymousClassDescriptor generateObjectLiteral(JetObjectLiteralExpression literal, FunctionOrClosureCodegen closure) {
|
public GeneratedAnonymousClassDescriptor generateObjectLiteral(JetObjectLiteralExpression literal, FunctionOrClosureCodegen closure) {
|
||||||
JetObjectDeclaration objectDeclaration = literal.getObjectDeclaration();
|
JetObjectDeclaration objectDeclaration = literal.getObjectDeclaration();
|
||||||
Pair<String, ClassVisitor> nameAndVisitor = forAnonymousSubclass(objectDeclaration);
|
Pair<String, ClassBuilder> nameAndVisitor = forAnonymousSubclass(objectDeclaration);
|
||||||
|
|
||||||
closure.cv = nameAndVisitor.getSecond();
|
closure.cv = nameAndVisitor.getSecond();
|
||||||
closure.name = nameAndVisitor.getFirst();
|
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.JetType;
|
||||||
import org.jetbrains.jet.lang.types.TypeProjection;
|
import org.jetbrains.jet.lang.types.TypeProjection;
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
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.InstructionAdapter;
|
||||||
import org.objectweb.asm.commons.Method;
|
import org.objectweb.asm.commons.Method;
|
||||||
|
|
||||||
@@ -26,7 +29,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
private JetDelegationSpecifier superCall;
|
private JetDelegationSpecifier superCall;
|
||||||
private String superClass = "java/lang/Object";
|
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);
|
super(aClass, context, v, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,21 +92,23 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
v.visit(Opcodes.V1_6,
|
v.defineClass(Opcodes.V1_6,
|
||||||
Opcodes.ACC_PUBLIC | (isAbstract ? Opcodes.ACC_ABSTRACT : 0) | (isInterface ? Opcodes.ACC_INTERFACE : 0),
|
Opcodes.ACC_PUBLIC | (isAbstract ? Opcodes.ACC_ABSTRACT : 0) | (isInterface
|
||||||
jvmName(),
|
? Opcodes.ACC_INTERFACE
|
||||||
null,
|
: 0),
|
||||||
superClass,
|
jvmName(),
|
||||||
interfaces.toArray(new String[interfaces.size()])
|
null,
|
||||||
|
superClass,
|
||||||
|
interfaces.toArray(new String[interfaces.size()])
|
||||||
);
|
);
|
||||||
v.visitSource(myClass.getContainingFile().getName(), null);
|
v.visitSource(myClass.getContainingFile().getName(), null);
|
||||||
|
|
||||||
if(descriptor.getContainingDeclaration() instanceof ClassDescriptor) {
|
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) {
|
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.visit("value", SignatureUtil.classToSignature((JetClass)myClass, state.getBindingContext(), state.getTypeMapper()));
|
||||||
annotationVisitor.visitEnd();
|
annotationVisitor.visitEnd();
|
||||||
}
|
}
|
||||||
@@ -162,7 +167,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
private void generateFieldForObjectInstance() {
|
private void generateFieldForObjectInstance() {
|
||||||
if (isNonLiteralObject()) {
|
if (isNonLiteralObject()) {
|
||||||
Type type = JetTypeMapper.jetImplementationType(descriptor);
|
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() {
|
staticInitializerChunks.add(new CodeChunk() {
|
||||||
@Override
|
@Override
|
||||||
@@ -182,7 +187,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
final JetClassObject classObject = getClassObject();
|
final JetClassObject classObject = getClassObject();
|
||||||
if (classObject != null) {
|
if (classObject != null) {
|
||||||
Type type = Type.getObjectType(state.getTypeMapper().jvmName(classObject));
|
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() {
|
staticInitializerChunks.add(new CodeChunk() {
|
||||||
@Override
|
@Override
|
||||||
@@ -242,7 +247,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int flags = Opcodes.ACC_PUBLIC; // TODO
|
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();
|
mv.visitCode();
|
||||||
|
|
||||||
List<ValueParameterDescriptor> paramDescrs = constructorDescriptor != null
|
List<ValueParameterDescriptor> paramDescrs = constructorDescriptor != null
|
||||||
@@ -312,7 +317,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
String delegateField = "$delegate_" + n;
|
String delegateField = "$delegate_" + n;
|
||||||
Type fieldType = JetTypeMapper.jetInterfaceType(superClassDescriptor);
|
Type fieldType = JetTypeMapper.jetInterfaceType(superClassDescriptor);
|
||||||
String fieldDesc = fieldType.getDescriptor();
|
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);
|
iv.putfield(classname, delegateField, fieldDesc);
|
||||||
|
|
||||||
JetClass superClass = (JetClass) state.getBindingContext().get(BindingContext.DESCRIPTOR_TO_DECLARATION, superClassDescriptor);
|
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);
|
final Type type = JetTypeMapper.jetImplementationType(outerDescriptor);
|
||||||
String interfaceDesc = type.getDescriptor();
|
String interfaceDesc = type.getDescriptor();
|
||||||
final String fieldName = "this$0";
|
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(0, classType);
|
||||||
iv.load(frameMap.getOuterThisIndex(), type);
|
iv.load(frameMap.getOuterThisIndex(), type);
|
||||||
iv.putfield(classname, fieldName, interfaceDesc);
|
iv.putfield(classname, fieldName, interfaceDesc);
|
||||||
@@ -393,7 +398,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
Method function = state.getTypeMapper().mapSignature(fun.getName(), fun);
|
Method function = state.getTypeMapper().mapSignature(fun.getName(), fun);
|
||||||
Method functionOriginal = state.getTypeMapper().mapSignature(fun.getName(), fun.getOriginal());
|
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();
|
mv.visitCode();
|
||||||
|
|
||||||
codegen.generateThisOrOuter(descriptor);
|
codegen.generateThisOrOuter(descriptor);
|
||||||
@@ -475,7 +480,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
else if (declaration instanceof JetEnumEntry && !((JetEnumEntry) declaration).hasPrimaryConstructor()) {
|
else if (declaration instanceof JetEnumEntry && !((JetEnumEntry) declaration).hasPrimaryConstructor()) {
|
||||||
String name = declaration.getName();
|
String name = declaration.getName();
|
||||||
final String desc = "L" + state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION) + ";";
|
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()) {
|
if (myEnumConstants.isEmpty()) {
|
||||||
staticInitializerChunks.add(new CodeChunk() {
|
staticInitializerChunks.add(new CodeChunk() {
|
||||||
@Override
|
@Override
|
||||||
@@ -533,7 +538,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
CallableMethod method = state.getTypeMapper().mapToCallableMethod(constructorDescriptor, kind);
|
CallableMethod method = state.getTypeMapper().mapToCallableMethod(constructorDescriptor, kind);
|
||||||
int flags = Opcodes.ACC_PUBLIC; // TODO
|
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();
|
mv.visitCode();
|
||||||
|
|
||||||
ConstructorFrameMap frameMap = new ConstructorFrameMap(method, constructorDescriptor, descriptor, kind);
|
ConstructorFrameMap frameMap = new ConstructorFrameMap(method, constructorDescriptor, descriptor, kind);
|
||||||
@@ -677,9 +682,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
if (p.getValOrVarNode() != null) {
|
if (p.getValOrVarNode() != null) {
|
||||||
PropertyDescriptor propertyDescriptor = state.getBindingContext().get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, p);
|
PropertyDescriptor propertyDescriptor = state.getBindingContext().get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, p);
|
||||||
if (propertyDescriptor != null) {
|
if (propertyDescriptor != null) {
|
||||||
propertyCodegen.generateDefaultGetter(propertyDescriptor, Opcodes.ACC_PUBLIC);
|
propertyCodegen.generateDefaultGetter(propertyDescriptor, Opcodes.ACC_PUBLIC, p);
|
||||||
if (propertyDescriptor.isVar()) {
|
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();
|
JetType defaultType = descriptor.getDefaultType();
|
||||||
if(CodegenUtil.hasTypeInfoField(defaultType)) {
|
if(CodegenUtil.hasTypeInfoField(defaultType)) {
|
||||||
if(!CodegenUtil.hasDerivedTypeInfoField(defaultType, true)) {
|
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();
|
mv.visitCode();
|
||||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||||
String owner = state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION);
|
String owner = state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION);
|
||||||
@@ -715,7 +720,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
mv.visitMaxs(0, 0);
|
mv.visitMaxs(0, 0);
|
||||||
mv.visitEnd();
|
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();
|
mv.visitCode();
|
||||||
iv = new InstructionAdapter(mv);
|
iv = new InstructionAdapter(mv);
|
||||||
owner = state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION);
|
owner = state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION);
|
||||||
@@ -734,7 +739,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void genGetStaticGetTypeInfoMethod() {
|
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();
|
mv.visitCode();
|
||||||
InstructionAdapter v = new InstructionAdapter(mv);
|
InstructionAdapter v = new InstructionAdapter(mv);
|
||||||
String owner = state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION);
|
String owner = state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION);
|
||||||
@@ -745,7 +750,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void staticTypeInfoField() {
|
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() {
|
staticInitializerChunks.add(new CodeChunk() {
|
||||||
@Override
|
@Override
|
||||||
public void generate(InstructionAdapter v) {
|
public void generate(InstructionAdapter v) {
|
||||||
@@ -776,11 +781,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
String sig = getGetSuperTypesTypeInfoSignature(descriptor.getDefaultType());
|
String sig = getGetSuperTypesTypeInfoSignature(descriptor.getDefaultType());
|
||||||
|
|
||||||
final MethodVisitor mv = v.visitMethod(Opcodes.ACC_PUBLIC|Opcodes.ACC_STATIC,
|
final MethodVisitor mv = v.newMethod(myClass, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,
|
||||||
"$$getSuperTypesTypeInfo",
|
"$$getSuperTypesTypeInfo",
|
||||||
sig,
|
sig,
|
||||||
null /* TODO */,
|
null /* TODO */,
|
||||||
null);
|
null);
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
InstructionAdapter v = new InstructionAdapter(mv);
|
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.JetType;
|
||||||
import org.jetbrains.jet.lang.types.TypeProjection;
|
import org.jetbrains.jet.lang.types.TypeProjection;
|
||||||
import org.jetbrains.jet.lang.types.TypeUtils;
|
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 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.*;
|
import static org.objectweb.asm.Opcodes.*;
|
||||||
|
|
||||||
@@ -20,20 +24,20 @@ import static org.objectweb.asm.Opcodes.*;
|
|||||||
* @author max
|
* @author max
|
||||||
*/
|
*/
|
||||||
public class NamespaceCodegen {
|
public class NamespaceCodegen {
|
||||||
private final ClassVisitor v;
|
private final ClassBuilder v;
|
||||||
private final GenerationState state;
|
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.v = v;
|
||||||
this.state = state;
|
this.state = state;
|
||||||
|
|
||||||
v.visit(V1_6,
|
v.defineClass(V1_6,
|
||||||
ACC_PUBLIC,
|
ACC_PUBLIC,
|
||||||
getJVMClassName(fqName),
|
getJVMClassName(fqName),
|
||||||
null,
|
null,
|
||||||
//"jet/lang/Namespace",
|
//"jet/lang/Namespace",
|
||||||
"java/lang/Object",
|
"java/lang/Object",
|
||||||
new String[0]
|
new String[0]
|
||||||
);
|
);
|
||||||
// TODO figure something out for a namespace that spans multiple files
|
// TODO figure something out for a namespace that spans multiple files
|
||||||
v.visitSource(sourceFile.getName(), null);
|
v.visitSource(sourceFile.getName(), null);
|
||||||
@@ -76,8 +80,8 @@ public class NamespaceCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void generateStaticInitializers(JetNamespace namespace) {
|
private void generateStaticInitializers(JetNamespace namespace) {
|
||||||
MethodVisitor mv = v.visitMethod(ACC_PUBLIC | ACC_STATIC,
|
MethodVisitor mv = v.newMethod(namespace, ACC_PUBLIC | ACC_STATIC,
|
||||||
"<clinit>", "()V", null, null);
|
"<clinit>", "()V", null, null);
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
|
|
||||||
FrameMap frameMap = new FrameMap();
|
FrameMap frameMap = new FrameMap();
|
||||||
@@ -104,9 +108,9 @@ public class NamespaceCodegen {
|
|||||||
String jvmClassName = getJVMClassName(namespace.getName());
|
String jvmClassName = getJVMClassName(namespace.getName());
|
||||||
for(Map.Entry<JetType,Integer> e : (context.typeInfoConstants != null ? context.typeInfoConstants : Collections.<JetType,Integer>emptyMap()).entrySet()) {
|
for(Map.Entry<JetType,Integer> e : (context.typeInfoConstants != null ? context.typeInfoConstants : Collections.<JetType,Integer>emptyMap()).entrySet()) {
|
||||||
String fieldName = "$typeInfoCache$" + e.getValue();
|
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);
|
InstructionAdapter v = new InstructionAdapter(mmv);
|
||||||
v.visitFieldInsn(GETSTATIC, jvmClassName, fieldName, "Ljet/typeinfo/TypeInfo;");
|
v.visitFieldInsn(GETSTATIC, jvmClassName, fieldName, "Ljet/typeinfo/TypeInfo;");
|
||||||
v.visitInsn(DUP);
|
v.visitInsn(DUP);
|
||||||
@@ -185,7 +189,7 @@ public class NamespaceCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void done() {
|
public void done() {
|
||||||
v.visitEnd();
|
v.done();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getJVMClassName(String fqName) {
|
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.openapi.util.text.StringUtil;
|
||||||
import com.intellij.psi.PsiElement;
|
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.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
import org.objectweb.asm.ClassVisitor;
|
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
@@ -19,10 +21,10 @@ import org.objectweb.asm.commons.InstructionAdapter;
|
|||||||
public class PropertyCodegen {
|
public class PropertyCodegen {
|
||||||
private final GenerationState state;
|
private final GenerationState state;
|
||||||
private final FunctionCodegen functionCodegen;
|
private final FunctionCodegen functionCodegen;
|
||||||
private final ClassVisitor v;
|
private final ClassBuilder v;
|
||||||
private final OwnerKind kind;
|
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.v = v;
|
||||||
this.functionCodegen = functionCodegen;
|
this.functionCodegen = functionCodegen;
|
||||||
this.state = state;
|
this.state = state;
|
||||||
@@ -41,9 +43,9 @@ public class PropertyCodegen {
|
|||||||
generateSetter(p, propertyDescriptor);
|
generateSetter(p, propertyDescriptor);
|
||||||
}
|
}
|
||||||
else if (kind instanceof OwnerKind.DelegateKind) {
|
else if (kind instanceof OwnerKind.DelegateKind) {
|
||||||
generateDefaultGetter(propertyDescriptor, Opcodes.ACC_PUBLIC);
|
generateDefaultGetter(propertyDescriptor, Opcodes.ACC_PUBLIC, p);
|
||||||
if (propertyDescriptor.isVar()) {
|
if (propertyDescriptor.isVar()) {
|
||||||
generateDefaultSetter(propertyDescriptor, Opcodes.ACC_PUBLIC);
|
generateDefaultSetter(propertyDescriptor, Opcodes.ACC_PUBLIC, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -71,7 +73,7 @@ public class PropertyCodegen {
|
|||||||
else {
|
else {
|
||||||
modifiers = Opcodes.ACC_PRIVATE;
|
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) {
|
private void generateDefaultGetter(JetProperty p, JetDeclaration declaration) {
|
||||||
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, p);
|
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, p);
|
||||||
int flags = JetTypeMapper.getAccessModifiers(declaration, Opcodes.ACC_PUBLIC);
|
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) {
|
if (kind == OwnerKind.NAMESPACE) {
|
||||||
flags |= Opcodes.ACC_STATIC;
|
flags |= Opcodes.ACC_STATIC;
|
||||||
}
|
}
|
||||||
@@ -129,7 +131,7 @@ public class PropertyCodegen {
|
|||||||
|
|
||||||
final String signature = state.getTypeMapper().mapGetterSignature(propertyDescriptor).getDescriptor();
|
final String signature = state.getTypeMapper().mapGetterSignature(propertyDescriptor).getDescriptor();
|
||||||
String getterName = getterName(propertyDescriptor.getName());
|
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) {
|
if (!isTrait || kind instanceof OwnerKind.DelegateKind) {
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||||
@@ -156,10 +158,10 @@ public class PropertyCodegen {
|
|||||||
private void generateDefaultSetter(JetProperty p, JetDeclaration declaration) {
|
private void generateDefaultSetter(JetProperty p, JetDeclaration declaration) {
|
||||||
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, p);
|
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) state.getBindingContext().get(BindingContext.VARIABLE, p);
|
||||||
int flags = JetTypeMapper.getAccessModifiers(declaration, Opcodes.ACC_PUBLIC);
|
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) {
|
if (kind == OwnerKind.NAMESPACE) {
|
||||||
flags |= Opcodes.ACC_STATIC;
|
flags |= Opcodes.ACC_STATIC;
|
||||||
}
|
}
|
||||||
@@ -170,7 +172,7 @@ public class PropertyCodegen {
|
|||||||
flags |= Opcodes.ACC_ABSTRACT;
|
flags |= Opcodes.ACC_ABSTRACT;
|
||||||
|
|
||||||
final String signature = state.getTypeMapper().mapSetterSignature(propertyDescriptor).getDescriptor();
|
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) {
|
if (!isTrait || kind instanceof OwnerKind.DelegateKind) {
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
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.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
|
||||||
import org.objectweb.asm.ClassVisitor;
|
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class TraitImplBodyCodegen extends ClassBodyCodegen {
|
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);
|
super(aClass, context, v, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,12 +45,12 @@ public class TraitImplBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void generateDeclaration() {
|
protected void generateDeclaration() {
|
||||||
v.visit(Opcodes.V1_6,
|
v.defineClass(Opcodes.V1_6,
|
||||||
Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL,
|
Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL,
|
||||||
jvmName(),
|
jvmName(),
|
||||||
null,
|
null,
|
||||||
"java/lang/Object",
|
"java/lang/Object",
|
||||||
new String[0]
|
new String[0]
|
||||||
);
|
);
|
||||||
v.visitSource(myClass.getContainingFile().getName(), null);
|
v.visitSource(myClass.getContainingFile().getName(), null);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user