From 7b374b95099c6c22a6b829be2b5aa40f5507a57a Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Fri, 19 Sep 2014 16:26:28 +0400 Subject: [PATCH] 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 --- .../binding/CodegenAnnotatingVisitor.java | 32 +++++----- .../jet/codegen/binding/CodegenBinding.java | 62 +++++++------------ .../jet/codegen/binding/MutableClosure.java | 22 +++++-- .../asJava/KotlinJavaFileStubProvider.java | 5 +- 4 files changed, 57 insertions(+), 64 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenAnnotatingVisitor.java b/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenAnnotatingVisitor.java index 93ac994f757..25d33c04524 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenAnnotatingVisitor.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenAnnotatingVisitor.java @@ -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 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(""), Modality.FINAL, supertypes, - SourceElement.NO_SOURCE + SourcePackage.toSourceElement(element) ); classDescriptor.initialize(JetScope.EMPTY, Collections.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 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 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); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenBinding.java b/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenBinding.java index 86197dc6b85..06279cf32a9 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenBinding.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenBinding.java @@ -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 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.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) 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) resolvedCall; } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/binding/MutableClosure.java b/compiler/backend/src/org/jetbrains/jet/codegen/binding/MutableClosure.java index 35694b8b726..b4325e07627 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/binding/MutableClosure.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/binding/MutableClosure.java @@ -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 superCall; @@ -40,13 +42,25 @@ public final class MutableClosure implements CalculatedClosure { private List> recordedFields; MutableClosure( + @NotNull ClassDescriptor classDescriptor, @Nullable ResolvedCall 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 diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinJavaFileStubProvider.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinJavaFileStubProvider.java index 7b0feafea82..6e6ed8be32f 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinJavaFileStubProvider.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinJavaFileStubProvider.java @@ -169,8 +169,9 @@ public class KotlinJavaFileStubProvider 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),