Merge remote branch 'origin/master'

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