jvm backend: use JvmClassName instead of String

This commit is contained in:
Stepan Koltsov
2012-05-21 19:20:23 +04:00
parent 724f69bced
commit 99cc26866e
8 changed files with 71 additions and 58 deletions
@@ -16,9 +16,11 @@
package org.jetbrains.jet.codegen; package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.lang.psi.JetPsiUtil;
import org.jetbrains.jet.lang.resolve.FqName; import org.jetbrains.jet.lang.resolve.FqName;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.*; import java.util.*;
@@ -55,8 +57,8 @@ public class ClassFileFactory {
return answer; return answer;
} }
ClassBuilder forAnonymousSubclass(String className) { ClassBuilder forAnonymousSubclass(@NotNull JvmClassName className) {
return newVisitor(className + ".class"); return newVisitor(className.getInternalName() + ".class");
} }
NamespaceCodegen forNamespace(JetFile file) { NamespaceCodegen forNamespace(JetFile file) {
@@ -25,6 +25,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.FqName; import org.jetbrains.jet.lang.resolve.FqName;
import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.java.JvmAbi;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses; import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
@@ -36,8 +37,8 @@ import java.util.*;
* @author alex.tkachman * @author alex.tkachman
*/ */
public class ClosureAnnotator { public class ClosureAnnotator {
private final Map<JetElement, String> classNamesForAnonymousClasses = new HashMap<JetElement, String>(); private final Map<JetElement, JvmClassName> classNamesForAnonymousClasses = new HashMap<JetElement, JvmClassName>();
private final Map<ClassDescriptor, String> classNamesForClassDescriptor = new HashMap<ClassDescriptor, String>(); private final Map<ClassDescriptor, JvmClassName> classNamesForClassDescriptor = new HashMap<ClassDescriptor, JvmClassName>();
private final Map<String, Integer> anonymousSubclassesCount = new HashMap<String, Integer>(); private final Map<String, Integer> anonymousSubclassesCount = new HashMap<String, Integer>();
private final Map<FunctionDescriptor, ClassDescriptorImpl> classesForFunctions = new HashMap<FunctionDescriptor, ClassDescriptorImpl>(); private final Map<FunctionDescriptor, ClassDescriptorImpl> classesForFunctions = new HashMap<FunctionDescriptor, ClassDescriptorImpl>();
private final Map<DeclarationDescriptor,ClassDescriptor> enclosing = new HashMap<DeclarationDescriptor, ClassDescriptor>(); private final Map<DeclarationDescriptor,ClassDescriptor> enclosing = new HashMap<DeclarationDescriptor, ClassDescriptor>();
@@ -64,7 +65,7 @@ public class ClosureAnnotator {
} }
public ClassDescriptor classDescriptorForFunctionDescriptor(FunctionDescriptor funDescriptor, String name) { public ClassDescriptor classDescriptorForFunctionDescriptor(FunctionDescriptor funDescriptor, JvmClassName name) {
ClassDescriptorImpl classDescriptor = classesForFunctions.get(funDescriptor); ClassDescriptorImpl classDescriptor = classesForFunctions.get(funDescriptor);
if(classDescriptor == null) { if(classDescriptor == null) {
int arity = funDescriptor.getValueParameters().size(); int arity = funDescriptor.getValueParameters().size();
@@ -72,7 +73,8 @@ public class ClosureAnnotator {
classDescriptor = new ClassDescriptorImpl( classDescriptor = new ClassDescriptorImpl(
funDescriptor, funDescriptor,
Collections.<AnnotationDescriptor>emptyList(), Collections.<AnnotationDescriptor>emptyList(),
name); // TODO: internal name used as identifier
name.getInternalName()); // TODO:
classDescriptor.initialize( classDescriptor.initialize(
false, false,
Collections.<TypeParameterDescriptor>emptyList(), Collections.<TypeParameterDescriptor>emptyList(),
@@ -98,7 +100,7 @@ public class ClosureAnnotator {
} }
} }
public String classNameForAnonymousClass(JetElement expression) { public JvmClassName classNameForAnonymousClass(JetElement expression) {
if(expression instanceof JetObjectLiteralExpression) { if(expression instanceof JetObjectLiteralExpression) {
JetObjectLiteralExpression jetObjectLiteralExpression = (JetObjectLiteralExpression) expression; JetObjectLiteralExpression jetObjectLiteralExpression = (JetObjectLiteralExpression) expression;
expression = jetObjectLiteralExpression.getObjectDeclaration(); expression = jetObjectLiteralExpression.getObjectDeclaration();
@@ -109,7 +111,7 @@ public class ClosureAnnotator {
expression = jetFunctionLiteralExpression.getFunctionLiteral(); expression = jetFunctionLiteralExpression.getFunctionLiteral();
} }
String name = classNamesForAnonymousClasses.get(expression); JvmClassName name = classNamesForAnonymousClasses.get(expression);
assert name != null; assert name != null;
return name; return name;
} }
@@ -137,8 +139,8 @@ public class ClosureAnnotator {
} }
} }
private String recordAnonymousClass(JetElement declaration) { private JvmClassName recordAnonymousClass(JetElement declaration) {
String name = classNamesForAnonymousClasses.get(declaration); JvmClassName name = classNamesForAnonymousClasses.get(declaration);
assert name == null; assert name == null;
String top = nameStack.peek(); String top = nameStack.peek();
@@ -146,18 +148,18 @@ public class ClosureAnnotator {
if(cnt == null) { if(cnt == null) {
cnt = 0; cnt = 0;
} }
name = top + "$" + (cnt + 1); name = JvmClassName.byInternalName(top + "$" + (cnt + 1));
classNamesForAnonymousClasses.put(declaration, name); classNamesForAnonymousClasses.put(declaration, name);
anonymousSubclassesCount.put(top, cnt + 1); anonymousSubclassesCount.put(top, cnt + 1);
return name; return name;
} }
private String recordClassObject(JetClassObject declaration) { private JvmClassName recordClassObject(JetClassObject declaration) {
String name = classNamesForAnonymousClasses.get(declaration.getObjectDeclaration()); JvmClassName name = classNamesForAnonymousClasses.get(declaration.getObjectDeclaration());
assert name == null; assert name == null;
name = nameStack.peek() + JvmAbi.CLASS_OBJECT_SUFFIX; name = JvmClassName.byInternalName(nameStack.peek() + JvmAbi.CLASS_OBJECT_SUFFIX);
classNamesForAnonymousClasses.put(declaration.getObjectDeclaration(), name); classNamesForAnonymousClasses.put(declaration.getObjectDeclaration(), name);
return name; return name;
@@ -178,12 +180,12 @@ public class ClosureAnnotator {
@Override @Override
public void visitClassObject(JetClassObject classObject) { public void visitClassObject(JetClassObject classObject) {
String name = recordClassObject(classObject); JvmClassName name = recordClassObject(classObject);
ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, classObject.getObjectDeclaration()); ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, classObject.getObjectDeclaration());
recordEnclosing(classDescriptor); recordEnclosing(classDescriptor);
recordName(classDescriptor, name); recordName(classDescriptor, name);
classStack.push(classDescriptor); classStack.push(classDescriptor);
nameStack.push(name); nameStack.push(name.getInternalName());
super.visitClassObject(classObject); super.visitClassObject(classObject);
nameStack.pop(); nameStack.pop();
classStack.pop(); classStack.pop();
@@ -232,12 +234,12 @@ public class ClosureAnnotator {
@Override @Override
public void visitObjectLiteralExpression(JetObjectLiteralExpression expression) { public void visitObjectLiteralExpression(JetObjectLiteralExpression expression) {
String name = recordAnonymousClass(expression.getObjectDeclaration()); JvmClassName name = recordAnonymousClass(expression.getObjectDeclaration());
ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, expression.getObjectDeclaration()); ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, expression.getObjectDeclaration());
recordName(classDescriptor, name); recordName(classDescriptor, name);
recordEnclosing(classDescriptor); recordEnclosing(classDescriptor);
classStack.push(classDescriptor); classStack.push(classDescriptor);
nameStack.push(classNameForClassDescriptor(classDescriptor)); nameStack.push(classNameForClassDescriptor(classDescriptor).getInternalName());
super.visitObjectLiteralExpression(expression); super.visitObjectLiteralExpression(expression);
nameStack.pop(); nameStack.pop();
classStack.pop(); classStack.pop();
@@ -245,7 +247,7 @@ public class ClosureAnnotator {
@Override @Override
public void visitFunctionLiteralExpression(JetFunctionLiteralExpression expression) { public void visitFunctionLiteralExpression(JetFunctionLiteralExpression expression) {
String name = recordAnonymousClass(expression.getFunctionLiteral()); JvmClassName name = recordAnonymousClass(expression.getFunctionLiteral());
FunctionDescriptor declarationDescriptor = (FunctionDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, expression); FunctionDescriptor declarationDescriptor = (FunctionDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, expression);
// working around a problem with shallow analysis // working around a problem with shallow analysis
if (declarationDescriptor == null) return; if (declarationDescriptor == null) return;
@@ -253,7 +255,7 @@ public class ClosureAnnotator {
recordName(classDescriptor, name); recordName(classDescriptor, name);
recordEnclosing(classDescriptor); recordEnclosing(classDescriptor);
classStack.push(classDescriptor); classStack.push(classDescriptor);
nameStack.push(classNameForClassDescriptor(classDescriptor)); nameStack.push(classNameForClassDescriptor(classDescriptor).getInternalName());
super.visitFunctionLiteralExpression(expression); super.visitFunctionLiteralExpression(expression);
nameStack.pop(); nameStack.pop();
classStack.pop(); classStack.pop();
@@ -261,8 +263,8 @@ public class ClosureAnnotator {
// TODO: please insert either @NotNull or @Nullable here // TODO: please insert either @NotNull or @Nullable here
// stepan.koltsov@ 2012-04-08 // stepan.koltsov@ 2012-04-08
private void recordName(ClassDescriptor classDescriptor, @NotNull String name) { private void recordName(ClassDescriptor classDescriptor, @NotNull JvmClassName name) {
String old = classNamesForClassDescriptor.put(classDescriptor, name); JvmClassName old = classNamesForClassDescriptor.put(classDescriptor, name);
if (old == null) { if (old == null) {
// TODO: fix this assertion // TODO: fix this assertion
// previosly here was incorrect assert that was ignored without -ea // previosly here was incorrect assert that was ignored without -ea
@@ -300,12 +302,12 @@ public class ClosureAnnotator {
nameStack.pop(); nameStack.pop();
} }
else { else {
String name = recordAnonymousClass(function); JvmClassName name = recordAnonymousClass(function);
ClassDescriptor classDescriptor = classDescriptorForFunctionDescriptor(functionDescriptor, name); ClassDescriptor classDescriptor = classDescriptorForFunctionDescriptor(functionDescriptor, name);
recordName(classDescriptor, name); recordName(classDescriptor, name);
recordEnclosing(classDescriptor); recordEnclosing(classDescriptor);
classStack.push(classDescriptor); classStack.push(classDescriptor);
nameStack.push(name); nameStack.push(name.getInternalName());
super.visitNamedFunction(function); super.visitNamedFunction(function);
nameStack.pop(); nameStack.pop();
classStack.pop(); classStack.pop();
@@ -313,8 +315,8 @@ public class ClosureAnnotator {
} }
} }
public String classNameForClassDescriptor(ClassDescriptor classDescriptor) { public JvmClassName classNameForClassDescriptor(ClassDescriptor classDescriptor) {
String name = classNamesForClassDescriptor.get(classDescriptor); JvmClassName name = classNamesForClassDescriptor.get(classDescriptor);
assert name != null; assert name != null;
return name; return name;
} }
@@ -31,6 +31,7 @@ import org.jetbrains.jet.lang.psi.JetElement;
import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.lang.JetStandardClasses; import org.jetbrains.jet.lang.types.lang.JetStandardClasses;
@@ -102,7 +103,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
} }
public GeneratedAnonymousClassDescriptor gen(JetExpression fun) { public GeneratedAnonymousClassDescriptor gen(JetExpression fun) {
final Pair<String, ClassBuilder> nameAndVisitor = state.forAnonymousSubclass(fun); final Pair<JvmClassName, ClassBuilder> nameAndVisitor = state.forAnonymousSubclass(fun);
final FunctionDescriptor funDescriptor = (FunctionDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, fun); final FunctionDescriptor funDescriptor = (FunctionDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, fun);
@@ -124,7 +125,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
cv.defineClass(fun, cv.defineClass(fun,
V1_6, V1_6,
ACC_PUBLIC/*|ACC_SUPER*/, ACC_PUBLIC/*|ACC_SUPER*/,
name, name.getInternalName(),
null, null,
funClass, funClass,
new String[0] new String[0]
@@ -132,7 +133,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
cv.visitSource(fun.getContainingFile().getName(), null); cv.visitSource(fun.getContainingFile().getName(), null);
generateBridge(name, funDescriptor, fun, cv); generateBridge(name.getInternalName(), funDescriptor, fun, cv);
captureThis = generateBody(funDescriptor, cv, (JetDeclarationWithBody) fun); captureThis = generateBody(funDescriptor, cv, (JetDeclarationWithBody) fun);
ClassDescriptor thisDescriptor = context.getThisDescriptor(); ClassDescriptor thisDescriptor = context.getThisDescriptor();
final Type enclosingType = thisDescriptor == null ? null : state.getInjector().getJetTypeMapper().mapType(thisDescriptor.getDefaultType(), MapTypeMode.VALUE); final Type enclosingType = thisDescriptor == null ? null : state.getInjector().getJetTypeMapper().mapType(thisDescriptor.getDefaultType(), MapTypeMode.VALUE);
@@ -166,7 +167,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
} }
private void generateConstInstance(PsiElement fun) { private void generateConstInstance(PsiElement fun) {
String classDescr = "L" + name + ";"; String classDescr = name.getDescriptor();
cv.newField(fun, ACC_PRIVATE | ACC_STATIC | ACC_FINAL, "$instance", classDescr, null, null); cv.newField(fun, ACC_PRIVATE | ACC_STATIC | ACC_FINAL, "$instance", classDescr, null, null);
MethodVisitor mv = cv.newMethod(fun, ACC_PUBLIC | ACC_STATIC, "$getInstance", "()" + classDescr, null, new String[0]); MethodVisitor mv = cv.newMethod(fun, ACC_PUBLIC | ACC_STATIC, "$getInstance", "()" + classDescr, null, new String[0]);
@@ -175,17 +176,17 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
} }
else if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { else if (state.getClassBuilderMode() == ClassBuilderMode.FULL) {
mv.visitCode(); mv.visitCode();
mv.visitFieldInsn(GETSTATIC, name, "$instance", classDescr); mv.visitFieldInsn(GETSTATIC, name.getInternalName(), "$instance", classDescr);
mv.visitInsn(DUP); mv.visitInsn(DUP);
Label ret = new Label(); Label ret = new Label();
mv.visitJumpInsn(IFNONNULL, ret); mv.visitJumpInsn(IFNONNULL, ret);
mv.visitInsn(POP); mv.visitInsn(POP);
mv.visitTypeInsn(NEW, name); mv.visitTypeInsn(NEW, name.getInternalName());
mv.visitInsn(DUP); mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKESPECIAL, name, "<init>", "()V"); mv.visitMethodInsn(INVOKESPECIAL, name.getInternalName(), "<init>", "()V");
mv.visitInsn(DUP); mv.visitInsn(DUP);
mv.visitFieldInsn(PUTSTATIC, name, "$instance", classDescr); mv.visitFieldInsn(PUTSTATIC, name.getInternalName(), "$instance", classDescr);
mv.visitLabel(ret); mv.visitLabel(ret);
mv.visitInsn(ARETURN); mv.visitInsn(ARETURN);
@@ -196,7 +197,8 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
private Type generateBody(FunctionDescriptor funDescriptor, ClassBuilder cv, JetDeclarationWithBody body) { private Type generateBody(FunctionDescriptor funDescriptor, ClassBuilder cv, JetDeclarationWithBody body) {
ClassDescriptor function = state.getInjector().getJetTypeMapper().getClosureAnnotator().classDescriptorForFunctionDescriptor(funDescriptor, name); ClassDescriptor function = state.getInjector().getJetTypeMapper().getClosureAnnotator().classDescriptorForFunctionDescriptor(funDescriptor, name);
final CodegenContext.ClosureContext closureContext = context.intoClosure(funDescriptor, function, name, this, state.getInjector().getJetTypeMapper()); final CodegenContext.ClosureContext closureContext = context.intoClosure(
funDescriptor, function, name.getInternalName(), this, state.getInjector().getJetTypeMapper());
FunctionCodegen fc = new FunctionCodegen(closureContext, cv, state); FunctionCodegen fc = new FunctionCodegen(closureContext, cv, state);
JvmMethodSignature jvmMethodSignature = invokeSignature(funDescriptor); JvmMethodSignature jvmMethodSignature = invokeSignature(funDescriptor);
fc.generateMethod(body, jvmMethodSignature, false, null, funDescriptor); fc.generateMethod(body, jvmMethodSignature, false, null, funDescriptor);
@@ -289,7 +291,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
argTypes[i++] = type; argTypes[i++] = type;
} }
else if(CodegenUtil.isNamedFun(descriptor, state.getBindingContext()) && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) { else if(CodegenUtil.isNamedFun(descriptor, state.getBindingContext()) && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) {
final Type type = Type.getObjectType(state.getInjector().getJetTypeMapper().getClosureAnnotator().classNameForAnonymousClass((JetElement) BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor))); final Type type = state.getInjector().getJetTypeMapper().getClosureAnnotator().classNameForAnonymousClass((JetElement) BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor)).getAsmType();
argTypes[i++] = type; argTypes[i++] = type;
} }
} }
@@ -325,7 +327,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
} }
i += type.getSize(); i += type.getSize();
StackValue.field(type, name, fieldName, false).store(iv); StackValue.field(type, name.getInternalName(), fieldName, false).store(iv);
} }
iv.visitInsn(RETURN); iv.visitInsn(RETURN);
@@ -752,10 +752,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
final GeneratedAnonymousClassDescriptor closure = closureCodegen.gen(expression); final GeneratedAnonymousClassDescriptor closure = closureCodegen.gen(expression);
if(closureCodegen.isConst()) { if(closureCodegen.isConst()) {
v.invokestatic(closure.getClassname(), "$getInstance", "()L" + closure.getClassname() + ";"); v.invokestatic(closure.getClassname().getInternalName(), "$getInstance", "()" + closure.getClassname().getDescriptor());
} }
else { else {
v.anew(Type.getObjectType(closure.getClassname())); v.anew(closure.getClassname().getAsmType());
v.dup(); v.dup();
final Method cons = closure.getConstructor(); final Method cons = closure.getConstructor();
@@ -776,16 +776,16 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
arg.put(cons.getArgumentTypes()[i+k], v); arg.put(cons.getArgumentTypes()[i+k], v);
} }
v.invokespecial(closure.getClassname(), "<init>", cons.getDescriptor()); v.invokespecial(closure.getClassname().getInternalName(), "<init>", cons.getDescriptor());
} }
return StackValue.onStack(Type.getObjectType(closure.getClassname())); return StackValue.onStack(closure.getClassname().getAsmType());
} }
@Override @Override
public StackValue visitObjectLiteralExpression(JetObjectLiteralExpression expression, StackValue receiver) { public StackValue visitObjectLiteralExpression(JetObjectLiteralExpression expression, StackValue receiver) {
ObjectOrClosureCodegen closureCodegen = new ObjectOrClosureCodegen(this, context, state); ObjectOrClosureCodegen closureCodegen = new ObjectOrClosureCodegen(this, context, state);
GeneratedAnonymousClassDescriptor closure = state.generateObjectLiteral(expression, closureCodegen); GeneratedAnonymousClassDescriptor closure = state.generateObjectLiteral(expression, closureCodegen);
Type type = Type.getObjectType(closure.getClassname()); Type type = closure.getClassname().getAsmType();
v.anew(type); v.anew(type);
v.dup(); v.dup();
final List<Type> consArgTypes = new LinkedList<Type>(Arrays.asList(closure.getConstructor().getArgumentTypes())); final List<Type> consArgTypes = new LinkedList<Type>(Arrays.asList(closure.getConstructor().getArgumentTypes()));
@@ -819,8 +819,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
} }
Method cons = new Method("<init>", Type.VOID_TYPE, consArgTypes.toArray(new Type[consArgTypes.size()])); Method cons = new Method("<init>", Type.VOID_TYPE, consArgTypes.toArray(new Type[consArgTypes.size()]));
v.invokespecial(closure.getClassname(), "<init>", cons.getDescriptor()); v.invokespecial(closure.getClassname().getInternalName(), "<init>", cons.getDescriptor());
return StackValue.onStack(Type.getObjectType(closure.getClassname())); return StackValue.onStack(closure.getClassname().getAsmType());
} }
private Label continueLabel; private Label continueLabel;
@@ -19,6 +19,7 @@
*/ */
package org.jetbrains.jet.codegen; package org.jetbrains.jet.codegen;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
import org.objectweb.asm.commons.Method; import org.objectweb.asm.commons.Method;
@@ -26,20 +27,20 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
public class GeneratedAnonymousClassDescriptor { public class GeneratedAnonymousClassDescriptor {
private final String classname; private final JvmClassName classname;
private Method constructor; private Method constructor;
private final Type captureThis; private final Type captureThis;
private final Type captureReceiver; private final Type captureReceiver;
private List<StackValue> args = new ArrayList<StackValue>(); private List<StackValue> args = new ArrayList<StackValue>();
public GeneratedAnonymousClassDescriptor(String classname, Method constructor, Type captureThis, Type captureReceiver) { public GeneratedAnonymousClassDescriptor(JvmClassName classname, Method constructor, Type captureThis, Type captureReceiver) {
this.classname = classname; this.classname = classname;
this.constructor = constructor; this.constructor = constructor;
this.captureThis = captureThis; this.captureThis = captureThis;
this.captureReceiver = captureReceiver; this.captureReceiver = captureReceiver;
} }
public String getClassname() { public JvmClassName getClassname() {
return classname; return classname;
} }
@@ -36,6 +36,7 @@ import org.jetbrains.jet.lang.psi.JetObjectDeclaration;
import org.jetbrains.jet.lang.psi.JetObjectLiteralExpression; import org.jetbrains.jet.lang.psi.JetObjectLiteralExpression;
import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode; import org.jetbrains.jet.lang.resolve.java.CompilerSpecialMode;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.jetbrains.jet.utils.Progress; import org.jetbrains.jet.utils.Progress;
import java.util.List; import java.util.List;
@@ -99,8 +100,8 @@ public class GenerationState {
return getFactory().newVisitor(getInjector().getJetTypeMapper().mapType(aClass.getDefaultType(), MapTypeMode.TRAIT_IMPL).getInternalName() + ".class"); return getFactory().newVisitor(getInjector().getJetTypeMapper().mapType(aClass.getDefaultType(), MapTypeMode.TRAIT_IMPL).getInternalName() + ".class");
} }
public Pair<String, ClassBuilder> forAnonymousSubclass(JetExpression expression) { public Pair<JvmClassName, ClassBuilder> forAnonymousSubclass(JetExpression expression) {
String className = getInjector().getJetTypeMapper().getClosureAnnotator().classNameForAnonymousClass(expression); JvmClassName className = getInjector().getJetTypeMapper().getClosureAnnotator().classNameForAnonymousClass(expression);
return Pair.create(className, getFactory().forAnonymousSubclass(className)); return Pair.create(className, getFactory().forAnonymousSubclass(className));
} }
@@ -137,7 +138,7 @@ public class GenerationState {
public GeneratedAnonymousClassDescriptor generateObjectLiteral(JetObjectLiteralExpression literal, ObjectOrClosureCodegen closure) { public GeneratedAnonymousClassDescriptor generateObjectLiteral(JetObjectLiteralExpression literal, ObjectOrClosureCodegen closure) {
JetObjectDeclaration objectDeclaration = literal.getObjectDeclaration(); JetObjectDeclaration objectDeclaration = literal.getObjectDeclaration();
Pair<String, ClassBuilder> nameAndVisitor = forAnonymousSubclass(objectDeclaration); Pair<JvmClassName, ClassBuilder> nameAndVisitor = forAnonymousSubclass(objectDeclaration);
closure.cv = nameAndVisitor.getSecond(); closure.cv = nameAndVisitor.getSecond();
closure.name = nameAndVisitor.getFirst(); closure.name = nameAndVisitor.getFirst();
@@ -320,7 +320,9 @@ public class JetTypeMapper {
DeclarationDescriptor container = descriptor.getContainingDeclaration(); DeclarationDescriptor container = descriptor.getContainingDeclaration();
String name = descriptor.getName(); String name = descriptor.getName();
if(JetPsiUtil.NO_NAME_PROVIDED.equals(name)) { if(JetPsiUtil.NO_NAME_PROVIDED.equals(name)) {
return closureAnnotator.classNameForAnonymousClass((JetElement) BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor)); return closureAnnotator
.classNameForAnonymousClass((JetElement) BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor))
.getInternalName();
} }
if(name.contains("/")) if(name.contains("/"))
return name; return name;
@@ -978,7 +980,7 @@ public class JetTypeMapper {
} }
else if (descriptor instanceof SimpleFunctionDescriptor && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) { else if (descriptor instanceof SimpleFunctionDescriptor && descriptor.getContainingDeclaration() instanceof FunctionDescriptor) {
PsiElement psiElement = BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor); PsiElement psiElement = BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor);
return Type.getObjectType(closureAnnotator.classNameForAnonymousClass((JetElement) psiElement)); return closureAnnotator.classNameForAnonymousClass((JetElement) psiElement).getAsmType();
} }
else if (descriptor instanceof FunctionDescriptor) { else if (descriptor instanceof FunctionDescriptor) {
return StackValue.sharedTypeForType(mapType(((FunctionDescriptor) descriptor).getReceiverParameter().getType(), MapTypeMode.VALUE)); return StackValue.sharedTypeForType(mapType(((FunctionDescriptor) descriptor).getReceiverParameter().getType(), MapTypeMode.VALUE));
@@ -20,6 +20,7 @@ import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.JetDelegatorToSuperCall; import org.jetbrains.jet.lang.psi.JetDelegatorToSuperCall;
import org.jetbrains.jet.lang.psi.JetElement; import org.jetbrains.jet.lang.psi.JetElement;
import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.java.JvmClassName;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
@@ -37,7 +38,7 @@ public class ObjectOrClosureCodegen {
protected final ExpressionCodegen exprContext; protected final ExpressionCodegen exprContext;
protected final CodegenContext context; protected final CodegenContext context;
protected ClassBuilder cv = null; protected ClassBuilder cv = null;
public String name = null; public JvmClassName name = null;
protected Map<DeclarationDescriptor, EnclosedValueDescriptor> closure = new LinkedHashMap<DeclarationDescriptor, EnclosedValueDescriptor>(); protected Map<DeclarationDescriptor, EnclosedValueDescriptor> closure = new LinkedHashMap<DeclarationDescriptor, EnclosedValueDescriptor>();
public JetDelegatorToSuperCall superCall; public JetDelegatorToSuperCall superCall;
@@ -66,7 +67,9 @@ public class ObjectOrClosureCodegen {
StackValue outerValue = StackValue.local(idx, type); StackValue outerValue = StackValue.local(idx, type);
final String fieldName = "$" + vd.getName(); final String fieldName = "$" + vd.getName();
StackValue innerValue = sharedVarType != null ? StackValue.fieldForSharedVar(localType, name, fieldName) : StackValue.field(type, name, fieldName, false); StackValue innerValue = sharedVarType != null
? StackValue.fieldForSharedVar(localType, name.getInternalName(), fieldName)
: StackValue.field(type, name.getInternalName(), fieldName, false);
cv.newField(null, Opcodes.ACC_PUBLIC, fieldName, type.getDescriptor(), null, null); cv.newField(null, Opcodes.ACC_PUBLIC, fieldName, type.getDescriptor(), null, null);
@@ -83,12 +86,12 @@ public class ObjectOrClosureCodegen {
if (idx < 0) return null; if (idx < 0) return null;
JetElement expression = (JetElement) BindingContextUtils.callableDescriptorToDeclaration(state.getBindingContext(), vd); JetElement expression = (JetElement) BindingContextUtils.callableDescriptorToDeclaration(state.getBindingContext(), vd);
String cn = state.getInjector().getJetTypeMapper().getClosureAnnotator().classNameForAnonymousClass(expression); JvmClassName cn = state.getInjector().getJetTypeMapper().getClosureAnnotator().classNameForAnonymousClass(expression);
Type localType = Type.getObjectType(cn); Type localType = cn.getAsmType();
StackValue outerValue = StackValue.local(idx, localType); StackValue outerValue = StackValue.local(idx, localType);
final String fieldName = "$" + vd.getName(); final String fieldName = "$" + vd.getName();
StackValue innerValue = StackValue.field(localType, name, fieldName, false); StackValue innerValue = StackValue.field(localType, name.getInternalName(), fieldName, false);
cv.newField(null, Opcodes.ACC_PUBLIC, fieldName, localType.getDescriptor(), null, null); cv.newField(null, Opcodes.ACC_PUBLIC, fieldName, localType.getDescriptor(), null, null);
@@ -114,7 +117,7 @@ public class ObjectOrClosureCodegen {
boolean isStatic = fcontext.getContextDescriptor().getContainingDeclaration() instanceof NamespaceDescriptor; boolean isStatic = fcontext.getContextDescriptor().getContainingDeclaration() instanceof NamespaceDescriptor;
StackValue outerValue = StackValue.local(isStatic ? 0 : 1, type); StackValue outerValue = StackValue.local(isStatic ? 0 : 1, type);
final String fieldName = "receiver$0"; final String fieldName = "receiver$0";
StackValue innerValue = StackValue.field(type, name, fieldName, false); StackValue innerValue = StackValue.field(type, name.getInternalName(), fieldName, false);
cv.newField(null, Opcodes.ACC_PUBLIC, fieldName, type.getDescriptor(), null, null); cv.newField(null, Opcodes.ACC_PUBLIC, fieldName, type.getDescriptor(), null, null);