Deprecate and don't write KotlinClass$Kind, to be removed later

This commit is contained in:
Alexander Udalov
2015-10-01 19:12:07 +03:00
parent 056bb3f833
commit 041af28166
17 changed files with 101 additions and 158 deletions
@@ -43,7 +43,6 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.lexer.JetTokens;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinClass;
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.FqNameUnsafe;
@@ -256,17 +255,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
protected void generateKotlinAnnotation() {
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) return;
KotlinClass.Kind kind;
if (isAnonymousObject(descriptor)) {
kind = KotlinClass.Kind.ANONYMOUS_OBJECT;
}
else if (isTopLevelOrInnerClass(descriptor)) {
// Default value is Kind.CLASS
kind = null;
}
else {
// LOCAL_CLASS is also written to inner classes of local classes
kind = KotlinClass.Kind.LOCAL_CLASS;
if (!isTopLevelOrInnerClass(descriptor)) {
AnnotationVisitor av = v.getVisitor().visitAnnotation(
asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_LOCAL_CLASS), true
);
av.visit(JvmAnnotationNames.VERSION_FIELD_NAME, JvmAbi.VERSION.toArray());
av.visitEnd();
}
DescriptorSerializer serializer =
@@ -276,13 +270,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
AnnotationVisitor av = v.getVisitor().visitAnnotation(asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_CLASS), true);
writeAnnotationData(av, serializer, classProto);
if (kind != null) {
av.visitEnum(
JvmAnnotationNames.KIND_FIELD_NAME,
Type.getObjectType(KotlinClass.KIND_INTERNAL_NAME).getDescriptor(),
kind.toString()
);
}
av.visitEnd();
}
@@ -270,9 +270,6 @@ public abstract class FileBasedKotlinClass implements KotlinJvmBinaryClass {
if (name.equals(JvmAnnotationNames.KotlinSyntheticClass.KIND_INTERNAL_NAME)) {
return JvmAnnotationNames.KotlinSyntheticClass.KIND_CLASS_ID;
}
else if (name.equals(JvmAnnotationNames.KotlinClass.KIND_INTERNAL_NAME)) {
return JvmAnnotationNames.KotlinClass.KIND_CLASS_ID;
}
List<String> classes = new ArrayList<String>(1);
boolean local = false;
@@ -20,7 +20,7 @@
method <init>(p0: int): void
}
@kotlin.jvm.internal.KotlinClass LiteralsKt$foo$3 {
@kotlin.jvm.internal.KotlinLocalClass @kotlin.jvm.internal.KotlinClass LiteralsKt$foo$3 {
inner class LiteralsKt$foo$3
field $kotlinClass: kotlin.reflect.KClass
method <clinit>(): void
@@ -185,7 +185,7 @@ public object InlineTestUtil {
}
private fun isClassOrPackagePartKind(header: KotlinClassHeader): Boolean {
return header.classKind == JvmAnnotationNames.KotlinClass.Kind.CLASS || header.isInterfaceDefaultImpls
return (header.kind == KotlinClassHeader.Kind.CLASS && !header.isLocalClass) || header.isInterfaceDefaultImpls
}
private fun getClassHeader(file: OutputFile): KotlinClassHeader {
@@ -19,14 +19,12 @@ package org.jetbrains.kotlin.codegen;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.backend.common.output.OutputFile;
import org.jetbrains.kotlin.load.java.AbiVersionUtil;
import org.jetbrains.kotlin.load.java.JvmAbi;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinClass;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinSyntheticClass;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.resolve.jvm.JvmClassName;
import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion;
import org.jetbrains.kotlin.test.ConfigurationKind;
@@ -34,9 +32,6 @@ import java.lang.annotation.Annotation;
import java.util.Collection;
import java.util.List;
import static org.jetbrains.kotlin.load.java.JvmAnnotationNames.KIND_FIELD_NAME;
import static org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinClass.Kind.ANONYMOUS_OBJECT;
import static org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinClass.Kind.LOCAL_CLASS;
import static org.jetbrains.kotlin.load.java.JvmAnnotationNames.VERSION_FIELD_NAME;
public class KotlinSyntheticClassAnnotationTest extends CodegenTestCase {
@@ -93,8 +88,7 @@ public class KotlinSyntheticClassAnnotationTest extends CodegenTestCase {
public void testLocalClass() {
doTestKotlinClass(
"fun foo() { class Local }",
"Local",
LOCAL_CLASS
"Local"
);
}
@@ -108,24 +102,21 @@ public class KotlinSyntheticClassAnnotationTest extends CodegenTestCase {
public void testLocalTraitInterface() {
doTestKotlinClass(
"fun foo() { interface Local { fun bar() = 42 } }",
"Local.class",
LOCAL_CLASS
"Local.class"
);
}
public void testInnerClassOfLocalClass() {
doTestKotlinClass(
"fun foo() { class Local { inner class Inner } }",
"Inner",
LOCAL_CLASS
"Inner"
);
}
public void testAnonymousObject() {
doTestKotlinClass(
"val o = object {}",
"$1",
ANONYMOUS_OBJECT
"$1"
);
}
@@ -138,22 +129,17 @@ public class KotlinSyntheticClassAnnotationTest extends CodegenTestCase {
}
private void doTestKotlinSyntheticClass(@NotNull String code, @NotNull String classFilePart) {
doTest(code, classFilePart, KotlinSyntheticClass.CLASS_NAME, null);
doTest(code, classFilePart, KotlinSyntheticClass.CLASS_NAME.getFqNameForClassNameWithoutDollars());
}
private void doTestKotlinClass(
@NotNull String code,
@NotNull String classFilePart,
@NotNull KotlinClass.Kind expectedKind
) {
doTest(code, classFilePart, KotlinClass.CLASS_NAME, expectedKind.toString());
private void doTestKotlinClass(@NotNull String code, @NotNull String classFilePart) {
doTest(code, classFilePart, JvmAnnotationNames.KOTLIN_CLASS, JvmAnnotationNames.KOTLIN_LOCAL_CLASS);
}
private void doTest(
@NotNull String code,
@NotNull final String classFilePart,
@NotNull JvmClassName annotationName,
@Nullable String expectedKind
@NotNull FqName... annotationFqNames
) {
loadText("package " + PACKAGE_NAME + "\n\n" + code);
List<OutputFile> output = generateClassesInFile().asList();
@@ -169,14 +155,12 @@ public class KotlinSyntheticClassAnnotationTest extends CodegenTestCase {
String path = files.iterator().next().getRelativePath();
String fqName = path.substring(0, path.length() - ".class".length()).replace('/', '.');
Class<?> aClass = generateClass(fqName);
assertAnnotatedWithKind(aClass, annotationName.getFqNameForClassNameWithoutDollars().asString(), expectedKind);
for (FqName annotationFqName : annotationFqNames) {
assertAnnotatedWith(aClass, annotationFqName.asString());
}
}
private void assertAnnotatedWithKind(
@NotNull Class<?> aClass,
@NotNull String annotationFqName,
@Nullable String expectedKind
) {
private void assertAnnotatedWith(@NotNull Class<?> aClass, @NotNull String annotationFqName) {
Class<? extends Annotation> annotationClass = loadAnnotationClassQuietly(annotationFqName);
assertTrue("No annotation " + annotationFqName + " found in " + aClass, aClass.isAnnotationPresent(annotationClass));
@@ -186,9 +170,5 @@ public class KotlinSyntheticClassAnnotationTest extends CodegenTestCase {
assertNotNull(version);
assertTrue("Annotation " + annotationFqName + " is written with an unsupported format",
AbiVersionUtil.isAbiVersionCompatible(BinaryVersion.create(version)));
Object actualKind = CodegenTestUtil.getAnnotationAttribute(annotation, KIND_FIELD_NAME);
assertNotNull(actualKind);
assertEquals("Annotation " + annotationFqName + " has the wrong kind", expectedKind, actualKind.toString());
}
}
@@ -150,11 +150,10 @@ public abstract class AbstractJvmRuntimeDescriptorLoaderTest : TestCaseWithTmpdi
val packageView = module.getPackage(LoadDescriptorUtil.TEST_PACKAGE_FQNAME)
packageScopes.add(packageView.memberScope)
}
else if (header == null ||
(header.kind == KotlinClassHeader.Kind.CLASS && header.classKind == JvmAnnotationNames.KotlinClass.Kind.CLASS)) {
else if (header == null || (header.kind == KotlinClassHeader.Kind.CLASS && !header.isLocalClass)) {
// Either a normal Kotlin class or a Java class
val classId = klass.classId
if (!classId.isLocal()) {
if (!classId.isLocal) {
val classDescriptor = module.findClassAcrossModuleDependencies(classId).sure { "Couldn't resolve class $className" }
if (DescriptorUtils.isTopLevelDeclaration(classDescriptor)) {
classes.add(classDescriptor)
@@ -76,17 +76,13 @@ public abstract class AbstractLocalClassProtoTest : TestCaseWithTmpdir() {
)
}
@Suppress("UNCHECKED_CAST")
private fun assertHasAnnotationData(clazz: Class<*>) {
@Suppress("UNCHECKED_CAST")
val annotation = clazz.getAnnotation(
checkNotNull(clazz.getAnnotation(
clazz.classLoader.loadClass(JvmAnnotationNames.KOTLIN_CLASS.asString()) as Class<Annotation>
)
assert(annotation != null) { "KotlinClass annotation is not found for class $clazz" }
val kindMethod = annotation.annotationType().getDeclaredMethod("kind")
val kind = kindMethod(annotation)
assert(kind.toString() != JvmAnnotationNames.KotlinClass.Kind.CLASS.toString()) {
"'kind' should not be CLASS: $clazz (was $kind)"
}
)) { "KotlinClass annotation is not found for class $clazz" }
checkNotNull(clazz.getAnnotation(
clazz.classLoader.loadClass(JvmAnnotationNames.KOTLIN_LOCAL_CLASS.asString()) as Class<Annotation>
)) { "KotlinLocalClass annotation is not found for class $clazz" }
}
}
@@ -28,13 +28,14 @@ import java.util.HashSet;
import java.util.Set;
public final class JvmAnnotationNames {
public static final FqName KOTLIN_CLASS = KotlinClass.CLASS_NAME.getFqNameForClassNameWithoutDollars();
public static final FqName KOTLIN_CLASS = new FqName("kotlin.jvm.internal.KotlinClass");
public static final FqName KOTLIN_PACKAGE = new FqName("kotlin.jvm.internal.KotlinPackage");
public static final FqName KOTLIN_FILE_FACADE = new FqName("kotlin.jvm.internal.KotlinFileFacade");
public static final FqName KOTLIN_MULTIFILE_CLASS = new FqName("kotlin.jvm.internal.KotlinMultifileClass");
public static final FqName KOTLIN_MULTIFILE_CLASS_PART = new FqName("kotlin.jvm.internal.KotlinMultifileClassPart");
public static final FqName KOTLIN_CALLABLE = new FqName("kotlin.jvm.internal.KotlinCallable");
public static final FqName KOTLIN_INTERFACE_DEFAULT_IMPLS = new FqName("kotlin.jvm.internal.KotlinInterfaceDefaultImpls");
public static final FqName KOTLIN_LOCAL_CLASS = new FqName("kotlin.jvm.internal.KotlinLocalClass");
public static final FqName JAVA_LANG_DEPRECATED = new FqName("java.lang.Deprecated");
@@ -68,23 +69,6 @@ public final class JvmAnnotationNames {
public static final FqName ENHANCED_NULLABILITY_ANNOTATION = new FqName("kotlin.jvm.internal.EnhancedNullability");
public static final FqName ENHANCED_MUTABILITY_ANNOTATION = new FqName("kotlin.jvm.internal.EnhancedMutability");
public static class KotlinClass {
public static final JvmClassName CLASS_NAME = JvmClassName.byInternalName("kotlin/jvm/internal/KotlinClass");
public static final ClassId KIND_CLASS_ID =
ClassId.topLevel(CLASS_NAME.getFqNameForClassNameWithoutDollars()).createNestedClassId(Name.identifier("Kind"));
public static final String KIND_INTERNAL_NAME = JvmClassName.byClassId(KIND_CLASS_ID).getInternalName();
/**
* This enum duplicates {@link kotlin.jvm.internal.KotlinClass.Kind}. Both places should be updated simultaneously.
*/
public enum Kind {
CLASS,
LOCAL_CLASS,
ANONYMOUS_OBJECT,
;
}
}
public static class KotlinSyntheticClass {
public static final JvmClassName CLASS_NAME = JvmClassName.byInternalName("kotlin/jvm/internal/KotlinSyntheticClass");
public static final ClassId KIND_CLASS_ID =
@@ -125,6 +109,7 @@ public final class JvmAnnotationNames {
}
SPECIAL_ANNOTATIONS.add(KotlinSyntheticClass.CLASS_NAME);
SPECIAL_ANNOTATIONS.add(JvmClassName.byFqNameWithoutInnerClasses(KOTLIN_INTERFACE_DEFAULT_IMPLS));
SPECIAL_ANNOTATIONS.add(JvmClassName.byFqNameWithoutInnerClasses(KOTLIN_LOCAL_CLASS));
for (FqName fqName : Arrays.asList(JETBRAINS_NOT_NULL_ANNOTATION, JETBRAINS_NULLABLE_ANNOTATION)) {
NULLABILITY_ANNOTATIONS.add(JvmClassName.byFqNameWithoutInnerClasses(fqName));
@@ -17,24 +17,22 @@
package org.jetbrains.kotlin.load.kotlin.header
import org.jetbrains.kotlin.load.java.AbiVersionUtil
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinClass
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinSyntheticClass
import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion
public class KotlinClassHeader(
public val kind: KotlinClassHeader.Kind,
public val version: BinaryVersion,
public val annotationData: Array<String>?,
public val strings: Array<String>?,
public val classKind: KotlinClass.Kind?,
public val syntheticClassKind: String?,
public val filePartClassNames: Array<String>?,
public val multifileClassName: String?,
public val isInterfaceDefaultImpls: Boolean
class KotlinClassHeader(
val kind: KotlinClassHeader.Kind,
val version: BinaryVersion,
val annotationData: Array<String>?,
val strings: Array<String>?,
val syntheticClassKind: String?,
val filePartClassNames: Array<String>?,
val multifileClassName: String?,
val isInterfaceDefaultImpls: Boolean,
val isLocalClass: Boolean
) {
public val isCompatibleAbiVersion: Boolean get() = AbiVersionUtil.isAbiVersionCompatible(version)
val isCompatibleAbiVersion: Boolean get() = AbiVersionUtil.isAbiVersionCompatible(version)
public enum class Kind {
enum class Kind {
CLASS,
PACKAGE_FACADE,
FILE_FACADE,
@@ -45,13 +43,13 @@ public class KotlinClassHeader(
override fun toString() =
"$kind " +
(if (classKind != null) "$classKind " else "") +
(if (isLocalClass) "(local) " else "") +
(if (syntheticClassKind != null) "$syntheticClassKind " else "") +
"version=$version"
}
public fun KotlinClassHeader.isCompatibleClassKind(): Boolean = isCompatibleAbiVersion && kind == KotlinClassHeader.Kind.CLASS
public fun KotlinClassHeader.isCompatiblePackageFacadeKind(): Boolean = isCompatibleAbiVersion && kind == KotlinClassHeader.Kind.PACKAGE_FACADE
public fun KotlinClassHeader.isCompatibleFileFacadeKind(): Boolean = isCompatibleAbiVersion && kind == KotlinClassHeader.Kind.FILE_FACADE
public fun KotlinClassHeader.isCompatibleMultifileClassKind(): Boolean = isCompatibleAbiVersion && kind == KotlinClassHeader.Kind.MULTIFILE_CLASS
public fun KotlinClassHeader.isCompatibleMultifileClassPartKind(): Boolean = isCompatibleAbiVersion && kind == KotlinClassHeader.Kind.MULTIFILE_CLASS_PART
fun KotlinClassHeader.isCompatibleClassKind(): Boolean = isCompatibleAbiVersion && kind == KotlinClassHeader.Kind.CLASS
fun KotlinClassHeader.isCompatiblePackageFacadeKind(): Boolean = isCompatibleAbiVersion && kind == KotlinClassHeader.Kind.PACKAGE_FACADE
fun KotlinClassHeader.isCompatibleFileFacadeKind(): Boolean = isCompatibleAbiVersion && kind == KotlinClassHeader.Kind.FILE_FACADE
fun KotlinClassHeader.isCompatibleMultifileClassKind(): Boolean = isCompatibleAbiVersion && kind == KotlinClassHeader.Kind.MULTIFILE_CLASS
fun KotlinClassHeader.isCompatibleMultifileClassPartKind(): Boolean = isCompatibleAbiVersion && kind == KotlinClassHeader.Kind.MULTIFILE_CLASS_PART
@@ -21,6 +21,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.SourceElement;
import org.jetbrains.kotlin.load.java.AbiVersionUtil;
import org.jetbrains.kotlin.name.ClassId;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.resolve.jvm.JvmClassName;
import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion;
@@ -39,7 +40,7 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
private static final Map<JvmClassName, KotlinClassHeader.Kind> OLD_DEPRECATED_ANNOTATIONS_KINDS = new HashMap<JvmClassName, KotlinClassHeader.Kind>();
static {
HEADER_KINDS.put(KotlinClass.CLASS_NAME, CLASS);
HEADER_KINDS.put(JvmClassName.byFqNameWithoutInnerClasses(KOTLIN_CLASS), CLASS);
HEADER_KINDS.put(JvmClassName.byFqNameWithoutInnerClasses(KOTLIN_PACKAGE), PACKAGE_FACADE);
HEADER_KINDS.put(JvmClassName.byFqNameWithoutInnerClasses(KOTLIN_FILE_FACADE), FILE_FACADE);
HEADER_KINDS.put(JvmClassName.byFqNameWithoutInnerClasses(KOTLIN_MULTIFILE_CLASS), MULTIFILE_CLASS);
@@ -66,9 +67,9 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
private String[] annotationData = null;
private String[] strings = null;
private KotlinClassHeader.Kind headerKind = null;
private KotlinClass.Kind classKind = null;
private String syntheticClassKind = null;
private boolean isInterfaceDefaultImpls = false;
private boolean isLocalClass = false;
@Nullable
public KotlinClassHeader createHeader() {
@@ -76,11 +77,6 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
return null;
}
if (headerKind == CLASS && classKind == null) {
// Default class kind is Kind.CLASS
classKind = KotlinClass.Kind.CLASS;
}
if (!AbiVersionUtil.isAbiVersionCompatible(version)) {
annotationData = null;
}
@@ -91,8 +87,8 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
}
return new KotlinClassHeader(
headerKind, version, annotationData, strings, classKind, syntheticClassKind, filePartClassNames, multifileClassName,
isInterfaceDefaultImpls
headerKind, version, annotationData, strings, syntheticClassKind, filePartClassNames, multifileClassName,
isInterfaceDefaultImpls, isLocalClass
);
}
@@ -106,10 +102,15 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
@Nullable
@Override
public AnnotationArgumentVisitor visitAnnotation(@NotNull ClassId classId, @NotNull SourceElement source) {
if (KOTLIN_INTERFACE_DEFAULT_IMPLS.equals(classId.asSingleFqName())) {
FqName fqName = classId.asSingleFqName();
if (KOTLIN_INTERFACE_DEFAULT_IMPLS.equals(fqName)) {
isInterfaceDefaultImpls = true;
return null;
}
else if (KOTLIN_LOCAL_CLASS.equals(fqName)) {
isLocalClass = true;
return null;
}
if (headerKind != null) {
// Ignore all Kotlin annotations except the first found
@@ -269,14 +270,7 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
private class ClassHeaderReader extends HeaderAnnotationArgumentVisitor {
public ClassHeaderReader() {
super(KotlinClass.CLASS_NAME);
}
@Override
public void visitEnum(@NotNull Name name, @NotNull ClassId enumClassId, @NotNull Name enumEntryName) {
if (KotlinClass.KIND_CLASS_ID.equals(enumClassId) && KIND_FIELD_NAME.equals(name.asString())) {
classKind = valueOfOrNull(KotlinClass.Kind.class, enumEntryName.asString());
}
super(JvmClassName.byFqNameWithoutInnerClasses(KOTLIN_CLASS));
}
}
@@ -316,16 +310,4 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
}
}
}
// This function is needed here because Enum.valueOf() throws exception if there's no such value,
// but we don't want to fail if we're loading the header with an _incompatible_ ABI version
@Nullable
private static <E extends Enum<E>> E valueOfOrNull(@NotNull Class<E> enumClass, @NotNull String entry) {
try {
return Enum.valueOf(enumClass, entry);
}
catch (IllegalArgumentException e) {
return null;
}
}
}
@@ -29,12 +29,14 @@ public @interface KotlinClass {
int[] version() default {};
Kind kind() default Kind.CLASS;
String[] data();
String[] strings();
@Deprecated
Kind kind() default Kind.CLASS;
@Deprecated
enum Kind {
CLASS,
@@ -0,0 +1,28 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package kotlin.jvm.internal;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface KotlinLocalClass {
int[] version() default {};
}
@@ -21,7 +21,6 @@ import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.ClassFileViewProvider
import org.jetbrains.kotlin.idea.caches.JarUserDataManager
import org.jetbrains.kotlin.idea.decompiler.textBuilder.DirectoryBasedClassFinder
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinClass
import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
@@ -71,9 +70,8 @@ public fun isKotlinInternalCompiledFile(file: VirtualFile): Boolean {
val header = KotlinBinaryClassCache.getKotlinBinaryClass(file)?.classHeader ?: return false
return header.kind == KotlinClassHeader.Kind.SYNTHETIC_CLASS ||
(header.kind == KotlinClassHeader.Kind.CLASS && header.classKind != null && header.classKind != KotlinClass.Kind.CLASS) ||
header.kind == KotlinClassHeader.Kind.MULTIFILE_CLASS_PART ||
header.syntheticClassKind == "PACKAGE_PART"
header.isLocalClass || header.syntheticClassKind == "PACKAGE_PART"
}
public fun isKotlinJavaScriptInternalCompiledFile(file: VirtualFile): Boolean =
@@ -27,7 +27,6 @@ import org.jetbrains.kotlin.idea.decompiler.isKotlinInternalCompiledFile
import org.jetbrains.kotlin.idea.decompiler.textBuilder.DirectoryBasedClassFinder
import org.jetbrains.kotlin.idea.decompiler.textBuilder.DirectoryBasedDataFinder
import org.jetbrains.kotlin.idea.decompiler.textBuilder.LoggingErrorReporter
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache
import org.jetbrains.kotlin.load.kotlin.header.isCompatibleClassKind
import org.jetbrains.kotlin.load.kotlin.header.isCompatibleFileFacadeKind
@@ -82,7 +81,7 @@ public open class KotlinClsStubBuilder : ClsStubBuilder() {
createPackageFacadeStub(packageProto, packageFqName, context)
}
header.isCompatibleClassKind() -> {
if (header.classKind != JvmAnnotationNames.KotlinClass.Kind.CLASS) return null
if (header.isLocalClass) return null
val (nameResolver, classProto) = JvmProtoBufUtil.readClassDataFrom(annotationData, strings)
val context = components.createContext(nameResolver, packageFqName)
createTopLevelClassStub(classId, classProto, context)
@@ -20,7 +20,6 @@ import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiManager
import org.jetbrains.kotlin.idea.decompiler.navigation.NavigateToDecompiledLibraryTest
import org.jetbrains.kotlin.idea.test.JetLightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinClass
import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import org.junit.Assert
@@ -34,11 +33,8 @@ public abstract class AbstractInternalCompiledClassesTest : JetLightCodeInsightF
protected fun isSyntheticClass(): VirtualFile.() -> Boolean =
isFileWithHeader { it.kind == KotlinClassHeader.Kind.SYNTHETIC_CLASS }
private fun isClassOfKind(kind: KotlinClass.Kind): VirtualFile.() -> Boolean =
isFileWithHeader { it.classKind == kind }
protected fun doTestNoPsiFilesAreBuiltForLocalClass(kind: KotlinClass.Kind): Unit =
doTestNoPsiFilesAreBuiltFor(kind.name(), isClassOfKind(kind))
protected fun doTestNoPsiFilesAreBuiltForLocalClass(): Unit =
doTestNoPsiFilesAreBuiltFor("local", isFileWithHeader { it.isLocalClass })
protected fun doTestNoPsiFilesAreBuiltForSyntheticClasses(): Unit =
doTestNoPsiFilesAreBuiltFor("synthetic", isSyntheticClass())
@@ -20,17 +20,13 @@ import com.intellij.psi.ClassFileViewProvider
import com.intellij.testFramework.LightProjectDescriptor
import org.jetbrains.kotlin.idea.test.JdkAndMockLibraryProjectDescriptor
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinClass.Kind.ANONYMOUS_OBJECT
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinClass.Kind.LOCAL_CLASS
public class InternalCompiledClassesTest : AbstractInternalCompiledClassesTest() {
private val TEST_DATA_PATH = PluginTestCaseBase.getTestDataPathBase() + "/decompiler/internalClasses"
fun testSyntheticClassesAreInvisible() = doTestNoPsiFilesAreBuiltForSyntheticClasses()
fun testLocalClassIsInvisible() = doTestNoPsiFilesAreBuiltForLocalClass(LOCAL_CLASS)
fun testAnonymousObjectIsInvisible() = doTestNoPsiFilesAreBuiltForLocalClass(ANONYMOUS_OBJECT)
fun testLocalClassesAreInvisible() = doTestNoPsiFilesAreBuiltForLocalClass()
fun testInnerClassIsInvisible() = doTestNoPsiFilesAreBuiltFor("inner or nested class") {
ClassFileViewProvider.isInnerClass(this)
@@ -31,7 +31,6 @@ import org.jetbrains.kotlin.jps.build.GeneratedJvmClass
import org.jetbrains.kotlin.jps.build.KotlinBuilder
import org.jetbrains.kotlin.jps.incremental.storage.BasicMap
import org.jetbrains.kotlin.jps.incremental.storage.BasicStringMap
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass
import org.jetbrains.kotlin.load.kotlin.ModuleMapping
import org.jetbrains.kotlin.load.kotlin.PackageClassUtils
@@ -216,10 +215,11 @@ public class IncrementalCacheImpl(
constantsMap.process(kotlinClass) +
inlineFunctionsMap.process(kotlinClass)
}
header.isCompatibleClassKind() && JvmAnnotationNames.KotlinClass.Kind.CLASS == header.classKind ->
header.isCompatibleClassKind() && !header.isLocalClass -> {
protoMap.process(kotlinClass, isPackage = false) +
constantsMap.process(kotlinClass) +
inlineFunctionsMap.process(kotlinClass)
}
else -> ChangesInfo.NO_CHANGES
}