Drop isLocalClass, do not write KotlinLocalClass
This commit is contained in:
@@ -247,10 +247,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
@Override
|
||||
protected void generateKotlinAnnotation() {
|
||||
if (!isTopLevelOrInnerClass(descriptor)) {
|
||||
v.getVisitor().visitAnnotation(asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_LOCAL_CLASS), true).visitEnd();
|
||||
}
|
||||
|
||||
final DescriptorSerializer serializer =
|
||||
DescriptorSerializer.create(descriptor, new JvmSerializerExtension(v.getSerializationBindings(), state));
|
||||
|
||||
@@ -260,9 +256,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
@Override
|
||||
public Unit invoke(AnnotationVisitor av) {
|
||||
writeAnnotationData(av, serializer, classProto, false);
|
||||
if (!isTopLevelOrInnerClass(descriptor)) {
|
||||
av.visit(JvmAnnotationNames.SYNTHETIC_CLASS_KIND_FIELD_NAME, KotlinClassHeader.SyntheticClassKind.LOCAL_CLASS.getId());
|
||||
}
|
||||
return Unit.INSTANCE;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -41,7 +41,6 @@ final class LiteralsKt$foo$2 {
|
||||
public synthetic method invoke(): java.lang.Object
|
||||
}
|
||||
|
||||
@kotlin.jvm.internal.KotlinLocalClass
|
||||
@kotlin.Metadata
|
||||
@kotlin.jvm.internal.KotlinClass
|
||||
public final class LiteralsKt$foo$3 {
|
||||
|
||||
+3
@@ -1,3 +1,6 @@
|
||||
// SKIP_IN_RUNTIME_TEST because the anonymous object has no container and thus a non-local ClassId
|
||||
// TODO: unskip
|
||||
|
||||
package test
|
||||
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.inline.inlineFunctionsJvmNames
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||
import org.jetbrains.kotlin.load.kotlin.FileBasedKotlinClass
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||
@@ -55,7 +56,7 @@ object InlineTestUtil {
|
||||
|
||||
private fun obtainInlineInfo(files: Iterable<OutputFile>): InlineInfo {
|
||||
val inlineMethods = HashSet<MethodInfo>()
|
||||
val classHeaders = hashMapOf<String, KotlinClassHeader>()
|
||||
val binaryClasses = hashMapOf<String, KotlinJvmBinaryClass>()
|
||||
|
||||
for (file in files) {
|
||||
val bytes = file.asByteArray()
|
||||
@@ -76,10 +77,10 @@ object InlineTestUtil {
|
||||
}
|
||||
|
||||
cr.accept(classVisitor, 0)
|
||||
classHeaders.put(classVisitor.className, getClassHeader(file))
|
||||
binaryClasses.put(classVisitor.className, loadBinaryClass(file))
|
||||
}
|
||||
|
||||
return InlineInfo(inlineMethods, classHeaders)
|
||||
return InlineInfo(inlineMethods, binaryClasses)
|
||||
}
|
||||
|
||||
private fun checkInlineMethodNotInvoked(files: Iterable<OutputFile>, inlinedMethods: Set<MethodInfo>): List<NotInlinedCall> {
|
||||
@@ -127,7 +128,7 @@ object InlineTestUtil {
|
||||
val inlinedMethods = inlineInfo.inlineMethods
|
||||
val notInlinedParameters = ArrayList<NotInlinedParameter>()
|
||||
for (file in files) {
|
||||
if (!isClassOrPackagePartKind(getClassHeader(file))) continue
|
||||
if (!isClassOrPackagePartKind(loadBinaryClass(file))) continue
|
||||
|
||||
ClassReader(file.asByteArray()).accept(object : ClassVisitorWithName() {
|
||||
override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array<String>?): MethodVisitor? {
|
||||
@@ -167,15 +168,15 @@ object InlineTestUtil {
|
||||
if (classInternalName.startsWith("kotlin/jvm/internal/"))
|
||||
return true
|
||||
|
||||
return isClassOrPackagePartKind(inlineInfo.classHeaders[classInternalName]!!)
|
||||
return isClassOrPackagePartKind(inlineInfo.binaryClasses[classInternalName]!!)
|
||||
}
|
||||
|
||||
private fun isClassOrPackagePartKind(header: KotlinClassHeader): Boolean {
|
||||
return header.kind == KotlinClassHeader.Kind.CLASS && !header.isLocalClass
|
||||
private fun isClassOrPackagePartKind(klass: KotlinJvmBinaryClass): Boolean {
|
||||
return klass.classHeader.kind == KotlinClassHeader.Kind.CLASS && !klass.classId.isLocal
|
||||
}
|
||||
|
||||
private fun getClassHeader(file: OutputFile): KotlinClassHeader {
|
||||
return FileBasedKotlinClass.create(file.asByteArray()) {
|
||||
private fun loadBinaryClass(file: OutputFile): KotlinJvmBinaryClass {
|
||||
val klass = FileBasedKotlinClass.create(file.asByteArray()) {
|
||||
className, classHeader, innerClasses ->
|
||||
object : FileBasedKotlinClass(className, classHeader, innerClasses) {
|
||||
override fun getLocation(): String = throw UnsupportedOperationException()
|
||||
@@ -184,10 +185,11 @@ object InlineTestUtil {
|
||||
override fun equals(other: Any?): Boolean = throw UnsupportedOperationException()
|
||||
override fun toString(): String = throw UnsupportedOperationException()
|
||||
}
|
||||
}!!.classHeader
|
||||
}!!
|
||||
return klass
|
||||
}
|
||||
|
||||
private class InlineInfo(val inlineMethods: Set<MethodInfo>, val classHeaders: Map<String, KotlinClassHeader>)
|
||||
private class InlineInfo(val inlineMethods: Set<MethodInfo>, val binaryClasses: Map<String, KotlinJvmBinaryClass>)
|
||||
|
||||
private data class NotInlinedCall(val fromCall: MethodInfo, val inlineMethod: MethodInfo)
|
||||
|
||||
|
||||
+1
-23
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.jvm.runtime
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import org.jetbrains.kotlin.cli.common.output.outputUtils.writeAllTo
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||
import org.jetbrains.kotlin.codegen.GenerationUtils
|
||||
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
@@ -26,8 +25,6 @@ import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.jvm.compiler.ExpectedLoadErrorsUtil
|
||||
import org.jetbrains.kotlin.jvm.compiler.LoadDescriptorUtil
|
||||
import org.jetbrains.kotlin.load.java.ANNOTATIONS_COPIED_TO_TYPES
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KOTLIN_LOCAL_CLASS
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
||||
import org.jetbrains.kotlin.load.java.structure.reflect.classId
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||
@@ -51,10 +48,6 @@ import org.jetbrains.kotlin.test.util.RecursiveDescriptorComparator.Configuratio
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
import org.jetbrains.kotlin.utils.sure
|
||||
import org.jetbrains.org.objectweb.asm.AnnotationVisitor
|
||||
import org.jetbrains.org.objectweb.asm.ClassReader
|
||||
import org.jetbrains.org.objectweb.asm.ClassVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import java.io.File
|
||||
import java.net.URLClassLoader
|
||||
import java.util.*
|
||||
@@ -168,7 +161,7 @@ abstract class AbstractJvmRuntimeDescriptorLoaderTest : TestCaseWithTmpdir() {
|
||||
packageScopes.add(packageView.memberScope)
|
||||
}
|
||||
}
|
||||
else if (header == null || (header.kind == KotlinClassHeader.Kind.CLASS && !classFile.isLocalClass())) {
|
||||
else if (header == null || header.kind == KotlinClassHeader.Kind.CLASS) {
|
||||
// Either a normal Kotlin class or a Java class
|
||||
val classId = klass.classId
|
||||
if (!classId.isLocal) {
|
||||
@@ -185,21 +178,6 @@ abstract class AbstractJvmRuntimeDescriptorLoaderTest : TestCaseWithTmpdir() {
|
||||
return SyntheticPackageViewForTest(module, packageScopes, classes)
|
||||
}
|
||||
|
||||
private fun File.isLocalClass(): Boolean {
|
||||
var result = false
|
||||
|
||||
ClassReader(inputStream()).accept(object : ClassVisitor(Opcodes.ASM5) {
|
||||
override fun visitAnnotation(desc: String, visible: Boolean): AnnotationVisitor? {
|
||||
if (desc == AsmUtil.asmDescByFqNameWithoutInnerClasses(KOTLIN_LOCAL_CLASS)) {
|
||||
result = true
|
||||
}
|
||||
return super.visitAnnotation(desc, visible)
|
||||
}
|
||||
}, ClassReader.SKIP_CODE or ClassReader.SKIP_DEBUG or ClassReader.SKIP_FRAMES)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun adaptJavaSource(text: String): String {
|
||||
val typeAnnotations = arrayOf("NotNull", "Nullable", "ReadOnly", "Mutable")
|
||||
return typeAnnotations.fold(text) { text, annotation -> text.replace("@$annotation", "") }.replace(
|
||||
|
||||
+1
-2
@@ -35,7 +35,6 @@ public final class JvmAnnotationNames {
|
||||
public static final FqName KOTLIN_MULTIFILE_CLASS_PART = new FqName("kotlin.jvm.internal.KotlinMultifileClassPart");
|
||||
public static final FqName KOTLIN_SYNTHETIC_CLASS = new FqName("kotlin.jvm.internal.KotlinSyntheticClass");
|
||||
public static final FqName KOTLIN_FUNCTION = new FqName("kotlin.jvm.internal.KotlinFunction");
|
||||
public static final FqName KOTLIN_LOCAL_CLASS = new FqName("kotlin.jvm.internal.KotlinLocalClass");
|
||||
|
||||
public static final String VERSION_FIELD_NAME = "version";
|
||||
public static final String METADATA_VERSION_FIELD_NAME = "mv";
|
||||
@@ -72,7 +71,7 @@ public final class JvmAnnotationNames {
|
||||
private static final Set<JvmClassName> NULLABILITY_ANNOTATIONS = new HashSet<JvmClassName>();
|
||||
private static final Set<JvmClassName> SPECIAL_META_ANNOTATIONS = new HashSet<JvmClassName>();
|
||||
static {
|
||||
for (FqName fqName : Arrays.asList(METADATA, KOTLIN_CLASS, KOTLIN_SYNTHETIC_CLASS, KOTLIN_LOCAL_CLASS)) {
|
||||
for (FqName fqName : Arrays.asList(METADATA, KOTLIN_CLASS, KOTLIN_SYNTHETIC_CLASS)) {
|
||||
SPECIAL_ANNOTATIONS.add(JvmClassName.byFqNameWithoutInnerClasses(fqName));
|
||||
}
|
||||
|
||||
|
||||
+2
-11
@@ -25,8 +25,7 @@ class KotlinClassHeader(
|
||||
val bytecodeVersion: JvmBytecodeBinaryVersion,
|
||||
val data: Array<String>?,
|
||||
val strings: Array<String>?,
|
||||
val multifileClassName: String?,
|
||||
val isLocalClass: Boolean
|
||||
val multifileClassName: String?
|
||||
) {
|
||||
// See kotlin.Metadata
|
||||
enum class Kind(val id: Int) {
|
||||
@@ -47,15 +46,7 @@ class KotlinClassHeader(
|
||||
|
||||
enum class SyntheticClassKind(val id: Int) {
|
||||
FUNCTION(1),
|
||||
LOCAL_CLASS(2);
|
||||
|
||||
companion object {
|
||||
private val entryById = values().toMapBy(SyntheticClassKind::id)
|
||||
|
||||
@JvmStatic
|
||||
fun getById(id: Int) = entryById[id]
|
||||
}
|
||||
}
|
||||
|
||||
override fun toString() = "$kind " + (if (isLocalClass) "(local) " else "") + "version=$metadataVersion"
|
||||
override fun toString() = "$kind version=$metadataVersion"
|
||||
}
|
||||
|
||||
+1
-14
@@ -53,8 +53,6 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
|
||||
private String[] data = null;
|
||||
private String[] strings = null;
|
||||
private KotlinClassHeader.Kind headerKind = null;
|
||||
private KotlinClassHeader.SyntheticClassKind syntheticClassKind = null;
|
||||
private boolean isLocalClass = false;
|
||||
|
||||
@Nullable
|
||||
public KotlinClassHeader createHeader() {
|
||||
@@ -77,8 +75,7 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
|
||||
bytecodeVersion != null ? bytecodeVersion : JvmBytecodeBinaryVersion.INVALID_VERSION,
|
||||
data,
|
||||
strings,
|
||||
multifileClassName,
|
||||
isLocalClass || syntheticClassKind == KotlinClassHeader.SyntheticClassKind.LOCAL_CLASS
|
||||
multifileClassName
|
||||
);
|
||||
}
|
||||
|
||||
@@ -98,11 +95,6 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
|
||||
|
||||
if (IGNORE_OLD_METADATA) return null;
|
||||
|
||||
if (KOTLIN_LOCAL_CLASS.equals(fqName)) {
|
||||
isLocalClass = true;
|
||||
return null;
|
||||
}
|
||||
|
||||
if (headerKind != null) {
|
||||
// Ignore all Kotlin annotations except the first found
|
||||
return null;
|
||||
@@ -142,11 +134,6 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
|
||||
bytecodeVersion = new JvmBytecodeBinaryVersion((int[]) value);
|
||||
}
|
||||
}
|
||||
else if (SYNTHETIC_CLASS_KIND_FIELD_NAME.equals(string)) {
|
||||
if (value instanceof Integer) {
|
||||
syntheticClassKind = KotlinClassHeader.SyntheticClassKind.getById((Integer) value);
|
||||
}
|
||||
}
|
||||
else if (METADATA_MULTIFILE_CLASS_NAME_FIELD_NAME.equals(string)) {
|
||||
if (value instanceof String) {
|
||||
multifileClassName = (String) value;
|
||||
|
||||
@@ -60,7 +60,6 @@ internal annotation class Metadata(
|
||||
* An extra integer. For a synthetic class, the specific kind of this class which is one of the following:
|
||||
*
|
||||
* 1 Anonymous class for a lambda or a function reference
|
||||
* 2 Local class or anonymous object literal
|
||||
*
|
||||
* A value other than this (e.g. 0) or a missing value means this is a synthetic class of some other sort.
|
||||
* This kind has no effect on the compiler because it doesn't read synthetic class metadata. It may be used in IDEs and tools.
|
||||
|
||||
+4
-3
@@ -69,11 +69,12 @@ fun isKotlinInternalCompiledFile(file: VirtualFile): Boolean {
|
||||
if (ClassFileViewProvider.isInnerClass(file)) {
|
||||
return true
|
||||
}
|
||||
val header = IDEKotlinBinaryClassCache.getKotlinBinaryClassHeaderData(file)?.classHeader ?: return false
|
||||
|
||||
val (header, classId) = IDEKotlinBinaryClassCache.getKotlinBinaryClassHeaderData(file) ?: return false
|
||||
if (classId.isLocal) return true
|
||||
|
||||
return header.kind == KotlinClassHeader.Kind.SYNTHETIC_CLASS ||
|
||||
header.kind == KotlinClassHeader.Kind.MULTIFILE_CLASS_PART ||
|
||||
header.isLocalClass
|
||||
header.kind == KotlinClassHeader.Kind.MULTIFILE_CLASS_PART
|
||||
}
|
||||
|
||||
fun findMultifileClassParts(file: VirtualFile, classId: ClassId, header: KotlinClassHeader): List<KotlinJvmBinaryClass> {
|
||||
|
||||
+1
-1
@@ -81,7 +81,7 @@ open class KotlinClsStubBuilder : ClsStubBuilder() {
|
||||
}
|
||||
return when (header.kind) {
|
||||
KotlinClassHeader.Kind.CLASS -> {
|
||||
if (header.isLocalClass) return null
|
||||
if (classId.isLocal) return null
|
||||
val (nameResolver, classProto) = JvmProtoBufUtil.readClassDataFrom(annotationData, strings)
|
||||
val context = components.createContext(nameResolver, packageFqName, TypeTable(classProto.typeTable))
|
||||
createTopLevelClassStub(classId, classProto, context)
|
||||
|
||||
+6
-5
@@ -22,19 +22,20 @@ import org.jetbrains.kotlin.idea.caches.IDEKotlinBinaryClassCache
|
||||
import org.jetbrains.kotlin.idea.decompiler.navigation.NavigateToDecompiledLibraryTest
|
||||
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.junit.Assert
|
||||
|
||||
abstract class AbstractInternalCompiledClassesTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
private fun isFileWithHeader(predicate: (KotlinClassHeader) -> Boolean) : VirtualFile.() -> Boolean = {
|
||||
val header = IDEKotlinBinaryClassCache.getKotlinBinaryClassHeaderData(this)?.classHeader
|
||||
header != null && predicate(header)
|
||||
private fun isFileWithHeader(predicate: (KotlinClassHeader, ClassId) -> Boolean) : VirtualFile.() -> Boolean = {
|
||||
val info = IDEKotlinBinaryClassCache.getKotlinBinaryClassHeaderData(this)
|
||||
info != null && predicate(info.classHeader, info.classId)
|
||||
}
|
||||
|
||||
protected fun isSyntheticClass(): VirtualFile.() -> Boolean =
|
||||
isFileWithHeader { it.kind == KotlinClassHeader.Kind.SYNTHETIC_CLASS }
|
||||
isFileWithHeader { header, classId -> header.kind == KotlinClassHeader.Kind.SYNTHETIC_CLASS }
|
||||
|
||||
protected fun doTestNoPsiFilesAreBuiltForLocalClass(): Unit =
|
||||
doTestNoPsiFilesAreBuiltFor("local", isFileWithHeader { it.isLocalClass })
|
||||
doTestNoPsiFilesAreBuiltFor("local", isFileWithHeader { header, classId -> classId.isLocal })
|
||||
|
||||
protected fun doTestNoPsiFilesAreBuiltForSyntheticClasses(): Unit =
|
||||
doTestNoPsiFilesAreBuiltFor("synthetic", isSyntheticClass())
|
||||
|
||||
@@ -143,11 +143,11 @@ open class IncrementalCacheImpl(
|
||||
sourceToClassesMap.add(it, className)
|
||||
}
|
||||
|
||||
val header = kotlinClass.classHeader
|
||||
if (header.isLocalClass) {
|
||||
if (kotlinClass.classId.isLocal) {
|
||||
return CompilationResult.NO_CHANGES
|
||||
}
|
||||
|
||||
val header = kotlinClass.classHeader
|
||||
val changesInfo = when (header.kind) {
|
||||
KotlinClassHeader.Kind.FILE_FACADE -> {
|
||||
assert(sourceFiles.size == 1) { "Package part from several source files: $sourceFiles" }
|
||||
|
||||
Reference in New Issue
Block a user