[cls] include property constant initializer in stubs

^KTIJ-24667
this would allow building FirElements from stubs
This commit is contained in:
Anna Kozlova
2023-04-11 19:41:05 +02:00
parent 70ef87354f
commit f0af7c4228
25 changed files with 1032 additions and 80 deletions
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.psi.stubs.KotlinStubVersions
import org.jetbrains.kotlin.resolve.constants.ClassLiteralValue
import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.resolve.constants.KClassValue
import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol
import org.jetbrains.kotlin.serialization.deserialization.getClassId
import org.jetbrains.kotlin.storage.LockBasedStorageManager
@@ -114,7 +115,7 @@ open class KotlinClsStubBuilder : ClsStubBuilder() {
val classFinder = DirectoryBasedClassFinder(file.parent!!, packageFqName)
val classDataFinder = DirectoryBasedDataFinder(classFinder, LOG, jvmMetadataVersion)
val annotationLoader = AnnotationLoaderForClassFileStubBuilder(classFinder, file, fileContent, jvmMetadataVersion)
return ClsStubBuilderComponents(classDataFinder, annotationLoader, file)
return ClsStubBuilderComponents(classDataFinder, annotationLoader, file, BuiltInSerializerProtocol, classFinder, jvmMetadataVersion)
}
companion object {
@@ -44,10 +44,12 @@ open class KotlinMetadataStubBuilder(
val packageProto = file.proto.`package`
val packageFqName = file.packageFqName
val nameResolver = file.nameResolver
val protocol = serializerProtocol()
val components = ClsStubBuilderComponents(
ProtoBasedClassDataFinder(file.proto, nameResolver, file.version),
AnnotationLoaderForStubBuilderImpl(serializerProtocol()),
virtualFile
AnnotationLoaderForStubBuilderImpl(protocol),
virtualFile,
protocol
)
val context = components.createContext(nameResolver, packageFqName, TypeTable(packageProto.typeTable))
@@ -0,0 +1,47 @@
package test
import kotlin.reflect.KClass
class PropertyInitializer {
annotation class Anno(
val arrayWithDefault: Array<String> = ["a", "b", "c"],
val enumWithDefault: E = E.B,
val klassWithDefault: KClass<E> = E::class,
//val klassWithDefaultDim: KClass<Array<*>> = Array::class,
val annotationWithDefault: A1 = A1(E.A, E.B),
val annotationArrayWithDefault: Array<A1> = [A1(E.A, E.B), A1(E.B, E.A)],
val bool: Boolean = true,
val byte: Byte = 1,
val short: Short = 2,
val int: Int = 3,
val long: Long = 4,
val float: Float = 5.0f,
val dbl: Double = 6.0,
val char: Char = '\n',
val str: String = "str",
val boolArray: BooleanArray
)
companion object {
const val b: Byte = 100
const val b1: Byte = 1
const val s: Short = 20000
const val s1: Short = 1
const val i: Int = 2000000
const val i1: Short = 1
const val l: Long = 2000000000000L
const val l1: Long = 1
const val f: Float = 3.14f
const val d: Double = 3.14
const val bb: Boolean = true
const val c: Char = '\u03c0' // pi symbol
const val MAX_HIGH_SURROGATE: Char = '\uDBFF'
const val nl = '\n'
const val str: String = ":)"
}
}
enum class E {
A, B;
}
annotation class A1(val e: E, val e1: E)
@@ -0,0 +1,445 @@
PsiJetFileStubImpl[package=test]
KotlinStub$PACKAGE_DIRECTIVE
KotlinStub$REFERENCE_EXPRESSION[referencedName=test]
KotlinStub$IMPORT_LIST
KotlinStub$CLASS[classId=test/PropertyInitializer, fqName=test.PropertyInitializer, isEnumEntry=false, isInterface=false, isLocal=false, isTopLevel=true, name=PropertyInitializer, superNames=[]]
KotlinStub$MODIFIER_LIST[public final]
KotlinStub$PRIMARY_CONSTRUCTOR[fqName=null, hasBody=false, isDelegatedCallToThis=false, isExtension=false, isTopLevel=false, name=PropertyInitializer]
KotlinStub$MODIFIER_LIST[public]
KotlinStub$VALUE_PARAMETER_LIST
KotlinStub$CLASS_BODY
KotlinStub$OBJECT_DECLARATION[classId=test/PropertyInitializer.Companion, fqName=test.PropertyInitializer.Companion, isCompanion=true, isLocal=false, isObjectLiteral=false, isTopLevel=false, name=Companion, superNames=[]]
KotlinStub$MODIFIER_LIST[public companion]
KotlinStub$CLASS_BODY
KotlinStub$PROPERTY[fqName=test.PropertyInitializer.Companion.MAX_HIGH_SURROGATE, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=MAX_HIGH_SURROGATE]
initializer: 56319
KotlinStub$MODIFIER_LIST[public final const]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Char]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$PROPERTY[fqName=test.PropertyInitializer.Companion.b, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=b]
initializer: 100
KotlinStub$MODIFIER_LIST[public final const]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Byte]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$PROPERTY[fqName=test.PropertyInitializer.Companion.b1, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=b1]
initializer: 1
KotlinStub$MODIFIER_LIST[public final const]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Byte]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$PROPERTY[fqName=test.PropertyInitializer.Companion.bb, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=bb]
initializer: 1
KotlinStub$MODIFIER_LIST[public final const]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Boolean]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$PROPERTY[fqName=test.PropertyInitializer.Companion.c, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=c]
initializer: 960
KotlinStub$MODIFIER_LIST[public final const]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Char]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$PROPERTY[fqName=test.PropertyInitializer.Companion.d, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=d]
initializer: 3.14
KotlinStub$MODIFIER_LIST[public final const]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Double]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$PROPERTY[fqName=test.PropertyInitializer.Companion.f, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=f]
initializer: 3.14
KotlinStub$MODIFIER_LIST[public final const]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Float]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$PROPERTY[fqName=test.PropertyInitializer.Companion.i, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=i]
initializer: 2000000
KotlinStub$MODIFIER_LIST[public final const]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Int]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$PROPERTY[fqName=test.PropertyInitializer.Companion.i1, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=i1]
initializer: 1
KotlinStub$MODIFIER_LIST[public final const]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Short]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$PROPERTY[fqName=test.PropertyInitializer.Companion.l, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=l]
initializer: 2000000000000
KotlinStub$MODIFIER_LIST[public final const]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Long]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$PROPERTY[fqName=test.PropertyInitializer.Companion.l1, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=l1]
initializer: 1
KotlinStub$MODIFIER_LIST[public final const]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Long]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$PROPERTY[fqName=test.PropertyInitializer.Companion.nl, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=nl]
initializer: 10
KotlinStub$MODIFIER_LIST[public final const]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Char]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$PROPERTY[fqName=test.PropertyInitializer.Companion.s, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=s]
initializer: 20000
KotlinStub$MODIFIER_LIST[public final const]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Short]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$PROPERTY[fqName=test.PropertyInitializer.Companion.s1, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=s1]
initializer: 1
KotlinStub$MODIFIER_LIST[public final const]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Short]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$PROPERTY[fqName=test.PropertyInitializer.Companion.str, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=str]
initializer: :)
KotlinStub$MODIFIER_LIST[public final const]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=String]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$CLASS[classId=test/PropertyInitializer.Anno, fqName=test.PropertyInitializer.Anno, isEnumEntry=false, isInterface=false, isLocal=false, isTopLevel=false, name=Anno, superNames=[Annotation]]
KotlinStub$MODIFIER_LIST[public final annotation]
KotlinStub$PRIMARY_CONSTRUCTOR[fqName=null, hasBody=false, isDelegatedCallToThis=false, isExtension=false, isTopLevel=false, name=Anno]
KotlinStub$MODIFIER_LIST[public]
KotlinStub$VALUE_PARAMETER_LIST
KotlinStub$VALUE_PARAMETER[fqName=null, hasDefaultValue=true, hasValOrVar=false, isMutable=false, name=arrayWithDefault]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Array]
KotlinStub$TYPE_ARGUMENT_LIST
KotlinStub$TYPE_PROJECTION[projectionKind=NONE]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=String]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$VALUE_PARAMETER[fqName=null, hasDefaultValue=true, hasValOrVar=false, isMutable=false, name=enumWithDefault]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=test]
KotlinStub$REFERENCE_EXPRESSION[referencedName=E]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$VALUE_PARAMETER[fqName=null, hasDefaultValue=true, hasValOrVar=false, isMutable=false, name=klassWithDefault]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=reflect]
KotlinStub$REFERENCE_EXPRESSION[referencedName=KClass]
KotlinStub$TYPE_ARGUMENT_LIST
KotlinStub$TYPE_PROJECTION[projectionKind=NONE]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=test]
KotlinStub$REFERENCE_EXPRESSION[referencedName=E]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$VALUE_PARAMETER[fqName=null, hasDefaultValue=true, hasValOrVar=false, isMutable=false, name=annotationWithDefault]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=test]
KotlinStub$REFERENCE_EXPRESSION[referencedName=A1]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$VALUE_PARAMETER[fqName=null, hasDefaultValue=true, hasValOrVar=false, isMutable=false, name=annotationArrayWithDefault]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Array]
KotlinStub$TYPE_ARGUMENT_LIST
KotlinStub$TYPE_PROJECTION[projectionKind=NONE]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=test]
KotlinStub$REFERENCE_EXPRESSION[referencedName=A1]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$VALUE_PARAMETER[fqName=null, hasDefaultValue=true, hasValOrVar=false, isMutable=false, name=bool]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Boolean]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$VALUE_PARAMETER[fqName=null, hasDefaultValue=true, hasValOrVar=false, isMutable=false, name=byte]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Byte]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$VALUE_PARAMETER[fqName=null, hasDefaultValue=true, hasValOrVar=false, isMutable=false, name=short]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Short]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$VALUE_PARAMETER[fqName=null, hasDefaultValue=true, hasValOrVar=false, isMutable=false, name=int]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Int]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$VALUE_PARAMETER[fqName=null, hasDefaultValue=true, hasValOrVar=false, isMutable=false, name=long]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Long]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$VALUE_PARAMETER[fqName=null, hasDefaultValue=true, hasValOrVar=false, isMutable=false, name=float]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Float]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$VALUE_PARAMETER[fqName=null, hasDefaultValue=true, hasValOrVar=false, isMutable=false, name=dbl]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Double]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$VALUE_PARAMETER[fqName=null, hasDefaultValue=true, hasValOrVar=false, isMutable=false, name=char]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Char]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$VALUE_PARAMETER[fqName=null, hasDefaultValue=true, hasValOrVar=false, isMutable=false, name=str]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=String]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$VALUE_PARAMETER[fqName=null, hasDefaultValue=false, hasValOrVar=false, isMutable=false, name=boolArray]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=BooleanArray]
KotlinStub$SUPER_TYPE_LIST
KotlinStub$SUPER_TYPE_ENTRY
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Annotation]
KotlinStub$CLASS_BODY
KotlinStub$PROPERTY[fqName=test.PropertyInitializer.Anno.annotationArrayWithDefault, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=annotationArrayWithDefault]
initializer: [Value(type=KotlinClassTypeBean(classId=test/A1, arguments=[], nullable=false), argumentsMapping={e=E.A, e1=E.B}), Value(type=KotlinClassTypeBean(classId=test/A1, arguments=[], nullable=false), argumentsMapping={e=E.B, e1=E.A})]
KotlinStub$MODIFIER_LIST[public final]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Array]
KotlinStub$TYPE_ARGUMENT_LIST
KotlinStub$TYPE_PROJECTION[projectionKind=NONE]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=test]
KotlinStub$REFERENCE_EXPRESSION[referencedName=A1]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$PROPERTY[fqName=test.PropertyInitializer.Anno.annotationWithDefault, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=annotationWithDefault]
initializer: Value(type=KotlinClassTypeBean(classId=test/A1, arguments=[], nullable=false), argumentsMapping={e=E.A, e1=E.B})
KotlinStub$MODIFIER_LIST[public final]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=test]
KotlinStub$REFERENCE_EXPRESSION[referencedName=A1]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$PROPERTY[fqName=test.PropertyInitializer.Anno.arrayWithDefault, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=arrayWithDefault]
initializer: ["a", "b", "c"]
KotlinStub$MODIFIER_LIST[public final]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Array]
KotlinStub$TYPE_ARGUMENT_LIST
KotlinStub$TYPE_PROJECTION[projectionKind=NONE]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=String]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$PROPERTY[fqName=test.PropertyInitializer.Anno.bool, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=bool]
initializer: true
KotlinStub$MODIFIER_LIST[public final]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Boolean]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$PROPERTY[fqName=test.PropertyInitializer.Anno.boolArray, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=boolArray]
KotlinStub$MODIFIER_LIST[public final]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=BooleanArray]
KotlinStub$PROPERTY[fqName=test.PropertyInitializer.Anno.byte, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=byte]
initializer: 1
KotlinStub$MODIFIER_LIST[public final]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Byte]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$PROPERTY[fqName=test.PropertyInitializer.Anno.char, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=char]
initializer:
KotlinStub$MODIFIER_LIST[public final]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Char]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$PROPERTY[fqName=test.PropertyInitializer.Anno.dbl, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=dbl]
initializer: 6.0
KotlinStub$MODIFIER_LIST[public final]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Double]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$PROPERTY[fqName=test.PropertyInitializer.Anno.enumWithDefault, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=enumWithDefault]
initializer: (test/E, B)
KotlinStub$MODIFIER_LIST[public final]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=test]
KotlinStub$REFERENCE_EXPRESSION[referencedName=E]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$PROPERTY[fqName=test.PropertyInitializer.Anno.float, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=float]
initializer: 5.0
KotlinStub$MODIFIER_LIST[public final]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Float]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$PROPERTY[fqName=test.PropertyInitializer.Anno.int, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=int]
initializer: 3
KotlinStub$MODIFIER_LIST[public final]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Int]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$PROPERTY[fqName=test.PropertyInitializer.Anno.klassWithDefault, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=klassWithDefault]
initializer: NormalClass(value=test/E)
KotlinStub$MODIFIER_LIST[public final]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=reflect]
KotlinStub$REFERENCE_EXPRESSION[referencedName=KClass]
KotlinStub$TYPE_ARGUMENT_LIST
KotlinStub$TYPE_PROJECTION[projectionKind=NONE]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=test]
KotlinStub$REFERENCE_EXPRESSION[referencedName=E]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$PROPERTY[fqName=test.PropertyInitializer.Anno.long, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=long]
initializer: 4
KotlinStub$MODIFIER_LIST[public final]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Long]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$PROPERTY[fqName=test.PropertyInitializer.Anno.short, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=short]
initializer: 2
KotlinStub$MODIFIER_LIST[public final]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=Short]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
KotlinStub$PROPERTY[fqName=test.PropertyInitializer.Anno.str, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=str]
initializer: str
KotlinStub$MODIFIER_LIST[public final]
KotlinStub$TYPE_REFERENCE
KotlinStub$USER_TYPE
KotlinStub$USER_TYPE
KotlinStub$REFERENCE_EXPRESSION[referencedName=kotlin]
KotlinStub$REFERENCE_EXPRESSION[referencedName=String]
KotlinStub$REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
@@ -37,10 +37,11 @@ PsiJetFileStubImpl[package=test.a]
USER_TYPE
REFERENCE_EXPRESSION[referencedName=kotlin]
REFERENCE_EXPRESSION[referencedName=Int]
PROPERTY[fqName=test.a.AnnotationClass.j, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=j]
PROPERTY[fqName=test.a.AnnotationClass.j, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=j]
MODIFIER_LIST[public final]
TYPE_REFERENCE
USER_TYPE
USER_TYPE
REFERENCE_EXPRESSION[referencedName=kotlin]
REFERENCE_EXPRESSION[referencedName=String]
REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
@@ -5,10 +5,11 @@ PsiJetFileStubImpl[package=test]
OBJECT_DECLARATION[classId=test/Const, fqName=test.Const, isCompanion=false, isLocal=false, isObjectLiteral=false, isTopLevel=true, name=Const, superNames=[]]
MODIFIER_LIST[public]
CLASS_BODY
PROPERTY[fqName=test.Const.inObject, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=inObject]
PROPERTY[fqName=test.Const.inObject, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=inObject]
MODIFIER_LIST[private final const]
TYPE_REFERENCE
USER_TYPE
USER_TYPE
REFERENCE_EXPRESSION[referencedName=kotlin]
REFERENCE_EXPRESSION[referencedName=Int]
REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
@@ -2,7 +2,7 @@ PsiJetFileStubImpl[package=test]
PACKAGE_DIRECTIVE
REFERENCE_EXPRESSION[referencedName=test]
IMPORT_LIST
PROPERTY[fqName=test.annotatedConstVal, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=false, isTopLevel=true, isVar=false, name=annotatedConstVal]
PROPERTY[fqName=test.annotatedConstVal, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=true, isVar=false, name=annotatedConstVal]
MODIFIER_LIST[public const]
ANNOTATION_ENTRY[hasValueArguments=false, shortName=Deprecated]
CONSTRUCTOR_CALLEE
@@ -16,6 +16,7 @@ PsiJetFileStubImpl[package=test]
USER_TYPE
REFERENCE_EXPRESSION[referencedName=kotlin]
REFERENCE_EXPRESSION[referencedName=Int]
REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
PROPERTY[fqName=test.p1Val, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=false, isTopLevel=true, isVar=false, name=p1Val]
MODIFIER_LIST[public]
TYPE_REFERENCE
@@ -11,14 +11,15 @@ PsiJetFileStubImpl[package=test]
OBJECT_DECLARATION[classId=test/PrivateConstField.Companion, fqName=test.PrivateConstField.Companion, isCompanion=true, isLocal=false, isObjectLiteral=false, isTopLevel=false, name=Companion, superNames=[]]
MODIFIER_LIST[private companion]
CLASS_BODY
PROPERTY[fqName=test.PrivateConstField.Companion.CONST, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=CONST]
PROPERTY[fqName=test.PrivateConstField.Companion.CONST, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=CONST]
MODIFIER_LIST[public final const]
TYPE_REFERENCE
USER_TYPE
USER_TYPE
REFERENCE_EXPRESSION[referencedName=kotlin]
REFERENCE_EXPRESSION[referencedName=Int]
PROPERTY[fqName=test.PrivateConstField.Companion.CONST_WITH_ANNOTATION, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=CONST_WITH_ANNOTATION]
REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
PROPERTY[fqName=test.PrivateConstField.Companion.CONST_WITH_ANNOTATION, hasDelegate=false, hasDelegateExpression=false, hasInitializer=true, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=CONST_WITH_ANNOTATION]
MODIFIER_LIST[public final const]
ANNOTATION_ENTRY[hasValueArguments=false, shortName=A]
CONSTRUCTOR_CALLEE
@@ -42,6 +43,7 @@ PsiJetFileStubImpl[package=test]
USER_TYPE
REFERENCE_EXPRESSION[referencedName=kotlin]
REFERENCE_EXPRESSION[referencedName=Int]
REFERENCE_EXPRESSION[referencedName=COMPILED_CODE]
PROPERTY[fqName=test.PrivateConstField.Companion.field, hasDelegate=false, hasDelegateExpression=false, hasInitializer=false, hasReturnTypeRef=true, isExtension=false, isTopLevel=false, isVar=false, name=field]
MODIFIER_LIST[public final]
TYPE_REFERENCE
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.psi.KtProjectionKind
import org.jetbrains.kotlin.psi.stubs.impl.*
import org.jetbrains.kotlin.test.KotlinTestUtils
import java.nio.file.Paths
import kotlin.reflect.KClass
abstract class AbstractAdditionalStubInfoTest : AbstractDecompiledClassTest() {
fun runTest(testDirectory: String) {
@@ -43,6 +44,12 @@ abstract class AbstractAdditionalStubInfoTest : AbstractDecompiledClassTest() {
}
}
}
is KotlinPropertyStubImpl -> {
val initializer = stub.constantInitializer
if (initializer != null) {
builder.append("\n").append(" ".repeat(level)).append("initializer: ${initializer.value}")
}
}
}
for (child in stub.childrenStubs) {
builder.append("\n").append(" ".repeat(level))
@@ -42,6 +42,12 @@ public class AdditionalStubInfoTestGenerated extends AbstractAdditionalStubInfoT
runTest("analysis/decompiled/decompiler-to-file-stubs/testData/additionalClsStubInfo/OuterClassesWithFlexibleArgs/");
}
@Test
@TestMetadata("PropertyInitializer")
public void testPropertyInitializer() throws Exception {
runTest("analysis/decompiled/decompiler-to-file-stubs/testData/additionalClsStubInfo/PropertyInitializer/");
}
@Test
@TestMetadata("TypeParametersInFlexibleTypes")
public void testTypeParametersInFlexibleTypes() throws Exception {
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.analysis.decompiler.psi.text
import com.intellij.openapi.diagnostic.Logger
import org.jetbrains.kotlin.analysis.decompiler.psi.file.KtDecompiledFile
import org.jetbrains.kotlin.analysis.decompiler.stub.COMPILED_DEFAULT_INITIALIZER
import org.jetbrains.kotlin.analysis.decompiler.stub.COMPILED_DEFAULT_PARAMETER_VALUE
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltInsSignatures
import org.jetbrains.kotlin.descriptors.*
@@ -110,6 +112,8 @@ object ByDescriptorIndexer : DecompiledTextIndexer<String> {
withDefinedIn = true
renderUnabbreviatedType = false
defaultParameterValueRenderer = null
includePropertyConstant = true
propertyConstantRenderer = { _ -> COMPILED_DEFAULT_INITIALIZER }
}
private val LOG = Logger.getInstance(this::class.java)
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.analysis.decompiler.psi.text
import com.intellij.openapi.util.TextRange
import org.jetbrains.kotlin.analysis.decompiler.stub.COMPILED_DEFAULT_INITIALIZER
import org.jetbrains.kotlin.analysis.decompiler.stub.COMPILED_DEFAULT_PARAMETER_VALUE
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.contracts.description.ContractProviderKey
@@ -19,6 +20,7 @@ import org.jetbrains.kotlin.renderer.DescriptorRendererOptions
import org.jetbrains.kotlin.renderer.render
import org.jetbrains.kotlin.resolve.DataClassDescriptorResolver
import org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumEntry
import org.jetbrains.kotlin.resolve.constants.*
import org.jetbrains.kotlin.resolve.descriptorUtil.secondaryConstructors
import org.jetbrains.kotlin.types.isFlexible
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
@@ -37,6 +39,8 @@ fun DescriptorRendererOptions.defaultDecompilerRendererOptions() {
alwaysRenderModifiers = true
parameterNamesInFunctionalTypes = false // to support parameters names in decompiled text we need to load annotation arguments
defaultParameterValueRenderer = { _ -> COMPILED_DEFAULT_PARAMETER_VALUE }
includePropertyConstant = true
propertyConstantRenderer = { _ -> COMPILED_DEFAULT_INITIALIZER }
}
internal fun CallableMemberDescriptor.mustNotBeWrittenToDecompiledText(): Boolean {
@@ -4,24 +4,34 @@ package org.jetbrains.kotlin.analysis.decompiler.stub
import com.intellij.psi.PsiElement
import com.intellij.psi.stubs.StubElement
import com.intellij.util.io.StringRef
import org.jetbrains.kotlin.analysis.decompiler.stub.flags.*
import org.jetbrains.kotlin.constant.ConstantValue
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.load.kotlin.*
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.ProtoBuf.MemberKind
import org.jetbrains.kotlin.metadata.ProtoBuf.Modality
import org.jetbrains.kotlin.metadata.deserialization.*
import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.stubs.KotlinPropertyStub
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
import org.jetbrains.kotlin.psi.stubs.impl.KotlinConstructorStubImpl
import org.jetbrains.kotlin.psi.stubs.impl.KotlinFunctionStubImpl
import org.jetbrains.kotlin.psi.stubs.impl.KotlinPropertyAccessorStubImpl
import org.jetbrains.kotlin.psi.stubs.impl.KotlinPropertyStubImpl
import org.jetbrains.kotlin.psi.stubs.impl.*
import org.jetbrains.kotlin.resolve.DataClassResolver
import org.jetbrains.kotlin.resolve.constants.ClassLiteralValue
import org.jetbrains.kotlin.serialization.deserialization.AnnotatedCallableKind
import org.jetbrains.kotlin.serialization.deserialization.ProtoContainer
import org.jetbrains.kotlin.serialization.deserialization.getName
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.addToStdlib.runIf
const val COMPILED_DEFAULT_INITIALIZER = "COMPILED_CODE"
fun createPackageDeclarationsStubs(
parentStub: StubElement<out PsiElement>,
outerContext: ClsStubBuilderContext,
@@ -248,6 +258,7 @@ private class PropertyClsStubBuilder(
override fun doCreateCallableStub(parent: StubElement<out PsiElement>): StubElement<out PsiElement> {
val callableName = c.nameResolver.getName(propertyProto.name)
val initializer = calcInitializer()
// Note that arguments passed to stubs here and elsewhere are based on what stabs would be generated based on decompiled code
// This info is anyway irrelevant for the purposes these stubs are used
@@ -258,14 +269,18 @@ private class PropertyClsStubBuilder(
isTopLevel,
hasDelegate = false,
hasDelegateExpression = false,
hasInitializer = false,
hasInitializer = initializer != null,
isExtension = propertyProto.hasReceiver(),
hasReturnTypeRef = true,
fqName = c.containerFqName.child(callableName)
fqName = c.containerFqName.child(callableName),
initializer
)
}
override fun createCallableSpecialParts() {
if ((callableStub as KotlinPropertyStub).hasInitializer()) {
KotlinNameReferenceExpressionStubImpl(callableStub, StringRef.fromString(COMPILED_DEFAULT_INITIALIZER))
}
val flags = propertyProto.flags
if (Flags.HAS_GETTER[flags] && propertyProto.hasGetterFlags()) {
val getterFlags = propertyProto.getterFlags
@@ -319,6 +334,143 @@ private class PropertyClsStubBuilder(
createAnnotationStubs(annotationIds, modifierList)
}
}
private fun calcInitializer(): ConstantValue<*>? {
val classFinder = c.components.classFinder
val containerClass =
if (classFinder != null) getSpecialCaseContainerClass(classFinder, c.components.jvmMetadataVersion!!) else null
val source = protoContainer.source
val binaryClass = containerClass ?: (source as? KotlinJvmBinarySourceElement)?.binaryClass
var constantInitializer: ConstantValue<*>? = null
if (binaryClass != null) {
val callableName = c.nameResolver.getName(propertyProto.name)
binaryClass.visitMembers(object : KotlinJvmBinaryClass.MemberVisitor {
private val getterName = lazy(LazyThreadSafetyMode.NONE) {
val signature = propertyProto.getExtensionOrNull(JvmProtoBuf.propertySignature) ?: return@lazy null
c.nameResolver.getName(signature.getter.name)
}
override fun visitMethod(name: Name, desc: String): KotlinJvmBinaryClass.MethodAnnotationVisitor? {
if (protoContainer is ProtoContainer.Class && protoContainer.kind == ProtoBuf.Class.Kind.ANNOTATION_CLASS && getterName.value == name) {
return object : KotlinJvmBinaryClass.MethodAnnotationVisitor {
override fun visitParameterAnnotation(
index: Int,
classId: ClassId,
source: SourceElement
): KotlinJvmBinaryClass.AnnotationArgumentVisitor? = null
override fun visitAnnotationMemberDefaultValue(): KotlinJvmBinaryClass.AnnotationArgumentVisitor {
class AnnotationMemberDefaultValueVisitor : KotlinJvmBinaryClass.AnnotationArgumentVisitor {
private val args = mutableMapOf<Name, ConstantValue<*>>()
private fun nameOrSpecial(name: Name?): Name {
return name ?: Name.special("<no_name>")
}
override fun visit(name: Name?, value: Any?) {
args[nameOrSpecial(name)] = createConstantValue(value)
}
override fun visitClassLiteral(name: Name?, value: ClassLiteralValue) {
args[nameOrSpecial(name)] = createConstantValue(KClassData(value.classId, value.arrayNestedness))
}
override fun visitEnum(name: Name?, enumClassId: ClassId, enumEntryName: Name) {
args[nameOrSpecial(name)] = createConstantValue(EnumData(enumClassId, enumEntryName))
}
override fun visitAnnotation(
name: Name?,
classId: ClassId
): KotlinJvmBinaryClass.AnnotationArgumentVisitor {
val visitor = AnnotationMemberDefaultValueVisitor()
return object : KotlinJvmBinaryClass.AnnotationArgumentVisitor by visitor {
override fun visitEnd() {
args[nameOrSpecial(name)] = createConstantValue(AnnotationData(classId, visitor.args))
}
}
}
override fun visitArray(name: Name?): KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor {
return object : KotlinJvmBinaryClass.AnnotationArrayArgumentVisitor {
private val elements = mutableListOf<Any>()
override fun visit(value: Any?) {
elements.addIfNotNull(value)
}
override fun visitEnum(enumClassId: ClassId, enumEntryName: Name) {
elements.add(EnumData(enumClassId, enumEntryName))
}
override fun visitClassLiteral(value: ClassLiteralValue) {
elements.add(KClassData(value.classId, value.arrayNestedness))
}
override fun visitAnnotation(classId: ClassId): KotlinJvmBinaryClass.AnnotationArgumentVisitor {
val visitor = AnnotationMemberDefaultValueVisitor()
return object : KotlinJvmBinaryClass.AnnotationArgumentVisitor by visitor {
override fun visitEnd() {
elements.addIfNotNull(AnnotationData(classId, visitor.args))
}
}
}
override fun visitEnd() {
args[nameOrSpecial(name)] = createConstantValue(elements.toTypedArray())
}
}
}
override fun visitEnd() {
constantInitializer = args.values.firstOrNull()
}
}
return AnnotationMemberDefaultValueVisitor()
}
override fun visitAnnotation(
classId: ClassId,
source: SourceElement
): KotlinJvmBinaryClass.AnnotationArgumentVisitor? = null
override fun visitEnd() {}
}
}
return null
}
override fun visitField(name: Name, desc: String, initializer: Any?): KotlinJvmBinaryClass.AnnotationVisitor? {
if (initializer != null && name == callableName) {
constantInitializer = createConstantValue(initializer)
}
return null
}
}, null)
} else {
val value = propertyProto.getExtensionOrNull(c.components.serializationProtocol.compileTimeValue)
if (value != null) {
constantInitializer = createConstantValue(value, c.nameResolver)
}
}
return constantInitializer
}
private fun getSpecialCaseContainerClass(
classFinder: KotlinClassFinder,
jvmMetadataVersion: JvmMetadataVersion
): KotlinJvmBinaryClass? {
return AbstractBinaryClassAnnotationLoader.getSpecialCaseContainerClass(
container = protoContainer,
property = true,
field = true,
isConst = Flags.IS_CONST.get(propertyProto.flags),
isMovedFromInterfaceCompanion = JvmProtoBufUtil.isMovedFromInterfaceCompanion(propertyProto),
kotlinClassFinder = classFinder,
jvmMetadataVersion = jvmMetadataVersion
)
}
}
private class ConstructorClsStubBuilder(
@@ -4,12 +4,15 @@ package org.jetbrains.kotlin.analysis.decompiler.stub
import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
import org.jetbrains.kotlin.metadata.deserialization.TypeTable
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.serialization.SerializerExtensionProtocol
import org.jetbrains.kotlin.serialization.deserialization.AnnotationLoader
import org.jetbrains.kotlin.serialization.deserialization.ClassDataFinder
import org.jetbrains.kotlin.serialization.deserialization.ProtoContainer
@@ -20,7 +23,10 @@ data class ClassIdWithTarget(val classId: ClassId, val target: AnnotationUseSite
class ClsStubBuilderComponents(
val classDataFinder: ClassDataFinder,
val annotationLoader: AnnotationLoader<ClassId>,
val virtualFileForDebug: VirtualFile
val virtualFileForDebug: VirtualFile,
val serializationProtocol: SerializerExtensionProtocol,
val classFinder: KotlinClassFinder? = null,
val jvmMetadataVersion: JvmMetadataVersion? = null
) {
fun createContext(
nameResolver: NameResolver,
@@ -287,4 +287,4 @@ class FirTypeDeserializer(
val coneType = type(type)
return coneType.toTypeProjection(variance)
}
}
}
@@ -23,10 +23,12 @@ import com.intellij.psi.stubs.StubOutputStream;
import com.intellij.util.io.StringRef;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.constant.ConstantValue;
import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.psi.KtProperty;
import org.jetbrains.kotlin.psi.psiUtil.KtPsiUtilKt;
import org.jetbrains.kotlin.psi.stubs.KotlinPropertyStub;
import org.jetbrains.kotlin.psi.stubs.impl.KotlinConstantValueKt;
import org.jetbrains.kotlin.psi.stubs.impl.KotlinPropertyStubImpl;
import java.io.IOException;
@@ -48,7 +50,7 @@ public class KtPropertyElementType extends KtStubElementType<KotlinPropertyStub,
psi.isVar(), psi.isTopLevel(), psi.hasDelegate(),
psi.hasDelegateExpression(), psi.hasInitializer(),
psi.getReceiverTypeReference() != null, psi.getTypeReference() != null,
KtPsiUtilKt.safeFqNameForLazyResolve(psi)
KtPsiUtilKt.safeFqNameForLazyResolve(psi), null
);
}
@@ -65,6 +67,13 @@ public class KtPropertyElementType extends KtStubElementType<KotlinPropertyStub,
FqName fqName = stub.getFqName();
dataStream.writeName(fqName != null ? fqName.asString() : null);
ConstantValue<?> constantInitializer = stub instanceof KotlinPropertyStubImpl ? ((KotlinPropertyStubImpl) stub).getConstantInitializer() : null;
if (constantInitializer != null) {
KotlinConstantValueKt.serialize(constantInitializer, dataStream);
}
else {
dataStream.writeInt(-1);
}
}
@NotNull
@@ -84,7 +93,7 @@ public class KtPropertyElementType extends KtStubElementType<KotlinPropertyStub,
return new KotlinPropertyStubImpl(
(StubElement<?>) parentStub, name, isVar, isTopLevel, hasDelegate, hasDelegateExpression, hasInitializer,
hasReceiverTypeRef, hasReturnTypeRef, fqName
hasReceiverTypeRef, hasReturnTypeRef, fqName, KotlinConstantValueKt.createConstantValue(dataStream)
);
}
@@ -0,0 +1,244 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.psi.stubs.impl
import com.intellij.psi.stubs.StubInputStream
import com.intellij.psi.stubs.StubOutputStream
import org.jetbrains.kotlin.constant.*
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.Flags
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.stubs.StubUtils
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
enum class KotlinConstantValueKind {
NULL, BOOLEAN, CHAR, BYTE, SHORT, INT, LONG, DOUBLE, FLOAT, ENUM, KCLASS, STRING, ARRAY, UBYTE, USHORT, UINT, ULONG, ANNO;
}
fun createConstantValue(dataStream: StubInputStream): ConstantValue<*>? {
val kind = dataStream.readInt()
if (kind == -1) return null
return when (KotlinConstantValueKind.values()[kind]) {
KotlinConstantValueKind.NULL -> NullValue
KotlinConstantValueKind.BOOLEAN -> BooleanValue(dataStream.readBoolean())
KotlinConstantValueKind.CHAR -> CharValue(dataStream.readChar())
KotlinConstantValueKind.BYTE -> ByteValue(dataStream.readByte())
KotlinConstantValueKind.SHORT -> ShortValue(dataStream.readShort())
KotlinConstantValueKind.INT -> IntValue(dataStream.readInt())
KotlinConstantValueKind.LONG -> LongValue(dataStream.readLong())
KotlinConstantValueKind.DOUBLE -> DoubleValue(dataStream.readDouble())
KotlinConstantValueKind.FLOAT -> FloatValue(dataStream.readFloat())
KotlinConstantValueKind.ENUM -> EnumValue(
StubUtils.deserializeClassId(dataStream)!!,
Name.identifier(dataStream.readNameString()!!)
)
KotlinConstantValueKind.KCLASS -> KClassValue(StubUtils.deserializeClassId(dataStream)!!, dataStream.readInt())
KotlinConstantValueKind.STRING -> StringValue(dataStream.readNameString()!!)
KotlinConstantValueKind.ARRAY -> {
val arraySize = dataStream.readInt() - 1
ArrayValue((0..arraySize).map {
createConstantValue(dataStream)!!
})
}
KotlinConstantValueKind.UBYTE -> UByteValue(dataStream.readByte())
KotlinConstantValueKind.USHORT -> UShortValue(dataStream.readShort())
KotlinConstantValueKind.UINT -> UIntValue(dataStream.readInt())
KotlinConstantValueKind.ULONG -> ULongValue(dataStream.readLong())
KotlinConstantValueKind.ANNO -> {
val classId = StubUtils.deserializeClassId(dataStream)!!
val numberOfArgs = dataStream.readInt() - 1
AnnotationValue.create(KotlinClassTypeBean(classId, emptyList(), false), (0..numberOfArgs).associate {
Name.identifier(dataStream.readNameString()!!) to createConstantValue(dataStream)!!
})
}
}
}
fun serialize(constantValue: ConstantValue<*>, dataStream: StubOutputStream) {
constantValue.accept(KotlinConstantValueSerializationVisitor(dataStream), null)
}
class KotlinConstantValueSerializationVisitor(private val dataStream: StubOutputStream) :
AnnotationArgumentVisitor<Unit, Nothing?>() {
override fun visitArrayValue(value: ArrayValue, data: Nothing?) {
dataStream.writeInt(KotlinConstantValueKind.ARRAY.ordinal)
dataStream.writeInt(value.value.size)
for (constantValue in value.value) {
constantValue.accept(this, data)
}
}
override fun visitBooleanValue(value: BooleanValue, data: Nothing?) {
dataStream.writeInt(KotlinConstantValueKind.BOOLEAN.ordinal)
dataStream.writeBoolean(value.value)
}
override fun visitByteValue(value: ByteValue, data: Nothing?) {
dataStream.writeInt(KotlinConstantValueKind.BYTE.ordinal)
dataStream.writeByte(value.value.toInt())
}
override fun visitCharValue(value: CharValue, data: Nothing?) {
dataStream.writeInt(KotlinConstantValueKind.CHAR.ordinal)
dataStream.writeChar(value.value.code)
}
override fun visitShortValue(value: ShortValue, data: Nothing?) {
dataStream.writeInt(KotlinConstantValueKind.SHORT.ordinal)
dataStream.writeShort(value.value.toInt())
}
override fun visitIntValue(value: IntValue, data: Nothing?) {
dataStream.writeInt(KotlinConstantValueKind.INT.ordinal)
dataStream.writeInt(value.value)
}
override fun visitLongValue(value: LongValue, data: Nothing?) {
dataStream.writeInt(KotlinConstantValueKind.LONG.ordinal)
dataStream.writeLong(value.value)
}
override fun visitDoubleValue(value: DoubleValue, data: Nothing?) {
dataStream.writeInt(KotlinConstantValueKind.DOUBLE.ordinal)
dataStream.writeDouble(value.value)
}
override fun visitFloatValue(value: FloatValue, data: Nothing?) {
dataStream.writeInt(KotlinConstantValueKind.FLOAT.ordinal)
dataStream.writeFloat(value.value)
}
override fun visitEnumValue(value: EnumValue, data: Nothing?) {
dataStream.writeInt(KotlinConstantValueKind.ENUM.ordinal)
StubUtils.serializeClassId(dataStream, value.enumClassId)
dataStream.writeName(value.enumEntryName.identifier)
}
override fun visitKClassValue(value: KClassValue, data: Nothing?) {
dataStream.writeInt(KotlinConstantValueKind.KCLASS.ordinal)
val normalClass = value.value as KClassValue.Value.NormalClass
StubUtils.serializeClassId(dataStream, normalClass.classId)
dataStream.writeInt(normalClass.arrayDimensions)
}
override fun visitNullValue(value: NullValue, data: Nothing?) {
dataStream.writeInt(KotlinConstantValueKind.NULL.ordinal)
}
override fun visitStringValue(value: StringValue, data: Nothing?) {
dataStream.writeInt(KotlinConstantValueKind.STRING.ordinal)
dataStream.writeName(value.value)
}
override fun visitUByteValue(value: UByteValue, data: Nothing?) {
dataStream.writeInt(KotlinConstantValueKind.UBYTE.ordinal)
dataStream.writeByte(value.value.toInt())
}
override fun visitUShortValue(value: UShortValue, data: Nothing?) {
dataStream.writeInt(KotlinConstantValueKind.USHORT.ordinal)
dataStream.writeShort(value.value.toInt())
}
override fun visitUIntValue(value: UIntValue, data: Nothing?) {
dataStream.writeInt(KotlinConstantValueKind.UINT.ordinal)
dataStream.writeInt(value.value)
}
override fun visitULongValue(value: ULongValue, data: Nothing?) {
dataStream.writeInt(KotlinConstantValueKind.ULONG.ordinal)
dataStream.writeLong(value.value)
}
override fun visitAnnotationValue(value: AnnotationValue, data: Nothing?) {
dataStream.writeInt(KotlinConstantValueKind.ANNO.ordinal)
StubUtils.serializeClassId(dataStream, (value.value.type as KotlinClassTypeBean).classId)
val args = value.value.argumentsMapping
dataStream.writeInt(args.size)
for (arg in args) {
dataStream.writeName(arg.key.asString())
arg.value.accept(this, data)
}
}
override fun visitErrorValue(value: ErrorValue, data: Nothing?) {
error("Error values should not be reachable in compiled code")
}
}
data class AnnotationData(val annoClassId: ClassId, val args: Map<Name, ConstantValue<*>>)
data class EnumData(val enumClassId: ClassId, val enumEntryName: Name)
data class KClassData(val classId: ClassId, val arrayNestedness: Int)
fun createConstantValue(value: Any?): ConstantValue<*> {
return when (value) {
is Byte -> ByteValue(value)
is Short -> ShortValue(value)
is Int -> IntValue(value)
is Long -> LongValue(value)
is Char -> CharValue(value)
is Float -> FloatValue(value)
is Double -> DoubleValue(value)
is Boolean -> BooleanValue(value)
is String -> StringValue(value)
is ByteArray -> ArrayValue(value.map { createConstantValue(it) }.toList())
is ShortArray -> ArrayValue(value.map { createConstantValue(it) }.toList())
is IntArray -> ArrayValue(value.map { createConstantValue(it) }.toList())
is LongArray -> ArrayValue(value.map { createConstantValue(it) }.toList())
is CharArray -> ArrayValue(value.map { createConstantValue(it) }.toList())
is FloatArray -> ArrayValue(value.map { createConstantValue(it) }.toList())
is DoubleArray -> ArrayValue(value.map { createConstantValue(it) }.toList())
is BooleanArray -> ArrayValue(value.map { createConstantValue(it) }.toList())
is Array<*> -> ArrayValue(value.map { createConstantValue(it) }.toList())
is EnumData -> EnumValue(value.enumClassId, value.enumEntryName)
is KClassData -> KClassValue(value.classId, value.arrayNestedness)
is AnnotationData -> AnnotationValue.create(KotlinClassTypeBean(value.annoClassId, emptyList(), false), value.args)
null -> NullValue
else -> error("Unsupported value $value")
}
}
fun createConstantValue(value: ProtoBuf.Annotation.Argument.Value, nameResolver: NameResolver): ConstantValue<*> {
val isUnsigned = Flags.IS_UNSIGNED.get(value.flags)
fun <T, R> T.letIf(predicate: Boolean, f: (T) -> R, g: (T) -> R): R =
if (predicate) f(this) else g(this)
return when (value.type) {
ProtoBuf.Annotation.Argument.Value.Type.BYTE -> value.intValue.toByte().letIf(isUnsigned, ::UByteValue, ::ByteValue)
ProtoBuf.Annotation.Argument.Value.Type.CHAR -> CharValue(value.intValue.toInt().toChar())
ProtoBuf.Annotation.Argument.Value.Type.SHORT -> value.intValue.toShort().letIf(isUnsigned, ::UShortValue, ::ShortValue)
ProtoBuf.Annotation.Argument.Value.Type.INT -> value.intValue.toInt().letIf(isUnsigned, ::UIntValue, ::IntValue)
ProtoBuf.Annotation.Argument.Value.Type.LONG -> value.intValue.letIf(isUnsigned, ::ULongValue, ::LongValue)
ProtoBuf.Annotation.Argument.Value.Type.FLOAT -> FloatValue(value.floatValue)
ProtoBuf.Annotation.Argument.Value.Type.DOUBLE -> DoubleValue(value.doubleValue)
ProtoBuf.Annotation.Argument.Value.Type.BOOLEAN -> BooleanValue(value.intValue != 0L)
ProtoBuf.Annotation.Argument.Value.Type.STRING -> StringValue(nameResolver.getString(value.stringValue))
ProtoBuf.Annotation.Argument.Value.Type.CLASS -> KClassValue(nameResolver.getClassId(value.classId), value.arrayDimensionCount)
ProtoBuf.Annotation.Argument.Value.Type.ENUM -> EnumValue(
nameResolver.getClassId(value.classId),
nameResolver.getName(value.enumValueId)
)
ProtoBuf.Annotation.Argument.Value.Type.ANNOTATION -> {
val args =
value.annotation.argumentList.associate { nameResolver.getName(it.nameId) to createConstantValue(it.value, nameResolver) }
AnnotationValue.create(KotlinClassTypeBean(nameResolver.getClassId(value.annotation.id), emptyList(), false), args)
}
ProtoBuf.Annotation.Argument.Value.Type.ARRAY -> ArrayValue(
value.arrayElementList.map { createConstantValue(it, nameResolver) }
)
else -> error("Unsupported annotation argument type: ${value.type}")
}
}
private fun NameResolver.getClassId(index: Int): ClassId {
return ClassId.fromString(getQualifiedClassName(index), isLocalClassName(index))
}
private fun NameResolver.getName(index: Int): Name =
Name.guessByFirstCharacter(getString(index))
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.psi.stubs.KotlinPropertyStub
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
import org.jetbrains.kotlin.name.FqName
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.constant.ConstantValue
class KotlinPropertyStubImpl(
parent: StubElement<out PsiElement>?,
@@ -34,7 +35,8 @@ class KotlinPropertyStubImpl(
private val hasInitializer: Boolean,
private val isExtension: Boolean,
private val hasReturnTypeRef: Boolean,
private val fqName: FqName?
private val fqName: FqName?,
val constantInitializer: ConstantValue<*>?
) : KotlinStubBaseImpl<KtProperty>(parent, KtStubElementTypes.PROPERTY), KotlinPropertyStub {
init {
@@ -23,17 +23,21 @@ import org.jetbrains.kotlin.psi.KtProjectionKind
import org.jetbrains.kotlin.psi.KtUserType
import org.jetbrains.kotlin.psi.stubs.KotlinUserTypeStub
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
import org.jetbrains.kotlin.types.model.FlexibleTypeMarker
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
import org.jetbrains.kotlin.types.model.SimpleTypeMarker
import org.jetbrains.kotlin.types.model.TypeArgumentMarker
class KotlinUserTypeStubImpl(
parent: StubElement<out PsiElement>?,
val upperBound: KotlinTypeBean? = null
) : KotlinStubBaseImpl<KtUserType>(parent, KtStubElementTypes.USER_TYPE), KotlinUserTypeStub
sealed interface KotlinTypeBean {
sealed interface KotlinTypeBean : KotlinTypeMarker {
val nullable: Boolean
}
data class KotlinFlexibleTypeBean(val lowerBound: KotlinTypeBean, val upperBound: KotlinTypeBean) : KotlinTypeBean {
data class KotlinFlexibleTypeBean(val lowerBound: KotlinTypeBean, val upperBound: KotlinTypeBean) : KotlinTypeBean, FlexibleTypeMarker {
override val nullable: Boolean
get() = lowerBound.nullable
}
@@ -42,12 +46,12 @@ data class KotlinClassTypeBean(
val classId: ClassId,
val arguments: List<KotlinTypeArgumentBean>,
override val nullable: Boolean,
) : KotlinTypeBean
) : KotlinTypeBean, SimpleTypeMarker
data class KotlinTypeArgumentBean(val projectionKind: KtProjectionKind, val type: KotlinTypeBean?)
data class KotlinTypeArgumentBean(val projectionKind: KtProjectionKind, val type: KotlinTypeBean?) : TypeArgumentMarker
data class KotlinTypeParameterTypeBean(
val typeParameterName: String,
override val nullable: Boolean,
val definitelyNotNull: Boolean
) : KotlinTypeBean
) : KotlinTypeBean, SimpleTypeMarker
@@ -30,7 +30,11 @@ abstract class IntegerValueConstant<out T> protected constructor(value: T) : Con
abstract class UnsignedValueConstant<out T> protected constructor(value: T) : ConstantValue<T>(value)
class AnnotationValue private constructor(value: Value) : ConstantValue<AnnotationValue.Value>(value) {
class Value(val type: KotlinTypeMarker, val argumentsMapping: Map<Name, ConstantValue<*>>)
class Value(val type: KotlinTypeMarker, val argumentsMapping: Map<Name, ConstantValue<*>>) {
override fun toString(): String {
return "Value(type=$type, argumentsMapping=$argumentsMapping)"
}
}
override fun <R, D> accept(visitor: AnnotationArgumentVisitor<R, D>, data: D): R = visitor.visitAnnotationValue(this, data)
@@ -74,7 +74,8 @@ abstract class AbstractBinaryClassAnnotationAndConstantLoader<A : Any, C : Any>(
property = true,
field = true,
isConst = Flags.IS_CONST.get(proto.flags),
isMovedFromInterfaceCompanion = JvmProtoBufUtil.isMovedFromInterfaceCompanion(proto)
isMovedFromInterfaceCompanion = JvmProtoBufUtil.isMovedFromInterfaceCompanion(proto),
kotlinClassFinder = kotlinClassFinder, jvmMetadataVersion = jvmMetadataVersion
)
val kotlinClass = findClassWithAnnotationsAndInitializers(container, specialCase) ?: return null
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeConstructor
import org.jetbrains.kotlin.types.TypeProjection
@@ -233,6 +234,7 @@ interface DescriptorRendererOptions {
var boldOnlyForNamesInHtml: Boolean
var includePropertyConstant: Boolean
var propertyConstantRenderer: ((ConstantValue<*>) -> String?)?
var parameterNameRenderingPolicy: ParameterNameRenderingPolicy
var withoutTypeParameters: Boolean
var receiverAfterName: Boolean
@@ -491,9 +491,10 @@ internal class DescriptorRendererImpl(
return (defaultList + argumentList).sorted()
}
private fun renderConstant(value: ConstantValue<*>): String {
private fun renderConstant(value: ConstantValue<*>): String? {
options.propertyConstantRenderer?.let { return it.invoke(value) }
return when (value) {
is ArrayValue -> value.value.joinToString(", ", "{", "}") { renderConstant(it) }
is ArrayValue -> value.value.mapNotNull { renderConstant(it) }.joinToString(", ", "{", "}")
is AnnotationValue -> renderAnnotation(value.value).removePrefix("@")
is KClassValue -> when (val classValue = value.value) {
is KClassValue.Value.LocalClass -> "${classValue.type}::class"
@@ -986,7 +987,8 @@ internal class DescriptorRendererImpl(
private fun renderInitializer(variable: VariableDescriptor, builder: StringBuilder) {
if (includePropertyConstant) {
variable.compileTimeInitializer?.let { constant ->
builder.append(" = ").append(escape(renderConstant(constant)))
val renderedConstant = renderConstant(constant)
if (renderedConstant != null) builder.append(" = ").append(escape(renderedConstant))
}
}
}
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.types.KotlinType
import java.lang.IllegalStateException
import java.lang.reflect.Modifier
@@ -87,6 +88,7 @@ internal class DescriptorRendererOptionsImpl : DescriptorRendererOptions {
override var actualPropertiesInPrimaryConstructor: Boolean by property(false)
override var uninferredTypeParameterAsName by property(false)
override var includePropertyConstant by property(false)
override var propertyConstantRenderer: ((ConstantValue<*>) -> String?)? by property(null)
override var withoutTypeParameters by property(false)
override var withoutSuperTypes by property(false)
override var typeNormalizer by property<(KotlinType) -> KotlinType>({ it })
@@ -140,7 +140,8 @@ abstract class AbstractBinaryClassAnnotationLoader<A : Any, S : AbstractBinaryCl
property,
field,
isConst,
isMovedFromInterfaceCompanion
isMovedFromInterfaceCompanion,
kotlinClassFinder, jvmMetadataVersion
)
)
?: return listOf()
@@ -210,56 +211,6 @@ abstract class AbstractBinaryClassAnnotationLoader<A : Any, S : AbstractBinaryCl
}
}
// TODO: do not use KotlinClassFinder#findKotlinClass here because it traverses the file system in the compiler
// Introduce an API in KotlinJvmBinaryClass to find a class nearby instead
protected fun getSpecialCaseContainerClass(
container: ProtoContainer,
property: Boolean,
field: Boolean,
isConst: Boolean?,
isMovedFromInterfaceCompanion: Boolean
): KotlinJvmBinaryClass? {
if (property) {
checkNotNull(isConst) { "isConst should not be null for property (container=$container)" }
if (container is ProtoContainer.Class && container.kind == ProtoBuf.Class.Kind.INTERFACE) {
return kotlinClassFinder.findKotlinClass(
container.classId.createNestedClassId(Name.identifier(JvmAbi.DEFAULT_IMPLS_CLASS_NAME)),
jvmMetadataVersion
)
}
if (isConst && container is ProtoContainer.Package) {
// Const properties in multifile classes are generated into the facade class
val facadeClassName = (container.source as? JvmPackagePartSource)?.facadeClassName
if (facadeClassName != null) {
// Converting '/' to '.' is fine here because the facade class has a top level ClassId
return kotlinClassFinder.findKotlinClass(
ClassId.topLevel(FqName(facadeClassName.internalName.replace('/', '.'))),
jvmMetadataVersion
)
}
}
}
if (field && container is ProtoContainer.Class && container.kind == ProtoBuf.Class.Kind.COMPANION_OBJECT) {
val outerClass = container.outerClass
if (outerClass != null &&
(outerClass.kind == ProtoBuf.Class.Kind.CLASS || outerClass.kind == ProtoBuf.Class.Kind.ENUM_CLASS ||
(isMovedFromInterfaceCompanion &&
(outerClass.kind == ProtoBuf.Class.Kind.INTERFACE ||
outerClass.kind == ProtoBuf.Class.Kind.ANNOTATION_CLASS)))
) {
// Backing fields of properties of a companion object in a class are generated in the outer class
return outerClass.toBinaryClass()
}
}
if (container is ProtoContainer.Package && container.source is JvmPackagePartSource) {
val jvmPackagePartSource = container.source as JvmPackagePartSource
return jvmPackagePartSource.knownJvmBinaryClass
?: kotlinClassFinder.findKotlinClass(jvmPackagePartSource.classId, jvmMetadataVersion)
}
return null
}
protected fun getCallableSignature(
proto: MessageLite,
nameResolver: NameResolver,
@@ -304,6 +255,58 @@ abstract class AbstractBinaryClassAnnotationLoader<A : Any, S : AbstractBinaryCl
abstract class AnnotationsContainer<out A> {
abstract val memberAnnotations: Map<MemberSignature, List<A>>
}
companion object {
fun getSpecialCaseContainerClass(
container: ProtoContainer,
property: Boolean,
field: Boolean,
isConst: Boolean?,
isMovedFromInterfaceCompanion: Boolean,
kotlinClassFinder: KotlinClassFinder,
jvmMetadataVersion: JvmMetadataVersion
): KotlinJvmBinaryClass? {
if (property) {
checkNotNull(isConst) { "isConst should not be null for property (container=$container)" }
if (container is ProtoContainer.Class && container.kind == ProtoBuf.Class.Kind.INTERFACE) {
return kotlinClassFinder.findKotlinClass(
container.classId.createNestedClassId(Name.identifier(JvmAbi.DEFAULT_IMPLS_CLASS_NAME)),
jvmMetadataVersion
)
}
if (isConst && container is ProtoContainer.Package) {
// Const properties in multifile classes are generated into the facade class
val facadeClassName = (container.source as? JvmPackagePartSource)?.facadeClassName
if (facadeClassName != null) {
// Converting '/' to '.' is fine here because the facade class has a top level ClassId
return kotlinClassFinder.findKotlinClass(
ClassId.topLevel(FqName(facadeClassName.internalName.replace('/', '.'))),
jvmMetadataVersion
)
}
}
}
if (field && container is ProtoContainer.Class && container.kind == ProtoBuf.Class.Kind.COMPANION_OBJECT) {
val outerClass = container.outerClass
if (outerClass != null &&
(outerClass.kind == ProtoBuf.Class.Kind.CLASS || outerClass.kind == ProtoBuf.Class.Kind.ENUM_CLASS ||
(isMovedFromInterfaceCompanion &&
(outerClass.kind == ProtoBuf.Class.Kind.INTERFACE ||
outerClass.kind == ProtoBuf.Class.Kind.ANNOTATION_CLASS)))
) {
// Backing fields of properties of a companion object in a class are generated in the outer class
return (outerClass.source as? KotlinJvmBinarySourceElement)?.binaryClass
}
}
if (container is ProtoContainer.Package && container.source is JvmPackagePartSource) {
val jvmPackagePartSource = container.source as JvmPackagePartSource
return jvmPackagePartSource.knownJvmBinaryClass
?: kotlinClassFinder.findKotlinClass(jvmPackagePartSource.classId, jvmMetadataVersion)
}
return null
}
}
}
fun getPropertySignature(