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.Name;
|
||||
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.org.objectweb.asm.Type;
|
||||
|
||||
@@ -108,6 +109,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
||||
|
||||
@NotNull
|
||||
private ClassDescriptor recordClassForFunction(
|
||||
@NotNull JetElement element,
|
||||
@NotNull FunctionDescriptor funDescriptor,
|
||||
@NotNull Collection<JetType> supertypes,
|
||||
@NotNull String name
|
||||
@@ -115,7 +117,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
||||
String simpleName = name.substring(name.lastIndexOf('/') + 1);
|
||||
ClassDescriptorImpl classDescriptor = new ClassDescriptorImpl(
|
||||
funDescriptor.getContainingDeclaration(), Name.special("<closure-" + simpleName + ">"), Modality.FINAL, supertypes,
|
||||
SourceElement.NO_SOURCE
|
||||
SourcePackage.toSourceElement(element)
|
||||
);
|
||||
classDescriptor.initialize(JetScope.EMPTY, Collections.<ConstructorDescriptor>emptySet(), null);
|
||||
|
||||
@@ -194,7 +196,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
||||
JetPsiUtil.getElementTextWithContext(classObject));
|
||||
|
||||
String name = peekFromStack(nameStack) + JvmAbi.CLASS_OBJECT_SUFFIX;
|
||||
recordClosure(classObject, classDescriptor, name);
|
||||
recordClosure(classDescriptor, name);
|
||||
|
||||
pushClassDescriptor(classDescriptor);
|
||||
nameStack.push(name);
|
||||
@@ -216,7 +218,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
||||
if (classDescriptor == null) return;
|
||||
|
||||
String name = getName(classDescriptor);
|
||||
recordClosure(declaration, classDescriptor, name);
|
||||
recordClosure(classDescriptor, name);
|
||||
|
||||
pushClassDescriptor(classDescriptor);
|
||||
nameStack.push(name);
|
||||
@@ -235,7 +237,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
||||
if (classDescriptor == null) return;
|
||||
|
||||
String name = getName(classDescriptor);
|
||||
recordClosure(klass, classDescriptor, name);
|
||||
recordClosure(classDescriptor, name);
|
||||
|
||||
pushClassDescriptor(classDescriptor);
|
||||
nameStack.push(name);
|
||||
@@ -261,7 +263,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
||||
}
|
||||
|
||||
String name = inventAnonymousClassName(expression.getObjectDeclaration());
|
||||
recordClosure(expression.getObjectDeclaration(), classDescriptor, name);
|
||||
recordClosure(classDescriptor, name);
|
||||
|
||||
pushClassDescriptor(classDescriptor);
|
||||
nameStack.push(CodegenBinding.getAsmType(bindingContext, classDescriptor).getInternalName());
|
||||
@@ -280,8 +282,8 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
||||
|
||||
String name = inventAnonymousClassName(expression);
|
||||
Collection<JetType> supertypes = runtimeTypes.getSupertypesForClosure(functionDescriptor);
|
||||
ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor, supertypes, name);
|
||||
recordClosure(functionLiteral, classDescriptor, name);
|
||||
ClassDescriptor classDescriptor = recordClassForFunction(functionLiteral, functionDescriptor, supertypes, name);
|
||||
recordClosure(classDescriptor, name);
|
||||
|
||||
pushClassDescriptor(classDescriptor);
|
||||
nameStack.push(name);
|
||||
@@ -331,8 +333,8 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
||||
runtimeTypes.getSupertypesForFunctionReference((FunctionDescriptor) referencedFunction.getResultingDescriptor());
|
||||
|
||||
String name = inventAnonymousClassName(expression);
|
||||
ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor, supertypes, name);
|
||||
recordClosure(expression, classDescriptor, name);
|
||||
ClassDescriptor classDescriptor = recordClassForFunction(expression, functionDescriptor, supertypes, name);
|
||||
recordClosure(classDescriptor, name);
|
||||
|
||||
pushClassDescriptor(classDescriptor);
|
||||
nameStack.push(name);
|
||||
@@ -342,12 +344,8 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
||||
}
|
||||
|
||||
|
||||
private void recordClosure(
|
||||
@NotNull JetElement element,
|
||||
@NotNull ClassDescriptor classDescriptor,
|
||||
@NotNull String name
|
||||
) {
|
||||
CodegenBinding.recordClosure(bindingTrace, element, classDescriptor, getOuterClassDescriptor(), Type.getObjectType(name));
|
||||
private void recordClosure(@NotNull ClassDescriptor classDescriptor, @NotNull String name) {
|
||||
CodegenBinding.recordClosure(bindingTrace, classDescriptor, getOuterClassDescriptor(), Type.getObjectType(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -382,8 +380,8 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid {
|
||||
else {
|
||||
String name = inventAnonymousClassName(function);
|
||||
Collection<JetType> supertypes = runtimeTypes.getSupertypesForClosure(functionDescriptor);
|
||||
ClassDescriptor classDescriptor = recordClassForFunction(functionDescriptor, supertypes, name);
|
||||
recordClosure(function, classDescriptor, name);
|
||||
ClassDescriptor classDescriptor = recordClassForFunction(function, functionDescriptor, supertypes, name);
|
||||
recordClosure(classDescriptor, name);
|
||||
|
||||
pushClassDescriptor(classDescriptor);
|
||||
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.Name;
|
||||
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.util.slicedmap.BasicWritableSlice;
|
||||
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.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.source.SourcePackage.toSourceElement;
|
||||
|
||||
@@ -151,40 +151,28 @@ public class CodegenBinding {
|
||||
}
|
||||
|
||||
static void recordClosure(
|
||||
@NotNull BindingTrace bindingTrace,
|
||||
@NotNull JetElement element,
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull ClassDescriptor classDescriptor,
|
||||
@Nullable ClassDescriptor enclosing,
|
||||
@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;
|
||||
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);
|
||||
MutableClosure closure = new MutableClosure(classDescriptor, findSuperCall(trace.getBindingContext(), element), enclosing);
|
||||
|
||||
if (classDescriptor.isInner()) {
|
||||
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
|
||||
//TODO: we should understand that lambda/closure would be inlined and don't generate inner class record
|
||||
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));
|
||||
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);
|
||||
}
|
||||
@@ -285,28 +273,20 @@ public class CodegenBinding {
|
||||
@NotNull BindingContext bindingContext,
|
||||
@NotNull JetElement classOrObject
|
||||
) {
|
||||
if (!(classOrObject instanceof JetClassOrObject)) {
|
||||
return null;
|
||||
}
|
||||
if (!(classOrObject instanceof JetClassOrObject)) return null;
|
||||
|
||||
if (classOrObject instanceof JetClass && ((JetClass) classOrObject).isTrait()) {
|
||||
return null;
|
||||
}
|
||||
if (classOrObject instanceof JetClass && ((JetClass) classOrObject).isTrait()) return null;
|
||||
|
||||
for (JetDelegationSpecifier specifier : ((JetClassOrObject) classOrObject).getDelegationSpecifiers()) {
|
||||
if (specifier instanceof JetDelegatorToSuperCall) {
|
||||
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));
|
||||
if (!(specifier instanceof JetDelegatorToSuperCall)) continue;
|
||||
|
||||
ClassifierDescriptor superClass = supertype.getConstructor().getDeclarationDescriptor();
|
||||
if (superClass != null && !isInterface(superClass)) {
|
||||
ResolvedCall<?> resolvedCall = getResolvedCall(specifier, bindingContext);
|
||||
if (resolvedCall != null && resolvedCall.getResultingDescriptor() instanceof ConstructorDescriptor) {
|
||||
//noinspection unchecked
|
||||
return (ResolvedCall<ConstructorDescriptor>) resolvedCall;
|
||||
}
|
||||
}
|
||||
ResolvedCall<?> resolvedCall = getResolvedCall(specifier, bindingContext);
|
||||
if (resolvedCall == null) continue;
|
||||
|
||||
CallableDescriptor constructor = resolvedCall.getResultingDescriptor();
|
||||
if (constructor instanceof ConstructorDescriptor && !isInterface(constructor.getContainingDeclaration())) {
|
||||
//noinspection unchecked
|
||||
return (ResolvedCall<ConstructorDescriptor>) resolvedCall;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@ import org.jetbrains.org.objectweb.asm.Type;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.jet.codegen.JvmCodegenUtil.getDirectMember;
|
||||
|
||||
public final class MutableClosure implements CalculatedClosure {
|
||||
private final ResolvedCall<ConstructorDescriptor> superCall;
|
||||
|
||||
@@ -40,13 +42,25 @@ public final class MutableClosure implements CalculatedClosure {
|
||||
private List<Pair<String, Type>> recordedFields;
|
||||
|
||||
MutableClosure(
|
||||
@NotNull ClassDescriptor classDescriptor,
|
||||
@Nullable ResolvedCall<ConstructorDescriptor> superCall,
|
||||
@Nullable ClassDescriptor enclosingClass,
|
||||
@Nullable CallableDescriptor enclosingReceiverDescriptor
|
||||
@Nullable ClassDescriptor enclosingClass
|
||||
) {
|
||||
this.superCall = superCall;
|
||||
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
|
||||
|
||||
+3
-2
@@ -169,8 +169,9 @@ public class KotlinJavaFileStubProvider<T extends WithFileStubAndExtraDiagnostic
|
||||
|
||||
Map<JetClassOrObject, InnerKotlinClassLightClassData> innerClassesMap = ContainerUtil.newHashMap();
|
||||
for (ClassDescriptor innerClassDescriptor : allInnerClasses) {
|
||||
JetClassOrObject innerClass = (JetClassOrObject) descriptorToDeclaration(innerClassDescriptor);
|
||||
if (innerClass == null) continue;
|
||||
PsiElement declaration = descriptorToDeclaration(innerClassDescriptor);
|
||||
if (!(declaration instanceof JetClassOrObject)) continue;
|
||||
JetClassOrObject innerClass = (JetClassOrObject) declaration;
|
||||
|
||||
InnerKotlinClassLightClassData innerLightClassData = new InnerKotlinClassLightClassData(
|
||||
predictClassFqName(bindingContext, innerClassDescriptor),
|
||||
|
||||
Reference in New Issue
Block a user