FIR: Properly build nullable suspend function types, and aggregate
modifiers and annotations within KtTypeReference/REFERENCE_TYPE nodes.
This commit is contained in:
committed by
TeamCityServer
parent
9cf5ac1fbd
commit
9a4742c08d
+12
@@ -2794,6 +2794,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/isAs.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nullableParameter.kt")
|
||||
public void testNullableParameter() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/suspendConversion/nullableParameter.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
@@ -9252,6 +9258,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/coroutines/nonLocalReturnFromInlineLambdaDeep.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nullableSuspendFunctionType.kt")
|
||||
public void testNullableSuspendFunctionType() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/nullableSuspendFunctionType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("overrideDefaultArgument.kt")
|
||||
public void testOverrideDefaultArgument() throws Exception {
|
||||
|
||||
+51
-22
@@ -916,7 +916,8 @@ class DeclarationsConverter(
|
||||
}
|
||||
constructedTypeRef = delegatedType.copyWithNewSourceKind(FirFakeSourceElementKind.ImplicitTypeRef)
|
||||
this.isThis = isThis
|
||||
val calleeKind = if (isImplicit) FirFakeSourceElementKind.ImplicitConstructor else FirFakeSourceElementKind.DelegatingConstructorCall
|
||||
val calleeKind =
|
||||
if (isImplicit) FirFakeSourceElementKind.ImplicitConstructor else FirFakeSourceElementKind.DelegatingConstructorCall
|
||||
val calleeSource = constructorDelegationCall.getChildNodeByType(CONSTRUCTOR_DELEGATION_REFERENCE)
|
||||
?.toFirSourceElement(calleeKind)
|
||||
?: this@buildDelegatedConstructorCall.source?.fakeElement(calleeKind)
|
||||
@@ -1281,7 +1282,8 @@ class DeclarationsConverter(
|
||||
CONTRACT_EFFECT -> {
|
||||
val effect = it.getFirstChild()
|
||||
if (effect == null) {
|
||||
val errorExpression = buildErrorExpression(null, ConeSimpleDiagnostic(errorReason, DiagnosticKind.ExpressionExpected))
|
||||
val errorExpression =
|
||||
buildErrorExpression(null, ConeSimpleDiagnostic(errorReason, DiagnosticKind.ExpressionExpected))
|
||||
destination.add(errorExpression)
|
||||
} else {
|
||||
val expression = expressionConverter.convertExpression(effect, errorReason)
|
||||
@@ -1674,18 +1676,32 @@ class DeclarationsConverter(
|
||||
if (type.asText.isEmpty()) {
|
||||
return buildErrorTypeRef { diagnostic = ConeSimpleDiagnostic("Unwrapped type is null", DiagnosticKind.Syntax) }
|
||||
}
|
||||
var typeModifiers = TypeModifier()
|
||||
|
||||
// There can be MODIFIER_LIST children on the TYPE_REFERENCE node AND the descendant NULLABLE_TYPE nodes.
|
||||
// We aggregate them to get modifiers and annotations. Not only that, there could be multiple modifier lists on each. Examples:
|
||||
//
|
||||
// `@A() (@B Int)` -> Has 2 modifier lists (@A and @B) in TYPE_REFERENCE
|
||||
// `(@A() (@B Int))? -> No modifier list on TYPE_REFERENCE, but 2 modifier lists (@A and @B) on child NULLABLE_TYPE
|
||||
// `@A() (@B Int)? -> Has 1 modifier list (@A) on TYPE_REFERENCE, and 1 modifier list (@B) on child NULLABLE_TYPE
|
||||
// `@A (@B() (@C() (@Bar D)?)?)?` -> Has 1 modifier list (@A) on B and 1 modifier list on each of the
|
||||
// 3 descendant NULLABLE_TYPE (@B, @C, @D)
|
||||
//
|
||||
// We need to examine all modifier lists for some cases:
|
||||
// 1. `@A Int?` and `(@A Int)?` are effectively the same, but in the latter, the modifier list is on the child NULLABLE_TYPE
|
||||
// 2. `(suspend @A () -> Int)?` is a nullable suspend function type but the modifier list is on the child NULLABLE_TYPE
|
||||
//
|
||||
// TODO: Report MODIFIER_LIST_NOT_ALLOWED error when there are multiple modifier lists. How do we report on each of them?
|
||||
val allTypeModifiers = mutableListOf<TypeModifier>()
|
||||
|
||||
var firType: FirTypeRef = buildErrorTypeRef { diagnostic = ConeSimpleDiagnostic("Incomplete code", DiagnosticKind.Syntax) }
|
||||
var afterLPar = false
|
||||
type.forEachChildren {
|
||||
when (it.tokenType) {
|
||||
LPAR -> afterLPar = true
|
||||
TYPE_REFERENCE -> firType = convertType(it)
|
||||
MODIFIER_LIST -> if (!afterLPar || typeModifiers.hasNoAnnotations()) typeModifiers = convertTypeModifierList(it)
|
||||
MODIFIER_LIST -> allTypeModifiers += convertTypeModifierList(it)
|
||||
USER_TYPE -> firType = convertUserType(it)
|
||||
DEFINITELY_NOT_NULL_TYPE -> firType = unwrapDefinitelyNotNullableType(it)
|
||||
NULLABLE_TYPE -> firType = convertNullableType(it)
|
||||
FUNCTION_TYPE -> firType = convertFunctionType(it, isSuspend = typeModifiers.hasSuspend)
|
||||
DEFINITELY_NOT_NULL_TYPE -> firType = unwrapDefinitelyNotNullableType(it, allTypeModifiers)
|
||||
NULLABLE_TYPE -> firType = convertNullableType(it, allTypeModifiers)
|
||||
FUNCTION_TYPE -> firType = convertFunctionType(it, isSuspend = allTypeModifiers.hasSuspend())
|
||||
DYNAMIC_TYPE -> firType = buildDynamicTypeRef {
|
||||
source = type.toFirSourceElement()
|
||||
isMarkedNullable = false
|
||||
@@ -1695,9 +1711,14 @@ class DeclarationsConverter(
|
||||
}
|
||||
}
|
||||
|
||||
return firType.also { (it.annotations as MutableList<FirAnnotationCall>) += typeModifiers.annotations }
|
||||
for (modifierList in allTypeModifiers) {
|
||||
(firType.annotations as MutableList<FirAnnotationCall>) += modifierList.annotations
|
||||
}
|
||||
return firType
|
||||
}
|
||||
|
||||
private fun Collection<TypeModifier>.hasSuspend() = any { it.hasSuspend }
|
||||
|
||||
/**
|
||||
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parseTypeRefContents
|
||||
*/
|
||||
@@ -1715,15 +1736,19 @@ class DeclarationsConverter(
|
||||
/**
|
||||
* @see org.jetbrains.kotlin.parsing.KotlinParsing.parseNullableTypeSuffix
|
||||
*/
|
||||
private fun convertNullableType(nullableType: LighterASTNode): FirTypeRef {
|
||||
private fun convertNullableType(
|
||||
nullableType: LighterASTNode,
|
||||
allTypeModifiers: MutableList<TypeModifier>,
|
||||
isNullable: Boolean = true
|
||||
): FirTypeRef {
|
||||
lateinit var firType: FirTypeRef
|
||||
nullableType.forEachChildren {
|
||||
when (it.tokenType) {
|
||||
USER_TYPE -> firType =
|
||||
convertUserType(it, true)
|
||||
FUNCTION_TYPE -> firType = convertFunctionType(it, true)
|
||||
NULLABLE_TYPE -> firType = convertNullableType(it)
|
||||
DEFINITELY_NOT_NULL_TYPE -> firType = unwrapDefinitelyNotNullableType(it, nullable = true)
|
||||
MODIFIER_LIST -> allTypeModifiers += convertTypeModifierList(it)
|
||||
USER_TYPE -> firType = convertUserType(it, isNullable)
|
||||
FUNCTION_TYPE -> firType = convertFunctionType(it, isNullable, isSuspend = allTypeModifiers.hasSuspend())
|
||||
NULLABLE_TYPE -> firType = convertNullableType(it, allTypeModifiers)
|
||||
DEFINITELY_NOT_NULL_TYPE -> firType = unwrapDefinitelyNotNullableType(it, allTypeModifiers, isNullable = true)
|
||||
DYNAMIC_TYPE -> firType = buildDynamicTypeRef {
|
||||
source = nullableType.toFirSourceElement()
|
||||
isMarkedNullable = true
|
||||
@@ -1734,16 +1759,20 @@ class DeclarationsConverter(
|
||||
return firType
|
||||
}
|
||||
|
||||
private fun unwrapDefinitelyNotNullableType(definitelyNotNullType: LighterASTNode, nullable: Boolean = false): FirTypeRef {
|
||||
private fun unwrapDefinitelyNotNullableType(
|
||||
definitelyNotNullType: LighterASTNode,
|
||||
allTypeModifiers: MutableList<TypeModifier>,
|
||||
isNullable: Boolean = false
|
||||
): FirTypeRef {
|
||||
lateinit var firType: FirTypeRef
|
||||
// TODO: Support proper DefinitelyNotNullableType
|
||||
definitelyNotNullType.forEachChildren {
|
||||
when (it.tokenType) {
|
||||
USER_TYPE -> firType =
|
||||
convertUserType(it, nullable)
|
||||
FUNCTION_TYPE -> firType = convertFunctionType(it, nullable)
|
||||
NULLABLE_TYPE -> firType = convertNullableType(it)
|
||||
DEFINITELY_NOT_NULL_TYPE -> firType = unwrapDefinitelyNotNullableType(it, nullable)
|
||||
MODIFIER_LIST -> allTypeModifiers += convertTypeModifierList(it)
|
||||
USER_TYPE -> firType = convertUserType(it, isNullable)
|
||||
FUNCTION_TYPE -> firType = convertFunctionType(it, isNullable, isSuspend = allTypeModifiers.hasSuspend())
|
||||
NULLABLE_TYPE -> firType = convertNullableType(it, allTypeModifiers, isNullable = false)
|
||||
DEFINITELY_NOT_NULL_TYPE -> firType = unwrapDefinitelyNotNullableType(it, allTypeModifiers, isNullable)
|
||||
DYNAMIC_TYPE -> firType = buildDynamicTypeRef {
|
||||
source = definitelyNotNullType.toFirSourceElement()
|
||||
isMarkedNullable = false
|
||||
|
||||
+20
@@ -46,6 +46,16 @@ public class LightTree2FirConverterTestCaseGenerated extends AbstractLightTree2F
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/annotation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("annotationsOnNullableParenthesizedTypes.kt")
|
||||
public void testAnnotationsOnNullableParenthesizedTypes() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/annotationsOnNullableParenthesizedTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("annotationsOnParenthesizedTypes.kt")
|
||||
public void testAnnotationsOnParenthesizedTypes() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/annotationsOnParenthesizedTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("complexTypes.kt")
|
||||
public void testComplexTypes() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/complexTypes.kt");
|
||||
@@ -156,6 +166,16 @@ public class LightTree2FirConverterTestCaseGenerated extends AbstractLightTree2F
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/simpleTypeAlias.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("splitModifierList.kt")
|
||||
public void testSplitModifierList() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/splitModifierList.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("suspendFunctionTypes.kt")
|
||||
public void testSuspendFunctionTypes() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/suspendFunctionTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeAliasWithGeneric.kt")
|
||||
public void testTypeAliasWithGeneric() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/typeAliasWithGeneric.kt");
|
||||
|
||||
@@ -43,6 +43,7 @@ import org.jetbrains.kotlin.name.LocalCallableIdConstructor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
|
||||
import org.jetbrains.kotlin.types.ConstantValueKind
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
@@ -1354,11 +1355,37 @@ open class RawFirBuilder(
|
||||
val source = typeReference.toFirSourceElement()
|
||||
val isNullable = typeElement is KtNullableType
|
||||
|
||||
// There can be KtDeclarationModifierLists in the KtTypeReference AND the descendant KtNullableTypes.
|
||||
// We aggregate them to get modifiers and annotations. Not only that, there could be multiple modifier lists on each. Examples:
|
||||
//
|
||||
// `@A() (@B Int)` -> Has 2 modifier lists (@A and @B) on KtTypeReference
|
||||
// `(@A() (@B Int))? -> No modifier list on KtTypeReference, but 2 modifier lists (@A and @B) on child KtNullableType
|
||||
// `@A() (@B Int)? -> Has 1 modifier list (@A) on KtTypeReference, and 1 modifier list (@B) on child KtNullableType
|
||||
// `@A (@B() (@C() (@Bar D)?)?)?` -> Has 1 modifier list (@A) on KtTypeReference and 1 modifier list on each of the
|
||||
// 3 descendant KtNullableTypes (@B, @C, @D)
|
||||
//
|
||||
// We need to examine all modifier lists for some cases:
|
||||
// 1. `@A Int?` and `(@A Int)?` are effectively the same, but in the latter, the modifier list is on the child KtNullableType
|
||||
// 2. `(suspend @A () -> Int)?` is a nullable suspend function type but the modifier list is on the child KtNullableType
|
||||
//
|
||||
// `getModifierList()` only returns the first one so we have to get all modifier list children.
|
||||
// TODO: Report MODIFIER_LIST_NOT_ALLOWED error when there are multiple modifier lists. How do we report on each of them?
|
||||
fun KtElementImplStub<*>.getAllModifierLists(): Array<out KtDeclarationModifierList> =
|
||||
getStubOrPsiChildren(KtStubElementTypes.MODIFIER_LIST, KtStubElementTypes.MODIFIER_LIST.arrayFactory)
|
||||
|
||||
val allModifierLists = mutableListOf<KtModifierList>(*typeReference.getAllModifierLists())
|
||||
|
||||
fun KtTypeElement?.unwrapNullable(): KtTypeElement? =
|
||||
when (this) {
|
||||
is KtNullableType -> this.innerType.unwrapNullable()
|
||||
is KtNullableType -> {
|
||||
allModifierLists += getAllModifierLists()
|
||||
this.innerType.unwrapNullable()
|
||||
}
|
||||
// TODO: Support explicit definitely not null type
|
||||
is KtDefinitelyNotNullType -> this.innerType.unwrapNullable()
|
||||
is KtDefinitelyNotNullType -> {
|
||||
allModifierLists += getAllModifierLists()
|
||||
this.innerType.unwrapNullable()
|
||||
}
|
||||
else -> this
|
||||
}
|
||||
|
||||
@@ -1403,7 +1430,7 @@ open class RawFirBuilder(
|
||||
FirFunctionTypeRefBuilder().apply {
|
||||
this.source = source
|
||||
isMarkedNullable = isNullable
|
||||
isSuspend = typeReference.hasModifier(SUSPEND_KEYWORD)
|
||||
isSuspend = allModifierLists.any { it.hasSuspendModifier() }
|
||||
receiverTypeRef = unwrappedElement.receiverTypeReference.convertSafe()
|
||||
// TODO: probably implicit type should not be here
|
||||
returnTypeRef = unwrappedElement.returnTypeReference.toFirOrErrorType()
|
||||
@@ -1422,8 +1449,10 @@ open class RawFirBuilder(
|
||||
else -> throw AssertionError("Unexpected type element: ${unwrappedElement.text}")
|
||||
}
|
||||
|
||||
for (annotationEntry in typeReference.annotationEntries) {
|
||||
firTypeBuilder.annotations += annotationEntry.convert<FirAnnotationCall>()
|
||||
for (modifierList in allModifierLists) {
|
||||
for (annotationEntry in modifierList.annotationEntries) {
|
||||
firTypeBuilder.annotations += annotationEntry.convert<FirAnnotationCall>()
|
||||
}
|
||||
}
|
||||
return firTypeBuilder.build()
|
||||
}
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
interface AnnotationsOnNullableParenthesizedTypes {
|
||||
fun B<(@A C)?>.receiverArgument() {}
|
||||
|
||||
fun parameter(a: (@A C)?) {}
|
||||
|
||||
fun parameterArgument(a: B<(@A C)?>) {}
|
||||
|
||||
fun returnValue(): (@A C)?
|
||||
|
||||
fun <T> returnTypeParameterValue(): (@A T)?
|
||||
|
||||
fun returnArgument(): B<(@A C)?>
|
||||
|
||||
val lambdaType: (@A() (() -> C))?
|
||||
|
||||
val lambdaParameter: ((@A C)?) -> C
|
||||
|
||||
val lambdaReturnValue: () -> (@A C)?
|
||||
|
||||
val lambdaReceiver: (@A C)?.() -> C
|
||||
}
|
||||
|
||||
@Target(AnnotationTarget.TYPE, AnnotationTarget.TYPE_PARAMETER)
|
||||
annotation class A
|
||||
|
||||
interface B<T>
|
||||
interface C
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
FILE: annotationsOnNullableParenthesizedTypes.kt
|
||||
public? final? interface AnnotationsOnNullableParenthesizedTypes : R|kotlin/Any| {
|
||||
public? final? fun B<@A() C?>.receiverArgument(): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
public? final? fun parameter(a: @A() C?): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
public? final? fun parameterArgument(a: B<@A() C?>): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
public? final? fun returnValue(): @A() C?
|
||||
|
||||
public? final? fun <T> returnTypeParameterValue(): @A() T?
|
||||
|
||||
public? final? fun returnArgument(): B<@A() C?>
|
||||
|
||||
public? final? val lambdaType: @A() ( () -> C )?
|
||||
public? get(): @A() ( () -> C )?
|
||||
|
||||
public? final? val lambdaParameter: ( (@A() C?) -> C )
|
||||
public? get(): ( (@A() C?) -> C )
|
||||
|
||||
public? final? val lambdaReturnValue: ( () -> @A() C? )
|
||||
public? get(): ( () -> @A() C? )
|
||||
|
||||
public? final? val lambdaReceiver: ( @A() C?.() -> C )
|
||||
public? get(): ( @A() C?.() -> C )
|
||||
|
||||
}
|
||||
@Target(AnnotationTarget#.TYPE#, AnnotationTarget#.TYPE_PARAMETER#) public? final? annotation class A : R|kotlin/Annotation| {
|
||||
public? constructor(): R|A| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public? final? interface B<T> : R|kotlin/Any| {
|
||||
}
|
||||
public? final? interface C : R|kotlin/Any| {
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
FILE: annotationsOnNullableParenthesizedTypes.kt
|
||||
public? final? interface AnnotationsOnNullableParenthesizedTypes : R|kotlin/Any| {
|
||||
public? final? fun B<@A() C?>.receiverArgument(): R|kotlin/Unit| {
|
||||
}
|
||||
|
||||
public? final? fun parameter(a: @A() C?): R|kotlin/Unit| {
|
||||
}
|
||||
|
||||
public? final? fun parameterArgument(a: B<@A() C?>): R|kotlin/Unit| {
|
||||
}
|
||||
|
||||
public? final? fun returnValue(): @A() C?
|
||||
|
||||
public? final? fun <T> returnTypeParameterValue(): @A() T?
|
||||
|
||||
public? final? fun returnArgument(): B<@A() C?>
|
||||
|
||||
public? final? val lambdaType: @A() ( () -> C )?
|
||||
[ContainingClassKey=AnnotationsOnNullableParenthesizedTypes] public? get(): @A() ( () -> C )?
|
||||
|
||||
public? final? val lambdaParameter: ( (@A() C?) -> C )
|
||||
[ContainingClassKey=AnnotationsOnNullableParenthesizedTypes] public? get(): ( (@A() C?) -> C )
|
||||
|
||||
public? final? val lambdaReturnValue: ( () -> @A() C? )
|
||||
[ContainingClassKey=AnnotationsOnNullableParenthesizedTypes] public? get(): ( () -> @A() C? )
|
||||
|
||||
public? final? val lambdaReceiver: ( @A() C?.() -> C )
|
||||
[ContainingClassKey=AnnotationsOnNullableParenthesizedTypes] public? get(): ( @A() C?.() -> C )
|
||||
|
||||
}
|
||||
@Target(AnnotationTarget#.TYPE#, AnnotationTarget#.TYPE_PARAMETER#) public? final? annotation class A : R|kotlin/Annotation| {
|
||||
public? [ContainingClassKey=A] constructor(): R|A| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public? final? interface B<T> : R|kotlin/Any| {
|
||||
}
|
||||
public? final? interface C : R|kotlin/Any| {
|
||||
}
|
||||
Vendored
+29
@@ -0,0 +1,29 @@
|
||||
interface AnnotationsOnParenthesizedTypes {
|
||||
fun B<(@A C)>.receiverArgument() {}
|
||||
|
||||
fun parameter(a: (@A C)) {}
|
||||
|
||||
fun parameterArgument(a: B<(@A C)>) {}
|
||||
|
||||
fun returnValue(): (@A C)
|
||||
|
||||
fun <T> returnTypeParameterValue(): (@A T)
|
||||
|
||||
fun returnArgument(): B<(@A C)>
|
||||
|
||||
val lambdaType: (@A() (() -> C))
|
||||
|
||||
val lambdaParameter: ((@A C)) -> C
|
||||
|
||||
val lambdaReturnValue: () -> (@A C)
|
||||
|
||||
val lambdaReceiver: (@A C).() -> C
|
||||
|
||||
val lambdaParameterNP: (@A C) -> C
|
||||
}
|
||||
|
||||
@Target(AnnotationTarget.TYPE, AnnotationTarget.TYPE_PARAMETER)
|
||||
annotation class A
|
||||
|
||||
interface B<T>
|
||||
interface C
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
FILE: annotationsOnParenthesizedTypes.kt
|
||||
public? final? interface AnnotationsOnParenthesizedTypes : R|kotlin/Any| {
|
||||
public? final? fun B<@A() C>.receiverArgument(): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
public? final? fun parameter(a: @A() C): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
public? final? fun parameterArgument(a: B<@A() C>): R|kotlin/Unit| { LAZY_BLOCK }
|
||||
|
||||
public? final? fun returnValue(): @A() C
|
||||
|
||||
public? final? fun <T> returnTypeParameterValue(): @A() T
|
||||
|
||||
public? final? fun returnArgument(): B<@A() C>
|
||||
|
||||
public? final? val lambdaType: @A() ( () -> C )
|
||||
public? get(): @A() ( () -> C )
|
||||
|
||||
public? final? val lambdaParameter: ( (@A() C) -> C )
|
||||
public? get(): ( (@A() C) -> C )
|
||||
|
||||
public? final? val lambdaReturnValue: ( () -> @A() C )
|
||||
public? get(): ( () -> @A() C )
|
||||
|
||||
public? final? val lambdaReceiver: ( @A() C.() -> C )
|
||||
public? get(): ( @A() C.() -> C )
|
||||
|
||||
public? final? val lambdaParameterNP: ( (@A() C) -> C )
|
||||
public? get(): ( (@A() C) -> C )
|
||||
|
||||
}
|
||||
@Target(AnnotationTarget#.TYPE#, AnnotationTarget#.TYPE_PARAMETER#) public? final? annotation class A : R|kotlin/Annotation| {
|
||||
public? constructor(): R|A| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public? final? interface B<T> : R|kotlin/Any| {
|
||||
}
|
||||
public? final? interface C : R|kotlin/Any| {
|
||||
}
|
||||
Vendored
+43
@@ -0,0 +1,43 @@
|
||||
FILE: annotationsOnParenthesizedTypes.kt
|
||||
public? final? interface AnnotationsOnParenthesizedTypes : R|kotlin/Any| {
|
||||
public? final? fun B<@A() C>.receiverArgument(): R|kotlin/Unit| {
|
||||
}
|
||||
|
||||
public? final? fun parameter(a: @A() C): R|kotlin/Unit| {
|
||||
}
|
||||
|
||||
public? final? fun parameterArgument(a: B<@A() C>): R|kotlin/Unit| {
|
||||
}
|
||||
|
||||
public? final? fun returnValue(): @A() C
|
||||
|
||||
public? final? fun <T> returnTypeParameterValue(): @A() T
|
||||
|
||||
public? final? fun returnArgument(): B<@A() C>
|
||||
|
||||
public? final? val lambdaType: @A() ( () -> C )
|
||||
[ContainingClassKey=AnnotationsOnParenthesizedTypes] public? get(): @A() ( () -> C )
|
||||
|
||||
public? final? val lambdaParameter: ( (@A() C) -> C )
|
||||
[ContainingClassKey=AnnotationsOnParenthesizedTypes] public? get(): ( (@A() C) -> C )
|
||||
|
||||
public? final? val lambdaReturnValue: ( () -> @A() C )
|
||||
[ContainingClassKey=AnnotationsOnParenthesizedTypes] public? get(): ( () -> @A() C )
|
||||
|
||||
public? final? val lambdaReceiver: ( @A() C.() -> C )
|
||||
[ContainingClassKey=AnnotationsOnParenthesizedTypes] public? get(): ( @A() C.() -> C )
|
||||
|
||||
public? final? val lambdaParameterNP: ( (@A() C) -> C )
|
||||
[ContainingClassKey=AnnotationsOnParenthesizedTypes] public? get(): ( (@A() C) -> C )
|
||||
|
||||
}
|
||||
@Target(AnnotationTarget#.TYPE#, AnnotationTarget#.TYPE_PARAMETER#) public? final? annotation class A : R|kotlin/Annotation| {
|
||||
public? [ContainingClassKey=A] constructor(): R|A| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public? final? interface B<T> : R|kotlin/Any| {
|
||||
}
|
||||
public? final? interface C : R|kotlin/Any| {
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
@Target(AnnotationTarget.TYPE, AnnotationTarget.TYPE_PARAMETER)
|
||||
annotation class A
|
||||
|
||||
@Target(AnnotationTarget.TYPE, AnnotationTarget.TYPE_PARAMETER)
|
||||
annotation class B
|
||||
|
||||
typealias Test0 = @A @B Int
|
||||
typealias Test1 = @A() (@A Int)
|
||||
typealias Test2 = @A() (@B Int)
|
||||
typealias Test3 = @A() (@A Int) -> Int
|
||||
typealias Test4 = @A() (@B Int)?
|
||||
typealias Test5 = @A() ( (@B Int)? )
|
||||
typealias Test6 = (@A @B Int)
|
||||
typealias Test7 = (@A @B Int)?
|
||||
typealias Test8 = (@A() (@B Int)? )
|
||||
typealias Test9 = (@A() (@B Int) )?
|
||||
Vendored
+23
@@ -0,0 +1,23 @@
|
||||
FILE: splitModifierList.kt
|
||||
@Target(AnnotationTarget#.TYPE#, AnnotationTarget#.TYPE_PARAMETER#) public? final? annotation class A : R|kotlin/Annotation| {
|
||||
public? constructor(): R|A| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
@Target(AnnotationTarget#.TYPE#, AnnotationTarget#.TYPE_PARAMETER#) public? final? annotation class B : R|kotlin/Annotation| {
|
||||
public? constructor(): R|B| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public? final typealias Test0 = @A() @B() Int
|
||||
public? final typealias Test1 = @A() @A() Int
|
||||
public? final typealias Test2 = @A() @B() Int
|
||||
public? final typealias Test3 = @A() ( (@A() Int) -> Int )
|
||||
public? final typealias Test4 = @A() @B() Int?
|
||||
public? final typealias Test5 = @A() @B() Int?
|
||||
public? final typealias Test6 = @A() @B() Int
|
||||
public? final typealias Test7 = @A() @B() Int?
|
||||
public? final typealias Test8 = @A() @B() Int?
|
||||
public? final typealias Test9 = @A() @B() Int?
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
FILE: splitModifierList.kt
|
||||
@Target(AnnotationTarget#.TYPE#, AnnotationTarget#.TYPE_PARAMETER#) public? final? annotation class A : R|kotlin/Annotation| {
|
||||
public? [ContainingClassKey=A] constructor(): R|A| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
@Target(AnnotationTarget#.TYPE#, AnnotationTarget#.TYPE_PARAMETER#) public? final? annotation class B : R|kotlin/Annotation| {
|
||||
public? [ContainingClassKey=B] constructor(): R|B| {
|
||||
super<R|kotlin/Any|>()
|
||||
}
|
||||
|
||||
}
|
||||
public? final typealias Test0 = @A() @B() Int
|
||||
public? final typealias Test1 = @A() @A() Int
|
||||
public? final typealias Test2 = @A() @B() Int
|
||||
public? final typealias Test3 = @A() ( (@A() Int) -> Int )
|
||||
public? final typealias Test4 = @A() @B() Int?
|
||||
public? final typealias Test5 = @A() @B() Int?
|
||||
public? final typealias Test6 = @A() @B() Int
|
||||
public? final typealias Test7 = @A() @B() Int?
|
||||
public? final typealias Test8 = @A() @B() Int?
|
||||
public? final typealias Test9 = @A() @B() Int?
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
suspend fun <T> simpleRun(f: suspend () -> T): T = f()
|
||||
|
||||
suspend fun <T, R> List<T>.simpleMap(f: suspend (T) -> R): R {
|
||||
|
||||
}
|
||||
|
||||
suspend fun <T> simpleWith(t: T, f: suspend T.() -> Unit): Unit = t.f()
|
||||
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
FILE: suspendFunctionTypes.kt
|
||||
public? final? suspend fun <T> simpleRun(f: ( suspend () -> T )): T { LAZY_BLOCK }
|
||||
public? final? suspend fun <T, R> List<T>.simpleMap(f: ( suspend (T) -> R )): R { LAZY_BLOCK }
|
||||
public? final? suspend fun <T> simpleWith(t: T, f: ( suspend T.() -> Unit )): Unit { LAZY_BLOCK }
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
FILE: suspendFunctionTypes.kt
|
||||
public? final? suspend fun <T> simpleRun(f: ( suspend () -> T )): T {
|
||||
^simpleRun f#()
|
||||
}
|
||||
public? final? suspend fun <T, R> List<T>.simpleMap(f: ( suspend (T) -> R )): R {
|
||||
}
|
||||
public? final? suspend fun <T> simpleWith(t: T, f: ( suspend T.() -> Unit )): Unit {
|
||||
^simpleWith t#.f#()
|
||||
}
|
||||
+20
@@ -46,6 +46,16 @@ public class RawFirBuilderLazyBodiesTestCaseGenerated extends AbstractRawFirBuil
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/annotation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("annotationsOnNullableParenthesizedTypes.kt")
|
||||
public void testAnnotationsOnNullableParenthesizedTypes() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/annotationsOnNullableParenthesizedTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("annotationsOnParenthesizedTypes.kt")
|
||||
public void testAnnotationsOnParenthesizedTypes() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/annotationsOnParenthesizedTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("complexTypes.kt")
|
||||
public void testComplexTypes() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/complexTypes.kt");
|
||||
@@ -156,6 +166,16 @@ public class RawFirBuilderLazyBodiesTestCaseGenerated extends AbstractRawFirBuil
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/simpleTypeAlias.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("splitModifierList.kt")
|
||||
public void testSplitModifierList() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/splitModifierList.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("suspendFunctionTypes.kt")
|
||||
public void testSuspendFunctionTypes() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/suspendFunctionTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeAliasWithGeneric.kt")
|
||||
public void testTypeAliasWithGeneric() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/typeAliasWithGeneric.kt");
|
||||
|
||||
+20
@@ -46,6 +46,16 @@ public class RawFirBuilderTestCaseGenerated extends AbstractRawFirBuilderTestCas
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/annotation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("annotationsOnNullableParenthesizedTypes.kt")
|
||||
public void testAnnotationsOnNullableParenthesizedTypes() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/annotationsOnNullableParenthesizedTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("annotationsOnParenthesizedTypes.kt")
|
||||
public void testAnnotationsOnParenthesizedTypes() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/annotationsOnParenthesizedTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("complexTypes.kt")
|
||||
public void testComplexTypes() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/complexTypes.kt");
|
||||
@@ -156,6 +166,16 @@ public class RawFirBuilderTestCaseGenerated extends AbstractRawFirBuilderTestCas
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/simpleTypeAlias.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("splitModifierList.kt")
|
||||
public void testSplitModifierList() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/splitModifierList.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("suspendFunctionTypes.kt")
|
||||
public void testSuspendFunctionTypes() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/suspendFunctionTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeAliasWithGeneric.kt")
|
||||
public void testTypeAliasWithGeneric() throws Exception {
|
||||
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/typeAliasWithGeneric.kt");
|
||||
|
||||
@@ -983,7 +983,11 @@ class FirRenderer(builder: StringBuilder, private val mode: RenderMode = RenderM
|
||||
}
|
||||
|
||||
override fun visitFunctionTypeRef(functionTypeRef: FirFunctionTypeRef) {
|
||||
functionTypeRef.annotations.dropExtensionFunctionAnnotation().renderAnnotations()
|
||||
print("( ")
|
||||
if (functionTypeRef.isSuspend) {
|
||||
print("suspend ")
|
||||
}
|
||||
functionTypeRef.receiverTypeRef?.let {
|
||||
it.accept(this)
|
||||
print(".")
|
||||
|
||||
Reference in New Issue
Block a user