Support type annotations in cls stub builder
Also add test on decompiler
This commit is contained in:
+1
-1
@@ -36,7 +36,7 @@ import org.jetbrains.kotlin.psi.stubs.impl.KotlinFileStubImpl;
|
||||
import java.io.IOException;
|
||||
|
||||
public class JetFileElementType extends IStubFileElementType<KotlinFileStub> {
|
||||
public static final int STUB_VERSION = 42;
|
||||
public static final int STUB_VERSION = 43;
|
||||
|
||||
private static final String NAME = "kotlin.FILE";
|
||||
|
||||
|
||||
+17
-12
@@ -16,23 +16,22 @@
|
||||
|
||||
package org.jetbrains.kotlin.load.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import java.util.ArrayList
|
||||
import org.jetbrains.kotlin.serialization.deserialization.AnnotatedCallableKind
|
||||
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.*
|
||||
import org.jetbrains.kotlin.serialization.deserialization.ProtoContainer
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import java.util.HashMap
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.serialization.Flags
|
||||
import org.jetbrains.kotlin.serialization.deserialization.AnnotationAndConstantLoader
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||
import org.jetbrains.kotlin.serialization.deserialization.DeserializationContext
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.deserialization.*
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.implClassName
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.index
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.methodSignature
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf.propertySignature
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.types.JetType
|
||||
import java.util.ArrayList
|
||||
import java.util.HashMap
|
||||
|
||||
public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C : Any>(
|
||||
storageManager: StorageManager,
|
||||
@@ -51,6 +50,8 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
|
||||
result: MutableList<A>
|
||||
): KotlinJvmBinaryClass.AnnotationArgumentVisitor?
|
||||
|
||||
protected abstract fun loadTypeAnnotation(proto: ProtoBuf.Annotation, nameResolver: NameResolver): A
|
||||
|
||||
private fun loadAnnotationIfNotSpecial(
|
||||
annotationClassId: ClassId,
|
||||
result: MutableList<A>
|
||||
@@ -128,6 +129,10 @@ public abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C
|
||||
return listOf()
|
||||
}
|
||||
|
||||
override fun loadTypeAnnotations(type: ProtoBuf.Type, nameResolver: NameResolver): List<A> {
|
||||
return type.getExtension(JvmProtoBuf.typeAnnotation).map { loadTypeAnnotation(it, nameResolver) }
|
||||
}
|
||||
|
||||
override fun loadPropertyConstant(
|
||||
container: ProtoContainer,
|
||||
proto: ProtoBuf.Callable,
|
||||
|
||||
+2
-6
@@ -32,7 +32,6 @@ import org.jetbrains.kotlin.serialization.deserialization.AnnotationDeserializer
|
||||
import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
|
||||
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
|
||||
import org.jetbrains.kotlin.serialization.deserialization.findClassAcrossModuleDependencies
|
||||
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBuf
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
import java.util.ArrayList
|
||||
@@ -48,11 +47,8 @@ public class BinaryClassAnnotationAndConstantLoaderImpl(
|
||||
) {
|
||||
private val annotationDeserializer = AnnotationDeserializer(module)
|
||||
|
||||
override fun loadTypeAnnotations(type: ProtoBuf.Type, nameResolver: NameResolver): List<AnnotationDescriptor> {
|
||||
return type.getExtension(JvmProtoBuf.typeAnnotation).map { annotation ->
|
||||
annotationDeserializer.deserializeAnnotation(annotation, nameResolver)
|
||||
}
|
||||
}
|
||||
override fun loadTypeAnnotation(proto: ProtoBuf.Annotation, nameResolver: NameResolver): AnnotationDescriptor =
|
||||
annotationDeserializer.deserializeAnnotation(proto, nameResolver)
|
||||
|
||||
override fun loadConstant(desc: String, initializer: Any): CompileTimeConstant<*>? {
|
||||
val normalizedValue: Any = if (desc in "ZBCS") {
|
||||
|
||||
+11
-14
@@ -16,18 +16,17 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.decompiler.stubBuilder
|
||||
|
||||
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.serialization.deserialization.ClassDataFinder
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder
|
||||
import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
|
||||
import org.jetbrains.kotlin.load.kotlin.AbstractBinaryClassAnnotationAndConstantLoader
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass
|
||||
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.serialization.ProtoBuf
|
||||
import org.jetbrains.kotlin.serialization.deserialization.ClassDataFinder
|
||||
import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
|
||||
import org.jetbrains.kotlin.serialization.deserialization.NameResolver
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
|
||||
class ClsStubBuilderComponents(
|
||||
val classDataFinder: ClassDataFinder,
|
||||
@@ -92,10 +91,8 @@ class AnnotationLoaderForStubBuilder(
|
||||
errorReporter: ErrorReporter
|
||||
) : AbstractBinaryClassAnnotationAndConstantLoader<ClassId, Unit>(
|
||||
LockBasedStorageManager.NO_LOCKS, kotlinClassFinder, errorReporter) {
|
||||
override fun loadTypeAnnotations(type: ProtoBuf.Type, nameResolver: NameResolver): MutableList<ClassId> {
|
||||
// TODO: support type annotations in cls stubs
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
override fun loadTypeAnnotation(proto: ProtoBuf.Annotation, nameResolver: NameResolver): ClassId =
|
||||
nameResolver.getClassId(proto.getId())
|
||||
|
||||
override fun loadConstant(desc: String, initializer: Any) = null
|
||||
|
||||
|
||||
+6
@@ -42,6 +42,12 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
|
||||
|
||||
fun createTypeReferenceStub(parent: StubElement<out PsiElement>, typeProto: Type) {
|
||||
val typeReference = KotlinPlaceHolderStubImpl<JetTypeReference>(parent, JetStubElementTypes.TYPE_REFERENCE)
|
||||
|
||||
val typeAnnotations = c.components.annotationLoader.loadTypeAnnotations(typeProto, c.nameResolver)
|
||||
if (typeAnnotations.isNotEmpty()) {
|
||||
createAnnotationStubs(typeAnnotations, typeReference, needWrappingAnnotationEntries = true)
|
||||
}
|
||||
|
||||
createTypeStub(typeReference, typeProto)
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -170,14 +170,14 @@ fun createModifierListStub(
|
||||
|
||||
fun createAnnotationStubs(
|
||||
annotationIds: List<ClassId>,
|
||||
modifierList: KotlinModifierListStubImpl,
|
||||
parent: KotlinStubBaseImpl<*>,
|
||||
needWrappingAnnotationEntries: Boolean = false
|
||||
) {
|
||||
if (annotationIds.isEmpty()) return
|
||||
|
||||
val entriesParent =
|
||||
if (needWrappingAnnotationEntries) KotlinPlaceHolderStubImpl<JetAnnotation>(modifierList, JetStubElementTypes.ANNOTATION)
|
||||
else modifierList
|
||||
if (needWrappingAnnotationEntries) KotlinPlaceHolderStubImpl<JetAnnotation>(parent, JetStubElementTypes.ANNOTATION)
|
||||
else parent
|
||||
|
||||
annotationIds.forEach {
|
||||
annotationClassId ->
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
package test
|
||||
|
||||
kotlin.data dependency.A dependency.B dependency.C internal final class Annotations public () {
|
||||
kotlin.inline dependency.A dependency.B dependency.C internal final val p: kotlin.Int /* compiled code */
|
||||
kotlin.inline dependency.A dependency.B dependency.C internal final val p: [dependency.B] kotlin.Int /* compiled code */
|
||||
|
||||
kotlin.inline dependency.A dependency.B dependency.C internal final fun f(dependency.A dependency.B dependency.C kotlin.deprecated i: kotlin.Int): kotlin.Unit { /* compiled code */ }
|
||||
kotlin.inline dependency.A dependency.B dependency.C internal final fun f(dependency.A dependency.B dependency.C kotlin.deprecated i: [dependency.A] kotlin.Int): kotlin.Unit { /* compiled code */ }
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ import dependency.*
|
||||
|
||||
data A("a") B(1) C class Annotations {
|
||||
|
||||
inline A("f") B(2) C fun f(A("i") B(3) C deprecated("1") i: Int) {
|
||||
inline A("f") B(2) C fun f(A("i") B(3) C deprecated("1") i: [A("int")] Int) {
|
||||
}
|
||||
|
||||
inline A("p") B(3) C val p: Int = 2
|
||||
inline A("p") B(3) C val p: [B(4)] Int = 2
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@ a public class Annotations private [a] (private [a] val c1: Int, [a] val c2: Int
|
||||
}
|
||||
|
||||
class Nested [a] private [b(E.E1) b(E.E2)] ()
|
||||
|
||||
fun types(param: [a] [b(E.E1)] DoubleRange): [a] [b(E.E2)] Unit {}
|
||||
}
|
||||
|
||||
annotation class a
|
||||
|
||||
@@ -153,6 +153,42 @@ PsiJetFileStubImpl[package=]
|
||||
USER_TYPE:[isAbsoluteInRootPackage=false]
|
||||
REFERENCE_EXPRESSION:[referencedName=kotlin]
|
||||
REFERENCE_EXPRESSION:[referencedName=Unit]
|
||||
FUN:[fqName=Annotations.types, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=false, isExtension=false, isTopLevel=false, name=types]
|
||||
MODIFIER_LIST:[internal final]
|
||||
VALUE_PARAMETER_LIST:
|
||||
VALUE_PARAMETER:[fqName=null, hasDefaultValue=false, hasValOrVarNode=false, isMutable=false, name=param]
|
||||
TYPE_REFERENCE:
|
||||
ANNOTATION:
|
||||
ANNOTATION_ENTRY:[hasValueArguments=false, shortName=a]
|
||||
CONSTRUCTOR_CALLEE:
|
||||
TYPE_REFERENCE:
|
||||
USER_TYPE:[isAbsoluteInRootPackage=false]
|
||||
REFERENCE_EXPRESSION:[referencedName=a]
|
||||
ANNOTATION_ENTRY:[hasValueArguments=false, shortName=b]
|
||||
CONSTRUCTOR_CALLEE:
|
||||
TYPE_REFERENCE:
|
||||
USER_TYPE:[isAbsoluteInRootPackage=false]
|
||||
REFERENCE_EXPRESSION:[referencedName=b]
|
||||
USER_TYPE:[isAbsoluteInRootPackage=false]
|
||||
USER_TYPE:[isAbsoluteInRootPackage=false]
|
||||
REFERENCE_EXPRESSION:[referencedName=kotlin]
|
||||
REFERENCE_EXPRESSION:[referencedName=DoubleRange]
|
||||
TYPE_REFERENCE:
|
||||
ANNOTATION:
|
||||
ANNOTATION_ENTRY:[hasValueArguments=false, shortName=a]
|
||||
CONSTRUCTOR_CALLEE:
|
||||
TYPE_REFERENCE:
|
||||
USER_TYPE:[isAbsoluteInRootPackage=false]
|
||||
REFERENCE_EXPRESSION:[referencedName=a]
|
||||
ANNOTATION_ENTRY:[hasValueArguments=false, shortName=b]
|
||||
CONSTRUCTOR_CALLEE:
|
||||
TYPE_REFERENCE:
|
||||
USER_TYPE:[isAbsoluteInRootPackage=false]
|
||||
REFERENCE_EXPRESSION:[referencedName=b]
|
||||
USER_TYPE:[isAbsoluteInRootPackage=false]
|
||||
USER_TYPE:[isAbsoluteInRootPackage=false]
|
||||
REFERENCE_EXPRESSION:[referencedName=kotlin]
|
||||
REFERENCE_EXPRESSION:[referencedName=Unit]
|
||||
CLASS:[fqName=Annotations.Nested, isEnumEntry=false, isLocal=false, isTopLevel=false, isTrait=false, name=Nested, superNames=[]]
|
||||
MODIFIER_LIST:[internal final]
|
||||
PRIMARY_CONSTRUCTOR:
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
PsiJetFileStubImpl[package=]
|
||||
PACKAGE_DIRECTIVE:
|
||||
CLASS:[fqName=a, isEnumEntry=false, isLocal=false, isTopLevel=true, isTrait=false, name=a, superNames=[]]
|
||||
MODIFIER_LIST:[annotation]
|
||||
CLASS:[fqName=b, isEnumEntry=false, isLocal=false, isTopLevel=true, isTrait=false, name=b, superNames=[]]
|
||||
MODIFIER_LIST:[annotation]
|
||||
PRIMARY_CONSTRUCTOR:
|
||||
VALUE_PARAMETER_LIST:
|
||||
VALUE_PARAMETER:[fqName=b.e, hasDefaultValue=false, hasValOrVarNode=true, isMutable=false, name=e]
|
||||
TYPE_REFERENCE:
|
||||
USER_TYPE:[isAbsoluteInRootPackage=false]
|
||||
REFERENCE_EXPRESSION:[referencedName=E]
|
||||
CLASS:[fqName=E, isEnumEntry=false, isLocal=false, isTopLevel=true, isTrait=false, name=E, superNames=[]]
|
||||
MODIFIER_LIST:[enum]
|
||||
CLASS_BODY:
|
||||
ENUM_ENTRY:[fqName=E.E1, isEnumEntry=true, isLocal=false, isTopLevel=false, isTrait=false, name=E1, superNames=[]]
|
||||
ENUM_ENTRY:[fqName=E.E2, isEnumEntry=true, isLocal=false, isTopLevel=false, isTrait=false, name=E2, superNames=[]]
|
||||
FUN:[fqName=types, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=false, isExtension=false, isTopLevel=true, name=types]
|
||||
VALUE_PARAMETER_LIST:
|
||||
VALUE_PARAMETER:[fqName=null, hasDefaultValue=false, hasValOrVarNode=false, isMutable=false, name=param]
|
||||
TYPE_REFERENCE:
|
||||
ANNOTATION:
|
||||
ANNOTATION_ENTRY:[hasValueArguments=false, shortName=a]
|
||||
CONSTRUCTOR_CALLEE:
|
||||
TYPE_REFERENCE:
|
||||
USER_TYPE:[isAbsoluteInRootPackage=false]
|
||||
REFERENCE_EXPRESSION:[referencedName=a]
|
||||
ANNOTATION:
|
||||
ANNOTATION_ENTRY:[hasValueArguments=true, shortName=b]
|
||||
CONSTRUCTOR_CALLEE:
|
||||
TYPE_REFERENCE:
|
||||
USER_TYPE:[isAbsoluteInRootPackage=false]
|
||||
REFERENCE_EXPRESSION:[referencedName=b]
|
||||
USER_TYPE:[isAbsoluteInRootPackage=false]
|
||||
REFERENCE_EXPRESSION:[referencedName=DoubleRange]
|
||||
TYPE_REFERENCE:
|
||||
ANNOTATION:
|
||||
ANNOTATION_ENTRY:[hasValueArguments=false, shortName=a]
|
||||
CONSTRUCTOR_CALLEE:
|
||||
TYPE_REFERENCE:
|
||||
USER_TYPE:[isAbsoluteInRootPackage=false]
|
||||
REFERENCE_EXPRESSION:[referencedName=a]
|
||||
ANNOTATION:
|
||||
ANNOTATION_ENTRY:[hasValueArguments=true, shortName=b]
|
||||
CONSTRUCTOR_CALLEE:
|
||||
TYPE_REFERENCE:
|
||||
USER_TYPE:[isAbsoluteInRootPackage=false]
|
||||
REFERENCE_EXPRESSION:[referencedName=b]
|
||||
USER_TYPE:[isAbsoluteInRootPackage=false]
|
||||
REFERENCE_EXPRESSION:[referencedName=Unit]
|
||||
@@ -0,0 +1,7 @@
|
||||
annotation class a
|
||||
|
||||
annotation class b(val e: E)
|
||||
|
||||
enum class E { E1 E2 }
|
||||
|
||||
fun types(param: [a] [b(E.E1)] DoubleRange): [a] [b(E.E2)] Unit {}
|
||||
@@ -238,4 +238,10 @@ public class StubBuilderTestGenerated extends AbstractStubBuilderTest {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/stubs/StarProjection.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("TypeAnnotation.kt")
|
||||
public void testTypeAnnotation() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("idea/testData/stubs/TypeAnnotation.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user