Refactor CodegenBinding
- store source element in synthetic descriptor for easier debugging and lesser amount of needed method parameters everywhere - simplify methods which calculate necessary information for MutableClosure
This commit is contained in:
+15
-17
@@ -50,6 +50,7 @@ import org.jetbrains.jet.lang.resolve.kotlin.PackagePartClassUtils;
|
|||||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||||
|
import org.jetbrains.jet.lang.resolve.source.SourcePackage;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.org.objectweb.asm.Type;
|
import org.jetbrains.org.objectweb.asm.Type;
|
||||||
|
|
||||||
@@ -108,6 +109,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private ClassDescriptor recordClassForFunction(
|
private ClassDescriptor recordClassForFunction(
|
||||||
|
@NotNull JetElement element,
|
||||||
@NotNull FunctionDescriptor funDescriptor,
|
@NotNull FunctionDescriptor funDescriptor,
|
||||||
@NotNull Collection<JetType> supertypes,
|
@NotNull Collection<JetType> supertypes,
|
||||||
@NotNull String name
|
@NotNull String name
|
||||||
@@ -115,7 +117,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
|||||||
String simpleName = name.substring(name.lastIndexOf('/') + 1);
|
String simpleName = name.substring(name.lastIndexOf('/') + 1);
|
||||||
ClassDescriptorImpl classDescriptor = new ClassDescriptorImpl(
|
ClassDescriptorImpl classDescriptor = new ClassDescriptorImpl(
|
||||||
funDescriptor.getContainingDeclaration(), Name.special("<closure-" + simpleName + ">"), Modality.FINAL, supertypes,
|
funDescriptor.getContainingDeclaration(), Name.special("<closure-" + simpleName + ">"), Modality.FINAL, supertypes,
|
||||||
SourceElement.NO_SOURCE
|
SourcePackage.toSourceElement(element)
|
||||||
);
|
);
|
||||||
classDescriptor.initialize(JetScope.EMPTY, Collections.<ConstructorDescriptor>emptySet(), null);
|
classDescriptor.initialize(JetScope.EMPTY, Collections.<ConstructorDescriptor>emptySet(), null);
|
||||||
|
|
||||||
@@ -194,7 +196,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
|||||||
JetPsiUtil.getElementTextWithContext(classObject));
|
JetPsiUtil.getElementTextWithContext(classObject));
|
||||||
|
|
||||||
String name = peekFromStack(nameStack) + JvmAbi.CLASS_OBJECT_SUFFIX;
|
String name = peekFromStack(nameStack) + JvmAbi.CLASS_OBJECT_SUFFIX;
|
||||||
recordClosure(classObject, classDescriptor, name);
|
recordClosure(classDescriptor, name);
|
||||||
|
|
||||||
pushClassDescriptor(classDescriptor);
|
pushClassDescriptor(classDescriptor);
|
||||||
nameStack.push(name);
|
nameStack.push(name);
|
||||||
@@ -216,7 +218,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
|||||||
if (classDescriptor == null) return;
|
if (classDescriptor == null) return;
|
||||||
|
|
||||||
String name = getName(classDescriptor);
|
String name = getName(classDescriptor);
|
||||||
recordClosure(declaration, classDescriptor, name);
|
recordClosure(classDescriptor, name);
|
||||||
|
|
||||||
pushClassDescriptor(classDescriptor);
|
pushClassDescriptor(classDescriptor);
|
||||||
nameStack.push(name);
|
nameStack.push(name);
|
||||||
@@ -235,7 +237,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
|||||||
if (classDescriptor == null) return;
|
if (classDescriptor == null) return;
|
||||||
|
|
||||||
String name = getName(classDescriptor);
|
String name = getName(classDescriptor);
|
||||||
recordClosure(klass, classDescriptor, name);
|
recordClosure(classDescriptor, name);
|
||||||
|
|
||||||
pushClassDescriptor(classDescriptor);
|
pushClassDescriptor(classDescriptor);
|
||||||
nameStack.push(name);
|
nameStack.push(name);
|
||||||
@@ -261,7 +263,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String name = inventAnonymousClassName(expression.getObjectDeclaration());
|
String name = inventAnonymousClassName(expression.getObjectDeclaration());
|
||||||
recordClosure(expression.getObjectDeclaration(), classDescriptor, name);
|
recordClosure(classDescriptor, name);
|
||||||
|
|
||||||
pushClassDescriptor(classDescriptor);
|
pushClassDescriptor(classDescriptor);
|
||||||
nameStack.push(CodegenBinding.getAsmType(bindingContext, classDescriptor).getInternalName());
|
nameStack.push(CodegenBinding.getAsmType(bindingContext, classDescriptor).getInternalName());
|
||||||
@@ -280,8 +282,8 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
|||||||
|
|
||||||
String name = inventAnonymousClassName(expression);
|
String name = inventAnonymousClassName(expression);
|
||||||
Collection<JetType> supertypes = runtimeTypes.getSupertypesForClosure(functionDescriptor);
|
Collection<JetType> supertypes = runtimeTypes.getSupertypesForClosure(functionDescriptor);
|
||||||
ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor, supertypes, name);
|
ClassDescriptor classDescriptor = recordClassForFunction(functionLiteral, functionDescriptor, supertypes, name);
|
||||||
recordClosure(functionLiteral, classDescriptor, name);
|
recordClosure(classDescriptor, name);
|
||||||
|
|
||||||
pushClassDescriptor(classDescriptor);
|
pushClassDescriptor(classDescriptor);
|
||||||
nameStack.push(name);
|
nameStack.push(name);
|
||||||
@@ -331,8 +333,8 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
|||||||
runtimeTypes.getSupertypesForFunctionReference((FunctionDescriptor) referencedFunction.getResultingDescriptor());
|
runtimeTypes.getSupertypesForFunctionReference((FunctionDescriptor) referencedFunction.getResultingDescriptor());
|
||||||
|
|
||||||
String name = inventAnonymousClassName(expression);
|
String name = inventAnonymousClassName(expression);
|
||||||
ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor, supertypes, name);
|
ClassDescriptor classDescriptor = recordClassForFunction(expression, functionDescriptor, supertypes, name);
|
||||||
recordClosure(expression, classDescriptor, name);
|
recordClosure(classDescriptor, name);
|
||||||
|
|
||||||
pushClassDescriptor(classDescriptor);
|
pushClassDescriptor(classDescriptor);
|
||||||
nameStack.push(name);
|
nameStack.push(name);
|
||||||
@@ -342,12 +344,8 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void recordClosure(
|
private void recordClosure(@NotNull ClassDescriptor classDescriptor, @NotNull String name) {
|
||||||
@NotNull JetElement element,
|
CodegenBinding.recordClosure(bindingTrace, classDescriptor, getOuterClassDescriptor(), Type.getObjectType(name));
|
||||||
@NotNull ClassDescriptor classDescriptor,
|
|
||||||
@NotNull String name
|
|
||||||
) {
|
|
||||||
CodegenBinding.recordClosure(bindingTrace, element, classDescriptor, getOuterClassDescriptor(), Type.getObjectType(name));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -382,8 +380,8 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
|||||||
else {
|
else {
|
||||||
String name = inventAnonymousClassName(function);
|
String name = inventAnonymousClassName(function);
|
||||||
Collection<JetType> supertypes = runtimeTypes.getSupertypesForClosure(functionDescriptor);
|
Collection<JetType> supertypes = runtimeTypes.getSupertypesForClosure(functionDescriptor);
|
||||||
ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor, supertypes, name);
|
ClassDescriptor classDescriptor = recordClassForFunction(function, functionDescriptor, supertypes, name);
|
||||||
recordClosure(function, classDescriptor, name);
|
recordClosure(classDescriptor, name);
|
||||||
|
|
||||||
pushClassDescriptor(classDescriptor);
|
pushClassDescriptor(classDescriptor);
|
||||||
nameStack.push(name);
|
nameStack.push(name);
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
|
|||||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
|
||||||
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
||||||
import org.jetbrains.jet.util.slicedmap.BasicWritableSlice;
|
import org.jetbrains.jet.util.slicedmap.BasicWritableSlice;
|
||||||
import org.jetbrains.jet.util.slicedmap.Slices;
|
import org.jetbrains.jet.util.slicedmap.Slices;
|
||||||
@@ -42,6 +41,7 @@ import java.util.*;
|
|||||||
|
|
||||||
import static org.jetbrains.jet.codegen.JvmCodegenUtil.isInterface;
|
import static org.jetbrains.jet.codegen.JvmCodegenUtil.isInterface;
|
||||||
import static org.jetbrains.jet.lang.resolve.BindingContext.*;
|
import static org.jetbrains.jet.lang.resolve.BindingContext.*;
|
||||||
|
import static org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils.descriptorToDeclaration;
|
||||||
import static org.jetbrains.jet.lang.resolve.calls.callUtil.CallUtilPackage.getResolvedCall;
|
import static org.jetbrains.jet.lang.resolve.calls.callUtil.CallUtilPackage.getResolvedCall;
|
||||||
import static org.jetbrains.jet.lang.resolve.source.SourcePackage.toSourceElement;
|
import static org.jetbrains.jet.lang.resolve.source.SourcePackage.toSourceElement;
|
||||||
|
|
||||||
@@ -151,40 +151,28 @@ public class CodegenBinding {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void recordClosure(
|
static void recordClosure(
|
||||||
@NotNull BindingTrace bindingTrace,
|
@NotNull BindingTrace trace,
|
||||||
@NotNull JetElement element,
|
|
||||||
@NotNull ClassDescriptor classDescriptor,
|
@NotNull ClassDescriptor classDescriptor,
|
||||||
@Nullable ClassDescriptor enclosing,
|
@Nullable ClassDescriptor enclosing,
|
||||||
@NotNull Type asmType
|
@NotNull Type asmType
|
||||||
) {
|
) {
|
||||||
ResolvedCall<ConstructorDescriptor> superCall = findSuperCall(bindingTrace.getBindingContext(), element);
|
JetElement element = (JetElement) descriptorToDeclaration(classDescriptor);
|
||||||
|
assert element != null : "No source element for " + classDescriptor;
|
||||||
|
|
||||||
CallableDescriptor enclosingReceiver = null;
|
MutableClosure closure = new MutableClosure(classDescriptor, findSuperCall(trace.getBindingContext(), element), enclosing);
|
||||||
if (classDescriptor.getContainingDeclaration() instanceof CallableDescriptor) {
|
|
||||||
enclosingReceiver = (CallableDescriptor) classDescriptor.getContainingDeclaration();
|
|
||||||
enclosingReceiver = enclosingReceiver instanceof PropertyAccessorDescriptor
|
|
||||||
? ((PropertyAccessorDescriptor) enclosingReceiver).getCorrespondingProperty()
|
|
||||||
: enclosingReceiver;
|
|
||||||
|
|
||||||
if (enclosingReceiver.getReceiverParameter() == null) {
|
|
||||||
enclosingReceiver = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MutableClosure closure = new MutableClosure(superCall, enclosing, enclosingReceiver);
|
|
||||||
|
|
||||||
assert PsiCodegenPredictor.checkPredictedNameFromPsi(classDescriptor, asmType);
|
|
||||||
bindingTrace.record(ASM_TYPE, classDescriptor, asmType);
|
|
||||||
bindingTrace.record(CLOSURE, classDescriptor, closure);
|
|
||||||
|
|
||||||
if (classDescriptor.isInner()) {
|
if (classDescriptor.isInner()) {
|
||||||
closure.setCaptureThis();
|
closure.setCaptureThis();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert PsiCodegenPredictor.checkPredictedNameFromPsi(classDescriptor, asmType);
|
||||||
|
trace.record(ASM_TYPE, classDescriptor, asmType);
|
||||||
|
trace.record(CLOSURE, classDescriptor, closure);
|
||||||
|
|
||||||
//TEMPORARY EAT INNER CLASS INFO FOR FUNCTION LITERALS
|
//TEMPORARY EAT INNER CLASS INFO FOR FUNCTION LITERALS
|
||||||
//TODO: we should understand that lambda/closure would be inlined and don't generate inner class record
|
//TODO: we should understand that lambda/closure would be inlined and don't generate inner class record
|
||||||
if (enclosing != null && !(element instanceof JetFunctionLiteral)) {
|
if (enclosing != null && !(element instanceof JetFunctionLiteral)) {
|
||||||
recordInnerClass(bindingTrace, enclosing, classDescriptor);
|
recordInnerClass(trace, enclosing, classDescriptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,7 +202,7 @@ public class CodegenBinding {
|
|||||||
Collections.singleton(KotlinBuiltIns.getInstance().getAnyType()), toSourceElement(script));
|
Collections.singleton(KotlinBuiltIns.getInstance().getAnyType()), toSourceElement(script));
|
||||||
classDescriptor.initialize(JetScope.EMPTY, Collections.<ConstructorDescriptor>emptySet(), null);
|
classDescriptor.initialize(JetScope.EMPTY, Collections.<ConstructorDescriptor>emptySet(), null);
|
||||||
|
|
||||||
recordClosure(trace, script, classDescriptor, null, asmType);
|
recordClosure(trace, classDescriptor, null, asmType);
|
||||||
|
|
||||||
trace.record(CLASS_FOR_SCRIPT, descriptor, classDescriptor);
|
trace.record(CLASS_FOR_SCRIPT, descriptor, classDescriptor);
|
||||||
}
|
}
|
||||||
@@ -285,28 +273,20 @@ public class CodegenBinding {
|
|||||||
@NotNull BindingContext bindingContext,
|
@NotNull BindingContext bindingContext,
|
||||||
@NotNull JetElement classOrObject
|
@NotNull JetElement classOrObject
|
||||||
) {
|
) {
|
||||||
if (!(classOrObject instanceof JetClassOrObject)) {
|
if (!(classOrObject instanceof JetClassOrObject)) return null;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (classOrObject instanceof JetClass && ((JetClass) classOrObject).isTrait()) {
|
if (classOrObject instanceof JetClass && ((JetClass) classOrObject).isTrait()) return null;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (JetDelegationSpecifier specifier : ((JetClassOrObject) classOrObject).getDelegationSpecifiers()) {
|
for (JetDelegationSpecifier specifier : ((JetClassOrObject) classOrObject).getDelegationSpecifiers()) {
|
||||||
if (specifier instanceof JetDelegatorToSuperCall) {
|
if (!(specifier instanceof JetDelegatorToSuperCall)) continue;
|
||||||
JetType supertype = bindingContext.get(TYPE, specifier.getTypeReference());
|
|
||||||
assert supertype != null : String.format(
|
|
||||||
"No type in binding context for \n---\n%s\n---\n", JetPsiUtil.getElementTextWithContext(specifier));
|
|
||||||
|
|
||||||
ClassifierDescriptor superClass = supertype.getConstructor().getDeclarationDescriptor();
|
ResolvedCall<?> resolvedCall = getResolvedCall(specifier, bindingContext);
|
||||||
if (superClass != null && !isInterface(superClass)) {
|
if (resolvedCall == null) continue;
|
||||||
ResolvedCall<?> resolvedCall = getResolvedCall(specifier, bindingContext);
|
|
||||||
if (resolvedCall != null && resolvedCall.getResultingDescriptor() instanceof ConstructorDescriptor) {
|
CallableDescriptor constructor = resolvedCall.getResultingDescriptor();
|
||||||
//noinspection unchecked
|
if (constructor instanceof ConstructorDescriptor && !isInterface(constructor.getContainingDeclaration())) {
|
||||||
return (ResolvedCall<ConstructorDescriptor>) resolvedCall;
|
//noinspection unchecked
|
||||||
}
|
return (ResolvedCall<ConstructorDescriptor>) resolvedCall;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ import org.jetbrains.org.objectweb.asm.Type;
|
|||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
import static org.jetbrains.jet.codegen.JvmCodegenUtil.getDirectMember;
|
||||||
|
|
||||||
public final class MutableClosure implements CalculatedClosure {
|
public final class MutableClosure implements CalculatedClosure {
|
||||||
private final ResolvedCall<ConstructorDescriptor> superCall;
|
private final ResolvedCall<ConstructorDescriptor> superCall;
|
||||||
|
|
||||||
@@ -40,13 +42,25 @@ public final class MutableClosure implements CalculatedClosure {
|
|||||||
private List<Pair<String, Type>> recordedFields;
|
private List<Pair<String, Type>> recordedFields;
|
||||||
|
|
||||||
MutableClosure(
|
MutableClosure(
|
||||||
|
@NotNull ClassDescriptor classDescriptor,
|
||||||
@Nullable ResolvedCall<ConstructorDescriptor> superCall,
|
@Nullable ResolvedCall<ConstructorDescriptor> superCall,
|
||||||
@Nullable ClassDescriptor enclosingClass,
|
@Nullable ClassDescriptor enclosingClass
|
||||||
@Nullable CallableDescriptor enclosingReceiverDescriptor
|
|
||||||
) {
|
) {
|
||||||
this.superCall = superCall;
|
|
||||||
this.enclosingClass = enclosingClass;
|
this.enclosingClass = enclosingClass;
|
||||||
this.enclosingReceiverDescriptor = enclosingReceiverDescriptor;
|
this.superCall = superCall;
|
||||||
|
this.enclosingReceiverDescriptor = enclosingExtensionMemberForClass(classDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private static CallableDescriptor enclosingExtensionMemberForClass(@NotNull ClassDescriptor classDescriptor) {
|
||||||
|
DeclarationDescriptor classContainer = classDescriptor.getContainingDeclaration();
|
||||||
|
if (classContainer instanceof CallableMemberDescriptor) {
|
||||||
|
CallableMemberDescriptor member = getDirectMember((CallableMemberDescriptor) classContainer);
|
||||||
|
if (member.getReceiverParameter() != null) {
|
||||||
|
return member;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
+3
-2
@@ -169,8 +169,9 @@ public class KotlinJavaFileStubProvider<T extends WithFileStubAndExtraDiagnostic
|
|||||||
|
|
||||||
Map<JetClassOrObject, InnerKotlinClassLightClassData> innerClassesMap = ContainerUtil.newHashMap();
|
Map<JetClassOrObject, InnerKotlinClassLightClassData> innerClassesMap = ContainerUtil.newHashMap();
|
||||||
for (ClassDescriptor innerClassDescriptor : allInnerClasses) {
|
for (ClassDescriptor innerClassDescriptor : allInnerClasses) {
|
||||||
JetClassOrObject innerClass = (JetClassOrObject) descriptorToDeclaration(innerClassDescriptor);
|
PsiElement declaration = descriptorToDeclaration(innerClassDescriptor);
|
||||||
if (innerClass == null) continue;
|
if (!(declaration instanceof JetClassOrObject)) continue;
|
||||||
|
JetClassOrObject innerClass = (JetClassOrObject) declaration;
|
||||||
|
|
||||||
InnerKotlinClassLightClassData innerLightClassData = new InnerKotlinClassLightClassData(
|
InnerKotlinClassLightClassData innerLightClassData = new InnerKotlinClassLightClassData(
|
||||||
predictClassFqName(bindingContext, innerClassDescriptor),
|
predictClassFqName(bindingContext, innerClassDescriptor),
|
||||||
|
|||||||
Reference in New Issue
Block a user