FqName to ClassId
This commit is contained in:
@@ -31,12 +31,14 @@ import org.jetbrains.kotlin.codegen.context.PackageContext;
|
|||||||
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||||
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
import org.jetbrains.kotlin.codegen.state.JetTypeMapper;
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
|
import org.jetbrains.kotlin.name.ClassId;
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
|
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.JvmClassName;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterSignature;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||||
@@ -170,8 +172,12 @@ public class InlineCodegen extends CallGenerator {
|
|||||||
|
|
||||||
SMAPAndMethodNode nodeAndSMAP;
|
SMAPAndMethodNode nodeAndSMAP;
|
||||||
if (functionDescriptor instanceof DeserializedSimpleFunctionDescriptor) {
|
if (functionDescriptor instanceof DeserializedSimpleFunctionDescriptor) {
|
||||||
VirtualFile file = InlineCodegenUtil.getVirtualFileForCallable((DeserializedSimpleFunctionDescriptor) functionDescriptor, state);
|
ClassId containerClassId = InlineCodegenUtil.getContainerClassIdForInlineCallable(
|
||||||
nodeAndSMAP = InlineCodegenUtil.getMethodNode(file.contentsToByteArray(), asmMethod.getName(), asmMethod.getDescriptor());
|
(DeserializedSimpleFunctionDescriptor) functionDescriptor);
|
||||||
|
|
||||||
|
VirtualFile file = InlineCodegenUtil.getVirtualFileForCallable(containerClassId, state);
|
||||||
|
nodeAndSMAP = InlineCodegenUtil.getMethodNode(file.contentsToByteArray(), asmMethod.getName(), asmMethod.getDescriptor(),
|
||||||
|
JvmClassName.byClassId(containerClassId).getInternalName());
|
||||||
|
|
||||||
if (nodeAndSMAP == null) {
|
if (nodeAndSMAP == null) {
|
||||||
throw new RuntimeException("Couldn't obtain compiled function body for " + descriptorName(functionDescriptor));
|
throw new RuntimeException("Couldn't obtain compiled function body for " + descriptorName(functionDescriptor));
|
||||||
|
|||||||
@@ -34,11 +34,14 @@ import org.jetbrains.kotlin.load.java.JvmAbi;
|
|||||||
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils;
|
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils;
|
||||||
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils;
|
import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils;
|
||||||
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinder;
|
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinder;
|
||||||
|
import org.jetbrains.kotlin.name.ClassId;
|
||||||
import org.jetbrains.kotlin.name.FqName;
|
import org.jetbrains.kotlin.name.FqName;
|
||||||
|
import org.jetbrains.kotlin.name.FqNameUnsafe;
|
||||||
import org.jetbrains.kotlin.name.Name;
|
import org.jetbrains.kotlin.name.Name;
|
||||||
import org.jetbrains.kotlin.psi.JetFile;
|
import org.jetbrains.kotlin.psi.JetFile;
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
|
||||||
import org.jetbrains.kotlin.serialization.ProtoBuf;
|
import org.jetbrains.kotlin.serialization.ProtoBuf;
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor;
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor;
|
||||||
@@ -79,7 +82,8 @@ public class InlineCodegenUtil {
|
|||||||
public static SMAPAndMethodNode getMethodNode(
|
public static SMAPAndMethodNode getMethodNode(
|
||||||
byte[] classData,
|
byte[] classData,
|
||||||
final String methodName,
|
final String methodName,
|
||||||
final String methodDescriptor
|
final String methodDescriptor,
|
||||||
|
String containerInternalName
|
||||||
) throws ClassNotFoundException, IOException {
|
) throws ClassNotFoundException, IOException {
|
||||||
ClassReader cr = new ClassReader(classData);
|
ClassReader cr = new ClassReader(classData);
|
||||||
final MethodNode[] node = new MethodNode[1];
|
final MethodNode[] node = new MethodNode[1];
|
||||||
@@ -103,39 +107,43 @@ public class InlineCodegenUtil {
|
|||||||
}
|
}
|
||||||
}, ClassReader.SKIP_FRAMES);
|
}, ClassReader.SKIP_FRAMES);
|
||||||
|
|
||||||
return new SMAPAndMethodNode(node[0], debugInfo[0], "TODO", new SMAPParser(debugInfo[1], "TODO").parse());
|
return new SMAPAndMethodNode(node[0], debugInfo[0], containerInternalName, new SMAPParser(debugInfo[1], "TODO").parse());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static VirtualFile getVirtualFileForCallable(@NotNull DeserializedSimpleFunctionDescriptor deserializedDescriptor, @NotNull GenerationState state) {
|
public static VirtualFile getVirtualFileForCallable(@NotNull ClassId containerClassId, @NotNull GenerationState state) {
|
||||||
VirtualFile file;
|
VirtualFile file = findVirtualFileWithHeader(state.getProject(), containerClassId);
|
||||||
|
if (file == null) {
|
||||||
|
throw new IllegalStateException("Couldn't find declaration file for " + containerClassId);
|
||||||
|
}
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ClassId getContainerClassIdForInlineCallable(DeserializedSimpleFunctionDescriptor deserializedDescriptor) {
|
||||||
DeclarationDescriptor parentDeclaration = deserializedDescriptor.getContainingDeclaration();
|
DeclarationDescriptor parentDeclaration = deserializedDescriptor.getContainingDeclaration();
|
||||||
|
ClassId containerClassId;
|
||||||
if (parentDeclaration instanceof PackageFragmentDescriptor) {
|
if (parentDeclaration instanceof PackageFragmentDescriptor) {
|
||||||
ProtoBuf.Callable proto = deserializedDescriptor.getProto();
|
ProtoBuf.Callable proto = deserializedDescriptor.getProto();
|
||||||
if (!proto.hasExtension(JvmProtoBuf.implClassName)) {
|
if (!proto.hasExtension(JvmProtoBuf.implClassName)) {
|
||||||
throw new IllegalStateException("Function in namespace should have implClassName property in proto: " + deserializedDescriptor);
|
throw new IllegalStateException("Function in namespace should have implClassName property in proto: " + deserializedDescriptor);
|
||||||
}
|
}
|
||||||
Name name = deserializedDescriptor.getNameResolver().getName(proto.getExtension(JvmProtoBuf.implClassName));
|
Name name = deserializedDescriptor.getNameResolver().getName(proto.getExtension(JvmProtoBuf.implClassName));
|
||||||
FqName packagePartFqName =
|
ClassId packageClassId = PackageClassUtils.getPackageClassId(((PackageFragmentDescriptor) parentDeclaration).getFqName());
|
||||||
PackageClassUtils.getPackageClassFqName(((PackageFragmentDescriptor) parentDeclaration).getFqName()).parent().child(
|
containerClassId = new ClassId(packageClassId.getPackageFqName(), name);
|
||||||
name);
|
|
||||||
file = findVirtualFileWithHeader(state.getProject(), packagePartFqName);
|
|
||||||
} else {
|
} else {
|
||||||
file = findVirtualFileContainingDescriptor(state.getProject(), deserializedDescriptor);
|
containerClassId = getContainerClassId(deserializedDescriptor);
|
||||||
}
|
}
|
||||||
|
if (containerClassId == null) {
|
||||||
if (file == null) {
|
throw new IllegalStateException("Couldn't find container FQName for " + deserializedDescriptor.getName());
|
||||||
throw new IllegalStateException("Couldn't find declaration file for " + deserializedDescriptor.getName());
|
|
||||||
}
|
}
|
||||||
|
return containerClassId;
|
||||||
return file;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static VirtualFile findVirtualFileWithHeader(@NotNull Project project, @NotNull FqName containerFqName) {
|
public static VirtualFile findVirtualFileWithHeader(@NotNull Project project, @NotNull ClassId containerClassId) {
|
||||||
VirtualFileFinder fileFinder = VirtualFileFinder.SERVICE.getInstance(project);
|
VirtualFileFinder fileFinder = VirtualFileFinder.SERVICE.getInstance(project);
|
||||||
return fileFinder.findVirtualFileWithHeader(containerFqName);
|
return fileFinder.findVirtualFileWithHeader(containerClassId.asSingleFqName().toSafe());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -146,18 +154,19 @@ public class InlineCodegenUtil {
|
|||||||
|
|
||||||
//TODO: navigate to inner classes
|
//TODO: navigate to inner classes
|
||||||
@Nullable
|
@Nullable
|
||||||
public static FqName getContainerFqName(@NotNull DeclarationDescriptor referencedDescriptor) {
|
public static ClassId getContainerClassId(@NotNull DeclarationDescriptor referencedDescriptor) {
|
||||||
ClassOrPackageFragmentDescriptor
|
ClassOrPackageFragmentDescriptor
|
||||||
containerDescriptor = DescriptorUtils.getParentOfType(referencedDescriptor, ClassOrPackageFragmentDescriptor.class, false);
|
containerDescriptor = DescriptorUtils.getParentOfType(referencedDescriptor, ClassOrPackageFragmentDescriptor.class, false);
|
||||||
if (containerDescriptor instanceof PackageFragmentDescriptor) {
|
if (containerDescriptor instanceof PackageFragmentDescriptor) {
|
||||||
return PackageClassUtils.getPackageClassFqName(getFqName(containerDescriptor).toSafe());
|
return PackageClassUtils.getPackageClassId(getFqName(containerDescriptor).toSafe());
|
||||||
}
|
}
|
||||||
if (containerDescriptor instanceof ClassDescriptor) {
|
if (containerDescriptor instanceof ClassDescriptor) {
|
||||||
FqName fqName = getFqNameSafe(containerDescriptor);
|
ClassId classId = DescriptorUtilPackage.getClassId((ClassDescriptor) containerDescriptor);
|
||||||
if (isTrait(containerDescriptor)) {
|
if (isTrait(containerDescriptor)) {
|
||||||
return fqName.parent().child(Name.identifier(fqName.shortName() + JvmAbi.TRAIT_IMPL_SUFFIX));
|
FqNameUnsafe shortName = classId.getRelativeClassName();
|
||||||
|
classId = new ClassId(classId.getPackageFqName(), Name.identifier(shortName.shortName().toString() + JvmAbi.TRAIT_IMPL_SUFFIX));
|
||||||
}
|
}
|
||||||
return fqName;
|
return classId;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -206,18 +215,6 @@ public class InlineCodegenUtil {
|
|||||||
return getInlineName(codegenContext, currentDescriptor.getContainingDeclaration(), typeMapper) + "$" + suffix;
|
return getInlineName(codegenContext, currentDescriptor.getContainingDeclaration(), typeMapper) + "$" + suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
private static VirtualFile findVirtualFileContainingDescriptor(
|
|
||||||
@NotNull Project project,
|
|
||||||
@NotNull DeclarationDescriptor referencedDescriptor
|
|
||||||
) {
|
|
||||||
FqName containerFqName = getContainerFqName(referencedDescriptor);
|
|
||||||
if (containerFqName == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return findVirtualFileWithHeader(project, containerFqName);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static boolean isInvokeOnLambda(String owner, String name) {
|
public static boolean isInvokeOnLambda(String owner, String name) {
|
||||||
if (!INVOKE.equals(name)) {
|
if (!INVOKE.equals(name)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user