FIR type enhancements: support annotations for default parameter values
Related to KT-29937
This commit is contained in:
@@ -6,26 +6,35 @@
|
||||
package org.jetbrains.kotlin.fir.java.enhancement
|
||||
|
||||
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirCallableMember
|
||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
||||
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.resolvedFqName
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.expressions.*
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirConstExpressionImpl
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirQualifiedAccessExpressionImpl
|
||||
import org.jetbrains.kotlin.fir.java.createTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass
|
||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaField
|
||||
import org.jetbrains.kotlin.fir.java.toConeProjection
|
||||
import org.jetbrains.kotlin.fir.java.toNotNullConeKotlinType
|
||||
import org.jetbrains.kotlin.fir.java.types.FirJavaTypeRef
|
||||
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReferenceImpl
|
||||
import org.jetbrains.kotlin.fir.references.FirSimpleNamedReference
|
||||
import org.jetbrains.kotlin.fir.resolve.FirSymbolProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.constructType
|
||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||
import org.jetbrains.kotlin.fir.resolve.toTypeProjection
|
||||
import org.jetbrains.kotlin.fir.service
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeCallableSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
|
||||
import org.jetbrains.kotlin.fir.symbols.ConeClassifierSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||
import org.jetbrains.kotlin.fir.typeContext
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstKind
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||
import org.jetbrains.kotlin.load.java.descriptors.AnnotationDefaultValue
|
||||
import org.jetbrains.kotlin.load.java.descriptors.NullDefaultValue
|
||||
@@ -34,9 +43,11 @@ import org.jetbrains.kotlin.load.java.structure.*
|
||||
import org.jetbrains.kotlin.load.java.typeEnhancement.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.types.AbstractStrictEqualityTypeChecker
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.kotlin.utils.extractRadix
|
||||
|
||||
internal class IndexedJavaTypeQualifiers(private val data: Array<JavaTypeQualifiers>) {
|
||||
constructor(size: Int, compute: (Int) -> JavaTypeQualifiers) : this(Array(size) { compute(it) })
|
||||
@@ -220,7 +231,56 @@ internal fun FirTypeRef.typeArguments(): List<FirTypeProjection> =
|
||||
|
||||
internal fun JavaType.typeArguments(): List<JavaType?> = (this as? JavaClassifierType)?.typeArguments.orEmpty()
|
||||
|
||||
fun FirValueParameter.getDefaultValueFromAnnotation(): AnnotationDefaultValue? {
|
||||
internal fun ConeKotlinType.lexicalCastFrom(session: FirSession, value: String): FirExpression? {
|
||||
val lookupTagBasedType = when (this) {
|
||||
is ConeLookupTagBasedType -> this
|
||||
is ConeFlexibleType -> return lowerBound.lexicalCastFrom(session, value)
|
||||
else -> return null
|
||||
}
|
||||
val lookupTag = lookupTagBasedType.lookupTag
|
||||
val firElement = (lookupTag.toSymbol(session) as? FirBasedSymbol<*>)?.fir
|
||||
if (firElement is FirRegularClass && firElement.classKind == ClassKind.ENUM_CLASS) {
|
||||
val name = Name.identifier(value)
|
||||
val firEnumEntry = firElement.declarations.filterIsInstance<FirEnumEntry>().find { it.name == name }
|
||||
|
||||
return if (firEnumEntry != null) FirQualifiedAccessExpressionImpl(session, null).apply {
|
||||
calleeReference = FirSimpleNamedReference(
|
||||
session, null, name // TODO: , firEnumEntry.symbol
|
||||
)
|
||||
} else if (firElement is FirJavaClass) {
|
||||
val firStaticProperty = firElement.declarations.filterIsInstance<FirJavaField>().find {
|
||||
it.isStatic && it.modality == Modality.FINAL && it.name == name
|
||||
}
|
||||
if (firStaticProperty != null) {
|
||||
FirQualifiedAccessExpressionImpl(session, null).apply {
|
||||
calleeReference = FirResolvedCallableReferenceImpl(
|
||||
session, null, name, firStaticProperty.symbol as ConeCallableSymbol
|
||||
)
|
||||
}
|
||||
} else null
|
||||
} else null
|
||||
}
|
||||
|
||||
if (lookupTag !is ConeClassLikeLookupTag) return null
|
||||
val classId = lookupTag.classId
|
||||
if (classId.packageFqName != FqName("kotlin")) return null
|
||||
|
||||
val (number, radix) = extractRadix(value)
|
||||
return when (classId.relativeClassName.asString()) {
|
||||
"Boolean" -> FirConstExpressionImpl(session, null, IrConstKind.Boolean, value.toBoolean())
|
||||
"Char" -> FirConstExpressionImpl(session, null, IrConstKind.Char, value.singleOrNull() ?: return null)
|
||||
"Byte" -> FirConstExpressionImpl(session, null, IrConstKind.Byte, number.toByteOrNull(radix) ?: return null)
|
||||
"Short" -> FirConstExpressionImpl(session, null, IrConstKind.Short, number.toShortOrNull(radix) ?: return null)
|
||||
"Int" -> FirConstExpressionImpl(session, null, IrConstKind.Int, number.toIntOrNull(radix) ?: return null)
|
||||
"Long" -> FirConstExpressionImpl(session, null, IrConstKind.Long, number.toLongOrNull(radix) ?: return null)
|
||||
"Float" -> FirConstExpressionImpl(session, null, IrConstKind.Float, value.toFloatOrNull() ?: return null)
|
||||
"Double" -> FirConstExpressionImpl(session, null, IrConstKind.Double, value.toDoubleOrNull() ?: return null)
|
||||
"String" -> FirConstExpressionImpl(session, null, IrConstKind.String, value)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
internal fun FirValueParameter.getDefaultValueFromAnnotation(): AnnotationDefaultValue? {
|
||||
annotations.find { it.resolvedFqName == JvmAnnotationNames.DEFAULT_VALUE_FQ_NAME }
|
||||
?.arguments?.firstOrNull()
|
||||
?.safeAs<FirConstExpression<*>>()?.value?.safeAs<String>()
|
||||
|
||||
+23
-10
@@ -9,14 +9,14 @@ import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.impl.*
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotationContainer
|
||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||
import org.jetbrains.kotlin.fir.expressions.impl.FirConstExpressionImpl
|
||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaConstructor
|
||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaField
|
||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaMethod
|
||||
import org.jetbrains.kotlin.fir.java.declarations.FirJavaValueParameter
|
||||
import org.jetbrains.kotlin.fir.java.enhancement.*
|
||||
import org.jetbrains.kotlin.fir.java.enhancement.EnhancementSignatureParts
|
||||
import org.jetbrains.kotlin.fir.java.enhancement.FirAnnotationTypeQualifierResolver
|
||||
import org.jetbrains.kotlin.fir.java.enhancement.FirJavaEnhancementContext
|
||||
import org.jetbrains.kotlin.fir.java.enhancement.copyWithNewDefaultTypeQualifiers
|
||||
import org.jetbrains.kotlin.fir.java.types.FirJavaTypeRef
|
||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||
import org.jetbrains.kotlin.fir.scopes.ProcessorAction
|
||||
@@ -28,7 +28,10 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstKind
|
||||
import org.jetbrains.kotlin.load.java.AnnotationTypeQualifierResolver
|
||||
import org.jetbrains.kotlin.load.java.descriptors.NullDefaultValue
|
||||
import org.jetbrains.kotlin.load.java.descriptors.StringDefaultValue
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaPrimitiveType
|
||||
import org.jetbrains.kotlin.load.java.typeEnhancement.PREDEFINED_FUNCTION_ENHANCEMENT_INFO_BY_SIGNATURE
|
||||
import org.jetbrains.kotlin.load.java.typeEnhancement.PredefinedFunctionEnhancementInfo
|
||||
@@ -130,10 +133,10 @@ class JavaClassEnhancementScope(
|
||||
enhanceReturnType(firMethod, memberContext, predefinedEnhancementInfo)
|
||||
}
|
||||
|
||||
val newValueParameterTypeRefs = mutableListOf<FirResolvedTypeRef>()
|
||||
val newValueParameterInfo = mutableListOf<EnhanceValueParameterResult>()
|
||||
|
||||
for ((index, valueParameter) in firMethod.valueParameters.withIndex()) {
|
||||
newValueParameterTypeRefs += enhanceValueParameterType(
|
||||
newValueParameterInfo += enhanceValueParameter(
|
||||
firMethod, memberContext, predefinedEnhancementInfo, valueParameter as FirJavaValueParameter, index
|
||||
)
|
||||
}
|
||||
@@ -145,12 +148,13 @@ class JavaClassEnhancementScope(
|
||||
).apply {
|
||||
status = firMethod.status as FirDeclarationStatusImpl
|
||||
annotations += firMethod.annotations
|
||||
valueParameters += firMethod.valueParameters.zip(newValueParameterTypeRefs) { valueParameter, newTypeRef ->
|
||||
valueParameters += firMethod.valueParameters.zip(newValueParameterInfo) { valueParameter, newInfo ->
|
||||
val (newTypeRef, newDefaultValue) = newInfo
|
||||
with(valueParameter) {
|
||||
FirValueParameterImpl(
|
||||
this@JavaClassEnhancementScope.session, psi,
|
||||
this.name, newTypeRef,
|
||||
defaultValue, isCrossinline, isNoinline, isVararg
|
||||
defaultValue ?: newDefaultValue, isCrossinline, isNoinline, isVararg
|
||||
).apply {
|
||||
annotations += valueParameter.annotations
|
||||
}
|
||||
@@ -200,20 +204,29 @@ class JavaClassEnhancementScope(
|
||||
return signatureParts.type
|
||||
}
|
||||
|
||||
private fun enhanceValueParameterType(
|
||||
private data class EnhanceValueParameterResult(val typeRef: FirResolvedTypeRef, val defaultValue: FirExpression?)
|
||||
|
||||
private fun enhanceValueParameter(
|
||||
ownerFunction: FirCallableMember,
|
||||
memberContext: FirJavaEnhancementContext,
|
||||
predefinedEnhancementInfo: PredefinedFunctionEnhancementInfo?,
|
||||
ownerParameter: FirJavaValueParameter,
|
||||
index: Int
|
||||
): FirResolvedTypeRef {
|
||||
): EnhanceValueParameterResult {
|
||||
val signatureParts = ownerFunction.partsForValueParameter(
|
||||
typeQualifierResolver,
|
||||
parameterContainer = ownerParameter,
|
||||
methodContext = memberContext,
|
||||
typeInSignature = TypeInSignature.ValueParameter(index)
|
||||
).enhance(session, jsr305State, predefinedEnhancementInfo?.parametersInfo?.getOrNull(index))
|
||||
return signatureParts.type
|
||||
val firResolvedTypeRef = signatureParts.type
|
||||
val defaultValue = ownerParameter.getDefaultValueFromAnnotation()
|
||||
val defaultValueExpression = when (defaultValue) {
|
||||
NullDefaultValue -> FirConstExpressionImpl(session, null, IrConstKind.Null, null)
|
||||
is StringDefaultValue -> firResolvedTypeRef.type.lexicalCastFrom(session, defaultValue.value)
|
||||
null -> null
|
||||
}
|
||||
return EnhanceValueParameterResult(firResolvedTypeRef, defaultValueExpression)
|
||||
}
|
||||
|
||||
private fun enhanceReturnType(
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
public/*package*/ open class A : R|java/lang/Object| {
|
||||
public open operator function a(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(HELLO)) arg: R|ft<Signs, Signs?>|! = R|/Signs.HELLO|): R|ft<Signs, Signs?>|!
|
||||
|
||||
public open operator function bar(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(X)) arg: R|ft<Signs, Signs?>|! = R|/Signs.X|): R|ft<Signs, Signs?>|!
|
||||
|
||||
public open operator function baz(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(NOT_ENTRY_EITHER)) arg: R|ft<Signs, Signs?>|!): R|ft<Signs, Signs?>|!
|
||||
|
||||
public open operator function bam(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(NOT_ENTRY_EITHER)) arg: R|ft<Mixed, Mixed?>|! = R|/Mixed.NOT_ENTRY_EITHER|): R|ft<Mixed, Mixed?>|!
|
||||
|
||||
}
|
||||
public final enum class Mixed : R|java/lang/Enum<Mixed>| {
|
||||
public final static property NOT_ENTRY_EITHER(val): R|ft<Mixed, Mixed?>|!
|
||||
public get(): R|ft<Mixed, Mixed?>|!
|
||||
|
||||
}
|
||||
public final enum class Signs : R|java/lang/Enum<Signs>| {
|
||||
public final static property HELLO(val): R|ft<Signs, Signs?>|!
|
||||
public get(): R|ft<Signs, Signs?>|!
|
||||
|
||||
public final static property WORLD(val): R|ft<Signs, Signs?>|!
|
||||
public get(): R|ft<Signs, Signs?>|!
|
||||
|
||||
public final static property X(val): R|ft<Signs, Signs?>|!
|
||||
public get(): R|ft<Signs, Signs?>|!
|
||||
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
// FILE: Signs.java
|
||||
// ANDROID_ANNOTATIONS
|
||||
|
||||
public enum Signs {
|
||||
HELLO,
|
||||
WORLD;
|
||||
|
||||
public static final Signs X;
|
||||
public static final class NOT_ENTRY_EITHER {}
|
||||
}
|
||||
|
||||
// FILE: Mixed.java
|
||||
public enum Mixed {
|
||||
NOT_ENTRY_EITHER;
|
||||
|
||||
public static final class NOT_ENTRY_EITHER {}
|
||||
}
|
||||
|
||||
// FILE: A.java
|
||||
import kotlin.annotations.jvm.internal.*;
|
||||
|
||||
class A {
|
||||
public Signs a(@DefaultValue("HELLO") Signs arg) {
|
||||
return arg;
|
||||
}
|
||||
|
||||
public Signs bar(@DefaultValue("X") Signs arg) {
|
||||
return arg;
|
||||
}
|
||||
|
||||
public Signs baz(@DefaultValue("NOT_ENTRY_EITHER") Signs arg) {
|
||||
return arg;
|
||||
}
|
||||
|
||||
public Mixed bam(@DefaultValue("NOT_ENTRY_EITHER") Mixed arg) {
|
||||
return arg;
|
||||
}
|
||||
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
public open class A : R|java/lang/Object| {
|
||||
public open operator function first(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(0x1F)) value: R|ft<kotlin/Long, kotlin/Long?>|! = Long(31)): R|kotlin/Unit|
|
||||
|
||||
public open operator function second(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(0X1F)) value: R|ft<kotlin/Long, kotlin/Long?>|! = Long(31)): R|kotlin/Unit|
|
||||
|
||||
public open operator function third(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(0b1010)) value: R|ft<kotlin/Long, kotlin/Long?>|! = Long(10)): R|kotlin/Unit|
|
||||
|
||||
public open operator function fourth(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(0B1010)) value: R|ft<kotlin/Long, kotlin/Long?>|! = Long(10)): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
public open class B : R|java/lang/Object| {
|
||||
public open operator function first(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(0x)) value: R|ft<kotlin/Long, kotlin/Long?>|!): R|kotlin/Unit|
|
||||
|
||||
public open operator function second(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(0xZZ)) value: R|ft<kotlin/Long, kotlin/Long?>|!): R|kotlin/Unit|
|
||||
|
||||
public open operator function third(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(0b)) value: R|ft<kotlin/Long, kotlin/Long?>|!): R|kotlin/Unit|
|
||||
|
||||
public open operator function fourth(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(0B1234)) value: R|ft<kotlin/Long, kotlin/Long?>|!): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
// FILE: A.java
|
||||
// ANDROID_ANNOTATIONS
|
||||
|
||||
import kotlin.annotations.jvm.internal.*;
|
||||
|
||||
public class A {
|
||||
public void first(@DefaultValue("0x1F") Long value) {
|
||||
}
|
||||
|
||||
public void second(@DefaultValue("0X1F") Long value) {
|
||||
}
|
||||
|
||||
public void third(@DefaultValue("0b1010") Long value) {
|
||||
}
|
||||
|
||||
public void fourth(@DefaultValue("0B1010") Long value) {
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: B.java
|
||||
import kotlin.annotations.jvm.internal.*;
|
||||
|
||||
public class B {
|
||||
public void first(@DefaultValue("0x") Long value) {
|
||||
}
|
||||
|
||||
public void second(@DefaultValue("0xZZ") Long value) {
|
||||
}
|
||||
|
||||
public void third(@DefaultValue("0b") Long value) {
|
||||
}
|
||||
|
||||
public void fourth(@DefaultValue("0B1234") Long value) {
|
||||
}
|
||||
}
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
public open class A : R|java/lang/Object| {
|
||||
public open operator function foo(@R|kotlin/annotations/jvm/internal/DefaultNull|() x: R|ft<kotlin/Int, kotlin/Int?>|! = Null(null)): R|kotlin/Unit|
|
||||
|
||||
public open operator function bar(@R|kotlin/annotations/jvm/internal/DefaultNull|() x: R|kotlin/Int| = Null(null)): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
<T> public open class B : R|java/lang/Object| {
|
||||
public open operator function foo(@R|kotlin/annotations/jvm/internal/DefaultNull|() t: R|ft<T, T?>|! = Null(null)): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// FILE: A.java
|
||||
// ANDROID_ANNOTATIONS
|
||||
|
||||
import kotlin.annotations.jvm.internal.*;
|
||||
|
||||
public class A {
|
||||
public void foo(@DefaultNull Integer x) {}
|
||||
public void bar(@DefaultNull int x) {}
|
||||
}
|
||||
|
||||
// FILE: B.java
|
||||
import kotlin.annotations.jvm.internal.*;
|
||||
|
||||
public class B<T> {
|
||||
public void foo(@DefaultNull T t) { }
|
||||
}
|
||||
|
||||
Vendored
+26
@@ -0,0 +1,26 @@
|
||||
public open class A : R|java/lang/Object| {
|
||||
public open operator function foo(@R|kotlin/annotations/jvm/internal/DefaultNull|() i: R|ft<kotlin/Int, kotlin/Int?>|! = Null(null)): R|kotlin/Unit|
|
||||
|
||||
public open operator function bar(@R|kotlin/annotations/jvm/internal/DefaultNull|() a: R|ft<kotlin/Int, kotlin/Int?>|! = Null(null)): R|kotlin/Unit|
|
||||
|
||||
public open operator function bam(@R|kotlin/annotations/jvm/internal/DefaultNull|() a: R|ft<kotlin/Int, kotlin/Int?>|! = Null(null)): R|kotlin/Unit|
|
||||
|
||||
public open operator function baz(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(42)) a: R|ft<kotlin/Int, kotlin/Int?>|! = Int(42)): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
public abstract interface AInt : R|java/lang/Object| {
|
||||
public abstract operator function foo(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(42)) i: R|ft<kotlin/Int, kotlin/Int?>|! = Int(42)): R|kotlin/Unit|
|
||||
|
||||
public abstract operator function bar(@R|kotlin/annotations/jvm/internal/DefaultNull|() a: R|ft<kotlin/Int, kotlin/Int?>|! = Null(null)): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
public open class B : R|A| {
|
||||
public open operator function foo(i: R|ft<kotlin/Int, kotlin/Int?>|!): R|kotlin/Unit|
|
||||
|
||||
public open operator function bar(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(42)) a: R|ft<kotlin/Int, kotlin/Int?>|! = Int(42)): R|kotlin/Unit|
|
||||
|
||||
public open operator function bam(@R|kotlin/annotations/jvm/internal/DefaultNull|() @R|kotlin/annotations/jvm/internal/DefaultValue|(String(42)) a: R|ft<kotlin/Int, kotlin/Int?>|! = Int(42)): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
public open class C : R|A|, R|AInt| {
|
||||
}
|
||||
Vendored
+38
@@ -0,0 +1,38 @@
|
||||
// FILE: A.java
|
||||
// ANDROID_ANNOTATIONS
|
||||
|
||||
import kotlin.annotations.jvm.internal.*;
|
||||
|
||||
public class A {
|
||||
public void foo(@DefaultNull Integer i) {}
|
||||
|
||||
public void bar(@DefaultNull Integer a) {}
|
||||
|
||||
public void bam(@DefaultNull Integer a) {}
|
||||
|
||||
public void baz(@DefaultValue("42") Integer a) {}
|
||||
}
|
||||
|
||||
// FILE: AInt.java
|
||||
import kotlin.annotations.jvm.internal.*;
|
||||
|
||||
public interface AInt {
|
||||
public void foo(@DefaultValue("42") Integer i) {}
|
||||
public void bar(@DefaultNull Integer a) {}
|
||||
}
|
||||
|
||||
// FILE: B.java
|
||||
import kotlin.annotations.jvm.internal.*;
|
||||
|
||||
public class B extends A {
|
||||
public void foo(Integer i) {}
|
||||
|
||||
public void bar(@DefaultValue("42") Integer a) {}
|
||||
|
||||
public void bam(@DefaultNull @DefaultValue("42") Integer a) {}
|
||||
}
|
||||
|
||||
// FILE: C.java
|
||||
public class C extends A implements AInt {
|
||||
}
|
||||
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
public/*package*/ open class A : R|java/lang/Object| {
|
||||
public open operator function first(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(hello)) value: R|ft<kotlin/String, kotlin/String?>|! = String(hello)): R|kotlin/Unit|
|
||||
|
||||
public open operator function second(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(first)) a: R|ft<kotlin/String, kotlin/String?>|! = String(first), @R|kotlin/annotations/jvm/internal/DefaultValue|(String(second)) b: R|ft<kotlin/String, kotlin/String?>|! = String(second)): R|kotlin/Unit|
|
||||
|
||||
public open operator function third(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(first)) a: R|ft<kotlin/String, kotlin/String?>|! = String(first), b: R|ft<kotlin/String, kotlin/String?>|!): R|kotlin/Unit|
|
||||
|
||||
public open operator function fourth(first: R|ft<kotlin/String, kotlin/String?>|!, @R|kotlin/annotations/jvm/internal/DefaultValue|(String(second)) second: R|ft<kotlin/String, kotlin/String?>|! = String(second)): R|kotlin/Unit|
|
||||
|
||||
public open operator function wrong(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(hello)) i: R|ft<kotlin/Int, kotlin/Int?>|!): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
// FILE: A.java
|
||||
// ANDROID_ANNOTATIONS
|
||||
|
||||
import kotlin.annotations.jvm.internal.*;
|
||||
|
||||
class A {
|
||||
public void first(@DefaultValue("hello") String value) {
|
||||
}
|
||||
|
||||
public void second(@DefaultValue("first") String a, @DefaultValue("second") String b) {
|
||||
}
|
||||
|
||||
public void third(@DefaultValue("first") String a, String b) {
|
||||
}
|
||||
|
||||
public void fourth(String first, @DefaultValue("second") String second) {
|
||||
}
|
||||
|
||||
public void wrong(@DefaultValue("hello") Integer i) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
public/*package*/ open class A : R|java/lang/Object| {
|
||||
public open operator function emptyName(@R|kotlin/annotations/jvm/internal/ParameterName|(String()) first: R|ft<kotlin/String, kotlin/String?>|!, @R|kotlin/annotations/jvm/internal/ParameterName|(String(ok)) second: R|kotlin/Int|): R|kotlin/Unit|
|
||||
|
||||
public open operator function missingName(@R|kotlin/annotations/jvm/internal/ParameterName|() first: R|ft<kotlin/String, kotlin/String?>|!): R|kotlin/Unit|
|
||||
|
||||
public open operator function numberName(@R|kotlin/annotations/jvm/internal/ParameterName|(Int(42)) first: R|ft<kotlin/String, kotlin/String?>|!): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// FILE: A.java
|
||||
// ANDROID_ANNOTATIONS
|
||||
|
||||
import kotlin.annotations.jvm.internal.*;
|
||||
|
||||
class A {
|
||||
public void emptyName(@ParameterName("") String first, @ParameterName("ok") int second) {
|
||||
}
|
||||
|
||||
public void missingName(@ParameterName() String first) {
|
||||
}
|
||||
|
||||
public void numberName(@ParameterName(42) String first) {
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
public open class A : R|java/lang/Object| {
|
||||
public open operator function connect(@R|kotlin/annotations/jvm/internal/ParameterName|(String(host)) host: R|ft<kotlin/String, kotlin/String?>|!, @R|kotlin/annotations/jvm/internal/ParameterName|(String(port)) port: R|kotlin/Int|): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
|
||||
// FILE: A.java
|
||||
// ANDROID_ANNOTATIONS
|
||||
import kotlin.annotations.jvm.internal.*;
|
||||
|
||||
public class A {
|
||||
public void connect(@ParameterName("host") String host, @ParameterName("port") int port) {
|
||||
}
|
||||
}
|
||||
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
public open class A : R|java/lang/Object| {
|
||||
public open operator function same(@R|kotlin/annotations/jvm/internal/ParameterName|(String(ok)) first: R|ft<kotlin/String, kotlin/String?>|!, @R|kotlin/annotations/jvm/internal/ParameterName|(String(ok)) second: R|ft<kotlin/String, kotlin/String?>|!): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
|
||||
// FILE: A.java
|
||||
// ANDROID_ANNOTATIONS
|
||||
import kotlin.annotations.jvm.internal.*;
|
||||
|
||||
public class A {
|
||||
public void same(@ParameterName("ok") String first, @ParameterName("ok") String second) {
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
public open class A : R|java/lang/Object| {
|
||||
public open operator function dollarName(@R|kotlin/annotations/jvm/internal/ParameterName|(String($)) host: R|ft<kotlin/String, kotlin/String?>|!): R|kotlin/Unit|
|
||||
|
||||
public open operator function numberName(@R|kotlin/annotations/jvm/internal/ParameterName|(String(42)) field: R|ft<kotlin/String, kotlin/String?>|!): R|kotlin/Unit|
|
||||
|
||||
}
|
||||
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
// FILE: A.java
|
||||
// ANDROID_ANNOTATIONS
|
||||
import kotlin.annotations.jvm.internal.*;
|
||||
import kotlin.internal.*;
|
||||
|
||||
public class A {
|
||||
public void dollarName(@ParameterName("$") String host) {
|
||||
}
|
||||
|
||||
public void numberName(@ParameterName("42") String field) {
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
public/*package*/ open class A : R|java/lang/Object| {
|
||||
public open static operator function withDefault(@R|kotlin/annotations/jvm/internal/DefaultValue|(String(OK)) arg: R|ft<kotlin/String, kotlin/String?>|! = String(OK)): R|ft<kotlin/String, kotlin/String?>|!
|
||||
|
||||
}
|
||||
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
// IGNORE_BACKEND: JS, NATIVE
|
||||
|
||||
// FILE: A.java
|
||||
// ANDROID_ANNOTATIONS
|
||||
|
||||
import kotlin.annotations.jvm.internal.*;
|
||||
|
||||
class A {
|
||||
public static String withDefault(@DefaultValue("OK") String arg) {
|
||||
return arg;
|
||||
}
|
||||
}
|
||||
|
||||
Generated
+63
@@ -114,4 +114,67 @@ public class OwnFirTypeEnhancementTestGenerated extends AbstractOwnFirTypeEnhanc
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/fir/resolve/testData/enhancement/signatureAnnotations")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class SignatureAnnotations extends AbstractOwnFirTypeEnhancementTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInSignatureAnnotations() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/fir/resolve/testData/enhancement/signatureAnnotations"), Pattern.compile("^(.+)\\.java$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("DefaultEnum.java")
|
||||
public void testDefaultEnum() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/enhancement/signatureAnnotations/DefaultEnum.java");
|
||||
}
|
||||
|
||||
@TestMetadata("DefaultLongLiteral.java")
|
||||
public void testDefaultLongLiteral() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/enhancement/signatureAnnotations/DefaultLongLiteral.java");
|
||||
}
|
||||
|
||||
@TestMetadata("DefaultNull.java")
|
||||
public void testDefaultNull() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/enhancement/signatureAnnotations/DefaultNull.java");
|
||||
}
|
||||
|
||||
@TestMetadata("DefaultNullAndParameter.java")
|
||||
public void testDefaultNullAndParameter() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/enhancement/signatureAnnotations/DefaultNullAndParameter.java");
|
||||
}
|
||||
|
||||
@TestMetadata("DefaultParameter.java")
|
||||
public void testDefaultParameter() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/enhancement/signatureAnnotations/DefaultParameter.java");
|
||||
}
|
||||
|
||||
@TestMetadata("EmptyParameterName.java")
|
||||
public void testEmptyParameterName() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/enhancement/signatureAnnotations/EmptyParameterName.java");
|
||||
}
|
||||
|
||||
@TestMetadata("ReorderedParameterNames.java")
|
||||
public void testReorderedParameterNames() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/enhancement/signatureAnnotations/ReorderedParameterNames.java");
|
||||
}
|
||||
|
||||
@TestMetadata("SameParameterName.java")
|
||||
public void testSameParameterName() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/enhancement/signatureAnnotations/SameParameterName.java");
|
||||
}
|
||||
|
||||
@TestMetadata("SpecialCharsParameterName.java")
|
||||
public void testSpecialCharsParameterName() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/enhancement/signatureAnnotations/SpecialCharsParameterName.java");
|
||||
}
|
||||
|
||||
@TestMetadata("StaticMethodWithDefaultValue.java")
|
||||
public void testStaticMethodWithDefaultValue() throws Exception {
|
||||
runTest("compiler/fir/resolve/testData/enhancement/signatureAnnotations/StaticMethodWithDefaultValue.java");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user