Write KotlinInterfaceDefaultImpls annotation to DefaultImpls classes
Instead of KotlinSyntheticClass with kind = TRAIT_IMPL
This commit is contained in:
@@ -19,13 +19,13 @@ package org.jetbrains.kotlin.codegen
|
|||||||
import com.intellij.util.ArrayUtil
|
import com.intellij.util.ArrayUtil
|
||||||
import org.jetbrains.kotlin.backend.common.bridges.findImplementationFromInterface
|
import org.jetbrains.kotlin.backend.common.bridges.findImplementationFromInterface
|
||||||
import org.jetbrains.kotlin.backend.common.bridges.firstSuperMethodFromKotlin
|
import org.jetbrains.kotlin.backend.common.bridges.firstSuperMethodFromKotlin
|
||||||
import org.jetbrains.kotlin.codegen.AsmUtil.writeKotlinSyntheticClassAnnotation
|
|
||||||
import org.jetbrains.kotlin.codegen.context.ClassContext
|
import org.jetbrains.kotlin.codegen.context.ClassContext
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
|
||||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinSyntheticClass.Kind.LOCAL_TRAIT_IMPL
|
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||||
|
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KOTLIN_INTERFACE_DEFAULT_IMPLS
|
||||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinSyntheticClass.Kind.TRAIT_IMPL
|
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinSyntheticClass.Kind.TRAIT_IMPL
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
|
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -35,7 +35,9 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
|
|||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.DelegationToTraitImpl
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.DelegationToTraitImpl
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||||
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes.*
|
import org.jetbrains.org.objectweb.asm.Opcodes.ACC_FINAL
|
||||||
|
import org.jetbrains.org.objectweb.asm.Opcodes.ACC_PUBLIC
|
||||||
|
import org.jetbrains.org.objectweb.asm.Opcodes.ACC_STATIC
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes.V1_6
|
import org.jetbrains.org.objectweb.asm.Opcodes.V1_6
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@@ -144,9 +146,9 @@ public class InterfaceImplBodyCodegen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun generateKotlinAnnotation() {
|
override fun generateKotlinAnnotation() {
|
||||||
writeKotlinSyntheticClassAnnotation(
|
val av = v.newAnnotation(AsmUtil.asmDescByFqNameWithoutInnerClasses(KOTLIN_INTERFACE_DEFAULT_IMPLS), true)
|
||||||
v,
|
av.visit(JvmAnnotationNames.VERSION_FIELD_NAME, JvmAbi.VERSION.toArray())
|
||||||
if (DescriptorUtils.isTopLevelOrInnerClass(descriptor)) TRAIT_IMPL else LOCAL_TRAIT_IMPL
|
av.visitEnd()
|
||||||
)
|
AsmUtil.writeKotlinSyntheticClassAnnotation(v, TRAIT_IMPL)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -187,7 +187,7 @@ public object InlineTestUtil {
|
|||||||
private fun isClassOrPackagePartKind(header: KotlinClassHeader): Boolean {
|
private fun isClassOrPackagePartKind(header: KotlinClassHeader): Boolean {
|
||||||
return header.classKind == JvmAnnotationNames.KotlinClass.Kind.CLASS
|
return header.classKind == JvmAnnotationNames.KotlinClass.Kind.CLASS
|
||||||
|| header.syntheticClassKind == JvmAnnotationNames.KotlinSyntheticClass.Kind.PACKAGE_PART
|
|| header.syntheticClassKind == JvmAnnotationNames.KotlinSyntheticClass.Kind.PACKAGE_PART
|
||||||
|| header.syntheticClassKind == JvmAnnotationNames.KotlinSyntheticClass.Kind.TRAIT_IMPL
|
|| header.isInterfaceDefaultImpls
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getClassHeader(file: OutputFile): KotlinClassHeader {
|
private fun getClassHeader(file: OutputFile): KotlinClassHeader {
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ public final class JvmAnnotationNames {
|
|||||||
public static final FqName KOTLIN_MULTIFILE_CLASS = new FqName("kotlin.jvm.internal.KotlinMultifileClass");
|
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_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_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 JAVA_LANG_DEPRECATED = new FqName("java.lang.Deprecated");
|
public static final FqName JAVA_LANG_DEPRECATED = new FqName("java.lang.Deprecated");
|
||||||
|
|
||||||
@@ -139,6 +140,7 @@ public final class JvmAnnotationNames {
|
|||||||
SPECIAL_ANNOTATIONS.add(JvmClassName.byFqNameWithoutInnerClasses(fqName));
|
SPECIAL_ANNOTATIONS.add(JvmClassName.byFqNameWithoutInnerClasses(fqName));
|
||||||
}
|
}
|
||||||
SPECIAL_ANNOTATIONS.add(KotlinSyntheticClass.CLASS_NAME);
|
SPECIAL_ANNOTATIONS.add(KotlinSyntheticClass.CLASS_NAME);
|
||||||
|
SPECIAL_ANNOTATIONS.add(JvmClassName.byFqNameWithoutInnerClasses(KOTLIN_INTERFACE_DEFAULT_IMPLS));
|
||||||
|
|
||||||
for (FqName fqName : Arrays.asList(JETBRAINS_NOT_NULL_ANNOTATION, JETBRAINS_NULLABLE_ANNOTATION)) {
|
for (FqName fqName : Arrays.asList(JETBRAINS_NOT_NULL_ANNOTATION, JETBRAINS_NULLABLE_ANNOTATION)) {
|
||||||
NULLABILITY_ANNOTATIONS.add(JvmClassName.byFqNameWithoutInnerClasses(fqName));
|
NULLABILITY_ANNOTATIONS.add(JvmClassName.byFqNameWithoutInnerClasses(fqName));
|
||||||
|
|||||||
+2
-1
@@ -29,7 +29,8 @@ public class KotlinClassHeader(
|
|||||||
public val classKind: KotlinClass.Kind?,
|
public val classKind: KotlinClass.Kind?,
|
||||||
public val syntheticClassKind: KotlinSyntheticClass.Kind?,
|
public val syntheticClassKind: KotlinSyntheticClass.Kind?,
|
||||||
public val filePartClassNames: Array<String>?,
|
public val filePartClassNames: Array<String>?,
|
||||||
public val multifileClassName: String?
|
public val multifileClassName: String?,
|
||||||
|
public val isInterfaceDefaultImpls: Boolean
|
||||||
) {
|
) {
|
||||||
public val isCompatibleAbiVersion: Boolean get() = AbiVersionUtil.isAbiVersionCompatible(version)
|
public val isCompatibleAbiVersion: Boolean get() = AbiVersionUtil.isAbiVersionCompatible(version)
|
||||||
|
|
||||||
|
|||||||
+10
-4
@@ -68,6 +68,7 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
|
|||||||
private KotlinClassHeader.Kind headerKind = null;
|
private KotlinClassHeader.Kind headerKind = null;
|
||||||
private KotlinClass.Kind classKind = null;
|
private KotlinClass.Kind classKind = null;
|
||||||
private KotlinSyntheticClass.Kind syntheticClassKind = null;
|
private KotlinSyntheticClass.Kind syntheticClassKind = null;
|
||||||
|
private boolean isInterfaceDefaultImpls = false;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public KotlinClassHeader createHeader() {
|
public KotlinClassHeader createHeader() {
|
||||||
@@ -81,17 +82,17 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!AbiVersionUtil.isAbiVersionCompatible(version)) {
|
if (!AbiVersionUtil.isAbiVersionCompatible(version)) {
|
||||||
return new KotlinClassHeader(headerKind, version, null, strings, classKind, syntheticClassKind, null, null);
|
annotationData = null;
|
||||||
}
|
}
|
||||||
|
else if (shouldHaveData() && annotationData == null) {
|
||||||
if (shouldHaveData() && annotationData == null) {
|
|
||||||
// This means that the annotation is found and its ABI version is compatible, but there's no "data" string array in it.
|
// This means that the annotation is found and its ABI version is compatible, but there's no "data" string array in it.
|
||||||
// We tell the outside world that there's really no annotation at all
|
// We tell the outside world that there's really no annotation at all
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new KotlinClassHeader(
|
return new KotlinClassHeader(
|
||||||
headerKind, version, annotationData, strings, classKind, syntheticClassKind, filePartClassNames, multifileClassName
|
headerKind, version, annotationData, strings, classKind, syntheticClassKind, filePartClassNames, multifileClassName,
|
||||||
|
isInterfaceDefaultImpls
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,6 +106,11 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
|
|||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public AnnotationArgumentVisitor visitAnnotation(@NotNull ClassId classId, @NotNull SourceElement source) {
|
public AnnotationArgumentVisitor visitAnnotation(@NotNull ClassId classId, @NotNull SourceElement source) {
|
||||||
|
if (KOTLIN_INTERFACE_DEFAULT_IMPLS.equals(classId.asSingleFqName())) {
|
||||||
|
isInterfaceDefaultImpls = true;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (headerKind != null) {
|
if (headerKind != null) {
|
||||||
// Ignore all Kotlin annotations except the first found
|
// Ignore all Kotlin annotations except the first found
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -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 KotlinInterfaceDefaultImpls {
|
||||||
|
int[] version() default {};
|
||||||
|
}
|
||||||
@@ -41,10 +41,8 @@ public fun isKotlinJvmCompiledFile(file: VirtualFile): Boolean {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
val header = KotlinBinaryClassCache.getKotlinBinaryClass(file)?.getClassHeader()
|
val header = KotlinBinaryClassCache.getKotlinBinaryClass(file)?.classHeader
|
||||||
return header != null &&
|
return header != null && !header.isInterfaceDefaultImpls
|
||||||
header.syntheticClassKind != KotlinSyntheticClass.Kind.TRAIT_IMPL &&
|
|
||||||
header.syntheticClassKind != KotlinSyntheticClass.Kind.LOCAL_TRAIT_IMPL
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun isKotlinJsMetaFile(file: VirtualFile): Boolean = file.getFileType() == KotlinJavaScriptMetaFileType
|
public fun isKotlinJsMetaFile(file: VirtualFile): Boolean = file.getFileType() == KotlinJavaScriptMetaFileType
|
||||||
|
|||||||
Reference in New Issue
Block a user