local classes without closures
This commit is contained in:
@@ -37,10 +37,11 @@ import java.util.*;
|
|||||||
* @author alex.tkachman
|
* @author alex.tkachman
|
||||||
*/
|
*/
|
||||||
public class ClosureAnnotator {
|
public class ClosureAnnotator {
|
||||||
private final Map<JetElement, JvmClassName> classNamesForAnonymousClasses = new HashMap<JetElement, JvmClassName>();
|
|
||||||
private final Map<ClassDescriptor, JvmClassName> classNamesForClassDescriptor = new HashMap<ClassDescriptor, JvmClassName>();
|
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<ScriptDescriptor, JvmClassName> classNameForScript = new HashMap<ScriptDescriptor, JvmClassName>();
|
private final Map<ScriptDescriptor, JvmClassName> classNameForScript = new HashMap<ScriptDescriptor, JvmClassName>();
|
||||||
|
private final Map<ClassDescriptor, LocalClassClosureCodegen> localClassCodegenForClass =
|
||||||
|
new HashMap<ClassDescriptor, LocalClassClosureCodegen>();
|
||||||
private final Set<JvmClassName> scriptClassNames = new HashSet<JvmClassName>();
|
private final Set<JvmClassName> scriptClassNames = new HashSet<JvmClassName>();
|
||||||
private final Map<DeclarationDescriptor, ClassDescriptorImpl> classesForFunctions =
|
private final Map<DeclarationDescriptor, ClassDescriptorImpl> classesForFunctions =
|
||||||
new HashMap<DeclarationDescriptor, ClassDescriptorImpl>();
|
new HashMap<DeclarationDescriptor, ClassDescriptorImpl>();
|
||||||
@@ -69,7 +70,8 @@ public class ClosureAnnotator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public ClassDescriptor classDescriptorForFunctionDescriptor(FunctionDescriptor funDescriptor, JvmClassName name) {
|
@NotNull
|
||||||
|
public ClassDescriptor classDescriptorForFunctionDescriptor(FunctionDescriptor funDescriptor) {
|
||||||
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();
|
||||||
@@ -79,7 +81,6 @@ public class ClosureAnnotator {
|
|||||||
Collections.<AnnotationDescriptor>emptyList(),
|
Collections.<AnnotationDescriptor>emptyList(),
|
||||||
Modality.FINAL,
|
Modality.FINAL,
|
||||||
Name.special("<closure>"));
|
Name.special("<closure>"));
|
||||||
recordName(classDescriptor, name);
|
|
||||||
classDescriptor.initialize(
|
classDescriptor.initialize(
|
||||||
false,
|
false,
|
||||||
Collections.<TypeParameterDescriptor>emptyList(),
|
Collections.<TypeParameterDescriptor>emptyList(),
|
||||||
@@ -204,14 +205,13 @@ public class ClosureAnnotator {
|
|||||||
expression = jetObjectLiteralExpression.getObjectDeclaration();
|
expression = jetObjectLiteralExpression.getObjectDeclaration();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expression instanceof JetFunctionLiteralExpression) {
|
ClassDescriptor descriptor = bindingContext.get(BindingContext.CLASS, expression);
|
||||||
JetFunctionLiteralExpression jetFunctionLiteralExpression = (JetFunctionLiteralExpression) expression;
|
if (descriptor == null) {
|
||||||
expression = jetFunctionLiteralExpression.getFunctionLiteral();
|
SimpleFunctionDescriptor functionDescriptor = bindingContext.get(BindingContext.FUNCTION, expression);
|
||||||
|
assert functionDescriptor != null;
|
||||||
|
descriptor = classDescriptorForFunctionDescriptor(functionDescriptor);
|
||||||
}
|
}
|
||||||
|
return classNameForClassDescriptor(descriptor);
|
||||||
JvmClassName name = classNamesForAnonymousClasses.get(expression);
|
|
||||||
assert name != null;
|
|
||||||
return name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ClassDescriptor getEclosingClassDescriptor(ClassDescriptor descriptor) {
|
public ClassDescriptor getEclosingClassDescriptor(ClassDescriptor descriptor) {
|
||||||
@@ -240,6 +240,11 @@ public class ClosureAnnotator {
|
|||||||
return aBoolean != null && aBoolean;
|
return aBoolean != null && aBoolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void recordLocalClass(ClassDescriptor descriptor, LocalClassClosureCodegen codegen) {
|
||||||
|
LocalClassClosureCodegen put = localClassCodegenForClass.put(descriptor, codegen);
|
||||||
|
assert put == null;
|
||||||
|
}
|
||||||
|
|
||||||
private class MyJetVisitorVoid extends JetVisitorVoid {
|
private class MyJetVisitorVoid extends JetVisitorVoid {
|
||||||
private final LinkedList<ClassDescriptor> classStack = new LinkedList<ClassDescriptor>();
|
private final LinkedList<ClassDescriptor> classStack = new LinkedList<ClassDescriptor>();
|
||||||
private final LinkedList<String> nameStack = new LinkedList<String>();
|
private final LinkedList<String> nameStack = new LinkedList<String>();
|
||||||
@@ -252,28 +257,41 @@ public class ClosureAnnotator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private JvmClassName recordAnonymousClass(JetElement declaration) {
|
private JvmClassName recordAnonymousClass(JetElement declaration) {
|
||||||
JvmClassName name = classNamesForAnonymousClasses.get(declaration);
|
|
||||||
assert name == null;
|
|
||||||
|
|
||||||
String top = nameStack.peek();
|
String top = nameStack.peek();
|
||||||
Integer cnt = anonymousSubclassesCount.get(top);
|
Integer cnt = anonymousSubclassesCount.get(top);
|
||||||
if (cnt == null) {
|
if (cnt == null) {
|
||||||
cnt = 0;
|
cnt = 0;
|
||||||
}
|
}
|
||||||
name = JvmClassName.byInternalName(top + "$" + (cnt + 1));
|
JvmClassName name = JvmClassName.byInternalName(top + "$" + (cnt + 1));
|
||||||
classNamesForAnonymousClasses.put(declaration, name);
|
ClassDescriptor descriptor = bindingContext.get(BindingContext.CLASS, declaration);
|
||||||
|
if (descriptor == null) {
|
||||||
|
if (declaration instanceof JetFunctionLiteralExpression || declaration instanceof JetNamedFunction) {
|
||||||
|
DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.FUNCTION, declaration);
|
||||||
|
assert declarationDescriptor instanceof FunctionDescriptor;
|
||||||
|
descriptor = classDescriptorForFunctionDescriptor((FunctionDescriptor) declarationDescriptor);
|
||||||
|
}
|
||||||
|
else if (declaration instanceof JetObjectLiteralExpression) {
|
||||||
|
descriptor =
|
||||||
|
bindingContext.get(BindingContext.CLASS, ((JetObjectLiteralExpression) declaration).getObjectDeclaration());
|
||||||
|
assert descriptor != null;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"Class-less declaration which is not JetFunctionLiteralExpression|JetNamedFunction|JetObjectLiteralExpression : " +
|
||||||
|
declaration.getClass().getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
recordName(descriptor, name);
|
||||||
anonymousSubclassesCount.put(top, cnt + 1);
|
anonymousSubclassesCount.put(top, cnt + 1);
|
||||||
|
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
private JvmClassName recordClassObject(JetClassObject declaration) {
|
private JvmClassName recordClassObject(JetClassObject declaration) {
|
||||||
JvmClassName name = classNamesForAnonymousClasses.get(declaration.getObjectDeclaration());
|
JvmClassName name = JvmClassName.byInternalName(nameStack.peek() + JvmAbi.CLASS_OBJECT_SUFFIX);
|
||||||
assert name == null;
|
ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, declaration.getObjectDeclaration());
|
||||||
|
assert classDescriptor != null;
|
||||||
name = JvmClassName.byInternalName(nameStack.peek() + JvmAbi.CLASS_OBJECT_SUFFIX);
|
recordName(classDescriptor, name);
|
||||||
classNamesForAnonymousClasses.put(declaration.getObjectDeclaration(), name);
|
|
||||||
|
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -309,7 +327,6 @@ public class ClosureAnnotator {
|
|||||||
ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, classObject.getObjectDeclaration());
|
ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, classObject.getObjectDeclaration());
|
||||||
assert classDescriptor != null;
|
assert classDescriptor != null;
|
||||||
recordEnclosing(classDescriptor);
|
recordEnclosing(classDescriptor);
|
||||||
recordName(classDescriptor, name);
|
|
||||||
classStack.push(classDescriptor);
|
classStack.push(classDescriptor);
|
||||||
nameStack.push(name.getInternalName());
|
nameStack.push(name.getInternalName());
|
||||||
super.visitClassObject(classObject);
|
super.visitClassObject(classObject);
|
||||||
@@ -335,6 +352,7 @@ public class ClosureAnnotator {
|
|||||||
else {
|
else {
|
||||||
nameStack.push(base + '$' + classDescriptor.getName());
|
nameStack.push(base + '$' + classDescriptor.getName());
|
||||||
}
|
}
|
||||||
|
recordName(classDescriptor, JvmClassName.byInternalName(nameStack.peek()));
|
||||||
super.visitObjectDeclaration(declaration);
|
super.visitObjectDeclaration(declaration);
|
||||||
nameStack.pop();
|
nameStack.pop();
|
||||||
classStack.pop();
|
classStack.pop();
|
||||||
@@ -355,6 +373,7 @@ public class ClosureAnnotator {
|
|||||||
else {
|
else {
|
||||||
nameStack.push(base + '$' + classDescriptor.getName());
|
nameStack.push(base + '$' + classDescriptor.getName());
|
||||||
}
|
}
|
||||||
|
recordName(classDescriptor, JvmClassName.byInternalName(nameStack.peek()));
|
||||||
super.visitClass(klass);
|
super.visitClass(klass);
|
||||||
nameStack.pop();
|
nameStack.pop();
|
||||||
classStack.pop();
|
classStack.pop();
|
||||||
@@ -362,13 +381,13 @@ public class ClosureAnnotator {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitObjectLiteralExpression(JetObjectLiteralExpression expression) {
|
public void visitObjectLiteralExpression(JetObjectLiteralExpression expression) {
|
||||||
JvmClassName name = recordAnonymousClass(expression.getObjectDeclaration());
|
|
||||||
ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, expression.getObjectDeclaration());
|
ClassDescriptor classDescriptor = bindingContext.get(BindingContext.CLASS, expression.getObjectDeclaration());
|
||||||
if (classDescriptor == null) {
|
if (classDescriptor == null) {
|
||||||
|
// working around a problem with shallow analysis
|
||||||
super.visitObjectLiteralExpression(expression);
|
super.visitObjectLiteralExpression(expression);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
recordName(classDescriptor, name);
|
recordAnonymousClass(expression.getObjectDeclaration());
|
||||||
recordEnclosing(classDescriptor);
|
recordEnclosing(classDescriptor);
|
||||||
classStack.push(classDescriptor);
|
classStack.push(classDescriptor);
|
||||||
nameStack.push(classNameForClassDescriptor(classDescriptor).getInternalName());
|
nameStack.push(classNameForClassDescriptor(classDescriptor).getInternalName());
|
||||||
@@ -379,15 +398,15 @@ public class ClosureAnnotator {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitFunctionLiteralExpression(JetFunctionLiteralExpression expression) {
|
public void visitFunctionLiteralExpression(JetFunctionLiteralExpression expression) {
|
||||||
JvmClassName name = recordAnonymousClass(expression.getFunctionLiteral());
|
FunctionDescriptor functionDescriptor =
|
||||||
FunctionDescriptor declarationDescriptor =
|
|
||||||
(FunctionDescriptor) bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, expression);
|
(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 (functionDescriptor == null) return;
|
||||||
ClassDescriptor classDescriptor = classDescriptorForFunctionDescriptor(declarationDescriptor, name);
|
JvmClassName name = recordAnonymousClass(expression);
|
||||||
|
ClassDescriptor classDescriptor = classDescriptorForFunctionDescriptor(functionDescriptor);
|
||||||
recordEnclosing(classDescriptor);
|
recordEnclosing(classDescriptor);
|
||||||
classStack.push(classDescriptor);
|
classStack.push(classDescriptor);
|
||||||
nameStack.push(classNameForClassDescriptor(classDescriptor).getInternalName());
|
nameStack.push(name.getInternalName());
|
||||||
super.visitFunctionLiteralExpression(expression);
|
super.visitFunctionLiteralExpression(expression);
|
||||||
nameStack.pop();
|
nameStack.pop();
|
||||||
classStack.pop();
|
classStack.pop();
|
||||||
@@ -426,7 +445,7 @@ public class ClosureAnnotator {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
JvmClassName name = recordAnonymousClass(function);
|
JvmClassName name = recordAnonymousClass(function);
|
||||||
ClassDescriptor classDescriptor = classDescriptorForFunctionDescriptor(functionDescriptor, name);
|
ClassDescriptor classDescriptor = classDescriptorForFunctionDescriptor(functionDescriptor);
|
||||||
recordEnclosing(classDescriptor);
|
recordEnclosing(classDescriptor);
|
||||||
classStack.push(classDescriptor);
|
classStack.push(classDescriptor);
|
||||||
nameStack.push(name.getInternalName());
|
nameStack.push(name.getInternalName());
|
||||||
@@ -444,7 +463,6 @@ public class ClosureAnnotator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public JvmClassName classNameForClassDescriptor(@NotNull ClassDescriptor classDescriptor) {
|
public JvmClassName classNameForClassDescriptor(@NotNull ClassDescriptor classDescriptor) {
|
||||||
return classNamesForClassDescriptor.get(classDescriptor);
|
return classNamesForClassDescriptor.get(classDescriptor);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,10 +51,14 @@ import static org.jetbrains.asm4.Opcodes.*;
|
|||||||
public class ClosureCodegen extends ObjectOrClosureCodegen {
|
public class ClosureCodegen extends ObjectOrClosureCodegen {
|
||||||
|
|
||||||
private final BindingContext bindingContext;
|
private final BindingContext bindingContext;
|
||||||
|
private final ClosureAnnotator closureAnnotator;
|
||||||
|
private final JetTypeMapper typeMapper;
|
||||||
|
|
||||||
public ClosureCodegen(GenerationState state, ExpressionCodegen exprContext, CodegenContext context) {
|
public ClosureCodegen(GenerationState state, ExpressionCodegen exprContext, CodegenContext context) {
|
||||||
super(exprContext, context, state);
|
super(exprContext, context, state);
|
||||||
bindingContext = state.getBindingContext();
|
bindingContext = state.getBindingContext();
|
||||||
|
typeMapper = this.state.getInjector().getJetTypeMapper();
|
||||||
|
closureAnnotator = typeMapper.getClosureAnnotator();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JvmMethodSignature erasedInvokeSignature(FunctionDescriptor fd) {
|
public static JvmMethodSignature erasedInvokeSignature(FunctionDescriptor fd) {
|
||||||
@@ -103,13 +107,13 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public JvmMethodSignature invokeSignature(FunctionDescriptor fd) {
|
public JvmMethodSignature invokeSignature(FunctionDescriptor fd) {
|
||||||
return state.getInjector().getJetTypeMapper().mapSignature(Name.identifier("invoke"), fd);
|
return typeMapper.mapSignature(Name.identifier("invoke"), fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GeneratedAnonymousClassDescriptor gen(JetExpression fun) {
|
public GeneratedAnonymousClassDescriptor gen(JetExpression fun) {
|
||||||
final Pair<JvmClassName, 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 = bindingContext.get(BindingContext.FUNCTION, fun);
|
||||||
|
|
||||||
cv = nameAndVisitor.getSecond();
|
cv = nameAndVisitor.getSecond();
|
||||||
name = nameAndVisitor.getFirst();
|
name = nameAndVisitor.getFirst();
|
||||||
@@ -143,7 +147,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
|||||||
ClassDescriptor thisDescriptor = context.getThisDescriptor();
|
ClassDescriptor thisDescriptor = context.getThisDescriptor();
|
||||||
final Type enclosingType = thisDescriptor == null
|
final Type enclosingType = thisDescriptor == null
|
||||||
? null
|
? null
|
||||||
: state.getInjector().getJetTypeMapper().mapType(thisDescriptor.getDefaultType(), MapTypeMode.VALUE);
|
: typeMapper.mapType(thisDescriptor.getDefaultType(), MapTypeMode.VALUE);
|
||||||
if (enclosingType == null) {
|
if (enclosingType == null) {
|
||||||
captureThis = null;
|
captureThis = null;
|
||||||
}
|
}
|
||||||
@@ -205,10 +209,10 @@ 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 =
|
ClassDescriptor function =
|
||||||
state.getInjector().getJetTypeMapper().getClosureAnnotator().classDescriptorForFunctionDescriptor(funDescriptor, name);
|
closureAnnotator.classDescriptorForFunctionDescriptor(funDescriptor);
|
||||||
|
|
||||||
final CodegenContexts.ClosureContext closureContext = context.intoClosure(
|
final CodegenContexts.ClosureContext closureContext = context.intoClosure(
|
||||||
funDescriptor, function, name, this, state.getInjector().getJetTypeMapper());
|
funDescriptor, function, name, this, typeMapper);
|
||||||
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);
|
||||||
@@ -241,7 +245,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
|||||||
if (receiver.exists()) {
|
if (receiver.exists()) {
|
||||||
StackValue.local(count, JetTypeMapper.TYPE_OBJECT).put(JetTypeMapper.TYPE_OBJECT, iv);
|
StackValue.local(count, JetTypeMapper.TYPE_OBJECT).put(JetTypeMapper.TYPE_OBJECT, iv);
|
||||||
StackValue.onStack(JetTypeMapper.TYPE_OBJECT)
|
StackValue.onStack(JetTypeMapper.TYPE_OBJECT)
|
||||||
.upcast(state.getInjector().getJetTypeMapper().mapType(receiver.getType(), MapTypeMode.VALUE), iv);
|
.upcast(typeMapper.mapType(receiver.getType(), MapTypeMode.VALUE), iv);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,7 +253,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
|||||||
for (ValueParameterDescriptor param : params) {
|
for (ValueParameterDescriptor param : params) {
|
||||||
StackValue.local(count, JetTypeMapper.TYPE_OBJECT).put(JetTypeMapper.TYPE_OBJECT, iv);
|
StackValue.local(count, JetTypeMapper.TYPE_OBJECT).put(JetTypeMapper.TYPE_OBJECT, iv);
|
||||||
StackValue.onStack(JetTypeMapper.TYPE_OBJECT)
|
StackValue.onStack(JetTypeMapper.TYPE_OBJECT)
|
||||||
.upcast(state.getInjector().getJetTypeMapper().mapType(param.getType(), MapTypeMode.VALUE), iv);
|
.upcast(typeMapper.mapType(param.getType(), MapTypeMode.VALUE), iv);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -290,7 +294,7 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
|||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
if (captureThis != null) {
|
if (captureThis != null) {
|
||||||
argTypes[i++] = state.getInjector().getJetTypeMapper().mapType(context.getThisDescriptor().getDefaultType(), MapTypeMode.VALUE);
|
argTypes[i++] = typeMapper.mapType(context.getThisDescriptor().getDefaultType(), MapTypeMode.VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (captureReceiver != null) {
|
if (captureReceiver != null) {
|
||||||
@@ -305,19 +309,19 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (descriptor instanceof VariableDescriptor && !(descriptor instanceof PropertyDescriptor)) {
|
if (descriptor instanceof VariableDescriptor && !(descriptor instanceof PropertyDescriptor)) {
|
||||||
final Type sharedVarType = state.getInjector().getJetTypeMapper().getSharedVarType(descriptor);
|
final Type sharedVarType = typeMapper.getSharedVarType(descriptor);
|
||||||
final Type type;
|
final Type type;
|
||||||
if (sharedVarType != null) {
|
if (sharedVarType != null) {
|
||||||
type = sharedVarType;
|
type = sharedVarType;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
type = state.getInjector().getJetTypeMapper().mapType(((VariableDescriptor) descriptor).getType(), MapTypeMode.VALUE);
|
type = typeMapper.mapType(((VariableDescriptor) descriptor).getType(), MapTypeMode.VALUE);
|
||||||
}
|
}
|
||||||
argTypes[i++] = type;
|
argTypes[i++] = type;
|
||||||
}
|
}
|
||||||
else if (CodegenUtil.isNamedFun(descriptor, state.getBindingContext()) &&
|
else if (CodegenUtil.isNamedFun(descriptor, state.getBindingContext()) &&
|
||||||
descriptor.getContainingDeclaration() instanceof FunctionDescriptor) {
|
descriptor.getContainingDeclaration() instanceof FunctionDescriptor) {
|
||||||
final Type type = state.getInjector().getJetTypeMapper().getClosureAnnotator()
|
final Type type = closureAnnotator
|
||||||
.classNameForAnonymousClass((JetElement) BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor))
|
.classNameForAnonymousClass((JetElement) BindingContextUtils.descriptorToDeclaration(bindingContext, descriptor))
|
||||||
.getAsmType();
|
.getAsmType();
|
||||||
argTypes[i++] = type;
|
argTypes[i++] = type;
|
||||||
@@ -387,7 +391,6 @@ public class ClosureCodegen extends ObjectOrClosureCodegen {
|
|||||||
private void appendType(SignatureWriter signatureWriter, JetType type, char variance) {
|
private void appendType(SignatureWriter signatureWriter, JetType type, char variance) {
|
||||||
signatureWriter.visitTypeArgument(variance);
|
signatureWriter.visitTypeArgument(variance);
|
||||||
|
|
||||||
final JetTypeMapper typeMapper = state.getInjector().getJetTypeMapper();
|
|
||||||
final Type rawRetType = typeMapper.mapType(type, MapTypeMode.TYPE_PARAMETER);
|
final Type rawRetType = typeMapper.mapType(type, MapTypeMode.TYPE_PARAMETER);
|
||||||
signatureWriter.visitClassType(rawRetType.getInternalName());
|
signatureWriter.visitClassType(rawRetType.getInternalName());
|
||||||
signatureWriter.visitEnd();
|
signatureWriter.visitEnd();
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package org.jetbrains.jet.codegen;
|
|||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.intellij.openapi.editor.Document;
|
import com.intellij.openapi.editor.Document;
|
||||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||||
|
import com.intellij.openapi.util.Pair;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import com.intellij.psi.PsiMethod;
|
import com.intellij.psi.PsiMethod;
|
||||||
import com.intellij.psi.tree.IElementType;
|
import com.intellij.psi.tree.IElementType;
|
||||||
@@ -194,6 +195,38 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
gen(expr, expressionType(expr));
|
gen(expr, expressionType(expr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StackValue visitClass(JetClass klass, StackValue data) {
|
||||||
|
ClassDescriptor descriptor = bindingContext.get(BindingContext.CLASS, klass);
|
||||||
|
ObjectOrClosureCodegen closure = new LocalClassClosureCodegen(this, context, state, descriptor);
|
||||||
|
Pair<JvmClassName, ClassBuilder> nameAndVisitor = state.forAnonymousSubclass(klass);
|
||||||
|
|
||||||
|
closure.cv = nameAndVisitor.getSecond();
|
||||||
|
closure.name = nameAndVisitor.getFirst();
|
||||||
|
final CodegenContext objectContext = closure.context.intoAnonymousClass(
|
||||||
|
closure, descriptor, OwnerKind.IMPLEMENTATION,
|
||||||
|
typeMapper);
|
||||||
|
|
||||||
|
new ImplementationBodyCodegen(klass, objectContext, nameAndVisitor.getSecond(), state).generate();
|
||||||
|
return StackValue.none();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public StackValue visitObjectDeclaration(JetObjectDeclaration declaration, StackValue data) {
|
||||||
|
ClassDescriptor descriptor = bindingContext.get(BindingContext.CLASS, declaration);
|
||||||
|
ObjectOrClosureCodegen closure = new LocalClassClosureCodegen(this, context, state, descriptor);
|
||||||
|
Pair<JvmClassName, ClassBuilder> nameAndVisitor = state.forAnonymousSubclass(declaration);
|
||||||
|
|
||||||
|
closure.cv = nameAndVisitor.getSecond();
|
||||||
|
closure.name = nameAndVisitor.getFirst();
|
||||||
|
final CodegenContext objectContext = closure.context.intoAnonymousClass(
|
||||||
|
closure, descriptor, OwnerKind.IMPLEMENTATION,
|
||||||
|
typeMapper);
|
||||||
|
|
||||||
|
new ImplementationBodyCodegen(declaration, objectContext, nameAndVisitor.getSecond(), state).generate();
|
||||||
|
return StackValue.none();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StackValue visitExpression(JetExpression expression, StackValue receiver) {
|
public StackValue visitExpression(JetExpression expression, StackValue receiver) {
|
||||||
throw new UnsupportedOperationException("Codegen for " + expression + " is not yet implemented");
|
throw new UnsupportedOperationException("Codegen for " + expression + " is not yet implemented");
|
||||||
@@ -931,7 +964,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
else {
|
else {
|
||||||
gen(statement, Type.VOID_TYPE);
|
gen(statement, Type.VOID_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
v.mark(blockEnd);
|
v.mark(blockEnd);
|
||||||
@@ -943,7 +975,11 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
return answer;
|
return answer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateLocalVariableDeclaration(@NotNull JetVariableDeclaration variableDeclaration, final @NotNull Label blockEnd, @NotNull List<Function<StackValue, Void>> leaveTasks) {
|
private void generateLocalVariableDeclaration(
|
||||||
|
@NotNull JetVariableDeclaration variableDeclaration,
|
||||||
|
final @NotNull Label blockEnd,
|
||||||
|
@NotNull List<Function<StackValue, Void>> leaveTasks
|
||||||
|
) {
|
||||||
final VariableDescriptor variableDescriptor = bindingContext.get(BindingContext.VARIABLE, variableDeclaration);
|
final VariableDescriptor variableDescriptor = bindingContext.get(BindingContext.VARIABLE, variableDeclaration);
|
||||||
assert variableDescriptor != null;
|
assert variableDescriptor != null;
|
||||||
|
|
||||||
@@ -982,7 +1018,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateLocalFunctionDeclaration(@NotNull JetNamedFunction namedFunction, @NotNull List<Function<StackValue, Void>> leaveTasks) {
|
private void generateLocalFunctionDeclaration(
|
||||||
|
@NotNull JetNamedFunction namedFunction,
|
||||||
|
@NotNull List<Function<StackValue, Void>> leaveTasks
|
||||||
|
) {
|
||||||
final DeclarationDescriptor descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, namedFunction);
|
final DeclarationDescriptor descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, namedFunction);
|
||||||
myFrameMap.enter(descriptor, TYPE_OBJECT);
|
myFrameMap.enter(descriptor, TYPE_OBJECT);
|
||||||
|
|
||||||
@@ -1099,6 +1138,14 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
assert descriptor != null;
|
assert descriptor != null;
|
||||||
final DeclarationDescriptor container = descriptor.getContainingDeclaration();
|
final DeclarationDescriptor container = descriptor.getContainingDeclaration();
|
||||||
|
|
||||||
|
if (descriptor instanceof VariableDescriptor) {
|
||||||
|
VariableDescriptor variableDescriptor = (VariableDescriptor) descriptor;
|
||||||
|
ClassDescriptor objectClassDescriptor = getBindingContext().get(BindingContext.OBJECT_DECLARATION_CLASS, variableDescriptor);
|
||||||
|
if (objectClassDescriptor != null) {
|
||||||
|
return genObjectClassInstance(variableDescriptor, objectClassDescriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int index = lookupLocal(descriptor);
|
int index = lookupLocal(descriptor);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
return stackValueForLocal(descriptor, index);
|
return stackValueForLocal(descriptor, index);
|
||||||
@@ -1107,22 +1154,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
if (descriptor instanceof PropertyDescriptor) {
|
if (descriptor instanceof PropertyDescriptor) {
|
||||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
|
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
|
||||||
|
|
||||||
ClassDescriptor objectClassDescriptor = getBindingContext().get(BindingContext.OBJECT_DECLARATION_CLASS, propertyDescriptor);
|
|
||||||
if (objectClassDescriptor != null) {
|
|
||||||
boolean isEnumEntry = DescriptorUtils.isEnumClassObject(propertyDescriptor.getContainingDeclaration());
|
|
||||||
if (isEnumEntry) {
|
|
||||||
ClassDescriptor containing = (ClassDescriptor) propertyDescriptor.getContainingDeclaration().getContainingDeclaration();
|
|
||||||
assert containing != null;
|
|
||||||
Type type = typeMapper.mapType(containing.getDefaultType(), MapTypeMode.VALUE);
|
|
||||||
StackValue.field(type, JvmClassName.byType(type), propertyDescriptor.getName().getName(), true).put(type, v);
|
|
||||||
return StackValue.onStack(type);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Type type = typeMapper.mapType(objectClassDescriptor.getDefaultType(), MapTypeMode.VALUE);
|
|
||||||
return StackValue.field(type, JvmClassName.byType(type), "$instance", true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isStatic = container instanceof NamespaceDescriptor;
|
boolean isStatic = container instanceof NamespaceDescriptor;
|
||||||
final boolean directToField =
|
final boolean directToField =
|
||||||
expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER && contextKind() != OwnerKind.TRAIT_IMPL;
|
expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER && contextKind() != OwnerKind.TRAIT_IMPL;
|
||||||
@@ -1228,6 +1259,21 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
throw new UnsupportedOperationException("don't know how to generate reference " + descriptor);
|
throw new UnsupportedOperationException("don't know how to generate reference " + descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private StackValue genObjectClassInstance(VariableDescriptor variableDescriptor, ClassDescriptor objectClassDescriptor) {
|
||||||
|
boolean isEnumEntry = DescriptorUtils.isEnumClassObject(variableDescriptor.getContainingDeclaration());
|
||||||
|
if (isEnumEntry) {
|
||||||
|
ClassDescriptor containing = (ClassDescriptor) variableDescriptor.getContainingDeclaration().getContainingDeclaration();
|
||||||
|
assert containing != null;
|
||||||
|
Type type = typeMapper.mapType(containing.getDefaultType(), MapTypeMode.VALUE);
|
||||||
|
StackValue.field(type, JvmClassName.byType(type), variableDescriptor.getName().getName(), true).put(type, v);
|
||||||
|
return StackValue.onStack(type);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Type type = typeMapper.mapType(objectClassDescriptor.getDefaultType(), MapTypeMode.VALUE);
|
||||||
|
return StackValue.field(type, JvmClassName.byType(type), "$instance", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private StackValue stackValueForLocal(DeclarationDescriptor descriptor, int index) {
|
private StackValue stackValueForLocal(DeclarationDescriptor descriptor, int index) {
|
||||||
if (descriptor instanceof VariableDescriptor) {
|
if (descriptor instanceof VariableDescriptor) {
|
||||||
Type sharedVarType = typeMapper.getSharedVarType(descriptor);
|
Type sharedVarType = typeMapper.getSharedVarType(descriptor);
|
||||||
@@ -1588,6 +1634,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
Call call = bindingContext.get(CALL, calleeExpression);
|
Call call = bindingContext.get(CALL, calleeExpression);
|
||||||
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, calleeExpression);
|
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, calleeExpression);
|
||||||
|
|
||||||
|
assert resolvedCall != null;
|
||||||
|
assert call != null;
|
||||||
invokeMethodWithArguments(callableMethod, resolvedCall, call, receiver);
|
invokeMethodWithArguments(callableMethod, resolvedCall, call, receiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2624,7 +2672,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
initializeLocalVariable(variableDeclaration, new Function<VariableDescriptor, Void>() {
|
initializeLocalVariable(variableDeclaration, new Function<VariableDescriptor, Void>() {
|
||||||
@Override
|
@Override
|
||||||
public Void fun(VariableDescriptor descriptor) {
|
public Void fun(VariableDescriptor descriptor) {
|
||||||
ResolvedCall<FunctionDescriptor> resolvedCall = bindingContext.get(BindingContext.COMPONENT_RESOLVED_CALL, variableDeclaration);
|
ResolvedCall<FunctionDescriptor> resolvedCall =
|
||||||
|
bindingContext.get(BindingContext.COMPONENT_RESOLVED_CALL, variableDeclaration);
|
||||||
assert resolvedCall != null : "Resolved call is null for " + variableDeclaration.getText();
|
assert resolvedCall != null : "Resolved call is null for " + variableDeclaration.getText();
|
||||||
Call call = CallMaker.makeCall(initializerAsReceiver, (JetExpression) null);
|
Call call = CallMaker.makeCall(initializerAsReceiver, (JetExpression) null);
|
||||||
invokeFunction(call, StackValue.none(), resolvedCall);
|
invokeFunction(call, StackValue.none(), resolvedCall);
|
||||||
|
|||||||
@@ -43,8 +43,6 @@ import java.util.Map;
|
|||||||
public class GenerationState {
|
public class GenerationState {
|
||||||
private final Progress progress;
|
private final Progress progress;
|
||||||
@NotNull
|
@NotNull
|
||||||
private final AnalyzeExhaust analyzeExhaust;
|
|
||||||
@NotNull
|
|
||||||
private final List<JetFile> files;
|
private final List<JetFile> files;
|
||||||
@NotNull
|
@NotNull
|
||||||
private final InjectorForJvmCodegen injector;
|
private final InjectorForJvmCodegen injector;
|
||||||
@@ -56,6 +54,8 @@ public class GenerationState {
|
|||||||
|
|
||||||
// out parameter
|
// out parameter
|
||||||
private Method scriptConstructorMethod;
|
private Method scriptConstructorMethod;
|
||||||
|
private final BindingContext bindingContext;
|
||||||
|
private final JetTypeMapper typeMapper;
|
||||||
|
|
||||||
|
|
||||||
public GenerationState(ClassBuilderFactory builderFactory, AnalyzeExhaust analyzeExhaust, List<JetFile> files) {
|
public GenerationState(ClassBuilderFactory builderFactory, AnalyzeExhaust analyzeExhaust, List<JetFile> files) {
|
||||||
@@ -67,12 +67,13 @@ public class GenerationState {
|
|||||||
@NotNull AnalyzeExhaust exhaust, @NotNull List<JetFile> files, @NotNull BuiltinToJavaTypesMapping builtinToJavaTypesMapping
|
@NotNull AnalyzeExhaust exhaust, @NotNull List<JetFile> files, @NotNull BuiltinToJavaTypesMapping builtinToJavaTypesMapping
|
||||||
) {
|
) {
|
||||||
this.progress = progress;
|
this.progress = progress;
|
||||||
this.analyzeExhaust = exhaust;
|
|
||||||
this.files = files;
|
this.files = files;
|
||||||
this.classBuilderMode = builderFactory.getClassBuilderMode();
|
this.classBuilderMode = builderFactory.getClassBuilderMode();
|
||||||
|
bindingContext = exhaust.getBindingContext();
|
||||||
this.injector = new InjectorForJvmCodegen(
|
this.injector = new InjectorForJvmCodegen(
|
||||||
analyzeExhaust.getBindingContext(),
|
bindingContext,
|
||||||
this.files, builtinToJavaTypesMapping, builderFactory.getClassBuilderMode(), this, builderFactory);
|
this.files, builtinToJavaTypesMapping, builderFactory.getClassBuilderMode(), this, builderFactory);
|
||||||
|
typeMapper = injector.getJetTypeMapper();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void markUsed() {
|
private void markUsed() {
|
||||||
@@ -98,7 +99,7 @@ public class GenerationState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public BindingContext getBindingContext() {
|
public BindingContext getBindingContext() {
|
||||||
return analyzeExhaust.getBindingContext();
|
return bindingContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -199,16 +200,16 @@ public class GenerationState {
|
|||||||
closure.cv = nameAndVisitor.getSecond();
|
closure.cv = nameAndVisitor.getSecond();
|
||||||
closure.name = nameAndVisitor.getFirst();
|
closure.name = nameAndVisitor.getFirst();
|
||||||
final CodegenContext objectContext = closure.context.intoAnonymousClass(
|
final CodegenContext objectContext = closure.context.intoAnonymousClass(
|
||||||
closure, analyzeExhaust.getBindingContext().get(BindingContext.CLASS, objectDeclaration), OwnerKind.IMPLEMENTATION,
|
closure, bindingContext.get(BindingContext.CLASS, objectDeclaration), OwnerKind.IMPLEMENTATION,
|
||||||
injector.getJetTypeMapper());
|
typeMapper);
|
||||||
|
|
||||||
new ImplementationBodyCodegen(objectDeclaration, objectContext, nameAndVisitor.getSecond(), this).generate();
|
new ImplementationBodyCodegen(objectDeclaration, objectContext, nameAndVisitor.getSecond(), this).generate();
|
||||||
|
|
||||||
ConstructorDescriptor constructorDescriptor = analyzeExhaust.getBindingContext().get(BindingContext.CONSTRUCTOR, objectDeclaration);
|
ConstructorDescriptor constructorDescriptor = bindingContext.get(BindingContext.CONSTRUCTOR, objectDeclaration);
|
||||||
assert constructorDescriptor != null;
|
assert constructorDescriptor != null;
|
||||||
CallableMethod callableMethod = injector.getJetTypeMapper().mapToCallableMethod(
|
CallableMethod callableMethod = typeMapper.mapToCallableMethod(
|
||||||
constructorDescriptor, OwnerKind.IMPLEMENTATION,
|
constructorDescriptor, OwnerKind.IMPLEMENTATION,
|
||||||
injector.getJetTypeMapper().hasThis0(constructorDescriptor.getContainingDeclaration()));
|
typeMapper.hasThis0(constructorDescriptor.getContainingDeclaration()));
|
||||||
return new GeneratedAnonymousClassDescriptor(nameAndVisitor.first, callableMethod.getSignature().getAsmMethod(),
|
return new GeneratedAnonymousClassDescriptor(nameAndVisitor.first, callableMethod.getSignature().getAsmMethod(),
|
||||||
objectContext.outerWasUsed, null);
|
objectContext.outerWasUsed, null);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import org.jetbrains.jet.codegen.signature.JvmMethodSignature;
|
|||||||
import org.jetbrains.jet.codegen.signature.JvmPropertyAccessorSignature;
|
import org.jetbrains.jet.codegen.signature.JvmPropertyAccessorSignature;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.psi.JetClassObject;
|
import org.jetbrains.jet.lang.psi.JetClassObject;
|
||||||
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
|
||||||
import org.jetbrains.jet.lang.psi.JetElement;
|
import org.jetbrains.jet.lang.psi.JetElement;
|
||||||
import org.jetbrains.jet.lang.psi.JetObjectDeclaration;
|
import org.jetbrains.jet.lang.psi.JetObjectDeclaration;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
@@ -392,6 +391,11 @@ public class JetTypeMapper {
|
|||||||
return getJvmInternalFQName(klass.getContainingDeclaration());
|
return getJvmInternalFQName(klass.getContainingDeclaration());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JvmClassName name = closureAnnotator.classNameForClassDescriptor((ClassDescriptor) descriptor);
|
||||||
|
if (name != null) {
|
||||||
|
return name.getInternalName();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DeclarationDescriptor container = descriptor.getContainingDeclaration();
|
DeclarationDescriptor container = descriptor.getContainingDeclaration();
|
||||||
@@ -402,12 +406,6 @@ public class JetTypeMapper {
|
|||||||
|
|
||||||
Name name = descriptor.getName();
|
Name name = descriptor.getName();
|
||||||
|
|
||||||
if (descriptor instanceof ClassDescriptor && name.isSpecial()) {
|
|
||||||
ClassDescriptor clazz = (ClassDescriptor) descriptor;
|
|
||||||
JvmClassName className = closureAnnotator.classNameForClassDescriptor(clazz);
|
|
||||||
return className.getInternalName();
|
|
||||||
}
|
|
||||||
|
|
||||||
String baseName = getJvmInternalFQName(container);
|
String baseName = getJvmInternalFQName(container);
|
||||||
if (!baseName.isEmpty()) {
|
if (!baseName.isEmpty()) {
|
||||||
return baseName + (container instanceof NamespaceDescriptor ? "/" : "$") + name.getIdentifier();
|
return baseName + (container instanceof NamespaceDescriptor ? "/" : "$") + name.getIdentifier();
|
||||||
@@ -511,8 +509,6 @@ public class JetTypeMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (descriptor instanceof ClassDescriptor) {
|
if (descriptor instanceof ClassDescriptor) {
|
||||||
|
|
||||||
|
|
||||||
JvmClassName name = getJvmClassName((ClassDescriptor) descriptor);
|
JvmClassName name = getJvmClassName((ClassDescriptor) descriptor);
|
||||||
Type asmType = Type.getObjectType(name.getInternalName() + (kind == MapTypeMode.TRAIT_IMPL ? JvmAbi.TRAIT_IMPL_SUFFIX : ""));
|
Type asmType = Type.getObjectType(name.getInternalName() + (kind == MapTypeMode.TRAIT_IMPL ? JvmAbi.TRAIT_IMPL_SUFFIX : ""));
|
||||||
boolean forceReal = isForceReal(name);
|
boolean forceReal = isForceReal(name);
|
||||||
@@ -1113,7 +1109,7 @@ public class JetTypeMapper {
|
|||||||
public boolean isVarCapturedInClosure(DeclarationDescriptor descriptor) {
|
public boolean isVarCapturedInClosure(DeclarationDescriptor descriptor) {
|
||||||
if (!(descriptor instanceof VariableDescriptor) || descriptor instanceof PropertyDescriptor) return false;
|
if (!(descriptor instanceof VariableDescriptor) || descriptor instanceof PropertyDescriptor) return false;
|
||||||
VariableDescriptor variableDescriptor = (VariableDescriptor) descriptor;
|
VariableDescriptor variableDescriptor = (VariableDescriptor) descriptor;
|
||||||
Boolean aBoolean = bindingContext.get(BindingContext.CAPTURED_IN_CLOSURE, variableDescriptor);
|
return Boolean.TRUE.equals(bindingContext.get(BindingContext.CAPTURED_IN_CLOSURE, variableDescriptor)) &&
|
||||||
return aBoolean != null && aBoolean && variableDescriptor.isVar();
|
variableDescriptor.isVar();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2012 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
public class LocalClassClosureCodegen extends ObjectOrClosureCodegen {
|
||||||
|
public LocalClassClosureCodegen(
|
||||||
|
ExpressionCodegen exprContext,
|
||||||
|
CodegenContext context,
|
||||||
|
@NotNull GenerationState state,
|
||||||
|
ClassDescriptor descriptor
|
||||||
|
) {
|
||||||
|
super(exprContext, context, state);
|
||||||
|
state.getInjector().getClosureAnnotator().recordLocalClass(descriptor, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
-2
@@ -29,13 +29,15 @@ import java.util.List;
|
|||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public class LocalVariableDescriptor extends VariableDescriptorImpl {
|
public class LocalVariableDescriptor extends VariableDescriptorImpl {
|
||||||
private boolean isVar;
|
private final boolean isVar;
|
||||||
|
|
||||||
public LocalVariableDescriptor(
|
public LocalVariableDescriptor(
|
||||||
@NotNull DeclarationDescriptor containingDeclaration,
|
@NotNull DeclarationDescriptor containingDeclaration,
|
||||||
@NotNull List<AnnotationDescriptor> annotations,
|
@NotNull List<AnnotationDescriptor> annotations,
|
||||||
@NotNull Name name,
|
@NotNull Name name,
|
||||||
@Nullable JetType type,
|
@Nullable JetType type,
|
||||||
boolean mutable) {
|
boolean mutable
|
||||||
|
) {
|
||||||
super(containingDeclaration, annotations, name, type);
|
super(containingDeclaration, annotations, name, type);
|
||||||
isVar = mutable;
|
isVar = mutable;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,11 +68,14 @@ public interface BindingContext {
|
|||||||
WritableSlice<JetExpression, JetType> EXPRESSION_TYPE = new BasicWritableSlice<JetExpression, JetType>(DO_NOTHING);
|
WritableSlice<JetExpression, JetType> EXPRESSION_TYPE = new BasicWritableSlice<JetExpression, JetType>(DO_NOTHING);
|
||||||
WritableSlice<JetExpression, DataFlowInfo> EXPRESSION_DATA_FLOW_INFO = new BasicWritableSlice<JetExpression, DataFlowInfo>(DO_NOTHING);
|
WritableSlice<JetExpression, DataFlowInfo> EXPRESSION_DATA_FLOW_INFO = new BasicWritableSlice<JetExpression, DataFlowInfo>(DO_NOTHING);
|
||||||
|
|
||||||
WritableSlice<JetReferenceExpression, DeclarationDescriptor> REFERENCE_TARGET = new BasicWritableSlice<JetReferenceExpression, DeclarationDescriptor>(DO_NOTHING);
|
WritableSlice<JetReferenceExpression, DeclarationDescriptor> REFERENCE_TARGET =
|
||||||
WritableSlice<JetElement, ResolvedCall<? extends CallableDescriptor>> RESOLVED_CALL = new BasicWritableSlice<JetElement, ResolvedCall<? extends CallableDescriptor>>(DO_NOTHING);
|
new BasicWritableSlice<JetReferenceExpression, DeclarationDescriptor>(DO_NOTHING);
|
||||||
|
WritableSlice<JetElement, ResolvedCall<? extends CallableDescriptor>> RESOLVED_CALL =
|
||||||
|
new BasicWritableSlice<JetElement, ResolvedCall<? extends CallableDescriptor>>(DO_NOTHING);
|
||||||
WritableSlice<JetElement, Call> CALL = new BasicWritableSlice<JetElement, Call>(DO_NOTHING);
|
WritableSlice<JetElement, Call> CALL = new BasicWritableSlice<JetElement, Call>(DO_NOTHING);
|
||||||
|
|
||||||
WritableSlice<JetReferenceExpression, Collection<? extends DeclarationDescriptor>> AMBIGUOUS_REFERENCE_TARGET = new BasicWritableSlice<JetReferenceExpression, Collection<? extends DeclarationDescriptor>>(DO_NOTHING);
|
WritableSlice<JetReferenceExpression, Collection<? extends DeclarationDescriptor>> AMBIGUOUS_REFERENCE_TARGET =
|
||||||
|
new BasicWritableSlice<JetReferenceExpression, Collection<? extends DeclarationDescriptor>>(DO_NOTHING);
|
||||||
|
|
||||||
WritableSlice<CallKey, OverloadResolutionResults<FunctionDescriptor>> RESOLUTION_RESULTS_FOR_FUNCTION = Slices.createSimpleSlice();
|
WritableSlice<CallKey, OverloadResolutionResults<FunctionDescriptor>> RESOLUTION_RESULTS_FOR_FUNCTION = Slices.createSimpleSlice();
|
||||||
WritableSlice<CallKey, OverloadResolutionResults<VariableDescriptor>> RESOLUTION_RESULTS_FOR_PROPERTY = Slices.createSimpleSlice();
|
WritableSlice<CallKey, OverloadResolutionResults<VariableDescriptor>> RESOLUTION_RESULTS_FOR_PROPERTY = Slices.createSimpleSlice();
|
||||||
@@ -89,35 +92,46 @@ public interface BindingContext {
|
|||||||
|
|
||||||
WritableSlice<JetExpression, JetType> AUTOCAST = Slices.createSimpleSlice();
|
WritableSlice<JetExpression, JetType> AUTOCAST = Slices.createSimpleSlice();
|
||||||
|
|
||||||
/** A scope where type of expression has been resolved */
|
/**
|
||||||
|
* A scope where type of expression has been resolved
|
||||||
|
*/
|
||||||
WritableSlice<JetTypeReference, JetScope> TYPE_RESOLUTION_SCOPE = Slices.createSimpleSlice();
|
WritableSlice<JetTypeReference, JetScope> TYPE_RESOLUTION_SCOPE = Slices.createSimpleSlice();
|
||||||
WritableSlice<JetExpression, JetScope> RESOLUTION_SCOPE = Slices.createSimpleSlice();
|
WritableSlice<JetExpression, JetScope> RESOLUTION_SCOPE = Slices.createSimpleSlice();
|
||||||
|
|
||||||
WritableSlice<ScriptDescriptor, JetScope> SCRIPT_SCOPE = Slices.createSimpleSlice();
|
WritableSlice<ScriptDescriptor, JetScope> SCRIPT_SCOPE = Slices.createSimpleSlice();
|
||||||
|
|
||||||
/** Collected during analyze, used in IDE in auto-cast completion */
|
/**
|
||||||
|
* Collected during analyze, used in IDE in auto-cast completion
|
||||||
|
*/
|
||||||
WritableSlice<JetExpression, DataFlowInfo> NON_DEFAULT_EXPRESSION_DATA_FLOW = Slices.createSimpleSlice();
|
WritableSlice<JetExpression, DataFlowInfo> NON_DEFAULT_EXPRESSION_DATA_FLOW = Slices.createSimpleSlice();
|
||||||
|
|
||||||
WritableSlice<JetExpression, Boolean> VARIABLE_REASSIGNMENT = Slices.createSimpleSetSlice();
|
WritableSlice<JetExpression, Boolean> VARIABLE_REASSIGNMENT = Slices.createSimpleSetSlice();
|
||||||
WritableSlice<ValueParameterDescriptor, Boolean> AUTO_CREATED_IT = Slices.createSimpleSetSlice();
|
WritableSlice<ValueParameterDescriptor, Boolean> AUTO_CREATED_IT = Slices.createSimpleSetSlice();
|
||||||
WritableSlice<JetExpression, DeclarationDescriptor> VARIABLE_ASSIGNMENT = Slices.createSimpleSlice();
|
WritableSlice<JetExpression, DeclarationDescriptor> VARIABLE_ASSIGNMENT = Slices.createSimpleSlice();
|
||||||
|
|
||||||
/** Has type of current expression has been already resolved */
|
/**
|
||||||
|
* Has type of current expression has been already resolved
|
||||||
|
*/
|
||||||
WritableSlice<JetExpression, Boolean> PROCESSED = Slices.createSimpleSetSlice();
|
WritableSlice<JetExpression, Boolean> PROCESSED = Slices.createSimpleSetSlice();
|
||||||
WritableSlice<JetElement, Boolean> STATEMENT = Slices.createRemovableSetSlice();
|
WritableSlice<JetElement, Boolean> STATEMENT = Slices.createRemovableSetSlice();
|
||||||
|
|
||||||
WritableSlice<VariableDescriptor, Boolean> CAPTURED_IN_CLOSURE = Slices.createSimpleSetSlice();
|
WritableSlice<VariableDescriptor, Boolean> CAPTURED_IN_CLOSURE = Slices.createSimpleSetSlice();
|
||||||
|
|
||||||
// enum DeferredTypeKey {DEFERRED_TYPE_KEY}
|
// enum DeferredTypeKey {DEFERRED_TYPE_KEY}
|
||||||
// WritableSlice<DeferredTypeKey, Collection<DeferredType>> DEFERRED_TYPES = Slices.createSimpleSlice();
|
// WritableSlice<DeferredTypeKey, Collection<DeferredType>> DEFERRED_TYPES = Slices.createSimpleSlice();
|
||||||
|
|
||||||
WritableSlice<Box<DeferredType>, Boolean> DEFERRED_TYPE = Slices.createCollectiveSetSlice();
|
WritableSlice<Box<DeferredType>, Boolean> DEFERRED_TYPE = Slices.createCollectiveSetSlice();
|
||||||
|
|
||||||
WritableSlice<PropertyDescriptor, ClassDescriptor> OBJECT_DECLARATION_CLASS = Slices.createSimpleSlice();
|
WritableSlice<VariableDescriptor, ClassDescriptor> OBJECT_DECLARATION_CLASS = Slices.createSimpleSlice();
|
||||||
|
|
||||||
WritableSlice<PropertyDescriptor, Boolean> BACKING_FIELD_REQUIRED = new Slices.SetSlice<PropertyDescriptor>(DO_NOTHING) {
|
WritableSlice<PropertyDescriptor, Boolean> BACKING_FIELD_REQUIRED = new Slices.SetSlice<PropertyDescriptor>(DO_NOTHING) {
|
||||||
@Override
|
@Override
|
||||||
public Boolean computeValue(SlicedMap map, PropertyDescriptor propertyDescriptor, Boolean backingFieldRequired, boolean valueNotFound) {
|
public Boolean computeValue(
|
||||||
|
SlicedMap map,
|
||||||
|
PropertyDescriptor propertyDescriptor,
|
||||||
|
Boolean backingFieldRequired,
|
||||||
|
boolean valueNotFound
|
||||||
|
) {
|
||||||
if (propertyDescriptor.getKind() != CallableMemberDescriptor.Kind.DECLARATION) {
|
if (propertyDescriptor.getKind() != CallableMemberDescriptor.Kind.DECLARATION) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -159,33 +173,56 @@ public interface BindingContext {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
WritableSlice<PsiElement, NamespaceDescriptor> NAMESPACE = Slices.<PsiElement, NamespaceDescriptor>sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build();
|
WritableSlice<PsiElement, NamespaceDescriptor> NAMESPACE = Slices.<PsiElement, NamespaceDescriptor>sliceBuilder()
|
||||||
WritableSlice<PsiElement, ClassDescriptor> CLASS = Slices.<PsiElement, ClassDescriptor>sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build();
|
.setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build();
|
||||||
WritableSlice<PsiElement, ScriptDescriptor> SCRIPT = Slices.<PsiElement, ScriptDescriptor>sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build();
|
WritableSlice<PsiElement, ClassDescriptor> CLASS =
|
||||||
WritableSlice<JetTypeParameter, TypeParameterDescriptor> TYPE_PARAMETER = Slices.<JetTypeParameter, TypeParameterDescriptor>sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build();
|
Slices.<PsiElement, ClassDescriptor>sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION)
|
||||||
/** @see BindingContextUtils#recordFunctionDeclarationToDescriptor(BindingTrace, PsiElement, SimpleFunctionDescriptor)} */
|
.build();
|
||||||
WritableSlice<PsiElement, SimpleFunctionDescriptor> FUNCTION = Slices.<PsiElement, SimpleFunctionDescriptor>sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build();
|
WritableSlice<PsiElement, ScriptDescriptor> SCRIPT =
|
||||||
WritableSlice<PsiElement, ConstructorDescriptor> CONSTRUCTOR = Slices.<PsiElement, ConstructorDescriptor>sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build();
|
Slices.<PsiElement, ScriptDescriptor>sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION)
|
||||||
WritableSlice<PsiElement, VariableDescriptor> VARIABLE = Slices.<PsiElement, VariableDescriptor>sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build();
|
.build();
|
||||||
WritableSlice<JetParameter, VariableDescriptor> VALUE_PARAMETER = Slices.<JetParameter, VariableDescriptor>sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build();
|
WritableSlice<JetTypeParameter, TypeParameterDescriptor> TYPE_PARAMETER =
|
||||||
WritableSlice<JetPropertyAccessor, PropertyAccessorDescriptor> PROPERTY_ACCESSOR = Slices.<JetPropertyAccessor, PropertyAccessorDescriptor>sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build();
|
Slices.<JetTypeParameter, TypeParameterDescriptor>sliceBuilder()
|
||||||
|
.setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build();
|
||||||
|
/**
|
||||||
|
* @see BindingContextUtils#recordFunctionDeclarationToDescriptor(BindingTrace, PsiElement, SimpleFunctionDescriptor)}
|
||||||
|
*/
|
||||||
|
WritableSlice<PsiElement, SimpleFunctionDescriptor> FUNCTION = Slices.<PsiElement, SimpleFunctionDescriptor>sliceBuilder()
|
||||||
|
.setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build();
|
||||||
|
WritableSlice<PsiElement, ConstructorDescriptor> CONSTRUCTOR = Slices.<PsiElement, ConstructorDescriptor>sliceBuilder()
|
||||||
|
.setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build();
|
||||||
|
WritableSlice<PsiElement, VariableDescriptor> VARIABLE =
|
||||||
|
Slices.<PsiElement, VariableDescriptor>sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION)
|
||||||
|
.build();
|
||||||
|
WritableSlice<JetParameter, VariableDescriptor> VALUE_PARAMETER = Slices.<JetParameter, VariableDescriptor>sliceBuilder()
|
||||||
|
.setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build();
|
||||||
|
WritableSlice<JetPropertyAccessor, PropertyAccessorDescriptor> PROPERTY_ACCESSOR =
|
||||||
|
Slices.<JetPropertyAccessor, PropertyAccessorDescriptor>sliceBuilder()
|
||||||
|
.setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build();
|
||||||
|
|
||||||
// normalize value to getOriginal(value)
|
// normalize value to getOriginal(value)
|
||||||
WritableSlice<PsiElement, PropertyDescriptor> PRIMARY_CONSTRUCTOR_PARAMETER = Slices.<PsiElement, PropertyDescriptor>sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build();
|
WritableSlice<PsiElement, PropertyDescriptor> PRIMARY_CONSTRUCTOR_PARAMETER =
|
||||||
WritableSlice<JetObjectDeclarationName, PropertyDescriptor> OBJECT_DECLARATION = Slices.<JetObjectDeclarationName, PropertyDescriptor>sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build();
|
Slices.<PsiElement, PropertyDescriptor>sliceBuilder().setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION)
|
||||||
|
.build();
|
||||||
|
WritableSlice<JetObjectDeclarationName, PropertyDescriptor> OBJECT_DECLARATION =
|
||||||
|
Slices.<JetObjectDeclarationName, PropertyDescriptor>sliceBuilder()
|
||||||
|
.setOpposite((WritableSlice) BindingContextUtils.DESCRIPTOR_TO_DECLARATION).build();
|
||||||
|
|
||||||
WritableSlice[] DECLARATIONS_TO_DESCRIPTORS = new WritableSlice[] {
|
WritableSlice[] DECLARATIONS_TO_DESCRIPTORS = new WritableSlice[] {
|
||||||
NAMESPACE, CLASS, TYPE_PARAMETER, FUNCTION, CONSTRUCTOR, VARIABLE, VALUE_PARAMETER, PROPERTY_ACCESSOR, PRIMARY_CONSTRUCTOR_PARAMETER, OBJECT_DECLARATION
|
NAMESPACE, CLASS, TYPE_PARAMETER, FUNCTION, CONSTRUCTOR, VARIABLE, VALUE_PARAMETER, PROPERTY_ACCESSOR,
|
||||||
|
PRIMARY_CONSTRUCTOR_PARAMETER, OBJECT_DECLARATION
|
||||||
};
|
};
|
||||||
|
|
||||||
ReadOnlySlice<PsiElement, DeclarationDescriptor> DECLARATION_TO_DESCRIPTOR = Slices.<PsiElement, DeclarationDescriptor>sliceBuilder()
|
ReadOnlySlice<PsiElement, DeclarationDescriptor> DECLARATION_TO_DESCRIPTOR = Slices.<PsiElement, DeclarationDescriptor>sliceBuilder()
|
||||||
.setFurtherLookupSlices(DECLARATIONS_TO_DESCRIPTORS).build();
|
.setFurtherLookupSlices(DECLARATIONS_TO_DESCRIPTORS).build();
|
||||||
|
|
||||||
WritableSlice<JetReferenceExpression, PsiElement> LABEL_TARGET = Slices.<JetReferenceExpression, PsiElement>sliceBuilder().build();
|
WritableSlice<JetReferenceExpression, PsiElement> LABEL_TARGET = Slices.<JetReferenceExpression, PsiElement>sliceBuilder().build();
|
||||||
WritableSlice<JetParameter, PropertyDescriptor> VALUE_PARAMETER_AS_PROPERTY = Slices.<JetParameter, PropertyDescriptor>sliceBuilder().build();
|
WritableSlice<JetParameter, PropertyDescriptor> VALUE_PARAMETER_AS_PROPERTY =
|
||||||
|
Slices.<JetParameter, PropertyDescriptor>sliceBuilder().build();
|
||||||
|
|
||||||
WritableSlice<FqName, ClassDescriptor> FQNAME_TO_CLASS_DESCRIPTOR = new BasicWritableSlice<FqName, ClassDescriptor>(DO_NOTHING, true);
|
WritableSlice<FqName, ClassDescriptor> FQNAME_TO_CLASS_DESCRIPTOR = new BasicWritableSlice<FqName, ClassDescriptor>(DO_NOTHING, true);
|
||||||
WritableSlice<FqName, NamespaceDescriptor> FQNAME_TO_NAMESPACE_DESCRIPTOR = new BasicWritableSlice<FqName, NamespaceDescriptor>(DO_NOTHING);
|
WritableSlice<FqName, NamespaceDescriptor> FQNAME_TO_NAMESPACE_DESCRIPTOR =
|
||||||
|
new BasicWritableSlice<FqName, NamespaceDescriptor>(DO_NOTHING);
|
||||||
WritableSlice<JetFile, NamespaceDescriptor> FILE_TO_NAMESPACE = Slices.createSimpleSlice();
|
WritableSlice<JetFile, NamespaceDescriptor> FILE_TO_NAMESPACE = Slices.createSimpleSlice();
|
||||||
WritableSlice<NamespaceDescriptor, Collection<JetFile>> NAMESPACE_TO_FILES = Slices.createSimpleSlice();
|
WritableSlice<NamespaceDescriptor, Collection<JetFile>> NAMESPACE_TO_FILES = Slices.createSimpleSlice();
|
||||||
|
|
||||||
@@ -193,13 +230,13 @@ public interface BindingContext {
|
|||||||
* Each namespace found in src must be registered here.
|
* Each namespace found in src must be registered here.
|
||||||
*/
|
*/
|
||||||
WritableSlice<NamespaceDescriptor, Boolean> NAMESPACE_IS_SRC = Slices.createSimpleSlice();
|
WritableSlice<NamespaceDescriptor, Boolean> NAMESPACE_IS_SRC = Slices.createSimpleSlice();
|
||||||
|
|
||||||
WritableSlice<ClassDescriptor, Boolean> INCOMPLETE_HIERARCHY = Slices.createCollectiveSetSlice();
|
WritableSlice<ClassDescriptor, Boolean> INCOMPLETE_HIERARCHY = Slices.createCollectiveSetSlice();
|
||||||
|
|
||||||
@SuppressWarnings("UnusedDeclaration")
|
@SuppressWarnings("UnusedDeclaration")
|
||||||
@Deprecated // This field is needed only for the side effects of its initializer
|
@Deprecated // This field is needed only for the side effects of its initializer
|
||||||
Void _static_initializer = BasicWritableSlice.initSliceDebugNames(BindingContext.class);
|
Void _static_initializer = BasicWritableSlice.initSliceDebugNames(BindingContext.class);
|
||||||
|
|
||||||
Collection<Diagnostic> getDiagnostics();
|
Collection<Diagnostic> getDiagnostics();
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
@@ -703,6 +703,7 @@ public class DescriptorResolver {
|
|||||||
JetPsiUtil.safeName(objectDeclaration.getName()),
|
JetPsiUtil.safeName(objectDeclaration.getName()),
|
||||||
classDescriptor.getDefaultType(),
|
classDescriptor.getDefaultType(),
|
||||||
/*isVar =*/ false);
|
/*isVar =*/ false);
|
||||||
|
trace.record(BindingContext.OBJECT_DECLARATION_CLASS, variableDescriptor, classDescriptor);
|
||||||
JetObjectDeclarationName nameAsDeclaration = objectDeclaration.getNameAsDeclaration();
|
JetObjectDeclarationName nameAsDeclaration = objectDeclaration.getNameAsDeclaration();
|
||||||
if (nameAsDeclaration != null) {
|
if (nameAsDeclaration != null) {
|
||||||
trace.record(BindingContext.VARIABLE, nameAsDeclaration, variableDescriptor);
|
trace.record(BindingContext.VARIABLE, nameAsDeclaration, variableDescriptor);
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ public class FqName extends FqNameBase {
|
|||||||
isValidAfterUnsafeCheck(qualifiedName);
|
isValidAfterUnsafeCheck(qualifiedName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
@NotNull
|
@NotNull
|
||||||
public String getFqName() {
|
public String getFqName() {
|
||||||
return fqName.getFqName();
|
return fqName.getFqName();
|
||||||
@@ -145,7 +146,6 @@ public class FqName extends FqNameBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static FqName topLevel(@NotNull Name shortName) {
|
public static FqName topLevel(@NotNull Name shortName) {
|
||||||
return new FqName(FqNameUnsafe.topLevel(shortName));
|
return new FqName(FqNameUnsafe.topLevel(shortName));
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fun box(): String {
|
||||||
|
enum class K {
|
||||||
|
O
|
||||||
|
K
|
||||||
|
}
|
||||||
|
|
||||||
|
return K.O.toString() + K.K.toString()
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fun box(): String {
|
||||||
|
open class K {
|
||||||
|
val o = "O"
|
||||||
|
}
|
||||||
|
|
||||||
|
class Bar : K() {
|
||||||
|
val k = "K"
|
||||||
|
}
|
||||||
|
|
||||||
|
return K().o + Bar().k
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fun box(): String {
|
||||||
|
object K {
|
||||||
|
val ok = "OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
return K.ok
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fun box(): String {
|
||||||
|
val x = "OK"
|
||||||
|
class Aaa {
|
||||||
|
val y = x
|
||||||
|
}
|
||||||
|
|
||||||
|
return Aaa().y
|
||||||
|
}
|
||||||
@@ -48,7 +48,7 @@ public class ClassGenTest extends CodegenTestCase {
|
|||||||
public void testArrayListInheritance() throws Exception {
|
public void testArrayListInheritance() throws Exception {
|
||||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
loadFile("classes/inheritingFromArrayList.jet");
|
loadFile("classes/inheritingFromArrayList.jet");
|
||||||
// System.out.println(generateToText());
|
// System.out.println(generateToText());
|
||||||
final Class aClass = loadClass("Foo", generateClassesInFile());
|
final Class aClass = loadClass("Foo", generateClassesInFile());
|
||||||
assertInstanceOf(aClass.newInstance(), List.class);
|
assertInstanceOf(aClass.newInstance(), List.class);
|
||||||
}
|
}
|
||||||
@@ -86,7 +86,7 @@ public class ClassGenTest extends CodegenTestCase {
|
|||||||
public void testNewInstanceExplicitConstructor() throws Exception {
|
public void testNewInstanceExplicitConstructor() throws Exception {
|
||||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
loadFile("classes/newInstanceDefaultConstructor.jet");
|
loadFile("classes/newInstanceDefaultConstructor.jet");
|
||||||
// System.out.println(generateToText());
|
// System.out.println(generateToText());
|
||||||
final Method method = generateFunction("test");
|
final Method method = generateFunction("test");
|
||||||
final Integer returnValue = (Integer) method.invoke(null);
|
final Integer returnValue = (Integer) method.invoke(null);
|
||||||
assertEquals(610, returnValue.intValue());
|
assertEquals(610, returnValue.intValue());
|
||||||
@@ -163,7 +163,7 @@ public class ClassGenTest extends CodegenTestCase {
|
|||||||
public void testClassObjectMethod() throws Exception {
|
public void testClassObjectMethod() throws Exception {
|
||||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
// todo to be implemented after removal of type info
|
// todo to be implemented after removal of type info
|
||||||
// blackBoxFile("classes/classObjectMethod.jet");
|
// blackBoxFile("classes/classObjectMethod.jet");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testClassObjectInterface() throws Exception {
|
public void testClassObjectInterface() throws Exception {
|
||||||
@@ -203,7 +203,7 @@ public class ClassGenTest extends CodegenTestCase {
|
|||||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
loadText("enum class Direction { NORTH; SOUTH; EAST; WEST }");
|
loadText("enum class Direction { NORTH; SOUTH; EAST; WEST }");
|
||||||
final Class direction = createClassLoader(generateClassesInFile()).loadClass("Direction");
|
final Class direction = createClassLoader(generateClassesInFile()).loadClass("Direction");
|
||||||
// System.out.println(generateToText());
|
// System.out.println(generateToText());
|
||||||
final Field north = direction.getField("NORTH");
|
final Field north = direction.getField("NORTH");
|
||||||
assertEquals(direction, north.getType());
|
assertEquals(direction, north.getType());
|
||||||
assertInstanceOf(north.get(null), direction);
|
assertInstanceOf(north.get(null), direction);
|
||||||
@@ -241,94 +241,94 @@ public class ClassGenTest extends CodegenTestCase {
|
|||||||
blackBoxFile("regressions/kt249.jet");
|
blackBoxFile("regressions/kt249.jet");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testKt48 () throws Exception {
|
public void testKt48() throws Exception {
|
||||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
blackBoxFile("regressions/kt48.jet");
|
blackBoxFile("regressions/kt48.jet");
|
||||||
// System.out.println(generateToText());
|
// System.out.println(generateToText());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testKt309 () throws Exception {
|
public void testKt309() throws Exception {
|
||||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
loadText("fun box() = null");
|
loadText("fun box() = null");
|
||||||
final Method method = generateFunction("box");
|
final Method method = generateFunction("box");
|
||||||
assertEquals(method.getReturnType().getName(), "java.lang.Object");
|
assertEquals(method.getReturnType().getName(), "java.lang.Object");
|
||||||
// System.out.println(generateToText());
|
// System.out.println(generateToText());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testKt343 () throws Exception {
|
public void testKt343() throws Exception {
|
||||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
blackBoxFile("regressions/kt343.jet");
|
blackBoxFile("regressions/kt343.jet");
|
||||||
// System.out.println(generateToText());
|
// System.out.println(generateToText());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testKt508 () throws Exception {
|
public void testKt508() throws Exception {
|
||||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
loadFile("regressions/kt508.jet");
|
loadFile("regressions/kt508.jet");
|
||||||
// System.out.println(generateToText());
|
// System.out.println(generateToText());
|
||||||
blackBox();
|
blackBox();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testKt504 () throws Exception {
|
public void testKt504() throws Exception {
|
||||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
loadFile("regressions/kt504.jet");
|
loadFile("regressions/kt504.jet");
|
||||||
// System.out.println(generateToText());
|
// System.out.println(generateToText());
|
||||||
blackBox();
|
blackBox();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testKt501 () throws Exception {
|
public void testKt501() throws Exception {
|
||||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
blackBoxFile("regressions/kt501.jet");
|
blackBoxFile("regressions/kt501.jet");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testKt496 () throws Exception {
|
public void testKt496() throws Exception {
|
||||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
blackBoxFile("regressions/kt496.jet");
|
blackBoxFile("regressions/kt496.jet");
|
||||||
// System.out.println(generateToText());
|
// System.out.println(generateToText());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testKt500 () throws Exception {
|
public void testKt500() throws Exception {
|
||||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
blackBoxFile("regressions/kt500.jet");
|
blackBoxFile("regressions/kt500.jet");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testKt694 () throws Exception {
|
public void testKt694() throws Exception {
|
||||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
// blackBoxFile("regressions/kt694.jet");
|
// blackBoxFile("regressions/kt694.jet");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testKt285 () throws Exception {
|
public void testKt285() throws Exception {
|
||||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
// blackBoxFile("regressions/kt285.jet");
|
// blackBoxFile("regressions/kt285.jet");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testKt707 () throws Exception {
|
public void testKt707() throws Exception {
|
||||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
blackBoxFile("regressions/kt707.jet");
|
blackBoxFile("regressions/kt707.jet");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testKt857 () throws Exception {
|
public void testKt857() throws Exception {
|
||||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
// blackBoxFile("regressions/kt857.jet");
|
// blackBoxFile("regressions/kt857.jet");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testKt903 () throws Exception {
|
public void testKt903() throws Exception {
|
||||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
blackBoxFile("regressions/kt903.jet");
|
blackBoxFile("regressions/kt903.jet");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testKt940 () throws Exception {
|
public void testKt940() throws Exception {
|
||||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
blackBoxFile("regressions/kt940.kt");
|
blackBoxFile("regressions/kt940.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testKt1018 () throws Exception {
|
public void testKt1018() throws Exception {
|
||||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
blackBoxFile("regressions/kt1018.kt");
|
blackBoxFile("regressions/kt1018.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testKt1120 () throws Exception {
|
public void testKt1120() throws Exception {
|
||||||
//createEnvironmentWithFullJdk();
|
//createEnvironmentWithFullJdk();
|
||||||
// blackBoxFile("regressions/kt1120.kt");
|
// blackBoxFile("regressions/kt1120.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSelfCreate() throws Exception {
|
public void testSelfCreate() throws Exception {
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2012 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
|
import org.jetbrains.jet.ConfigurationKind;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
public class LocalClassGenTest extends CodegenTestCase {
|
||||||
|
@Override
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testNoClosure() {
|
||||||
|
blackBoxFile("localcls/noclosure.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testWithClosure() {
|
||||||
|
//blackBoxFile("localcls/withclosure.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testEnum() {
|
||||||
|
//blackBoxFile("localcls/enum.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testObject() {
|
||||||
|
blackBoxFile("localcls/object.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user