[FIR] Add constructor for java annotations

This commit is contained in:
Dmitriy Novozhilov
2020-07-22 16:07:43 +03:00
committed by Mikhail Glukhikh
parent 644e9843f9
commit bc1fa8ed7f
14 changed files with 96 additions and 19 deletions
@@ -1,4 +1,6 @@
@R|java/lang/annotation/Documented|() @R|javax/annotation/meta/TypeQualifierNickname|() @R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.NEVER|()) @R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) public abstract annotation class MyNullable : R|kotlin/Annotation| {
public constructor(): R|MyNullable|
}
public open class NonNullNever : R|kotlin/Any| {
@R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.NEVER|()) public open field field: R|kotlin/String?|
@@ -11,4 +11,6 @@
}
@R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|javax/annotation/CheckForNull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.FIELD|())) public abstract annotation class FieldsAreNullable : R|kotlin/Annotation| {
public constructor(): R|FieldsAreNullable|
}
@@ -7,10 +7,18 @@
}
@R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|spr/UnknownNullability|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public abstract annotation class ForceFlexibility : R|kotlin/Annotation| {
public constructor(): R|spr/ForceFlexibility|
}
@R|java/lang/annotation/Target|(R|java/lang/annotation/ElementType.TYPE|()) @R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public abstract annotation class NonNullApi : R|kotlin/Annotation| {
public constructor(): R|spr/NonNullApi|
}
@R|java/lang/annotation/Target|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) @R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.MAYBE|()) @R|javax/annotation/meta/TypeQualifierNickname|() public abstract annotation class Nullable : R|kotlin/Annotation| {
public constructor(): R|spr/Nullable|
}
@R|java/lang/annotation/Documented|() @R|javax/annotation/meta/TypeQualifierNickname|() @R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.UNKNOWN|()) @R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) public abstract annotation class UnknownNullability : R|kotlin/Annotation| {
public constructor(): R|spr/UnknownNullability|
}
@@ -21,8 +21,14 @@ public abstract interface B : R|kotlin/Any| {
}
@R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|spr/UnknownNullability|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public abstract annotation class ForceFlexibility : R|kotlin/Annotation| {
public constructor(): R|spr/ForceFlexibility|
}
@R|java/lang/annotation/Target|(R|java/lang/annotation/ElementType.TYPE|()) @R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public abstract annotation class NonNullApi : R|kotlin/Annotation| {
public constructor(): R|spr/NonNullApi|
}
@R|java/lang/annotation/Documented|() @R|javax/annotation/meta/TypeQualifierNickname|() @R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.UNKNOWN|()) @R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) public abstract annotation class UnknownNullability : R|kotlin/Annotation| {
public constructor(): R|spr/UnknownNullability|
}
@@ -55,6 +55,10 @@
}
@R|java/lang/annotation/Target|(R|java/lang/annotation/ElementType.TYPE|()) @R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|(), R|java/lang/annotation/ElementType.FIELD|())) public abstract annotation class NonNullApi : R|kotlin/Annotation| {
public constructor(): R|NonNullApi|
}
@R|java/lang/annotation/Target|(R|java/lang/annotation/ElementType.TYPE|()) @R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|javax/annotation/CheckForNull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|(), R|java/lang/annotation/ElementType.FIELD|())) public abstract annotation class NullableApi : R|kotlin/Annotation| {
public constructor(): R|NullableApi|
}
@@ -13,8 +13,14 @@
}
@R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|javax/annotation/CheckForNull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.FIELD|())) public abstract annotation class FieldsAreNullable : R|kotlin/Annotation| {
public constructor(): R|FieldsAreNullable|
}
@R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|(), R|java/lang/annotation/ElementType.FIELD|())) public abstract annotation class NonNullApi : R|kotlin/Annotation| {
public constructor(): R|NonNullApi|
}
@R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|javax/annotation/CheckForNull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|(), R|java/lang/annotation/ElementType.FIELD|())) public abstract annotation class NullableApi : R|kotlin/Annotation| {
public constructor(): R|NullableApi|
}
@@ -11,6 +11,10 @@
}
@R|java/lang/annotation/Target|(R|java/lang/annotation/ElementType.TYPE|()) @R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public abstract annotation class NonNullApi : R|kotlin/Annotation| {
public constructor(): R|spr/NonNullApi|
}
@R|java/lang/annotation/Target|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) @R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.MAYBE|()) @R|javax/annotation/meta/TypeQualifierNickname|() public abstract annotation class Nullable : R|kotlin/Annotation| {
public constructor(): R|spr/Nullable|
}
@@ -11,6 +11,10 @@ public open class A : R|kotlin/Any| {
}
@R|java/lang/annotation/Target|(R|java/lang/annotation/ElementType.PACKAGE|()) @R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public abstract annotation class NonNullApi : R|kotlin/Annotation| {
public constructor(): R|spr/NonNullApi|
}
@R|java/lang/annotation/Target|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) @R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.MAYBE|()) @R|javax/annotation/meta/TypeQualifierNickname|() public abstract annotation class Nullable : R|kotlin/Annotation| {
public constructor(): R|spr/Nullable|
}
@@ -11,10 +11,13 @@ import com.intellij.psi.PsiElement
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.builder.*
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
import org.jetbrains.kotlin.fir.expressions.builder.*
import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusImpl
import org.jetbrains.kotlin.fir.java.declarations.*
import org.jetbrains.kotlin.fir.resolve.constructType
@@ -29,8 +32,7 @@ import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
import org.jetbrains.kotlin.load.java.JavaClassFinder
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter
import org.jetbrains.kotlin.load.java.structure.*
import org.jetbrains.kotlin.load.java.structure.impl.JavaElementImpl
import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder
import org.jetbrains.kotlin.name.ClassId
@@ -38,6 +40,7 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade
import org.jetbrains.kotlin.types.Variance.INVARIANT
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.util.OperatorNameConventions
class JavaSymbolProvider(
@@ -45,6 +48,9 @@ class JavaSymbolProvider(
val project: Project,
private val searchScope: GlobalSearchScope,
) : AbstractFirSymbolProvider<FirRegularClassSymbol>() {
companion object {
private val VALUE_METHOD_NAME = Name.identifier("value")
}
private val scopeProvider = JavaScopeProvider(::wrapScopeWithJvmMapped, this)
@@ -241,6 +247,10 @@ class JavaSymbolProvider(
}
declarations += firJavaDeclaration
}
val valueParametersForAnnotationConstructor = mutableListOf<FirJavaValueParameter>()
var valueParameterForValueInAnnotationConstructor: FirJavaValueParameter? = null
val classIsAnnotation = classKind == ClassKind.ANNOTATION_CLASS
for (javaMethod in javaClass.methods) {
val methodName = javaMethod.name
val methodId = CallableId(classId.packageFqName, classId.relativeClassName, methodName)
@@ -280,11 +290,34 @@ class JavaSymbolProvider(
isSuspend = false
}
}
if (classIsAnnotation) {
val parameterForAnnotationConstructor = buildJavaValueParameter {
session = this@JavaSymbolProvider.session
returnTypeRef = firJavaMethod.returnTypeRef
name = firJavaMethod.name
if (javaMethod.hasAnnotationParameterDefaultValue) {
defaultValue = buildExpressionStub()
}
isVararg = javaMethod.returnType is JavaArrayType
}
if (firJavaMethod.name == VALUE_METHOD_NAME) {
valueParameterForValueInAnnotationConstructor = parameterForAnnotationConstructor
} else {
valueParametersForAnnotationConstructor += parameterForAnnotationConstructor
}
}
declarations += firJavaMethod
}
val javaClassDeclaredConstructors = javaClass.constructors
val constructorId = CallableId(classId.packageFqName, classId.relativeClassName, classId.shortClassName)
fun buildSelfTypeRef() = firSymbol.constructType(
this@buildJavaClass.typeParameters.map {
ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false)
}.toTypedArray(),
false,
)
fun prepareJavaConstructor(
visibility: Visibility = this.visibility,
psi: PsiElement? = null,
@@ -309,10 +342,7 @@ class JavaSymbolProvider(
this.visibility = visibility
this.isPrimary = isPrimary
returnTypeRef = buildResolvedTypeRef {
type = firSymbol.constructType(
this@buildJavaClass.typeParameters.map { ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), false) }.toTypedArray(),
false,
)
type = buildSelfTypeRef()
}
typeParameters += classTypeParameters.map { buildConstructedClassTypeParameterRef { symbol = it.symbol } }
}
@@ -342,6 +372,20 @@ class JavaSymbolProvider(
generateValuesFunction(session, classId.packageFqName, classId.relativeClassName)
generateValueOfFunction(session, classId.packageFqName, classId.relativeClassName)
}
if (classIsAnnotation) {
declarations += buildJavaConstructor {
session = this@JavaSymbolProvider.session
symbol = FirConstructorSymbol(constructorId)
returnTypeRef = buildResolvedTypeRef {
type = buildSelfTypeRef()
}
valueParameters.addIfNotNull(valueParameterForValueInAnnotationConstructor)
valueParameters += valueParametersForAnnotationConstructor
visibility = Visibilities.PUBLIC
isInner = false
isPrimary = true
}
}
parentClassTypeParameterStackCache.remove(firSymbol)
}
firJavaClass.replaceSuperTypeRefs(
@@ -60,7 +60,7 @@ class FirJavaValueParameterBuilder : FirValueParameterBuilder() {
name,
symbol = FirVariableSymbol(name),
annotations,
defaultValue = null,
defaultValue,
isCrossinline = false,
isNoinline = false,
isVararg,
@@ -81,13 +81,6 @@ class FirJavaValueParameterBuilder : FirValueParameterBuilder() {
throw IllegalStateException()
}
@Deprecated("Modification of 'defaultValue' has no impact for FirJavaValueParameterBuilder", level = DeprecationLevel.HIDDEN)
override var defaultValue: FirExpression?
get() = throw IllegalStateException()
set(value) {
throw IllegalStateException()
}
@Deprecated("Modification of 'isCrossinline' has no impact for FirJavaValueParameterBuilder", level = DeprecationLevel.HIDDEN)
override var isCrossinline: Boolean
get() = throw IllegalStateException()
@@ -112,4 +105,4 @@ class FirJavaValueParameterBuilder : FirValueParameterBuilder() {
inline fun buildJavaValueParameter(init: FirJavaValueParameterBuilder.() -> Unit): FirJavaValueParameter {
return FirJavaValueParameterBuilder().apply(init).build()
}
}
@@ -3,4 +3,4 @@ import java.util.ArrayList
@ArrayList<Int>(1, 1) fun b() {}
@<!UNRESOLVED_REFERENCE!>Xoo<!>(<!UNRESOLVED_REFERENCE!>x<!>) fun c() {}
@java.lang.Deprecated(<!UNRESOLVED_REFERENCE!>x<!>) fun a() {}
@java.lang.Deprecated(x) fun a() {}
@@ -12,8 +12,8 @@ public @interface B {
}
// FILE: c.kt
@A(arg = String::class, b = <!UNRESOLVED_REFERENCE!>B<!>(y = 1)) class MyClass1
@A(arg = String::class, b = B(y = 1)) class MyClass1
@A(b = <!UNRESOLVED_REFERENCE!>B<!>(y = 3)) class MyClass2
@A(b = B(y = 3)) class MyClass2
@A(arg = String::class, b = <!UNRESOLVED_REFERENCE!>B<!>(arg = Boolean::class)) class MyClass3
@A(arg = String::class, b = <!INAPPLICABLE_CANDIDATE!>B<!>(arg = Boolean::class)) class MyClass3
@@ -1,2 +1,4 @@
@R|test/AnnotatedAnnotation|() public abstract annotation class AnnotatedAnnotation : R|kotlin/Annotation| {
public constructor(): R|test/AnnotatedAnnotation|
}
@@ -1,2 +1,4 @@
public abstract annotation class SimpleAnnotation : R|kotlin/Annotation| {
public constructor(): R|test/SimpleAnnotation|
}