jvm backend: use JvmClassName instead of String
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
+4
-3
@@ -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);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user