Move and simplify AsmUtil.writeOuterClassAndEnclosingMethod
This commit is contained in:
@@ -27,7 +27,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType;
|
||||
import org.jetbrains.kotlin.codegen.binding.CalculatedClosure;
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
|
||||
import org.jetbrains.kotlin.codegen.context.CodegenContext;
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods;
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||
@@ -37,11 +36,7 @@ import org.jetbrains.kotlin.lexer.JetTokens;
|
||||
import org.jetbrains.kotlin.load.java.JavaVisibilities;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor;
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.psi.JetFile;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
import org.jetbrains.kotlin.resolve.annotations.AnnotationsPackage;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
@@ -62,7 +57,6 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isInterface;
|
||||
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.asmTypeForAnonymousClass;
|
||||
import static org.jetbrains.kotlin.load.java.JvmAnnotationNames.ABI_VERSION_FIELD_NAME;
|
||||
import static org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinSyntheticClass;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
||||
@@ -855,54 +849,6 @@ public class AsmUtil {
|
||||
return JvmClassName.byFqNameWithoutInnerClasses(fqName).getInternalName();
|
||||
}
|
||||
|
||||
public static void writeOuterClassAndEnclosingMethod(
|
||||
@NotNull ClassDescriptor descriptor,
|
||||
@NotNull DeclarationDescriptor originalDescriptor,
|
||||
@NotNull JetTypeMapper typeMapper,
|
||||
@NotNull ClassBuilder v
|
||||
) {
|
||||
String outerClassName = getOuterClassName(descriptor, originalDescriptor, typeMapper);
|
||||
|
||||
FunctionDescriptor function = DescriptorUtils.getParentOfType(descriptor, FunctionDescriptor.class);
|
||||
while (function != null && JvmCodegenUtil.isLambdaWhichWillBeInlined(typeMapper.getBindingContext(), function)) {
|
||||
function = DescriptorUtils.getParentOfType(function, FunctionDescriptor.class);
|
||||
}
|
||||
|
||||
if (function != null) {
|
||||
Method method = typeMapper.mapSignature(function).getAsmMethod();
|
||||
v.visitOuterClass(outerClassName, method.getName(), method.getDescriptor());
|
||||
}
|
||||
else {
|
||||
v.visitOuterClass(outerClassName, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getOuterClassName(
|
||||
@NotNull ClassDescriptor classDescriptor,
|
||||
@NotNull DeclarationDescriptor originalDescriptor,
|
||||
@NotNull JetTypeMapper typeMapper
|
||||
) {
|
||||
BindingContext bindingContext = typeMapper.getBindingContext();
|
||||
|
||||
DeclarationDescriptor container = classDescriptor.getContainingDeclaration();
|
||||
while (container != null) {
|
||||
if (container instanceof ClassDescriptor) {
|
||||
return typeMapper.mapClass((ClassDescriptor) container).getInternalName();
|
||||
}
|
||||
else if (CodegenBinding.isLocalFunOrLambda(container) &&
|
||||
!JvmCodegenUtil.isLambdaWhichWillBeInlined(bindingContext, container)) {
|
||||
return asmTypeForAnonymousClass(bindingContext, (FunctionDescriptor) container).getInternalName();
|
||||
}
|
||||
|
||||
container = container.getContainingDeclaration();
|
||||
}
|
||||
|
||||
JetFile containingFile = DescriptorToSourceUtils.getContainingFile(originalDescriptor);
|
||||
assert containingFile != null : "Containing file should be present for " + classDescriptor;
|
||||
return PackagePartClassUtils.getPackagePartInternalName(containingFile);
|
||||
}
|
||||
|
||||
public static void putJavaLangClassInstance(@NotNull InstructionAdapter v, @NotNull Type type) {
|
||||
if (isPrimitive(type)) {
|
||||
v.getstatic(boxType(type).getInternalName(), "TYPE", "Ljava/lang/Class;");
|
||||
|
||||
@@ -209,7 +209,7 @@ public class ClosureCodegen extends MemberCodegen<JetElement> {
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
writeOuterClassAndEnclosingMethod(classDescriptor, funDescriptor, typeMapper, v);
|
||||
writeOuterClassAndEnclosingMethod(classDescriptor);
|
||||
super.done();
|
||||
}
|
||||
|
||||
|
||||
@@ -249,16 +249,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
}
|
||||
|
||||
private void writeEnclosingMethod() {
|
||||
//JVMS7: A class must have an EnclosingMethod attribute if and only if it is a local class or an anonymous class.
|
||||
DeclarationDescriptor parentDescriptor = descriptor.getContainingDeclaration();
|
||||
|
||||
boolean isObjectLiteral = DescriptorUtils.isAnonymousObject(descriptor);
|
||||
|
||||
boolean isLocalOrAnonymousClass = isObjectLiteral ||
|
||||
!(parentDescriptor instanceof PackageFragmentDescriptor || parentDescriptor instanceof ClassDescriptor);
|
||||
// Do not emit enclosing method in "light-classes mode" since currently we generate local light classes as if they're top level
|
||||
if (isLocalOrAnonymousClass && state.getClassBuilderMode() != ClassBuilderMode.LIGHT_CLASSES) {
|
||||
writeOuterClassAndEnclosingMethod(descriptor, descriptor, typeMapper, v);
|
||||
if (state.getClassBuilderMode() == ClassBuilderMode.LIGHT_CLASSES) {
|
||||
return;
|
||||
}
|
||||
|
||||
//JVMS7: A class must have an EnclosingMethod attribute if and only if it is a local class or an anonymous class.
|
||||
if (isAnonymousObject(descriptor) || !(descriptor.getContainingDeclaration() instanceof ClassOrPackageFragmentDescriptor)) {
|
||||
writeOuterClassAndEnclosingMethod(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import kotlin.Function0;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding;
|
||||
import org.jetbrains.kotlin.codegen.context.ClassContext;
|
||||
import org.jetbrains.kotlin.codegen.context.CodegenContext;
|
||||
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext;
|
||||
@@ -32,13 +33,11 @@ import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.name.SpecialNames;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.BindingContextUtils;
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace;
|
||||
import org.jetbrains.kotlin.resolve.TemporaryBindingTrace;
|
||||
import org.jetbrains.kotlin.resolve.*;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant;
|
||||
@@ -250,6 +249,44 @@ public abstract class MemberCodegen<T extends JetElement/* TODO: & JetDeclaratio
|
||||
v.visitInnerClass(innerClassInternalName, outerClassInternalName, innerName, calculateInnerClassAccessFlags(innerClass));
|
||||
}
|
||||
|
||||
protected void writeOuterClassAndEnclosingMethod(@NotNull ClassDescriptor descriptor) {
|
||||
ClassDescriptor outerClass = findOuterClass(descriptor);
|
||||
String outerClassName = outerClass != null
|
||||
? typeMapper.mapClass(outerClass).getInternalName()
|
||||
: PackagePartClassUtils.getPackagePartInternalName(element.getContainingJetFile());
|
||||
|
||||
FunctionDescriptor function = DescriptorUtils.getParentOfType(descriptor, FunctionDescriptor.class);
|
||||
while (function != null && JvmCodegenUtil.isLambdaWhichWillBeInlined(bindingContext, function)) {
|
||||
function = DescriptorUtils.getParentOfType(function, FunctionDescriptor.class);
|
||||
}
|
||||
|
||||
if (function != null) {
|
||||
Method method = typeMapper.mapSignature(function).getAsmMethod();
|
||||
v.visitOuterClass(outerClassName, method.getName(), method.getDescriptor());
|
||||
}
|
||||
else {
|
||||
v.visitOuterClass(outerClassName, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ClassDescriptor findOuterClass(@NotNull ClassDescriptor classDescriptor) {
|
||||
DeclarationDescriptor container = classDescriptor.getContainingDeclaration();
|
||||
while (container != null) {
|
||||
if (container instanceof ClassDescriptor) {
|
||||
return (ClassDescriptor) container;
|
||||
}
|
||||
else if (CodegenBinding.isLocalFunOrLambda(container) &&
|
||||
!JvmCodegenUtil.isLambdaWhichWillBeInlined(bindingContext, container)) {
|
||||
return CodegenBinding.anonymousClassForFunction(bindingContext, (FunctionDescriptor) container);
|
||||
}
|
||||
|
||||
container = container.getContainingDeclaration();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public NameGenerator getInlineNameGenerator() {
|
||||
if (inlineNameGenerator == null) {
|
||||
|
||||
Reference in New Issue
Block a user