Merge remote branch 'origin/master'
Conflicts: idea/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java
This commit is contained in:
@@ -3,8 +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.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.types.JetStandardLibrary;
|
|
||||||
import org.objectweb.asm.ClassVisitor;
|
import org.objectweb.asm.ClassVisitor;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
@@ -16,21 +14,16 @@ import java.util.List;
|
|||||||
* @author yole
|
* @author yole
|
||||||
*/
|
*/
|
||||||
public abstract class ClassBodyCodegen {
|
public abstract class ClassBodyCodegen {
|
||||||
protected final BindingContext bindingContext;
|
protected final GenerationState state;
|
||||||
protected final JetStandardLibrary stdlib;
|
|
||||||
protected final JetTypeMapper typeMapper;
|
|
||||||
protected final Codegens factory;
|
|
||||||
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 ClassVisitor v;
|
||||||
|
|
||||||
public ClassBodyCodegen(BindingContext bindingContext, JetStandardLibrary stdlib, JetClassOrObject aClass, OwnerKind kind, ClassVisitor v, Codegens factory) {
|
public ClassBodyCodegen(JetClassOrObject aClass, OwnerKind kind, ClassVisitor v, GenerationState state) {
|
||||||
this.bindingContext = bindingContext;
|
this.state = state;
|
||||||
this.stdlib = stdlib;
|
descriptor = state.getBindingContext().getClassDescriptor(aClass);
|
||||||
this.factory = factory;
|
|
||||||
this.typeMapper = new JetTypeMapper(stdlib, bindingContext);
|
|
||||||
descriptor = bindingContext.getClassDescriptor(aClass);
|
|
||||||
myClass = aClass;
|
myClass = aClass;
|
||||||
this.kind = kind;
|
this.kind = kind;
|
||||||
this.v = v;
|
this.v = v;
|
||||||
@@ -52,8 +45,8 @@ public abstract class ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void generateClassBody() {
|
private void generateClassBody() {
|
||||||
final FunctionCodegen functionCodegen = new FunctionCodegen((JetDeclaration) myClass, v, stdlib, bindingContext, factory);
|
final FunctionCodegen functionCodegen = new FunctionCodegen((JetDeclaration) myClass, v, state);
|
||||||
final PropertyCodegen propertyCodegen = new PropertyCodegen(v, stdlib, bindingContext, functionCodegen);
|
final PropertyCodegen propertyCodegen = new PropertyCodegen(v, functionCodegen, state);
|
||||||
|
|
||||||
for (JetDeclaration declaration : myClass.getDeclarations()) {
|
for (JetDeclaration declaration : myClass.getDeclarations()) {
|
||||||
generateDeclaration(propertyCodegen, declaration, functionCodegen);
|
generateDeclaration(propertyCodegen, declaration, functionCodegen);
|
||||||
@@ -78,15 +71,15 @@ public abstract class ClassBodyCodegen {
|
|||||||
private void generatePrimaryConstructorProperties(PropertyCodegen propertyCodegen) {
|
private void generatePrimaryConstructorProperties(PropertyCodegen propertyCodegen) {
|
||||||
for (JetParameter p : getPrimaryConstructorParameters()) {
|
for (JetParameter p : getPrimaryConstructorParameters()) {
|
||||||
if (p.getValOrVarNode() != null) {
|
if (p.getValOrVarNode() != null) {
|
||||||
PropertyDescriptor propertyDescriptor = bindingContext.getPropertyDescriptor(p);
|
PropertyDescriptor propertyDescriptor = state.getBindingContext().getPropertyDescriptor(p);
|
||||||
if (propertyDescriptor != null) {
|
if (propertyDescriptor != null) {
|
||||||
propertyCodegen.generateDefaultGetter(propertyDescriptor, Opcodes.ACC_PUBLIC, kind);
|
propertyCodegen.generateDefaultGetter(propertyDescriptor, Opcodes.ACC_PUBLIC, kind);
|
||||||
if (propertyDescriptor.isVar()) {
|
if (propertyDescriptor.isVar()) {
|
||||||
propertyCodegen.generateDefaultSetter(propertyDescriptor, Opcodes.ACC_PUBLIC, kind);
|
propertyCodegen.generateDefaultSetter(propertyDescriptor, Opcodes.ACC_PUBLIC, kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(kind instanceof OwnerKind.DelegateKind) && kind != OwnerKind.INTERFACE && bindingContext.hasBackingField(propertyDescriptor)) {
|
if (!(kind instanceof OwnerKind.DelegateKind) && kind != OwnerKind.INTERFACE && state.getBindingContext().hasBackingField(propertyDescriptor)) {
|
||||||
v.visitField(Opcodes.ACC_PRIVATE, p.getName(), typeMapper.mapType(propertyDescriptor.getOutType()).getDescriptor(), null, null);
|
v.visitField(Opcodes.ACC_PRIVATE, p.getName(), state.getTypeMapper().mapType(propertyDescriptor.getOutType()).getDescriptor(), null, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -99,5 +92,4 @@ public abstract class ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
package org.jetbrains.jet.codegen;
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project;
|
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.JetClass;
|
import org.jetbrains.jet.lang.psi.JetClass;
|
||||||
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
||||||
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
||||||
import org.jetbrains.jet.lang.psi.JetObjectDeclaration;
|
import org.jetbrains.jet.lang.psi.JetObjectDeclaration;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
|
||||||
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
|
||||||
import org.objectweb.asm.ClassVisitor;
|
import org.objectweb.asm.ClassVisitor;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
import org.objectweb.asm.commons.InstructionAdapter;
|
||||||
@@ -16,14 +13,10 @@ import org.objectweb.asm.commons.InstructionAdapter;
|
|||||||
* @author max
|
* @author max
|
||||||
*/
|
*/
|
||||||
public class ClassCodegen {
|
public class ClassCodegen {
|
||||||
private final Project project;
|
private final GenerationState state;
|
||||||
private final BindingContext bindingContext;
|
|
||||||
private final Codegens factory;
|
|
||||||
|
|
||||||
public ClassCodegen(Project project, Codegens factory, BindingContext bindingContext) {
|
public ClassCodegen(GenerationState state) {
|
||||||
this.project = project;
|
this.state = state;
|
||||||
this.factory = factory;
|
|
||||||
this.bindingContext = bindingContext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generate(JetClassOrObject aClass) {
|
public void generate(JetClassOrObject aClass) {
|
||||||
@@ -44,16 +37,16 @@ public class ClassCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void generateInterface(JetClassOrObject aClass) {
|
private void generateInterface(JetClassOrObject aClass) {
|
||||||
final ClassVisitor visitor = factory.forClassInterface(bindingContext.getClassDescriptor(aClass));
|
final ClassVisitor visitor = state.forClassInterface(state.getBindingContext().getClassDescriptor(aClass));
|
||||||
new InterfaceBodyCodegen(bindingContext, JetStandardLibrary.getJetStandardLibrary(project), aClass, visitor, factory).generate();
|
new InterfaceBodyCodegen(aClass, visitor, state).generate();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateImplementation(JetClassOrObject aClass, OwnerKind kind) {
|
private void generateImplementation(JetClassOrObject aClass, OwnerKind kind) {
|
||||||
ClassDescriptor descriptor = bindingContext.getClassDescriptor(aClass);
|
ClassDescriptor descriptor = state.getBindingContext().getClassDescriptor(aClass);
|
||||||
ClassVisitor v = kind == OwnerKind.IMPLEMENTATION
|
ClassVisitor v = kind == OwnerKind.IMPLEMENTATION
|
||||||
? factory.forClassImplementation(descriptor)
|
? state.forClassImplementation(descriptor)
|
||||||
: factory.forClassDelegatingImplementation(descriptor);
|
: state.forClassDelegatingImplementation(descriptor);
|
||||||
new ImplementationBodyCodegen(bindingContext, JetStandardLibrary.getJetStandardLibrary(project), aClass, kind, v, factory).generate();
|
new ImplementationBodyCodegen(aClass, kind, v, state).generate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+8
-32
@@ -2,9 +2,7 @@ package org.jetbrains.jet.codegen;
|
|||||||
|
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.openapi.util.Pair;
|
import com.intellij.openapi.util.Pair;
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.psi.JetNamespace;
|
import org.jetbrains.jet.lang.psi.JetNamespace;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
|
||||||
import org.objectweb.asm.ClassVisitor;
|
import org.objectweb.asm.ClassVisitor;
|
||||||
import org.objectweb.asm.ClassWriter;
|
import org.objectweb.asm.ClassWriter;
|
||||||
import org.objectweb.asm.util.TraceClassVisitor;
|
import org.objectweb.asm.util.TraceClassVisitor;
|
||||||
@@ -16,20 +14,22 @@ import java.util.*;
|
|||||||
/**
|
/**
|
||||||
* @author max
|
* @author max
|
||||||
*/
|
*/
|
||||||
public class Codegens {
|
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, ClassVisitor> generators = new LinkedHashMap<String, ClassVisitor>();
|
||||||
private final Map<String, Integer> closuresCount = new HashMap<String, Integer>();
|
private final Map<String, Integer> closuresCount = new HashMap<String, Integer>();
|
||||||
private boolean isDone = false;
|
private boolean isDone = false;
|
||||||
|
public final GenerationState state;
|
||||||
|
|
||||||
public Codegens(Project project, boolean text) {
|
public ClassFileFactory(Project project, boolean text, GenerationState state) {
|
||||||
this.project = project;
|
this.project = project;
|
||||||
isText = text;
|
isText = text;
|
||||||
|
this.state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassVisitor newVisitor(String filePath) {
|
ClassVisitor 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()));
|
||||||
@@ -42,31 +42,7 @@ public class Codegens {
|
|||||||
return visitor;
|
return visitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassVisitor forClassInterface(ClassDescriptor aClass) {
|
Pair<String, ClassVisitor> forClosureIn(String baseName) {
|
||||||
return newVisitor(JetTypeMapper.jvmNameForInterface(aClass) + ".class");
|
|
||||||
}
|
|
||||||
|
|
||||||
public ClassCodegen forClass(BindingContext bindingContext) {
|
|
||||||
return new ClassCodegen(project, this, bindingContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ClassVisitor forClassImplementation(ClassDescriptor aClass) {
|
|
||||||
return newVisitor(JetTypeMapper.jvmNameForImplementation(aClass) + ".class");
|
|
||||||
}
|
|
||||||
|
|
||||||
public ClassVisitor forClassDelegatingImplementation(ClassDescriptor aClass) {
|
|
||||||
return newVisitor(JetTypeMapper.jvmNameForDelegatingImplementation(aClass) + ".class");
|
|
||||||
}
|
|
||||||
|
|
||||||
public Pair<String, ClassVisitor> forClosureIn(ClassDescriptor aClass) {
|
|
||||||
return forClosureIn(JetTypeMapper.jvmNameForInterface(aClass));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Pair<String, ClassVisitor> forClosureIn(JetNamespace namespace) {
|
|
||||||
return forClosureIn(NamespaceCodegen.getJVMClassName(namespace.getFQName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private Pair<String, ClassVisitor> forClosureIn(String baseName) {
|
|
||||||
Integer count = closuresCount.get(baseName);
|
Integer count = closuresCount.get(baseName);
|
||||||
if (count == null) count = 0;
|
if (count == null) count = 0;
|
||||||
|
|
||||||
@@ -76,12 +52,12 @@ public class Codegens {
|
|||||||
return new Pair<String, ClassVisitor>(className, newVisitor(className + ".class"));
|
return new Pair<String, ClassVisitor>(className, newVisitor(className + ".class"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public NamespaceCodegen forNamespace(JetNamespace namespace) {
|
NamespaceCodegen forNamespace(JetNamespace namespace) {
|
||||||
assert !isDone : "Already done!";
|
assert !isDone : "Already done!";
|
||||||
String fqName = namespace.getFQName();
|
String fqName = namespace.getFQName();
|
||||||
NamespaceCodegen codegen = ns2codegen.get(fqName);
|
NamespaceCodegen codegen = ns2codegen.get(fqName);
|
||||||
if (codegen == null) {
|
if (codegen == null) {
|
||||||
codegen = new NamespaceCodegen(project, newVisitor(NamespaceCodegen.getJVMClassName(fqName) + ".class"), fqName, this);
|
codegen = new NamespaceCodegen(project, newVisitor(NamespaceCodegen.getJVMClassName(fqName) + ".class"), fqName, state);
|
||||||
ns2codegen.put(fqName, codegen);
|
ns2codegen.put(fqName, codegen);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9,8 +9,6 @@ import com.intellij.psi.util.PsiTreeUtil;
|
|||||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
|
||||||
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.objectweb.asm.ClassVisitor;
|
import org.objectweb.asm.ClassVisitor;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
@@ -24,14 +22,10 @@ import java.util.Arrays;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class ClosureCodegen {
|
public class ClosureCodegen {
|
||||||
private final BindingContext bindingContext;
|
private final GenerationState state;
|
||||||
private final JetTypeMapper typeMapper;
|
|
||||||
private final Codegens factory;
|
|
||||||
|
|
||||||
public ClosureCodegen(BindingContext bindingContext, JetTypeMapper typeMapper, Codegens factory) {
|
public ClosureCodegen(GenerationState state) {
|
||||||
this.bindingContext = bindingContext;
|
this.state = state;
|
||||||
this.typeMapper = typeMapper;
|
|
||||||
this.factory = factory;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Method erasedInvokeSignature(FunctionDescriptor fd) {
|
public static Method erasedInvokeSignature(FunctionDescriptor fd) {
|
||||||
@@ -47,7 +41,7 @@ public class ClosureCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Method invokeSignature(FunctionDescriptor fd) {
|
public Method invokeSignature(FunctionDescriptor fd) {
|
||||||
return typeMapper.mapSignature("invoke", fd);
|
return state.getTypeMapper().mapSignature("invoke", fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GeneratedClosureDescriptor gen(JetFunctionLiteralExpression fun) {
|
public GeneratedClosureDescriptor gen(JetFunctionLiteralExpression fun) {
|
||||||
@@ -55,14 +49,14 @@ public class ClosureCodegen {
|
|||||||
|
|
||||||
final Pair<String, ClassVisitor> nameAndVisitor;
|
final Pair<String, ClassVisitor> nameAndVisitor;
|
||||||
if (container instanceof JetNamespace) {
|
if (container instanceof JetNamespace) {
|
||||||
nameAndVisitor = factory.forClosureIn((JetNamespace) container);
|
nameAndVisitor = state.forClosureIn((JetNamespace) container);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
nameAndVisitor = factory.forClosureIn(bindingContext.getClassDescriptor((JetClassOrObject) container));
|
nameAndVisitor = state.forClosureIn(state.getBindingContext().getClassDescriptor((JetClassOrObject) container));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
final FunctionDescriptor funDescriptor = (FunctionDescriptor) bindingContext.getDeclarationDescriptor(fun);
|
final FunctionDescriptor funDescriptor = (FunctionDescriptor) state.getBindingContext().getDeclarationDescriptor(fun);
|
||||||
|
|
||||||
final ClassVisitor cv = nameAndVisitor.getSecond();
|
final ClassVisitor cv = nameAndVisitor.getSecond();
|
||||||
final String name = nameAndVisitor.getFirst();
|
final String name = nameAndVisitor.getFirst();
|
||||||
@@ -98,7 +92,7 @@ public class ClosureCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void generateBody(String className, FunctionDescriptor funDescriptor, ClassVisitor cv, Project project, List<JetElement> body) {
|
private void generateBody(String className, FunctionDescriptor funDescriptor, ClassVisitor cv, Project project, List<JetElement> body) {
|
||||||
FunctionCodegen fc = new FunctionCodegen(null, cv, JetStandardLibrary.getJetStandardLibrary(project), bindingContext, factory);
|
FunctionCodegen fc = new FunctionCodegen(null, cv, state);
|
||||||
fc.generatedMethod(body, OwnerKind.IMPLEMENTATION, invokeSignature(funDescriptor), null, funDescriptor.getUnsubstitutedValueParameters(), null);
|
fc.generatedMethod(body, OwnerKind.IMPLEMENTATION, invokeSignature(funDescriptor), null, funDescriptor.getUnsubstitutedValueParameters(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,7 +100,7 @@ public class ClosureCodegen {
|
|||||||
final Method bridge = erasedInvokeSignature(funDescriptor);
|
final Method bridge = erasedInvokeSignature(funDescriptor);
|
||||||
final Method delegate = invokeSignature(funDescriptor);
|
final Method delegate = invokeSignature(funDescriptor);
|
||||||
|
|
||||||
final MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC, "invoke", bridge.getDescriptor(), typeMapper.genericSignature(funDescriptor), new String[0]);
|
final MethodVisitor mv = cv.visitMethod(Opcodes.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);
|
||||||
@@ -117,7 +111,7 @@ public class ClosureCodegen {
|
|||||||
int count = 1;
|
int count = 1;
|
||||||
for (ValueParameterDescriptor param : params) {
|
for (ValueParameterDescriptor param : params) {
|
||||||
StackValue.local(count, JetTypeMapper.TYPE_OBJECT).put(JetTypeMapper.TYPE_OBJECT, iv);
|
StackValue.local(count, JetTypeMapper.TYPE_OBJECT).put(JetTypeMapper.TYPE_OBJECT, iv);
|
||||||
StackValue.onStack(JetTypeMapper.TYPE_OBJECT).upcast(typeMapper.mapType(param.getOutType()), iv);
|
StackValue.onStack(JetTypeMapper.TYPE_OBJECT).upcast(state.getTypeMapper().mapType(param.getOutType()), iv);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,6 +154,7 @@ public class ClosureCodegen {
|
|||||||
private void appendType(SignatureWriter signatureWriter, JetType type, char variance) {
|
private void appendType(SignatureWriter signatureWriter, JetType type, char variance) {
|
||||||
signatureWriter.visitTypeArgument(variance);
|
signatureWriter.visitTypeArgument(variance);
|
||||||
|
|
||||||
|
final JetTypeMapper typeMapper = state.getTypeMapper();
|
||||||
final Type rawRetType = typeMapper.boxType(typeMapper.mapType(type));
|
final Type rawRetType = typeMapper.boxType(typeMapper.mapType(type));
|
||||||
signatureWriter.visitClassType(rawRetType.getInternalName());
|
signatureWriter.visitClassType(rawRetType.getInternalName());
|
||||||
signatureWriter.visitEnd();
|
signatureWriter.visitEnd();
|
||||||
|
|||||||
@@ -12,7 +12,10 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
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.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
||||||
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
import org.jetbrains.jet.lang.types.TypeProjection;
|
||||||
|
import org.jetbrains.jet.lang.types.TypeUtils;
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
||||||
import org.objectweb.asm.Label;
|
import org.objectweb.asm.Label;
|
||||||
@@ -61,7 +64,7 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
private final InstructionAdapter v;
|
private final InstructionAdapter v;
|
||||||
private final FrameMap myMap;
|
private final FrameMap myMap;
|
||||||
private final JetTypeMapper typeMapper;
|
private final JetTypeMapper typeMapper;
|
||||||
private final Codegens factory;
|
private final GenerationState state;
|
||||||
private final Type returnType;
|
private final Type returnType;
|
||||||
private final DeclarationDescriptor contextType;
|
private final DeclarationDescriptor contextType;
|
||||||
private final OwnerKind contextKind;
|
private final OwnerKind contextKind;
|
||||||
@@ -70,22 +73,20 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
private final Map<ClassDescriptor, StackValue> outerThisExpressions = new HashMap<ClassDescriptor, StackValue>();
|
private final Map<ClassDescriptor, StackValue> outerThisExpressions = new HashMap<ClassDescriptor, StackValue>();
|
||||||
|
|
||||||
public ExpressionCodegen(MethodVisitor v,
|
public ExpressionCodegen(MethodVisitor v,
|
||||||
BindingContext bindingContext,
|
|
||||||
FrameMap myMap,
|
FrameMap myMap,
|
||||||
JetTypeMapper typeMapper,
|
|
||||||
Type returnType,
|
Type returnType,
|
||||||
DeclarationDescriptor contextType,
|
DeclarationDescriptor contextType,
|
||||||
OwnerKind contextKind,
|
OwnerKind contextKind,
|
||||||
@Nullable StackValue thisExpression,
|
@Nullable StackValue thisExpression,
|
||||||
Codegens factory) {
|
GenerationState state) {
|
||||||
this.myMap = myMap;
|
this.myMap = myMap;
|
||||||
this.typeMapper = typeMapper;
|
this.typeMapper = state.getTypeMapper();
|
||||||
this.returnType = returnType;
|
this.returnType = returnType;
|
||||||
this.contextType = contextType;
|
this.contextType = contextType;
|
||||||
this.contextKind = contextKind;
|
this.contextKind = contextKind;
|
||||||
this.factory = factory;
|
this.state = state;
|
||||||
this.v = new InstructionAdapter(v);
|
this.v = new InstructionAdapter(v);
|
||||||
this.bindingContext = bindingContext;
|
this.bindingContext = state.getBindingContext();
|
||||||
this.thisExpression = thisExpression;
|
this.thisExpression = thisExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -481,7 +482,7 @@ public class ExpressionCodegen extends JetVisitor {
|
|||||||
generateBlock(expression.getFunctionLiteral().getBodyExpression().getStatements());
|
generateBlock(expression.getFunctionLiteral().getBodyExpression().getStatements());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
final GeneratedClosureDescriptor closure = new ClosureCodegen(bindingContext, typeMapper, factory).gen(expression);
|
final GeneratedClosureDescriptor closure = new ClosureCodegen(state).gen(expression);
|
||||||
v.anew(Type.getObjectType(closure.getClassname()));
|
v.anew(Type.getObjectType(closure.getClassname()));
|
||||||
v.dup();
|
v.dup();
|
||||||
v.invokespecial(closure.getClassname(), "<init>", closure.getConstructor().getDescriptor());
|
v.invokespecial(closure.getClassname(), "<init>", closure.getConstructor().getDescriptor());
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
|
||||||
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.objectweb.asm.ClassVisitor;
|
import org.objectweb.asm.ClassVisitor;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
@@ -23,23 +21,19 @@ import java.util.List;
|
|||||||
public class FunctionCodegen {
|
public class FunctionCodegen {
|
||||||
private final JetDeclaration owner;
|
private final JetDeclaration owner;
|
||||||
private final ClassVisitor v;
|
private final ClassVisitor v;
|
||||||
private final BindingContext bindingContext;
|
private final GenerationState state;
|
||||||
private final JetTypeMapper typeMapper;
|
|
||||||
private final Codegens factory;
|
|
||||||
|
|
||||||
public FunctionCodegen(JetDeclaration owner, ClassVisitor v, JetStandardLibrary standardLibrary, BindingContext bindingContext, Codegens factory) {
|
public FunctionCodegen(JetDeclaration owner, ClassVisitor v, GenerationState state) {
|
||||||
this.owner = owner;
|
this.owner = owner;
|
||||||
this.v = v;
|
this.v = v;
|
||||||
this.bindingContext = bindingContext;
|
this.state = state;
|
||||||
this.factory = factory;
|
|
||||||
typeMapper = new JetTypeMapper(standardLibrary, bindingContext);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void gen(JetNamedFunction f, OwnerKind kind) {
|
public void gen(JetNamedFunction f, OwnerKind kind) {
|
||||||
final JetTypeReference receiverTypeRef = f.getReceiverTypeRef();
|
final JetTypeReference receiverTypeRef = f.getReceiverTypeRef();
|
||||||
final JetType receiverType = receiverTypeRef == null ? null : bindingContext.resolveTypeReference(receiverTypeRef);
|
final JetType receiverType = receiverTypeRef == null ? null : state.getBindingContext().resolveTypeReference(receiverTypeRef);
|
||||||
Method method = typeMapper.mapSignature(f);
|
Method method = state.getTypeMapper().mapSignature(f);
|
||||||
List<ValueParameterDescriptor> paramDescrs = bindingContext.getFunctionDescriptor(f).getUnsubstitutedValueParameters();
|
List<ValueParameterDescriptor> paramDescrs = state.getBindingContext().getFunctionDescriptor(f).getUnsubstitutedValueParameters();
|
||||||
generateMethod(f, kind, method, receiverType, paramDescrs);
|
generateMethod(f, kind, method, receiverType, paramDescrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,8 +43,8 @@ public class FunctionCodegen {
|
|||||||
@Nullable JetType receiverType,
|
@Nullable JetType receiverType,
|
||||||
List<ValueParameterDescriptor> paramDescrs) {
|
List<ValueParameterDescriptor> paramDescrs) {
|
||||||
final DeclarationDescriptor contextDesc = owner instanceof JetClassOrObject
|
final DeclarationDescriptor contextDesc = owner instanceof JetClassOrObject
|
||||||
? bindingContext.getClassDescriptor((JetClassOrObject) owner)
|
? state.getBindingContext().getClassDescriptor((JetClassOrObject) owner)
|
||||||
: bindingContext.getNamespaceDescriptor((JetNamespace) owner);
|
: state.getBindingContext().getNamespaceDescriptor((JetNamespace) owner);
|
||||||
final JetExpression bodyExpression = f.getBodyExpression();
|
final JetExpression bodyExpression = f.getBodyExpression();
|
||||||
final List<JetElement> bodyExpressions = bodyExpression != null ? Collections.<JetElement>singletonList(bodyExpression) : null;
|
final List<JetElement> bodyExpressions = bodyExpression != null ? Collections.<JetElement>singletonList(bodyExpression) : null;
|
||||||
generatedMethod(bodyExpressions, kind, jvmSignature, receiverType, paramDescrs, contextDesc);
|
generatedMethod(bodyExpressions, kind, jvmSignature, receiverType, paramDescrs, contextDesc);
|
||||||
@@ -90,9 +84,8 @@ public class FunctionCodegen {
|
|||||||
frameMap.enter(parameter, argTypes[i].getSize());
|
frameMap.enter(parameter, argTypes[i].getSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
StackValue thisExpression = receiverType == null ? null : StackValue.local(0, typeMapper.mapType(receiverType));
|
StackValue thisExpression = receiverType == null ? null : StackValue.local(0, state.getTypeMapper().mapType(receiverType));
|
||||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, bindingContext, frameMap, typeMapper,
|
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, jvmSignature.getReturnType(), contextDesc, kind, thisExpression, state);
|
||||||
jvmSignature.getReturnType(), contextDesc, kind, thisExpression, factory);
|
|
||||||
if (kind instanceof OwnerKind.DelegateKind) {
|
if (kind instanceof OwnerKind.DelegateKind) {
|
||||||
OwnerKind.DelegateKind dk = (OwnerKind.DelegateKind) kind;
|
OwnerKind.DelegateKind dk = (OwnerKind.DelegateKind) kind;
|
||||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
/*
|
||||||
|
* @author max
|
||||||
|
*/
|
||||||
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
|
import com.intellij.openapi.project.Project;
|
||||||
|
import com.intellij.openapi.util.Pair;
|
||||||
|
import com.intellij.util.containers.Stack;
|
||||||
|
import org.jetbrains.jet.lang.ErrorHandler;
|
||||||
|
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetNamespace;
|
||||||
|
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
|
||||||
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
|
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
||||||
|
import org.objectweb.asm.ClassVisitor;
|
||||||
|
|
||||||
|
public class GenerationState {
|
||||||
|
private final ClassFileFactory factory;
|
||||||
|
private final Project project;
|
||||||
|
|
||||||
|
private JetTypeMapper typeMapper;
|
||||||
|
private final Stack<BindingContext> bindingContexts;
|
||||||
|
private final JetStandardLibrary standardLibrary;
|
||||||
|
|
||||||
|
public GenerationState(Project project, boolean text) {
|
||||||
|
this.project = project;
|
||||||
|
this.bindingContexts = new Stack<BindingContext>();
|
||||||
|
this.standardLibrary = JetStandardLibrary.getJetStandardLibrary(project);
|
||||||
|
this.factory = new ClassFileFactory(project, text, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClassFileFactory getFactory() {
|
||||||
|
return factory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Project getProject() {
|
||||||
|
return project;
|
||||||
|
}
|
||||||
|
|
||||||
|
public JetTypeMapper getTypeMapper() {
|
||||||
|
return typeMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BindingContext getBindingContext() {
|
||||||
|
return bindingContexts.peek();
|
||||||
|
}
|
||||||
|
|
||||||
|
public JetStandardLibrary getStandardLibrary() {
|
||||||
|
return standardLibrary;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClassVisitor forClassInterface(ClassDescriptor aClass) {
|
||||||
|
return factory.newVisitor(JetTypeMapper.jvmNameForInterface(aClass) + ".class");
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClassCodegen forClass() {
|
||||||
|
return new ClassCodegen(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClassVisitor forClassImplementation(ClassDescriptor aClass) {
|
||||||
|
return factory.newVisitor(JetTypeMapper.jvmNameForImplementation(aClass) + ".class");
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClassVisitor forClassDelegatingImplementation(ClassDescriptor aClass) {
|
||||||
|
return factory.newVisitor(JetTypeMapper.jvmNameForDelegatingImplementation(aClass) + ".class");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pair<String, ClassVisitor> forClosureIn(ClassDescriptor aClass) {
|
||||||
|
return factory.forClosureIn(JetTypeMapper.jvmNameForInterface(aClass));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pair<String, ClassVisitor> forClosureIn(JetNamespace namespace) {
|
||||||
|
return factory.forClosureIn(NamespaceCodegen.getJVMClassName(namespace.getFQName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public NamespaceCodegen forNamespace(JetNamespace namespace) {
|
||||||
|
return factory.forNamespace(namespace);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void compile(JetFile psiFile) {
|
||||||
|
final JetNamespace namespace = ((JetFile) psiFile).getRootNamespace();
|
||||||
|
NamespaceCodegen codegen = forNamespace(namespace);
|
||||||
|
final BindingContext bindingContext = AnalyzingUtils.analyzeNamespace(namespace, JetControlFlowDataTraceFactory.EMPTY);
|
||||||
|
bindingContexts.push(bindingContext);
|
||||||
|
typeMapper = new JetTypeMapper(standardLibrary, bindingContext);
|
||||||
|
try {
|
||||||
|
AnalyzingUtils.applyHandler(ErrorHandler.THROW_EXCEPTION, bindingContext);
|
||||||
|
codegen.generate(namespace);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
bindingContexts.pop();
|
||||||
|
typeMapper = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,8 +4,6 @@ import com.intellij.psi.PsiClass;
|
|||||||
import com.intellij.psi.PsiElement;
|
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.types.JetStandardLibrary;
|
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.objectweb.asm.ClassVisitor;
|
import org.objectweb.asm.ClassVisitor;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
@@ -21,9 +19,8 @@ import java.util.*;
|
|||||||
* @author yole
|
* @author yole
|
||||||
*/
|
*/
|
||||||
public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||||
public ImplementationBodyCodegen(BindingContext bindingContext, JetStandardLibrary stdlib, JetClassOrObject aClass,
|
public ImplementationBodyCodegen(JetClassOrObject aClass, OwnerKind kind, ClassVisitor v, GenerationState state) {
|
||||||
OwnerKind kind, ClassVisitor v, Codegens factory) {
|
super(aClass, kind, v, state);
|
||||||
super(bindingContext, stdlib, aClass, kind, v, factory);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -55,9 +52,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
JetDelegationSpecifier first = delegationSpecifiers.get(0);
|
JetDelegationSpecifier first = delegationSpecifiers.get(0);
|
||||||
if (first instanceof JetDelegatorToSuperClass || first instanceof JetDelegatorToSuperCall) {
|
if (first instanceof JetDelegatorToSuperClass || first instanceof JetDelegatorToSuperCall) {
|
||||||
JetType superType = bindingContext.resolveTypeReference(first.getTypeReference());
|
JetType superType = state.getBindingContext().resolveTypeReference(first.getTypeReference());
|
||||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
||||||
return typeMapper.jvmName(superClassDescriptor, kind);
|
return state.getTypeMapper().jvmName(superClassDescriptor, kind);
|
||||||
}
|
}
|
||||||
|
|
||||||
return "java/lang/Object";
|
return "java/lang/Object";
|
||||||
@@ -86,7 +83,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void generatePrimaryConstructor() {
|
protected void generatePrimaryConstructor() {
|
||||||
ConstructorDescriptor constructorDescriptor = bindingContext.getConstructorDescriptor((JetElement) myClass);
|
ConstructorDescriptor constructorDescriptor = state.getBindingContext().getConstructorDescriptor((JetElement) myClass);
|
||||||
if (constructorDescriptor == null && !(myClass instanceof JetObjectDeclaration)) return;
|
if (constructorDescriptor == null && !(myClass instanceof JetObjectDeclaration)) return;
|
||||||
|
|
||||||
Method method;
|
Method method;
|
||||||
@@ -94,7 +91,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
method = new Method("<init>", Type.VOID_TYPE, new Type[0]);
|
method = new Method("<init>", Type.VOID_TYPE, new Type[0]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
method = typeMapper.mapConstructorSignature(constructorDescriptor, kind);
|
method = state.getTypeMapper().mapConstructorSignature(constructorDescriptor, kind);
|
||||||
}
|
}
|
||||||
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.visitMethod(flags, "<init>", method.getDescriptor(), null, null);
|
||||||
@@ -105,13 +102,13 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
? constructorDescriptor.getUnsubstitutedValueParameters()
|
? constructorDescriptor.getUnsubstitutedValueParameters()
|
||||||
: Collections.<ValueParameterDescriptor>emptyList();
|
: Collections.<ValueParameterDescriptor>emptyList();
|
||||||
|
|
||||||
ConstructorFrameMap frameMap = new ConstructorFrameMap(typeMapper, constructorDescriptor, kind);
|
ConstructorFrameMap frameMap = new ConstructorFrameMap(state.getTypeMapper(), constructorDescriptor, kind);
|
||||||
|
|
||||||
final InstructionAdapter iv = new InstructionAdapter(mv);
|
final InstructionAdapter iv = new InstructionAdapter(mv);
|
||||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, bindingContext, frameMap, typeMapper, Type.VOID_TYPE,
|
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE,
|
||||||
descriptor, kind, StackValue.local(0, typeMapper.jvmType(descriptor, kind)), factory);
|
descriptor, kind, StackValue.local(0, state.getTypeMapper().jvmType(descriptor, kind)), state);
|
||||||
|
|
||||||
String classname = typeMapper.jvmName(descriptor, kind);
|
String classname = state.getTypeMapper().jvmName(descriptor, kind);
|
||||||
final Type classType = Type.getType("L" + classname + ";");
|
final Type classType = Type.getType("L" + classname + ";");
|
||||||
|
|
||||||
List<JetDelegationSpecifier> specifiers = myClass.getDelegationSpecifiers();
|
List<JetDelegationSpecifier> specifiers = myClass.getDelegationSpecifiers();
|
||||||
@@ -120,7 +117,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
// TODO correct calculation of super class
|
// TODO correct calculation of super class
|
||||||
String superClass = "java/lang/Object";
|
String superClass = "java/lang/Object";
|
||||||
if (!specifiers.isEmpty()) {
|
if (!specifiers.isEmpty()) {
|
||||||
final JetType superType = bindingContext.resolveTypeReference(specifiers.get(0).getTypeReference());
|
final JetType superType = state.getBindingContext().resolveTypeReference(specifiers.get(0).getTypeReference());
|
||||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
||||||
if (superClassDescriptor.hasConstructors()) {
|
if (superClassDescriptor.hasConstructors()) {
|
||||||
superClass = getSuperClass();
|
superClass = getSuperClass();
|
||||||
@@ -153,8 +150,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
HashSet<FunctionDescriptor> overridden = new HashSet<FunctionDescriptor>();
|
HashSet<FunctionDescriptor> overridden = new HashSet<FunctionDescriptor>();
|
||||||
for (JetDeclaration declaration : myClass.getDeclarations()) {
|
for (JetDeclaration declaration : myClass.getDeclarations()) {
|
||||||
if (declaration instanceof JetNamedFunction) {
|
if (declaration instanceof JetFunction) {
|
||||||
overridden.addAll(bindingContext.getFunctionDescriptor((JetNamedFunction) declaration).getOverriddenFunctions());
|
overridden.addAll(state.getBindingContext().getFunctionDescriptor((JetFunction) declaration).getOverriddenFunctions());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,7 +165,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (specifier instanceof JetDelegatorToSuperCall) {
|
if (specifier instanceof JetDelegatorToSuperCall) {
|
||||||
ConstructorDescriptor constructorDescriptor1 = bindingContext.resolveSuperConstructor((JetDelegatorToSuperCall) specifier);
|
ConstructorDescriptor constructorDescriptor1 = state.getBindingContext().resolveSuperConstructor((JetDelegatorToSuperCall) specifier);
|
||||||
generateDelegatorToConstructorCall(iv, codegen, (JetDelegatorToSuperCall) specifier, constructorDescriptor1, n == 0, frameMap);
|
generateDelegatorToConstructorCall(iv, codegen, (JetDelegatorToSuperCall) specifier, constructorDescriptor1, n == 0, frameMap);
|
||||||
}
|
}
|
||||||
else if (specifier instanceof JetDelegatorByExpressionSpecifier) {
|
else if (specifier instanceof JetDelegatorByExpressionSpecifier) {
|
||||||
@@ -176,7 +173,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (delegateOnStack) {
|
if (delegateOnStack) {
|
||||||
JetType superType = bindingContext.resolveTypeReference(specifier.getTypeReference());
|
JetType superType = state.getBindingContext().resolveTypeReference(specifier.getTypeReference());
|
||||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
||||||
String delegateField = "$delegate_" + n;
|
String delegateField = "$delegate_" + n;
|
||||||
Type fieldType = JetTypeMapper.jetInterfaceType(superClassDescriptor);
|
Type fieldType = JetTypeMapper.jetInterfaceType(superClassDescriptor);
|
||||||
@@ -184,7 +181,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
v.visitField(Opcodes.ACC_PRIVATE, delegateField, fieldDesc, /*TODO*/null, null);
|
v.visitField(Opcodes.ACC_PRIVATE, delegateField, fieldDesc, /*TODO*/null, null);
|
||||||
iv.putfield(classname, delegateField, fieldDesc);
|
iv.putfield(classname, delegateField, fieldDesc);
|
||||||
|
|
||||||
JetClass superClass = (JetClass) bindingContext.getDeclarationPsiElement(superClassDescriptor);
|
JetClass superClass = (JetClass) state.getBindingContext().getDeclarationPsiElement(superClassDescriptor);
|
||||||
generateDelegates(myClass, superClass,
|
generateDelegates(myClass, superClass,
|
||||||
new OwnerKind.DelegateKind(StackValue.field(fieldType, classname, delegateField, false),
|
new OwnerKind.DelegateKind(StackValue.field(fieldType, classname, delegateField, false),
|
||||||
JetTypeMapper.jvmNameForInterface(superClassDescriptor)), overridden);
|
JetTypeMapper.jvmNameForInterface(superClassDescriptor)), overridden);
|
||||||
@@ -204,7 +201,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
for (JetParameter parameter : constructorParameters) {
|
for (JetParameter parameter : constructorParameters) {
|
||||||
if (parameter.getValOrVarNode() != null) {
|
if (parameter.getValOrVarNode() != null) {
|
||||||
VariableDescriptor descriptor = paramDescrs.get(curParam);
|
VariableDescriptor descriptor = paramDescrs.get(curParam);
|
||||||
Type type = typeMapper.mapType(descriptor.getOutType());
|
Type type = state.getTypeMapper().mapType(descriptor.getOutType());
|
||||||
iv.load(0, classType);
|
iv.load(0, classType);
|
||||||
iv.load(frameMap.getIndex(descriptor), type);
|
iv.load(frameMap.getIndex(descriptor), type);
|
||||||
iv.putfield(classname, descriptor.getName(), type.getDescriptor());
|
iv.putfield(classname, descriptor.getName(), type.getDescriptor());
|
||||||
@@ -222,7 +219,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
ConstructorFrameMap frameMap) {
|
ConstructorFrameMap frameMap) {
|
||||||
ClassDescriptor classDecl = constructorDescriptor.getContainingDeclaration();
|
ClassDescriptor classDecl = constructorDescriptor.getContainingDeclaration();
|
||||||
boolean isDelegating = kind == OwnerKind.DELEGATING_IMPLEMENTATION;
|
boolean isDelegating = kind == OwnerKind.DELEGATING_IMPLEMENTATION;
|
||||||
PsiElement declaration = bindingContext.getDeclarationPsiElement(classDecl);
|
PsiElement declaration = state.getBindingContext().getDeclarationPsiElement(classDecl);
|
||||||
Type type;
|
Type type;
|
||||||
if (declaration instanceof PsiClass) {
|
if (declaration instanceof PsiClass) {
|
||||||
type = JetTypeMapper.psiClassType((PsiClass) declaration);
|
type = JetTypeMapper.psiClassType((PsiClass) declaration);
|
||||||
@@ -248,18 +245,18 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (kind == OwnerKind.DELEGATING_IMPLEMENTATION) {
|
if (kind == OwnerKind.DELEGATING_IMPLEMENTATION) {
|
||||||
iv.load(frameMap.getDelegateThisIndex(), typeMapper.jvmType(classDecl, OwnerKind.INTERFACE));
|
iv.load(frameMap.getDelegateThisIndex(), state.getTypeMapper().jvmType(classDecl, OwnerKind.INTERFACE));
|
||||||
}
|
}
|
||||||
if (classDecl.getContainingDeclaration() instanceof ClassDescriptor) {
|
if (classDecl.getContainingDeclaration() instanceof ClassDescriptor) {
|
||||||
iv.load(frameMap.getOuterThisIndex(), typeMapper.jvmType((ClassDescriptor) descriptor.getContainingDeclaration(), OwnerKind.IMPLEMENTATION));
|
iv.load(frameMap.getOuterThisIndex(), state.getTypeMapper().jvmType((ClassDescriptor) descriptor.getContainingDeclaration(), OwnerKind.IMPLEMENTATION));
|
||||||
}
|
}
|
||||||
|
|
||||||
Method method = typeMapper.mapConstructorSignature(constructorDescriptor, kind);
|
Method method = state.getTypeMapper().mapConstructorSignature(constructorDescriptor, kind);
|
||||||
List<ValueParameterDescriptor> valueParameters = constructorDescriptor.getUnsubstitutedValueParameters();
|
List<ValueParameterDescriptor> valueParameters = constructorDescriptor.getUnsubstitutedValueParameters();
|
||||||
List<JetArgument> args = constructorCall.getValueArguments();
|
List<JetArgument> args = constructorCall.getValueArguments();
|
||||||
for (int i = 0, argsSize = args.size(); i < argsSize; i++) {
|
for (int i = 0, argsSize = args.size(); i < argsSize; i++) {
|
||||||
JetArgument arg = args.get(i);
|
JetArgument arg = args.get(i);
|
||||||
codegen.gen(arg.getArgumentExpression(), typeMapper.mapType(valueParameters.get(i).getOutType()));
|
codegen.gen(arg.getArgumentExpression(), state.getTypeMapper().mapType(valueParameters.get(i).getOutType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
iv.invokespecial(type.getInternalName(), "<init>", method.getDescriptor());
|
iv.invokespecial(type.getInternalName(), "<init>", method.getDescriptor());
|
||||||
@@ -276,25 +273,25 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void generateSecondaryConstructor(JetConstructor constructor) {
|
private void generateSecondaryConstructor(JetConstructor constructor) {
|
||||||
ConstructorDescriptor constructorDescriptor = bindingContext.getConstructorDescriptor(constructor);
|
ConstructorDescriptor constructorDescriptor = state.getBindingContext().getConstructorDescriptor(constructor);
|
||||||
if (constructorDescriptor == null) {
|
if (constructorDescriptor == null) {
|
||||||
throw new UnsupportedOperationException("failed to get descriptor for secondary constructor");
|
throw new UnsupportedOperationException("failed to get descriptor for secondary constructor");
|
||||||
}
|
}
|
||||||
Method method = typeMapper.mapConstructorSignature(constructorDescriptor, kind);
|
Method method = state.getTypeMapper().mapConstructorSignature(constructorDescriptor, kind);
|
||||||
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.visitMethod(flags, "<init>", method.getDescriptor(), null, null);
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
|
|
||||||
ConstructorFrameMap frameMap = new ConstructorFrameMap(typeMapper, constructorDescriptor, kind);
|
ConstructorFrameMap frameMap = new ConstructorFrameMap(state.getTypeMapper(), constructorDescriptor, kind);
|
||||||
|
|
||||||
final InstructionAdapter iv = new InstructionAdapter(mv);
|
final InstructionAdapter iv = new InstructionAdapter(mv);
|
||||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, bindingContext, frameMap, typeMapper, Type.VOID_TYPE,
|
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE,
|
||||||
descriptor, kind, StackValue.local(0, typeMapper.jvmType(descriptor, kind)), factory);
|
descriptor, kind, StackValue.local(0, state.getTypeMapper().jvmType(descriptor, kind)), state);
|
||||||
|
|
||||||
for (JetDelegationSpecifier initializer : constructor.getInitializers()) {
|
for (JetDelegationSpecifier initializer : constructor.getInitializers()) {
|
||||||
if (initializer instanceof JetDelegatorToThisCall) {
|
if (initializer instanceof JetDelegatorToThisCall) {
|
||||||
JetDelegatorToThisCall thisCall = (JetDelegatorToThisCall) initializer;
|
JetDelegatorToThisCall thisCall = (JetDelegatorToThisCall) initializer;
|
||||||
DeclarationDescriptor thisDescriptor = bindingContext.resolveReferenceExpression(thisCall.getThisReference());
|
DeclarationDescriptor thisDescriptor = state.getBindingContext().resolveReferenceExpression(thisCall.getThisReference());
|
||||||
if (!(thisDescriptor instanceof ConstructorDescriptor)) {
|
if (!(thisDescriptor instanceof ConstructorDescriptor)) {
|
||||||
throw new UnsupportedOperationException("expected 'this' delegator to resolve to constructor");
|
throw new UnsupportedOperationException("expected 'this' delegator to resolve to constructor");
|
||||||
}
|
}
|
||||||
@@ -320,7 +317,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
iv.anew(JetTypeMapper.TYPE_TYPEINFO);
|
iv.anew(JetTypeMapper.TYPE_TYPEINFO);
|
||||||
iv.dup();
|
iv.dup();
|
||||||
|
|
||||||
iv.aconst(typeMapper.jvmType(descriptor, OwnerKind.INTERFACE));
|
iv.aconst(state.getTypeMapper().jvmType(descriptor, OwnerKind.INTERFACE));
|
||||||
iv.iconst(typeParamCount);
|
iv.iconst(typeParamCount);
|
||||||
iv.newarray(JetTypeMapper.TYPE_TYPEINFO);
|
iv.newarray(JetTypeMapper.TYPE_TYPEINFO);
|
||||||
|
|
||||||
@@ -331,14 +328,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
iv.astore(JetTypeMapper.TYPE_OBJECT);
|
iv.astore(JetTypeMapper.TYPE_OBJECT);
|
||||||
}
|
}
|
||||||
iv.invokespecial("jet/typeinfo/TypeInfo", "<init>", "(Ljava/lang/Class;[Ljet/typeinfo/TypeInfo;)V");
|
iv.invokespecial("jet/typeinfo/TypeInfo", "<init>", "(Ljava/lang/Class;[Ljet/typeinfo/TypeInfo;)V");
|
||||||
iv.putfield(typeMapper.jvmName(descriptor, OwnerKind.IMPLEMENTATION), "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
iv.putfield(state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION), "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void generateInitializers(ExpressionCodegen codegen, InstructionAdapter iv) {
|
protected void generateInitializers(ExpressionCodegen codegen, InstructionAdapter iv) {
|
||||||
for (JetDeclaration declaration : myClass.getDeclarations()) {
|
for (JetDeclaration declaration : myClass.getDeclarations()) {
|
||||||
if (declaration instanceof JetProperty) {
|
if (declaration instanceof JetProperty) {
|
||||||
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) bindingContext.getVariableDescriptor((JetProperty) declaration);
|
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) state.getBindingContext().getVariableDescriptor((JetProperty) declaration);
|
||||||
if (bindingContext.hasBackingField(propertyDescriptor)) {
|
if (state.getBindingContext().hasBackingField(propertyDescriptor)) {
|
||||||
final JetExpression initializer = ((JetProperty) declaration).getInitializer();
|
final JetExpression initializer = ((JetProperty) declaration).getInitializer();
|
||||||
if (initializer != null) {
|
if (initializer != null) {
|
||||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||||
@@ -355,23 +352,23 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void generateDelegates(JetClassOrObject inClass, JetClass toClass, OwnerKind kind, Set<FunctionDescriptor> overriden) {
|
protected void generateDelegates(JetClassOrObject inClass, JetClass toClass, OwnerKind kind, Set<FunctionDescriptor> overriden) {
|
||||||
final FunctionCodegen functionCodegen = new FunctionCodegen(toClass, v, stdlib, bindingContext, factory);
|
final FunctionCodegen functionCodegen = new FunctionCodegen(toClass, v, state);
|
||||||
final PropertyCodegen propertyCodegen = new PropertyCodegen(v, stdlib, bindingContext, functionCodegen);
|
final PropertyCodegen propertyCodegen = new PropertyCodegen(v, functionCodegen, state);
|
||||||
|
|
||||||
for (JetDeclaration declaration : toClass.getDeclarations()) {
|
for (JetDeclaration declaration : toClass.getDeclarations()) {
|
||||||
if (declaration instanceof JetProperty) {
|
if (declaration instanceof JetProperty) {
|
||||||
propertyCodegen.gen((JetProperty) declaration, kind);
|
propertyCodegen.gen((JetProperty) declaration, kind);
|
||||||
}
|
}
|
||||||
else if (declaration instanceof JetNamedFunction) {
|
else if (declaration instanceof JetFunction) {
|
||||||
if (!overriden.contains(bindingContext.getFunctionDescriptor((JetNamedFunction) declaration))) {
|
if (!overriden.contains(state.getBindingContext().getFunctionDescriptor((JetFunction) declaration))) {
|
||||||
functionCodegen.gen((JetNamedFunction) declaration, kind);
|
functionCodegen.gen((JetFunction) declaration, kind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (JetParameter p : toClass.getPrimaryConstructorParameters()) {
|
for (JetParameter p : toClass.getPrimaryConstructorParameters()) {
|
||||||
if (p.getValOrVarNode() != null) {
|
if (p.getValOrVarNode() != null) {
|
||||||
PropertyDescriptor propertyDescriptor = bindingContext.getPropertyDescriptor(p);
|
PropertyDescriptor propertyDescriptor = state.getBindingContext().getPropertyDescriptor(p);
|
||||||
if (propertyDescriptor != null) {
|
if (propertyDescriptor != null) {
|
||||||
propertyCodegen.generateDefaultGetter(propertyDescriptor, Opcodes.ACC_PUBLIC, kind);
|
propertyCodegen.generateDefaultGetter(propertyDescriptor, Opcodes.ACC_PUBLIC, kind);
|
||||||
if (propertyDescriptor.isVar()) {
|
if (propertyDescriptor.isVar()) {
|
||||||
@@ -396,7 +393,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
InstructionAdapter v = new InstructionAdapter(mv);
|
InstructionAdapter v = new InstructionAdapter(mv);
|
||||||
|
|
||||||
if (needTypeInfo) {
|
if (needTypeInfo) {
|
||||||
ClassCodegen.newTypeInfo(v, typeMapper.jvmType(descriptor, OwnerKind.INTERFACE));
|
ClassCodegen.newTypeInfo(v, state.getTypeMapper().jvmType(descriptor, OwnerKind.INTERFACE));
|
||||||
v.putstatic(JetTypeMapper.jvmNameForImplementation(descriptor), "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
v.putstatic(JetTypeMapper.jvmNameForImplementation(descriptor), "$typeInfo", "Ljet/typeinfo/TypeInfo;");
|
||||||
}
|
}
|
||||||
if (needInstance) {
|
if (needInstance) {
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ import com.intellij.psi.PsiElement;
|
|||||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
||||||
import org.jetbrains.jet.lang.psi.JetDelegationSpecifier;
|
import org.jetbrains.jet.lang.psi.JetDelegationSpecifier;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
|
||||||
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.objectweb.asm.ClassVisitor;
|
import org.objectweb.asm.ClassVisitor;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
@@ -19,8 +17,8 @@ import java.util.Set;
|
|||||||
* @author yole
|
* @author yole
|
||||||
*/
|
*/
|
||||||
public class InterfaceBodyCodegen extends ClassBodyCodegen {
|
public class InterfaceBodyCodegen extends ClassBodyCodegen {
|
||||||
public InterfaceBodyCodegen(BindingContext bindingContext, JetStandardLibrary stdlib, JetClassOrObject aClass, ClassVisitor v, Codegens factory) {
|
public InterfaceBodyCodegen(JetClassOrObject aClass, ClassVisitor v, GenerationState state) {
|
||||||
super(bindingContext, stdlib, aClass, OwnerKind.INTERFACE, v, factory);
|
super(aClass, OwnerKind.INTERFACE, v, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void generateDeclaration() {
|
protected void generateDeclaration() {
|
||||||
@@ -41,9 +39,9 @@ public class InterfaceBodyCodegen extends ClassBodyCodegen {
|
|||||||
String superClassName = null;
|
String superClassName = null;
|
||||||
Set<String> superInterfaces = new LinkedHashSet<String>();
|
Set<String> superInterfaces = new LinkedHashSet<String>();
|
||||||
for (JetDelegationSpecifier specifier : delegationSpecifiers) {
|
for (JetDelegationSpecifier specifier : delegationSpecifiers) {
|
||||||
JetType superType = bindingContext.resolveTypeReference(specifier.getTypeReference());
|
JetType superType = state.getBindingContext().resolveTypeReference(specifier.getTypeReference());
|
||||||
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
|
||||||
PsiElement superPsi = bindingContext.getDeclarationPsiElement(superClassDescriptor);
|
PsiElement superPsi = state.getBindingContext().getDeclarationPsiElement(superClassDescriptor);
|
||||||
|
|
||||||
if (superPsi instanceof PsiClass) {
|
if (superPsi instanceof PsiClass) {
|
||||||
PsiClass psiClass = (PsiClass) superPsi;
|
PsiClass psiClass = (PsiClass) superPsi;
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
package org.jetbrains.jet.codegen;
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import org.jetbrains.jet.lang.ErrorHandler;
|
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
|
|
||||||
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.AnalyzingUtils;
|
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
|
||||||
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
||||||
import org.objectweb.asm.ClassVisitor;
|
import org.objectweb.asm.ClassVisitor;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
@@ -20,12 +16,12 @@ import org.objectweb.asm.commons.InstructionAdapter;
|
|||||||
public class NamespaceCodegen {
|
public class NamespaceCodegen {
|
||||||
private final Project project;
|
private final Project project;
|
||||||
private final ClassVisitor v;
|
private final ClassVisitor v;
|
||||||
private final Codegens codegens;
|
private final GenerationState state;
|
||||||
|
|
||||||
public NamespaceCodegen(Project project, ClassVisitor v, String fqName, Codegens codegens) {
|
public NamespaceCodegen(Project project, ClassVisitor v, String fqName, GenerationState state) {
|
||||||
this.project = project;
|
this.project = project;
|
||||||
this.v = v;
|
this.v = v;
|
||||||
this.codegens = codegens;
|
this.state = state;
|
||||||
|
|
||||||
v.visit(Opcodes.V1_6,
|
v.visit(Opcodes.V1_6,
|
||||||
Opcodes.ACC_PUBLIC,
|
Opcodes.ACC_PUBLIC,
|
||||||
@@ -34,23 +30,17 @@ public class NamespaceCodegen {
|
|||||||
//"jet/lang/Namespace",
|
//"jet/lang/Namespace",
|
||||||
"java/lang/Object",
|
"java/lang/Object",
|
||||||
new String[0]
|
new String[0]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generate(JetNamespace namespace) {
|
public void generate(JetNamespace namespace) {
|
||||||
generate(namespace, AnalyzingUtils.analyzeNamespace(namespace, JetControlFlowDataTraceFactory.EMPTY));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void generate(JetNamespace namespace, BindingContext bindingContext) {
|
|
||||||
AnalyzingUtils.applyHandler(ErrorHandler.THROW_EXCEPTION, bindingContext);
|
|
||||||
|
|
||||||
final JetStandardLibrary standardLibrary = JetStandardLibrary.getJetStandardLibrary(project);
|
final JetStandardLibrary standardLibrary = JetStandardLibrary.getJetStandardLibrary(project);
|
||||||
final FunctionCodegen functionCodegen = new FunctionCodegen(namespace, v, standardLibrary, bindingContext, codegens);
|
final FunctionCodegen functionCodegen = new FunctionCodegen(namespace, v, state);
|
||||||
final PropertyCodegen propertyCodegen = new PropertyCodegen(v, standardLibrary, bindingContext, functionCodegen);
|
final PropertyCodegen propertyCodegen = new PropertyCodegen(v, functionCodegen, state);
|
||||||
final ClassCodegen classCodegen = codegens.forClass(bindingContext);
|
final ClassCodegen classCodegen = state.forClass();
|
||||||
|
|
||||||
if (hasNonConstantPropertyInitializers(namespace)) {
|
if (hasNonConstantPropertyInitializers(namespace)) {
|
||||||
generateStaticInitializers(namespace, bindingContext);
|
generateStaticInitializers(namespace);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (JetDeclaration declaration : namespace.getDeclarations()) {
|
for (JetDeclaration declaration : namespace.getDeclarations()) {
|
||||||
@@ -69,25 +59,24 @@ public class NamespaceCodegen {
|
|||||||
}
|
}
|
||||||
else if (declaration instanceof JetNamespace) {
|
else if (declaration instanceof JetNamespace) {
|
||||||
JetNamespace childNamespace = (JetNamespace) declaration;
|
JetNamespace childNamespace = (JetNamespace) declaration;
|
||||||
codegens.forNamespace(childNamespace).generate(childNamespace, bindingContext);
|
state.forNamespace(childNamespace).generate(childNamespace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateStaticInitializers(JetNamespace namespace, BindingContext bindingContext) {
|
private void generateStaticInitializers(JetNamespace namespace) {
|
||||||
MethodVisitor mv = v.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,
|
MethodVisitor mv = v.visitMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,
|
||||||
"<clinit>", "()V", null, null);
|
"<clinit>", "()V", null, null);
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
|
|
||||||
FrameMap frameMap = new FrameMap();
|
FrameMap frameMap = new FrameMap();
|
||||||
JetTypeMapper typeMapper = new JetTypeMapper(JetStandardLibrary.getJetStandardLibrary(namespace.getProject()), bindingContext);
|
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, null, OwnerKind.NAMESPACE, null, state);
|
||||||
ExpressionCodegen codegen = new ExpressionCodegen(mv, bindingContext, frameMap, typeMapper, Type.VOID_TYPE, null, OwnerKind.NAMESPACE, null, codegens);
|
|
||||||
|
|
||||||
for (JetDeclaration declaration : namespace.getDeclarations()) {
|
for (JetDeclaration declaration : namespace.getDeclarations()) {
|
||||||
if (declaration instanceof JetProperty) {
|
if (declaration instanceof JetProperty) {
|
||||||
final JetExpression initializer = ((JetProperty) declaration).getInitializer();
|
final JetExpression initializer = ((JetProperty) declaration).getInitializer();
|
||||||
if (initializer != null && !(initializer instanceof JetConstantExpression)) {
|
if (initializer != null && !(initializer instanceof JetConstantExpression)) {
|
||||||
final PropertyDescriptor descriptor = (PropertyDescriptor) bindingContext.getVariableDescriptor((JetProperty) declaration);
|
final PropertyDescriptor descriptor = (PropertyDescriptor) state.getBindingContext().getVariableDescriptor((JetProperty) declaration);
|
||||||
codegen.genToJVMStack(initializer);
|
codegen.genToJVMStack(initializer);
|
||||||
codegen.intermediateValueForProperty(descriptor, false, false).store(new InstructionAdapter(mv));
|
codegen.intermediateValueForProperty(descriptor, false, false).store(new InstructionAdapter(mv));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
|||||||
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
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.types.*;
|
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
import org.objectweb.asm.ClassVisitor;
|
import org.objectweb.asm.ClassVisitor;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
@@ -21,16 +20,18 @@ import java.util.Collections;
|
|||||||
* @author max
|
* @author max
|
||||||
*/
|
*/
|
||||||
public class PropertyCodegen {
|
public class PropertyCodegen {
|
||||||
|
private final GenerationState state;
|
||||||
private final BindingContext context;
|
private final BindingContext context;
|
||||||
private final FunctionCodegen functionCodegen;
|
private final FunctionCodegen functionCodegen;
|
||||||
private final ClassVisitor v;
|
private final ClassVisitor v;
|
||||||
private final JetTypeMapper mapper;
|
private final JetTypeMapper mapper;
|
||||||
|
|
||||||
public PropertyCodegen(ClassVisitor v, JetStandardLibrary standardLibrary, BindingContext context, FunctionCodegen functionCodegen) {
|
public PropertyCodegen(ClassVisitor v, FunctionCodegen functionCodegen, GenerationState state) {
|
||||||
this.v = v;
|
this.v = v;
|
||||||
this.context = context;
|
|
||||||
this.functionCodegen = functionCodegen;
|
this.functionCodegen = functionCodegen;
|
||||||
this.mapper = new JetTypeMapper(standardLibrary, context);
|
this.state = state;
|
||||||
|
mapper = state.getTypeMapper();
|
||||||
|
context = state.getBindingContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void gen(JetProperty p, OwnerKind kind) {
|
public void gen(JetProperty p, OwnerKind kind) {
|
||||||
|
|||||||
@@ -12,11 +12,10 @@ import com.intellij.psi.PsiFile;
|
|||||||
import com.intellij.psi.PsiManager;
|
import com.intellij.psi.PsiManager;
|
||||||
import com.intellij.util.Chunk;
|
import com.intellij.util.Chunk;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.codegen.Codegens;
|
import org.jetbrains.jet.codegen.ClassFileFactory;
|
||||||
import org.jetbrains.jet.codegen.NamespaceCodegen;
|
import org.jetbrains.jet.codegen.GenerationState;
|
||||||
import org.jetbrains.jet.plugin.JetFileType;
|
|
||||||
import org.jetbrains.jet.lang.psi.JetFile;
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
import org.jetbrains.jet.lang.psi.JetNamespace;
|
import org.jetbrains.jet.plugin.JetFileType;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -65,7 +64,7 @@ public class JetCompiler implements TranslatingCompiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static class ModuleCompileState {
|
private static class ModuleCompileState {
|
||||||
private final Codegens codegens;
|
private final GenerationState state;
|
||||||
private final CompileContext compileContext;
|
private final CompileContext compileContext;
|
||||||
private final Module module;
|
private final Module module;
|
||||||
private final OutputSink outputSink;
|
private final OutputSink outputSink;
|
||||||
@@ -74,7 +73,7 @@ public class JetCompiler implements TranslatingCompiler {
|
|||||||
this.compileContext = compileContext;
|
this.compileContext = compileContext;
|
||||||
this.module = module;
|
this.module = module;
|
||||||
this.outputSink = outputSink;
|
this.outputSink = outputSink;
|
||||||
codegens = new Codegens(compileContext.getProject(), false);
|
state = new GenerationState(compileContext.getProject(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void compile(final VirtualFile virtualFile) {
|
public void compile(final VirtualFile virtualFile) {
|
||||||
@@ -83,9 +82,7 @@ public class JetCompiler implements TranslatingCompiler {
|
|||||||
public void run() {
|
public void run() {
|
||||||
PsiFile psiFile = PsiManager.getInstance(module.getProject()).findFile(virtualFile);
|
PsiFile psiFile = PsiManager.getInstance(module.getProject()).findFile(virtualFile);
|
||||||
if (psiFile instanceof JetFile) {
|
if (psiFile instanceof JetFile) {
|
||||||
final JetNamespace namespace = ((JetFile) psiFile).getRootNamespace();
|
state.compile((JetFile) psiFile);
|
||||||
NamespaceCodegen codegen = codegens.forNamespace(namespace);
|
|
||||||
codegen.generate(namespace);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -93,11 +90,12 @@ public class JetCompiler implements TranslatingCompiler {
|
|||||||
|
|
||||||
public void done() {
|
public void done() {
|
||||||
VirtualFile outputDir = compileContext.getModuleOutputDirectory(module);
|
VirtualFile outputDir = compileContext.getModuleOutputDirectory(module);
|
||||||
List<String> files = codegens.files();
|
final ClassFileFactory factory = state.getFactory();
|
||||||
|
List<String> files = factory.files();
|
||||||
for (String file : files) {
|
for (String file : files) {
|
||||||
File target = new File(outputDir.getPath(), file);
|
File target = new File(outputDir.getPath(), file);
|
||||||
try {
|
try {
|
||||||
FileUtil.writeToFile(target, codegens.asBytes(file));
|
FileUtil.writeToFile(target, factory.asBytes(file));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
compileContext.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, 0, 0);
|
compileContext.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, 0, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fun box() : String {
|
||||||
|
val cl = 39
|
||||||
|
return if (sum(200, { cl }) == 2) "OK" else "FAIL"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun sum(arg:Int, f : {() : Int}) : Int {
|
||||||
|
return arg + f()
|
||||||
|
}
|
||||||
@@ -72,7 +72,7 @@ public class ClassGenTest extends CodegenTestCase {
|
|||||||
public void testAbstractMethod() throws Exception {
|
public void testAbstractMethod() throws Exception {
|
||||||
loadText("class Foo { abstract fun x(): String; fun y(): Int = 0 }");
|
loadText("class Foo { abstract fun x(): String; fun y(): Int = 0 }");
|
||||||
|
|
||||||
final Codegens codegens = generateClassesInFile();
|
final ClassFileFactory codegens = generateClassesInFile();
|
||||||
final Class aClass = loadClass("Foo", codegens);
|
final Class aClass = loadClass("Foo", codegens);
|
||||||
assertNotNull(aClass.getMethod("x"));
|
assertNotNull(aClass.getMethod("x"));
|
||||||
final Class implClass = loadClass("Foo$$Impl", codegens);
|
final Class implClass = loadClass("Foo$$Impl", codegens);
|
||||||
|
|||||||
@@ -23,4 +23,8 @@ public class ClosuresGenTest extends CodegenTestCase {
|
|||||||
public void testExtensionClosure() throws Exception {
|
public void testExtensionClosure() throws Exception {
|
||||||
blackBoxFile("classes/extensionClosure.jet");
|
blackBoxFile("classes/extensionClosure.jet");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testEnclosingLocalVariable() throws Exception {
|
||||||
|
blackBoxFile("classes/enclosingLocalVariable.jet");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,11 +6,11 @@ import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.JetLightProjectDescriptor;
|
import org.jetbrains.jet.JetLightProjectDescriptor;
|
||||||
import org.jetbrains.jet.plugin.JetFileType;
|
|
||||||
import org.jetbrains.jet.lang.psi.JetFile;
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
import org.jetbrains.jet.lang.psi.JetNamespace;
|
import org.jetbrains.jet.lang.psi.JetNamespace;
|
||||||
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
|
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
|
||||||
import org.jetbrains.jet.parsing.JetParsingTest;
|
import org.jetbrains.jet.parsing.JetParsingTest;
|
||||||
|
import org.jetbrains.jet.plugin.JetFileType;
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
@@ -79,7 +79,7 @@ public abstract class CodegenTestCase extends LightCodeInsightFixtureTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected String blackBox() throws Exception {
|
protected String blackBox() throws Exception {
|
||||||
Codegens codegens = generateClassesInFile();
|
ClassFileFactory codegens = generateClassesInFile();
|
||||||
CodegensClassLoader loader = new CodegensClassLoader(codegens);
|
CodegensClassLoader loader = new CodegensClassLoader(codegens);
|
||||||
|
|
||||||
JetFile jetFile = (JetFile) myFixture.getFile();
|
JetFile jetFile = (JetFile) myFixture.getFile();
|
||||||
@@ -91,30 +91,29 @@ public abstract class CodegenTestCase extends LightCodeInsightFixtureTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected String generateToText() {
|
protected String generateToText() {
|
||||||
Codegens state = new Codegens(getProject(), true);
|
GenerationState state = new GenerationState(getProject(), true);
|
||||||
JetFile jetFile = (JetFile) myFixture.getFile();
|
JetFile jetFile = (JetFile) myFixture.getFile();
|
||||||
AnalyzingUtils.checkForSyntacticErrors(jetFile);
|
AnalyzingUtils.checkForSyntacticErrors(jetFile);
|
||||||
JetNamespace namespace = jetFile.getRootNamespace();
|
state.compile(jetFile);
|
||||||
NamespaceCodegen codegen = state.forNamespace(namespace);
|
|
||||||
codegen.generate(namespace);
|
|
||||||
|
|
||||||
StringBuilder answer = new StringBuilder();
|
StringBuilder answer = new StringBuilder();
|
||||||
|
|
||||||
List<String> files = state.files();
|
final ClassFileFactory factory = state.getFactory();
|
||||||
|
List<String> files = factory.files();
|
||||||
for (String file : files) {
|
for (String file : files) {
|
||||||
answer.append("@").append(file).append('\n');
|
answer.append("@").append(file).append('\n');
|
||||||
answer.append(state.asText(file));
|
answer.append(factory.asText(file));
|
||||||
}
|
}
|
||||||
|
|
||||||
return answer.toString();
|
return answer.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Class generateNamespaceClass() {
|
protected Class generateNamespaceClass() {
|
||||||
Codegens state = generateClassesInFile();
|
ClassFileFactory state = generateClassesInFile();
|
||||||
return loadRootNamespaceClass(state);
|
return loadRootNamespaceClass(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Class loadRootNamespaceClass(Codegens state) {
|
protected Class loadRootNamespaceClass(ClassFileFactory state) {
|
||||||
JetFile jetFile = (JetFile) myFixture.getFile();
|
JetFile jetFile = (JetFile) myFixture.getFile();
|
||||||
final JetNamespace namespace = jetFile.getRootNamespace();
|
final JetNamespace namespace = jetFile.getRootNamespace();
|
||||||
String fqName = NamespaceCodegen.getJVMClassName(namespace.getFQName()).replace("/", ".");
|
String fqName = NamespaceCodegen.getJVMClassName(namespace.getFQName()).replace("/", ".");
|
||||||
@@ -122,7 +121,7 @@ public abstract class CodegenTestCase extends LightCodeInsightFixtureTestCase {
|
|||||||
return classMap.get(fqName);
|
return classMap.get(fqName);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Class loadClass(String fqName, Codegens state) {
|
protected Class loadClass(String fqName, ClassFileFactory state) {
|
||||||
List<String> files = state.files();
|
List<String> files = state.files();
|
||||||
for (String file : files) {
|
for (String file : files) {
|
||||||
if (file.equals(fqName.replace('.', '/') + ".class")) {
|
if (file.equals(fqName.replace('.', '/') + ".class")) {
|
||||||
@@ -135,7 +134,7 @@ public abstract class CodegenTestCase extends LightCodeInsightFixtureTestCase {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Map<String, Class> loadAllClasses(Codegens state) {
|
protected Map<String, Class> loadAllClasses(ClassFileFactory state) {
|
||||||
Map<String, Class> result = new HashMap<String, Class>();
|
Map<String, Class> result = new HashMap<String, Class>();
|
||||||
for (String fileName : state.files()) {
|
for (String fileName : state.files()) {
|
||||||
String className = StringUtil.trimEnd(fileName, ".class").replace('/', '.');
|
String className = StringUtil.trimEnd(fileName, ".class").replace('/', '.');
|
||||||
@@ -146,16 +145,14 @@ public abstract class CodegenTestCase extends LightCodeInsightFixtureTestCase {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Codegens generateClassesInFile() {
|
protected ClassFileFactory generateClassesInFile() {
|
||||||
try {
|
try {
|
||||||
Codegens state = new Codegens(getProject(), false);
|
GenerationState state = new GenerationState(getProject(), false);
|
||||||
JetFile jetFile = (JetFile) myFixture.getFile();
|
JetFile jetFile = (JetFile) myFixture.getFile();
|
||||||
AnalyzingUtils.checkForSyntacticErrors(jetFile);
|
AnalyzingUtils.checkForSyntacticErrors(jetFile);
|
||||||
final JetNamespace namespace = jetFile.getRootNamespace();
|
state.compile(jetFile);
|
||||||
|
|
||||||
NamespaceCodegen codegen = state.forNamespace(namespace);
|
return state.getFactory();
|
||||||
codegen.generate(namespace);
|
|
||||||
return state;
|
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
System.out.println(generateToText());
|
System.out.println(generateToText());
|
||||||
throw e;
|
throw e;
|
||||||
@@ -196,7 +193,7 @@ public abstract class CodegenTestCase extends LightCodeInsightFixtureTestCase {
|
|||||||
assertTrue(Math.abs(returnValue - currentTime) <= 1L);
|
assertTrue(Math.abs(returnValue - currentTime) <= 1L);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Class loadImplementationClass(Codegens codegens, final String name) {
|
protected Class loadImplementationClass(ClassFileFactory codegens, final String name) {
|
||||||
loadClass(name, codegens);
|
loadClass(name, codegens);
|
||||||
return loadClass(name + "$$Impl", codegens);
|
return loadClass(name + "$$Impl", codegens);
|
||||||
}
|
}
|
||||||
@@ -217,9 +214,9 @@ public abstract class CodegenTestCase extends LightCodeInsightFixtureTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static class CodegensClassLoader extends ClassLoader {
|
private static class CodegensClassLoader extends ClassLoader {
|
||||||
private final Codegens state;
|
private final ClassFileFactory state;
|
||||||
|
|
||||||
public CodegensClassLoader(Codegens state) {
|
public CodegensClassLoader(ClassFileFactory state) {
|
||||||
super(CodegenTestCase.class.getClassLoader());
|
super(CodegenTestCase.class.getClassLoader());
|
||||||
this.state = state;
|
this.state = state;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ public class PropertyGenTest extends CodegenTestCase {
|
|||||||
|
|
||||||
public void testAbstractVal() throws Exception {
|
public void testAbstractVal() throws Exception {
|
||||||
loadText("class Foo { public abstract val x: String }");
|
loadText("class Foo { public abstract val x: String }");
|
||||||
final Codegens codegens = generateClassesInFile();
|
final ClassFileFactory codegens = generateClassesInFile();
|
||||||
final Class aClass = loadClass("Foo", codegens);
|
final Class aClass = loadClass("Foo", codegens);
|
||||||
assertNotNull(aClass.getMethod("getX"));
|
assertNotNull(aClass.getMethod("getX"));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user