|
|
|
@@ -44,10 +44,7 @@ import org.jetbrains.jet.lang.resolve.name.Name;
|
|
|
|
|
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
|
|
|
|
import org.jetbrains.jet.lang.types.JetType;
|
|
|
|
|
|
|
|
|
|
import java.util.Collections;
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
import java.util.*;
|
|
|
|
|
|
|
|
|
|
import static org.jetbrains.jet.codegen.CodegenUtil.peekFromStack;
|
|
|
|
|
import static org.jetbrains.jet.codegen.FunctionTypesUtil.getSuperTypeForClosure;
|
|
|
|
@@ -59,9 +56,32 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
|
|
|
|
private static final TokenSet BINARY_OPERATIONS = TokenSet.orSet(
|
|
|
|
|
AUGMENTED_ASSIGNMENTS, TokenSet.create(PLUS, MINUS, MUL, DIV, PERC, RANGE, LT, GT, LTEQ, GTEQ, IDENTIFIER));
|
|
|
|
|
|
|
|
|
|
private static class ClassDescriptorWithState {
|
|
|
|
|
|
|
|
|
|
private boolean isDelegationToSuperCall;
|
|
|
|
|
|
|
|
|
|
private ClassDescriptor descriptor;
|
|
|
|
|
|
|
|
|
|
public ClassDescriptorWithState(ClassDescriptor descriptor) {
|
|
|
|
|
this.descriptor = descriptor;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public boolean isDelegationToSuperCall() {
|
|
|
|
|
return isDelegationToSuperCall;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setDelegationToSuperCall(boolean isDelegationToSuperCall) {
|
|
|
|
|
this.isDelegationToSuperCall = isDelegationToSuperCall;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ClassDescriptor getDescriptor() {
|
|
|
|
|
return descriptor;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private final Map<String, Integer> anonymousSubclassesCount = new HashMap<String, Integer>();
|
|
|
|
|
|
|
|
|
|
private final Stack<ClassDescriptor> classStack = new Stack<ClassDescriptor>();
|
|
|
|
|
private final Stack<ClassDescriptorWithState> classStack = new Stack<ClassDescriptorWithState>();
|
|
|
|
|
private final Stack<String> nameStack = new Stack<String>();
|
|
|
|
|
private final BindingTrace bindingTrace;
|
|
|
|
|
private final BindingContext bindingContext;
|
|
|
|
@@ -129,7 +149,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
|
|
|
|
if (file.isScript()) {
|
|
|
|
|
//noinspection ConstantConditions
|
|
|
|
|
ClassDescriptor classDescriptor = bindingContext.get(CLASS_FOR_SCRIPT, bindingContext.get(SCRIPT, file.getScript()));
|
|
|
|
|
classStack.push(classDescriptor);
|
|
|
|
|
pushClassDescriptor(classDescriptor);
|
|
|
|
|
//noinspection ConstantConditions
|
|
|
|
|
nameStack.push(asmTypeForScriptPsi(bindingContext, file.getScript()).getInternalName());
|
|
|
|
|
}
|
|
|
|
@@ -139,7 +159,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
|
|
|
|
file.acceptChildren(this);
|
|
|
|
|
nameStack.pop();
|
|
|
|
|
if (file.isScript()) {
|
|
|
|
|
classStack.pop();
|
|
|
|
|
popClassDescriptor();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -154,7 +174,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
|
|
|
|
super.visitEnumEntry(enumEntry);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
Type asmType = bindingTrace.get(ASM_TYPE, peekFromStack(classStack));
|
|
|
|
|
Type asmType = bindingTrace.get(ASM_TYPE, getOuterClassDescriptor());
|
|
|
|
|
assert PsiCodegenPredictor.checkPredictedNameFromPsi(bindingTrace, descriptor, asmType);
|
|
|
|
|
bindingTrace.record(ASM_TYPE, descriptor, asmType);
|
|
|
|
|
}
|
|
|
|
@@ -168,11 +188,11 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
|
|
|
|
String name = peekFromStack(nameStack) + JvmAbi.CLASS_OBJECT_SUFFIX;
|
|
|
|
|
recordClosure(classObject, classDescriptor, name);
|
|
|
|
|
|
|
|
|
|
classStack.push(classDescriptor);
|
|
|
|
|
pushClassDescriptor(classDescriptor);
|
|
|
|
|
nameStack.push(name);
|
|
|
|
|
super.visitClassObject(classObject);
|
|
|
|
|
nameStack.pop();
|
|
|
|
|
classStack.pop();
|
|
|
|
|
popClassDescriptor();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@@ -188,11 +208,11 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
|
|
|
|
String name = getName(classDescriptor);
|
|
|
|
|
recordClosure(declaration, classDescriptor, name);
|
|
|
|
|
|
|
|
|
|
classStack.push(classDescriptor);
|
|
|
|
|
pushClassDescriptor(classDescriptor);
|
|
|
|
|
nameStack.push(name);
|
|
|
|
|
super.visitObjectDeclaration(declaration);
|
|
|
|
|
nameStack.pop();
|
|
|
|
|
classStack.pop();
|
|
|
|
|
popClassDescriptor();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -205,11 +225,11 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
|
|
|
|
String name = getName(classDescriptor);
|
|
|
|
|
recordClosure(klass, classDescriptor, name);
|
|
|
|
|
|
|
|
|
|
classStack.push(classDescriptor);
|
|
|
|
|
pushClassDescriptor(classDescriptor);
|
|
|
|
|
nameStack.push(name);
|
|
|
|
|
super.visitClass(klass);
|
|
|
|
|
nameStack.pop();
|
|
|
|
|
classStack.pop();
|
|
|
|
|
popClassDescriptor();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private String getName(ClassDescriptor classDescriptor) {
|
|
|
|
@@ -230,12 +250,12 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
|
|
|
|
String name = inventAnonymousClassName(expression.getObjectDeclaration());
|
|
|
|
|
recordClosure(expression.getObjectDeclaration(), classDescriptor, name);
|
|
|
|
|
|
|
|
|
|
classStack.push(classDescriptor);
|
|
|
|
|
pushClassDescriptor(classDescriptor);
|
|
|
|
|
//noinspection ConstantConditions
|
|
|
|
|
nameStack.push(bindingContext.get(ASM_TYPE, classDescriptor).getInternalName());
|
|
|
|
|
super.visitObjectLiteralExpression(expression);
|
|
|
|
|
nameStack.pop();
|
|
|
|
|
classStack.pop();
|
|
|
|
|
popClassDescriptor();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
@@ -251,13 +271,41 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
|
|
|
|
ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor, superType);
|
|
|
|
|
recordClosure(functionLiteral, classDescriptor, name);
|
|
|
|
|
|
|
|
|
|
classStack.push(classDescriptor);
|
|
|
|
|
pushClassDescriptor(classDescriptor);
|
|
|
|
|
nameStack.push(name);
|
|
|
|
|
super.visitFunctionLiteralExpression(expression);
|
|
|
|
|
nameStack.pop();
|
|
|
|
|
popClassDescriptor();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void pushClassDescriptor(ClassDescriptor classDescriptor) {
|
|
|
|
|
classStack.push(new ClassDescriptorWithState(classDescriptor));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void popClassDescriptor() {
|
|
|
|
|
classStack.pop();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private ClassDescriptor getOuterClassDescriptor() {
|
|
|
|
|
ListIterator<ClassDescriptorWithState> iterator = classStack.listIterator(classStack.size());
|
|
|
|
|
while(iterator.hasPrevious()) {
|
|
|
|
|
ClassDescriptorWithState previous = iterator.previous();
|
|
|
|
|
if (!previous.isDelegationToSuperCall()) {//find last not delegated to super call
|
|
|
|
|
return previous.getDescriptor();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void visitDelegationToSuperCallSpecifier(JetDelegatorToSuperCall call) {
|
|
|
|
|
ClassDescriptorWithState state = peekFromStack(classStack);
|
|
|
|
|
assert state != null : "Class descriptor should be recorded before " + call + " processing";
|
|
|
|
|
state.setDelegationToSuperCall(true);
|
|
|
|
|
super.visitDelegationToSuperCallSpecifier(call);
|
|
|
|
|
state.setDelegationToSuperCall(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void visitCallableReferenceExpression(JetCallableReferenceExpression expression) {
|
|
|
|
|
FunctionDescriptor functionDescriptor = bindingContext.get(FUNCTION, expression);
|
|
|
|
@@ -273,19 +321,20 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
|
|
|
|
ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor, superType);
|
|
|
|
|
recordClosure(expression, classDescriptor, name);
|
|
|
|
|
|
|
|
|
|
classStack.push(classDescriptor);
|
|
|
|
|
pushClassDescriptor(classDescriptor);
|
|
|
|
|
nameStack.push(name);
|
|
|
|
|
super.visitCallableReferenceExpression(expression);
|
|
|
|
|
nameStack.pop();
|
|
|
|
|
classStack.pop();
|
|
|
|
|
popClassDescriptor();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void recordClosure(
|
|
|
|
|
@NotNull JetElement element,
|
|
|
|
|
@NotNull ClassDescriptor classDescriptor,
|
|
|
|
|
@NotNull String name
|
|
|
|
|
) {
|
|
|
|
|
CodegenBinding.recordClosure(bindingTrace, element, classDescriptor, peekFromStack(classStack),
|
|
|
|
|
CodegenBinding.recordClosure(bindingTrace, element, classDescriptor, getOuterClassDescriptor(),
|
|
|
|
|
Type.getObjectType(name));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -324,11 +373,11 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
|
|
|
|
ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor, superType);
|
|
|
|
|
recordClosure(function, classDescriptor, name);
|
|
|
|
|
|
|
|
|
|
classStack.push(classDescriptor);
|
|
|
|
|
pushClassDescriptor(classDescriptor);
|
|
|
|
|
nameStack.push(name);
|
|
|
|
|
super.visitNamedFunction(function);
|
|
|
|
|
nameStack.pop();
|
|
|
|
|
classStack.pop();
|
|
|
|
|
popClassDescriptor();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|