[FIR] Add pretty rendering of functional types

This commit is contained in:
Dmitriy Novozhilov
2019-11-07 18:19:01 +03:00
parent 18dc652404
commit e910653d6f
66 changed files with 201 additions and 143 deletions
@@ -5,6 +5,10 @@
package org.jetbrains.kotlin.fir.types
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract
fun ConeKotlinType.render(): String {
val nullabilitySuffix = if (this !is ConeKotlinErrorType && this !is ConeClassErrorType) nullability.suffix else ""
return when (this) {
@@ -17,12 +21,7 @@ fun ConeKotlinType.render(): String {
append(lookupTag.classId.asString())
if (typeArguments.isNotEmpty()) {
append(typeArguments.joinToString(prefix = "<", postfix = ">") {
when (it) {
ConeStarProjection -> "*"
is ConeKotlinTypeProjectionIn -> "in ${it.type.render()}"
is ConeKotlinTypeProjectionOut -> "out ${it.type.render()}"
is ConeKotlinType -> it.render()
}
it.render()
})
}
}
@@ -49,3 +48,43 @@ fun ConeKotlinType.render(): String {
is ConeStubType -> "stub type: $variable"
} + nullabilitySuffix
}
private fun ConeKotlinTypeProjection.render(): String {
return when (this) {
ConeStarProjection -> "*"
is ConeKotlinTypeProjectionIn -> "in ${type.render()}"
is ConeKotlinTypeProjectionOut -> "out ${type.render()}"
is ConeKotlinType -> render()
}
}
fun ConeKotlinType.renderFunctionType(kind: FunctionClassDescriptor.Kind?, isExtension: Boolean): String {
if (!kind.withPrettyRender()) return render()
return buildString {
if (kind == FunctionClassDescriptor.Kind.SuspendFunction) {
append("suspend ")
}
val (receiver, otherTypeArguments) = if (isExtension && typeArguments.first() != ConeStarProjection) {
typeArguments.first() to typeArguments.drop(1)
} else {
null to typeArguments.toList()
}
val arguments = otherTypeArguments.subList(0, otherTypeArguments.size - 1)
val returnType = otherTypeArguments.last()
if (receiver != null) {
append(receiver.render())
append(".")
}
append(arguments.joinToString(", ", "(", ")") { it.render() })
append(" -> ")
append(returnType.render())
}
}
@UseExperimental(ExperimentalContracts::class)
fun FunctionClassDescriptor.Kind?.withPrettyRender(): Boolean {
contract {
returns(true) implies (this@withPrettyRender != null)
}
return this != null && this != FunctionClassDescriptor.Kind.KSuspendFunction && this != FunctionClassDescriptor.Kind.KFunction
}
@@ -31,10 +31,7 @@ import org.jetbrains.kotlin.fir.lightTree.fir.modifier.TypeParameterModifier
import org.jetbrains.kotlin.fir.lightTree.fir.modifier.TypeProjectionModifier
import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.FirDelegatedTypeRef
import org.jetbrains.kotlin.fir.types.FirTypeProjection
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.FirUserTypeRef
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.*
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
import org.jetbrains.kotlin.lexer.KtTokens.*
@@ -1463,7 +1460,7 @@ class DeclarationsConverter(
FirResolvedTypeRefImpl(
null,
ConeClassTypeImpl(
ConeClassLikeLookupTagImpl(ClassId.fromString("kotlin/ExtensionFunctionType")),
ConeClassLikeLookupTagImpl(ClassId.fromString(EXTENSION_FUNCTION_ANNOTATION)),
emptyArray(),
false
)
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.fir.impl.FirLabelImpl
import org.jetbrains.kotlin.fir.references.impl.*
import org.jetbrains.kotlin.fir.symbols.CallableId
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.EXTENSION_FUNCTION_ANNOTATION
import org.jetbrains.kotlin.fir.types.FirTypeProjection
import org.jetbrains.kotlin.fir.types.FirTypeRef
import org.jetbrains.kotlin.fir.types.impl.*
@@ -1376,7 +1377,7 @@ class RawFirBuilder(session: FirSession, val stubMode: Boolean) : BaseFirBuilder
FirResolvedTypeRefImpl(
null,
ConeClassTypeImpl(
ConeClassLikeLookupTagImpl(ClassId.fromString("kotlin/ExtensionFunctionType")),
ConeClassLikeLookupTagImpl(ClassId.fromString(EXTENSION_FUNCTION_ANNOTATION)),
emptyArray(),
false
)
@@ -172,10 +172,5 @@ abstract class AbstractRawFirBuilderTestCase : KtParsingTestCase(
}
private val FirElement.isExtensionFunctionAnnotationCall: Boolean get() = (this as? FirAnnotationCall)?.let {
(it.annotationTypeRef as? FirResolvedTypeRef)?.let {
(it.type as? ConeClassLikeType)?.let {
it.lookupTag.classId.asString() == "kotlin/ExtensionFunctionType"
}
}
} == true
private val FirElement.isExtensionFunctionAnnotationCall: Boolean
get() = (this as? FirAnnotationCall)?.isExtensionFunctionAnnotationCall == true
@@ -21,14 +21,6 @@ import org.jetbrains.kotlin.resolve.calls.inference.model.SimpleConstraintSystem
import org.jetbrains.kotlin.resolve.calls.model.PostponedResolvedAtomMarker
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
fun FirTypeRef.isExtensionFunctionType(): Boolean {
return annotations.any {
(it.annotationTypeRef as? FirResolvedTypeRef)?.let {
it.type.toString() == "kotlin/ExtensionFunctionType"
} == true
}
}
fun Candidate.preprocessLambdaArgument(
csBuilder: ConstraintSystemBuilder,
argument: FirAnonymousFunction,
@@ -88,18 +80,12 @@ private val ConeKotlinType.isSuspendFunctionType: Boolean
}
private fun ConeKotlinType.receiverType(expectedTypeRef: FirTypeRef): ConeKotlinType? {
if (isFunctionalTypeWithReceiver(expectedTypeRef)) {
if (expectedTypeRef.isExtensionFunctionType()) {
return (this.typeArguments.first() as ConeTypedProjection).type
}
return null
}
private fun isFunctionalTypeWithReceiver(typeRef: FirTypeRef) =
typeRef.annotations.any {
val coneTypeSafe = it.annotationTypeRef.coneTypeSafe<ConeClassType>() ?: return@any false
coneTypeSafe.lookupTag.classId.asString() == "kotlin/ExtensionFunctionType"
}
val ConeKotlinType.returnType: ConeKotlinType?
get() {
require(this is ConeClassType)
+3 -3
View File
@@ -1,9 +1,9 @@
FILE: lambda.kt
public final fun foo(f: R|kotlin/Function0<kotlin/Unit>|): R|kotlin/Unit| {
public final fun foo(f: R|() -> kotlin/Unit|): R|kotlin/Unit| {
}
public final fun bar(x: R|kotlin/Int|, f: R|kotlin/Function0<kotlin/Unit>|): R|kotlin/Unit| {
public final fun bar(x: R|kotlin/Int|, f: R|() -> kotlin/Unit|): R|kotlin/Unit| {
}
public final fun baz(f: R|kotlin/Function0<kotlin/Unit>|, other: R|kotlin/Boolean| = Boolean(true)): R|kotlin/Unit| {
public final fun baz(f: R|() -> kotlin/Unit|, other: R|kotlin/Boolean| = Boolean(true)): R|kotlin/Unit| {
}
public final fun test(): R|kotlin/Unit| {
R|/foo|(<L> = foo@fun <anonymous>(): R|kotlin/Unit| {
@@ -2,7 +2,7 @@ FILE: overloadWithDefault.kt
public abstract interface A : R|kotlin/Any| {
public abstract fun foo(b: R|kotlin/Boolean| = Boolean(false)): R|A|
public abstract fun foo(block: R|kotlin/Function0<kotlin/Boolean>|): R|A|
public abstract fun foo(block: R|() -> kotlin/Boolean|): R|A|
}
public final fun test(a: R|A|): R|kotlin/Unit| {
+8 -8
View File
@@ -3,23 +3,23 @@ FILE: cast.kt
public get(): R|kotlin/Int|
public final val y: R|kotlin/Any| = (Int(2) as R|kotlin/Any|)
public get(): R|kotlin/Any|
public final val f: R|kotlin/Function0<kotlin/Any>| = fun <anonymous>(): R|kotlin/Any| {
public final val f: R|() -> kotlin/Any| = fun <anonymous>(): R|kotlin/Any| {
^ (Int(3) as R|kotlin/Any|)
}
public get(): R|kotlin/Function0<kotlin/Any>|
public final val g: R|kotlin/Function0<kotlin/Unit>| = fun <anonymous>(): R|kotlin/Unit| {
public get(): R|() -> kotlin/Any|
public final val g: R|() -> kotlin/Unit| = fun <anonymous>(): R|kotlin/Unit| {
Unit
}
public get(): R|kotlin/Function0<kotlin/Unit>|
public final val h: R|kotlin/Function1<kotlin/String, kotlin/Boolean>| = fun <anonymous>(_: R|kotlin/String|): R|kotlin/Boolean| {
public get(): R|() -> kotlin/Unit|
public final val h: R|(kotlin/String) -> kotlin/Boolean| = fun <anonymous>(_: R|kotlin/String|): R|kotlin/Boolean| {
Boolean(false)
}
public get(): R|kotlin/Function1<kotlin/String, kotlin/Boolean>|
public final val hError: R|kotlin/Function1<class error: No type for parameter, kotlin/Boolean>| = fun <anonymous>(_: R|class error: No type for parameter|): R|kotlin/Boolean| {
public get(): R|(kotlin/String) -> kotlin/Boolean|
public final val hError: R|(class error: No type for parameter) -> kotlin/Boolean| = fun <anonymous>(_: R|class error: No type for parameter|): R|kotlin/Boolean| {
Boolean(true)
}
public get(): R|kotlin/Function1<class error: No type for parameter, kotlin/Boolean>|
public get(): R|(class error: No type for parameter) -> kotlin/Boolean|
+1 -1
View File
@@ -50,7 +50,7 @@ FILE: jumps.kt
}
}
public final inline fun run(block: R|kotlin/Function0<kotlin/Unit>|): R|kotlin/Unit| {
public final inline fun run(block: R|() -> kotlin/Unit|): R|kotlin/Unit| {
R|<local>/block|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
}
public final fun test_6(): R|kotlin/Unit| {
+1 -1
View File
@@ -110,7 +110,7 @@ digraph lambdas_kt {
subgraph cluster_13 {
color=blue
36 [label="Enter block"];
37 [label="Variable declaration: lval lambda: R|kotlin/Function0<kotlin/Int>|"];
37 [label="Variable declaration: lval lambda: R|() -> kotlin/Int|"];
38 [label="Exit block"];
}
39 [label="Exit when branch result"];
+3 -3
View File
@@ -1,5 +1,5 @@
FILE: lambdas.kt
public final inline fun run(block: R|kotlin/Function0<kotlin/Unit>|): R|kotlin/Unit| {
public final inline fun run(block: R|() -> kotlin/Unit|): R|kotlin/Unit| {
R|<local>/block|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
}
public final fun test_1(x: R|kotlin/Any?|): R|kotlin/Unit| {
@@ -16,7 +16,7 @@ FILE: lambdas.kt
public final fun test_2(x: R|kotlin/Any?|): R|kotlin/Unit| {
when () {
(R|<local>/x| is R|kotlin/Int|) -> {
lval lambda: R|kotlin/Function0<kotlin/Int>| = fun <anonymous>(): R|kotlin/Int| {
lval lambda: R|() -> kotlin/Int| = fun <anonymous>(): R|kotlin/Int| {
R|<local>/x|.R|kotlin/Int.inc|()
}
@@ -24,7 +24,7 @@ FILE: lambdas.kt
}
}
public final inline fun getInt(block: R|kotlin/Function0<kotlin/Unit>|): R|kotlin/Int| {
public final inline fun getInt(block: R|() -> kotlin/Unit|): R|kotlin/Int| {
R|<local>/block|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
^getInt Int(1)
}
@@ -1,5 +1,5 @@
FILE: propertiesAndInitBlocks.kt
public final inline fun run(block: R|kotlin/Function0<kotlin/Unit>|): R|kotlin/Unit| {
public final inline fun run(block: R|() -> kotlin/Unit|): R|kotlin/Unit| {
R|<local>/block|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
}
public final val x1: R|kotlin/Int| = Int(1)
@@ -16,7 +16,7 @@ FILE: extensionPropertyInLambda.kt
public set(v: R|T|): R|kotlin/Unit| {
this@R|/C|.R|/C.x| = R|<local>/v|
}
public final fun use(f: R|kotlin/Function0<kotlin/String>|): R|kotlin/Unit| {
public final fun use(f: R|() -> kotlin/String|): R|kotlin/Unit| {
}
public final fun test1(): R|kotlin/Unit| {
R|/use|(<L> = use@fun <anonymous>(): R|kotlin/String| {
@@ -1,6 +1,6 @@
FILE: propertyFromParameter.kt
public final class Bar : R|kotlin/Any| {
public constructor(name: R|kotlin/Function0<kotlin/String>|): R|Bar| {
public constructor(name: R|() -> kotlin/String|): R|Bar| {
super<R|kotlin/Any|>()
}
@@ -1,11 +1,11 @@
FILE: lambda.kt
public final fun foo(block: R|kotlin/Function0<kotlin/Unit>|): R|kotlin/Unit| {
public final fun foo(block: R|() -> kotlin/Unit|): R|kotlin/Unit| {
}
public final fun bar(block: R|kotlin/Function0<kotlin/String>|): R|kotlin/Unit| {
public final fun bar(block: R|() -> kotlin/String|): R|kotlin/Unit| {
}
public final fun itIs(block: R|kotlin/Function1<kotlin/String, kotlin/String>|): R|kotlin/Unit| {
public final fun itIs(block: R|(kotlin/String) -> kotlin/String|): R|kotlin/Unit| {
}
public final fun multipleArgs(block: R|kotlin/Function2<kotlin/String, kotlin/String, kotlin/String>|): R|kotlin/Unit| {
public final fun multipleArgs(block: R|(kotlin/String, kotlin/String) -> kotlin/String|): R|kotlin/Unit| {
}
public final fun main(): R|kotlin/Unit| {
R|/foo|(<L> = foo@fun <anonymous>(): R|kotlin/Unit| {
@@ -3,13 +3,13 @@ FILE: lambdaWithReceiver.kt
public abstract fun foo(): R|kotlin/Unit|
}
public final fun <T> myWith(receiver: R|T|, block: @R|kotlin/ExtensionFunctionType|() R|kotlin/Function1<T, kotlin/Unit>|): R|kotlin/Unit| {
public final fun <T> myWith(receiver: R|T|, block: R|T.() -> kotlin/Unit|): R|kotlin/Unit| {
R|<local>/receiver|.<Unresolved name: block>#()
}
public final fun <T> R|T|.myApply(block: @R|kotlin/ExtensionFunctionType|() R|kotlin/Function1<T, kotlin/Unit>|): R|kotlin/Unit| {
public final fun <T> R|T|.myApply(block: R|T.() -> kotlin/Unit|): R|kotlin/Unit| {
this@R|/myApply|.<Unresolved name: block>#()
}
public final fun withA(block: @R|kotlin/ExtensionFunctionType|() R|kotlin/Function1<A, kotlin/Unit>|): R|kotlin/Unit| {
public final fun withA(block: R|A.() -> kotlin/Unit|): R|kotlin/Unit| {
}
public final fun test_1(): R|kotlin/Unit| {
R|/withA|(<L> = withA@fun R|A|.<anonymous>(): R|kotlin/Unit| {
@@ -29,7 +29,7 @@ FILE: lambdaWithReceiver.kt
}
)
}
public final fun complexLambda(block: @R|kotlin/ExtensionFunctionType|() R|kotlin/Function2<kotlin/Int, kotlin/String, kotlin/Unit>|): R|kotlin/Unit| {
public final fun complexLambda(block: R|kotlin/Int.(kotlin/String) -> kotlin/Unit|): R|kotlin/Unit| {
}
public final fun test_4(): R|kotlin/Unit| {
R|/complexLambda|(<L> = complexLambda@fun R|kotlin/Int|.<anonymous>(it: R|kotlin/String|): R|kotlin/Unit| {
+1 -1
View File
@@ -1,5 +1,5 @@
FILE: ft.kt
public abstract interface KMutableProperty1<T> : R|KProperty1<T>| {
}
public abstract interface KProperty1<T> : R|kotlin/Function1<T, kotlin/Int>| {
public abstract interface KProperty1<T> : R|(T) -> kotlin/Int| {
}
+4 -4
View File
@@ -1,15 +1,15 @@
FILE: functionTypes.kt
public final fun <T> simpleRun(f: R|kotlin/Function1<T, kotlin/Unit>|): R|kotlin/Unit| {
public final fun <T> simpleRun(f: R|(T) -> kotlin/Unit|): R|kotlin/Unit| {
^simpleRun R|<local>/f|.R|FakeOverride<kotlin/Function1.invoke: R|kotlin/Unit|>|(^simpleRun Unit)
}
public final fun <T, R> R|kotlin/collections/List<T>|.simpleMap(f: R|kotlin/Function1<T, R>|): R|R| {
public final fun <T, R> R|kotlin/collections/List<T>|.simpleMap(f: R|(T) -> R|): R|R| {
}
public final fun <T> simpleWith(t: R|T|, f: @R|kotlin/ExtensionFunctionType|() R|kotlin/Function1<T, kotlin/Unit>|): R|kotlin/Unit| {
public final fun <T> simpleWith(t: R|T|, f: R|T.() -> kotlin/Unit|): R|kotlin/Unit| {
^simpleWith R|<local>/t|.<Unresolved name: f>#()
}
public abstract interface KMutableProperty1<T, R> : R|KProperty1<T, R>|, R|KMutableProperty<R>| {
}
public abstract interface KProperty1<T, out R> : R|KProperty<R>|, R|kotlin/Function1<T, R>| {
public abstract interface KProperty1<T, out R> : R|KProperty<R>|, R|(T) -> R| {
}
public abstract interface KProperty<out R> : R|kotlin/Any| {
}
+1 -1
View File
@@ -1,5 +1,5 @@
FILE: localObject.kt
public final fun <T> run(block: R|kotlin/Function0<T>|): R|T| {
public final fun <T> run(block: R|() -> T|): R|T| {
^run R|<local>/block|.R|FakeOverride<kotlin/Function0.invoke: R|T|>|()
}
public abstract interface Foo : R|kotlin/Any| {
@@ -14,7 +14,7 @@ FILE: kotlinSam.kt
>(R|<local>/it|, Int(1))
}
))
lval x: R|kotlin/Function1<kotlin/Int, kotlin/Boolean>| = fun <anonymous>(x: R|kotlin/Int|): R|kotlin/Boolean| {
lval x: R|(kotlin/Int) -> kotlin/Boolean| = fun <anonymous>(x: R|kotlin/Int|): R|kotlin/Boolean| {
>(R|<local>/x|, Int(1))
}
@@ -1,7 +1,7 @@
FILE: main.kt
public final fun foo(m: R|MyRunnable|): R|kotlin/Unit| {
}
public final fun MyRunnable(x: R|kotlin/Function1<kotlin/Int, kotlin/Boolean>|): R|kotlin/Int| {
public final fun MyRunnable(x: R|(kotlin/Int) -> kotlin/Boolean|): R|kotlin/Int| {
^MyRunnable Int(1)
}
public final fun main(): R|kotlin/Unit| {
@@ -13,7 +13,7 @@ FILE: main.kt
>(R|<local>/it|, Int(1))
}
))
lval x: R|kotlin/Function1<kotlin/Int, kotlin/Boolean>| = fun <anonymous>(x: R|kotlin/Int|): R|kotlin/Boolean| {
lval x: R|(kotlin/Int) -> kotlin/Boolean| = fun <anonymous>(x: R|kotlin/Int|): R|kotlin/Boolean| {
>(R|<local>/x|, Int(1))
}
@@ -10,7 +10,7 @@ FILE: main.kt
>(R|<local>/it|, Int(1))
}
))
lval x: R|kotlin/Function1<kotlin/Int, kotlin/Boolean>| = fun <anonymous>(x: R|kotlin/Int|): R|kotlin/Boolean| {
lval x: R|(kotlin/Int) -> kotlin/Boolean| = fun <anonymous>(x: R|kotlin/Int|): R|kotlin/Boolean| {
>(R|<local>/x|, Int(1))
}
@@ -29,7 +29,7 @@ FILE: kotlinSam.kt
public final fun foo4(m: R|Derived|): R|kotlin/Unit| {
}
public final fun main(): R|kotlin/Unit| {
lval f: R|kotlin/Function1<kotlin/Int, kotlin/Boolean>| = fun <anonymous>(t: R|kotlin/Int|): R|kotlin/Boolean| {
lval f: R|(kotlin/Int) -> kotlin/Boolean| = fun <anonymous>(t: R|kotlin/Int|): R|kotlin/Boolean| {
>(R|<local>/t|, Int(1))
}
@@ -10,7 +10,7 @@ FILE: main.kt
>(<Unresolved name: it>#, Int(1))
}
)
lval x: R|kotlin/Function1<kotlin/Int, kotlin/Boolean>| = fun <anonymous>(x: R|kotlin/Int|): R|kotlin/Boolean| {
lval x: R|(kotlin/Int) -> kotlin/Boolean| = fun <anonymous>(x: R|kotlin/Int|): R|kotlin/Boolean| {
>(R|<local>/x|, Int(1))
}
@@ -10,7 +10,7 @@ FILE: main.kt
>(R|<local>/it|, Int(1))
}
)
lval x: R|kotlin/Function1<kotlin/Int, kotlin/Boolean>| = fun <anonymous>(x: R|kotlin/Int|): R|kotlin/Boolean| {
lval x: R|(kotlin/Int) -> kotlin/Boolean| = fun <anonymous>(x: R|kotlin/Int|): R|kotlin/Boolean| {
>(R|<local>/x|, Int(1))
}
@@ -10,7 +10,7 @@ FILE: main.kt
>(R|<local>/it|, Int(1))
}
)
lval x: R|kotlin/Function1<kotlin/Int, kotlin/Boolean>| = fun <anonymous>(x: R|kotlin/Int|): R|kotlin/Boolean| {
lval x: R|(kotlin/Int) -> kotlin/Boolean| = fun <anonymous>(x: R|kotlin/Int|): R|kotlin/Boolean| {
>(R|<local>/x|, Int(1))
}
@@ -10,7 +10,7 @@ FILE: main.kt
>(R|<local>/it|, Int(1))
}
)
lval x: R|kotlin/Function1<kotlin/Int, kotlin/Boolean>| = fun <anonymous>(x: R|kotlin/Int|): R|kotlin/Boolean| {
lval x: R|(kotlin/Int) -> kotlin/Boolean| = fun <anonymous>(x: R|kotlin/Int|): R|kotlin/Boolean| {
>(R|<local>/x|, Int(1))
}
@@ -8,7 +8,7 @@ FILE: implicitReceivers.kt
}
}
public final fun <T> R|T|.with(block: @R|kotlin/ExtensionFunctionType|() R|kotlin/Function1<T, kotlin/Unit>|): R|kotlin/Unit| {
public final fun <T> R|T|.with(block: R|T.() -> kotlin/Unit|): R|kotlin/Unit| {
}
public final fun R|kotlin/Any?|.test_1(): R|kotlin/Unit| {
when () {
@@ -7,7 +7,7 @@ FILE: inPlaceLambdas.kt
public abstract fun bar(): R|kotlin/Unit|
}
public final inline fun run(block: R|kotlin/Function0<kotlin/Unit>|): R|kotlin/Unit| {
public final inline fun run(block: R|() -> kotlin/Unit|): R|kotlin/Unit| {
R|<local>/block|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
}
public final fun test_1(x: R|kotlin/Any?|): R|kotlin/Unit| {
@@ -12,9 +12,9 @@ FILE: beyoundCalls.kt
^foobaz R|kotlin/TODO|()
}
public final fun foo(): R|kotlin/Unit| {
lval x: R|kotlin/Function1<kotlin/String, kotlin/Int>| = ::R|/bar|
lval x: R|(kotlin/String) -> kotlin/Int| = ::R|/bar|
lval y: <ERROR TYPE REF: No result type for initializer> = ::<Unresolved reference: bar>#
lval z: R|kotlin/reflect/KFunction1<kotlin/String, kotlin/Int>| = ::R|/baz|
lval w: R|kotlin/Function1<kotlin/String, kotlin/Int>| = ::R|/foobaz<kotlin/String, kotlin/Int>|
lval w: R|(kotlin/String) -> kotlin/Int| = ::R|/foobaz<kotlin/String, kotlin/Int>|
::R|/baz|
}
@@ -41,13 +41,13 @@ FILE: main.kt
}
}
public final fun foo1(x: R|kotlin/Function1<kotlin/String, kotlin/Int>|): R|kotlin/Unit| {
public final fun foo1(x: R|(kotlin/String) -> kotlin/Int|): R|kotlin/Unit| {
}
public final fun foo2(x: R|kotlin/Function2<KotlinClass, kotlin/CharSequence, kotlin/Int>|): R|kotlin/Unit| {
public final fun foo2(x: R|(KotlinClass, kotlin/CharSequence) -> kotlin/Int|): R|kotlin/Unit| {
}
public final fun foo3(x: R|kotlin/Function2<KotlinClass, kotlin/CharSequence, kotlin/Int>|): R|kotlin/Unit| {
public final fun foo3(x: R|(KotlinClass, kotlin/CharSequence) -> kotlin/Int|): R|kotlin/Unit| {
}
public final fun foo3(x: R|kotlin/Function1<kotlin/String, kotlin/Int>|): R|kotlin/Unit| {
public final fun foo3(x: R|(kotlin/String) -> kotlin/Int|): R|kotlin/Unit| {
}
public final fun main(): R|kotlin/Unit| {
R|/foo1|(Q|KotlinClass|::R|/KotlinClass.Companion.baz|)
@@ -9,7 +9,7 @@ FILE: constructors.kt
}
}
public final fun user(f: R|kotlin/Function1<kotlin/Int, Klass>|): R|kotlin/Unit| {
public final fun user(f: R|(kotlin/Int) -> Klass|): R|kotlin/Unit| {
}
public final fun fn(): R|kotlin/Unit| {
R|/user|(::R|/Klass.Klass|)
@@ -1,5 +1,5 @@
FILE: differentLevels.kt
public final fun foo(x: R|kotlin/Function0<kotlin/Int>|, y: R|kotlin/Int|): R|kotlin/Unit| {
public final fun foo(x: R|() -> kotlin/Int|, y: R|kotlin/Int|): R|kotlin/Unit| {
}
public final fun bar(x: R|kotlin/String|): R|kotlin/Int| {
^bar Int(1)
@@ -9,7 +9,7 @@ FILE: differentLevels.kt
^bar Int(1)
}
local final fun foo(x: R|kotlin/Function1<kotlin/String, kotlin/Int>|, y: R|kotlin/String|): R|kotlin/Unit| {
local final fun foo(x: R|(kotlin/String) -> kotlin/Int|, y: R|kotlin/String|): R|kotlin/Unit| {
}
R|/foo|(::R|<local>/bar|, Int(1))
@@ -12,7 +12,7 @@ FILE: extensionReceiverInference.kt
public final fun <X> R|X|.baz(): R|kotlin/Int| {
^baz Int(1)
}
public final fun foo(x: R|kotlin/Function1<A, kotlin/Int>|): R|kotlin/Unit| {
public final fun foo(x: R|(A) -> kotlin/Int|): R|kotlin/Unit| {
}
public final fun main(): R|kotlin/Unit| {
R|/foo|(Q|A|::R|/prop<A>|)
@@ -3,7 +3,7 @@ FILE: ambiguityWhenNoApplicableCallableReferenceCandidate.kt
}
public final fun foo(y: R|kotlin/String|): R|kotlin/Unit| {
}
public final fun <T> bar(f: R|kotlin/Function1<T, kotlin/Unit>|): R|kotlin/Unit| {
public final fun <T> bar(f: R|(T) -> kotlin/Unit|): R|kotlin/Unit| {
}
public final fun test(): R|kotlin/Unit| {
R|/bar|<R|kotlin/Any?|>(::<Unresolved reference: foo>#)
@@ -12,7 +12,7 @@ FILE: applicableCallableReferenceFromDistantScope.kt
public final fun foo(b: R|kotlin/Boolean|): R|kotlin/Unit| {
}
public final fun <T> bar(f: R|kotlin/Function1<T, kotlin/Unit>|): R|T| {
public final fun <T> bar(f: R|(T) -> kotlin/Unit|): R|T| {
^bar R|kotlin/TODO|()
}
@@ -26,7 +26,7 @@ FILE: chooseCallableReferenceDependingOnInferredReceiver.kt
}
}
public final fun <T> bar(f: R|kotlin/Function1<T, kotlin/Unit>|): R|T| {
public final fun <T> bar(f: R|(T) -> kotlin/Unit|): R|T| {
^bar R|kotlin/TODO|()
}
public final fun test(): R|kotlin/Unit| {
@@ -43,6 +43,6 @@ FILE: chooseCallableReferenceDependingOnInferredReceiver.kt
}
)
}
public final inline fun <T, R> myWith(receiver: R|T|, block: @R|kotlin/ExtensionFunctionType|() R|kotlin/Function1<T, R>|): R|R| {
public final inline fun <T, R> myWith(receiver: R|T|, block: R|T.() -> R|): R|R| {
^myWith R|kotlin/TODO|()
}
@@ -11,7 +11,7 @@ FILE: eagerAndPostponedCallableReferences.kt
}
public final fun singleB(a: R|B|): R|kotlin/Unit| {
}
public final fun <T> foo(f: R|kotlin/Function1<T, kotlin/Unit>|, g: R|kotlin/Function1<T, kotlin/Unit>|): R|T| {
public final fun <T> foo(f: R|(T) -> kotlin/Unit|, g: R|(T) -> kotlin/Unit|): R|T| {
^foo R|kotlin/TODO|()
}
public final fun test(): R|kotlin/Unit| {
@@ -26,6 +26,6 @@ FILE: eagerResolveOfSingleCallableReference.kt
public final fun test(ls: R|Out<B>|): R|kotlin/Unit| {
R|<local>/ls|.R|/reduce|<R|A|, R|B|>(::R|/Or.Or|)
}
public final fun <S, T : R|S|> R|Out<T>|.reduce(operation: R|kotlin/Function2<S, T, S>|): R|S| {
public final fun <S, T : R|S|> R|Out<T>|.reduce(operation: R|(S, T) -> S|): R|S| {
^reduce R|kotlin/TODO|()
}
@@ -13,9 +13,9 @@ FILE: multipleOutersAndMultipleCallableReferences.kt
public final fun foo(y: R|kotlin/String|): R|Inv<kotlin/String>| {
^foo R|kotlin/TODO|()
}
public final fun <T, R : R|kotlin/Number|> bar(f: R|kotlin/Function1<T, Inv<R>>|, p: R|kotlin/String| = String()): R|kotlin/Unit| {
public final fun <T, R : R|kotlin/Number|> bar(f: R|(T) -> Inv<R>|, p: R|kotlin/String| = String()): R|kotlin/Unit| {
}
public final fun <T, R : R|Base|> bar(f: R|kotlin/Function1<T, Inv<R>>|, p: R|kotlin/Int| = Int(4)): R|kotlin/Unit| {
public final fun <T, R : R|Base|> bar(f: R|(T) -> Inv<R>|, p: R|kotlin/Int| = Int(4)): R|kotlin/Unit| {
}
public final fun test(): R|kotlin/Unit| {
R|/bar|<R|kotlin/Int|, R|kotlin/Int|>(::R|/foo|)
@@ -11,7 +11,7 @@ FILE: overloadsBound.kt
}
}
public final fun foo(p: R|kotlin/Function1<kotlin/String, kotlin/Unit>|): R|kotlin/Unit| {
public final fun foo(p: R|(kotlin/String) -> kotlin/Unit|): R|kotlin/Unit| {
}
public final fun bar(c: R|C|): R|kotlin/Unit| {
R|/foo|(R|<local>/c|::R|/C.xf1|)
@@ -7,10 +7,10 @@ FILE: postponedResolveOfManyCallableReference.kt
}
public final fun foo(b: R|B|): R|kotlin/Unit| {
}
public final fun <T> bar1(f: R|kotlin/Function1<T, kotlin/Unit>|): R|T| {
public final fun <T> bar1(f: R|(T) -> kotlin/Unit|): R|T| {
^bar1 R|kotlin/TODO|()
}
public final fun <T> bar2(f: R|kotlin/Function1<T, kotlin/Unit>|, e: R|T|): R|kotlin/Unit| {
public final fun <T> bar2(f: R|(T) -> kotlin/Unit|, e: R|T|): R|kotlin/Unit| {
}
public final fun test(a: R|A|, b: R|B|): R|kotlin/Unit| {
lval expectedType1: R|A| = R|/bar1|<R|A|>(::R|/foo|)
@@ -5,9 +5,9 @@ FILE: resolveCallableReferencesAfterAllSimpleArguments.kt
}
public final fun fooB(b: R|B|): R|kotlin/Unit| {
}
public final fun <T> bar(f: R|kotlin/Function1<T, kotlin/Unit>|, e: R|T|): R|kotlin/Unit| {
public final fun <T> bar(f: R|(T) -> kotlin/Unit|, e: R|T|): R|kotlin/Unit| {
}
public final fun <T> baz(e: R|T|, f: R|kotlin/Function1<T, kotlin/Unit>|): R|kotlin/Unit| {
public final fun <T> baz(e: R|T|, f: R|(T) -> kotlin/Unit|): R|kotlin/Unit| {
}
public final fun test(a: R|A|, b: R|B|): R|kotlin/Unit| {
<Inapplicable(INAPPLICABLE): [/baz]>#(R|<local>/a|, ::R|/fooB|)
@@ -1,5 +1,5 @@
FILE: withGenericFun.kt
public final fun <T, R> apply(x: R|T|, f: R|kotlin/Function1<T, R>|): R|R| {
public final fun <T, R> apply(x: R|T|, f: R|(T) -> R|): R|R| {
^apply R|<local>/f|.R|FakeOverride<kotlin/Function1.invoke: R|R|>|(R|<local>/x|)
}
public final fun foo(i: R|kotlin/Int|): R|kotlin/Unit| {
@@ -1,8 +1,8 @@
FILE: implicitTypes.kt
public final fun <T, R> use(x: R|kotlin/Function1<T, R>|): R|kotlin/Function1<T, R>| {
public final fun <T, R> use(x: R|(T) -> R|): R|(T) -> R| {
^use R|<local>/x|
}
public final fun foo(): R|kotlin/Function1<kotlin/String, kotlin/Int>| {
public final fun foo(): R|(kotlin/String) -> kotlin/Int| {
^foo R|/use|<R|kotlin/String|, R|kotlin/Int|>(::R|/bar|)
}
public final fun bar(x: R|kotlin/String|): R|kotlin/Int| {
@@ -1,7 +1,7 @@
FILE: inferenceFromCallableReferenceType.kt
public final fun <T, E> foo(x: R|kotlin/Function1<T, E>|): R|kotlin/Unit| {
public final fun <T, E> foo(x: R|(T) -> E|): R|kotlin/Unit| {
}
public final fun <T, E> foo2(x: R|kotlin/Function2<A, T, E>|): R|kotlin/Unit| {
public final fun <T, E> foo2(x: R|(A, T) -> E|): R|kotlin/Unit| {
}
public final class A : R|kotlin/Any| {
public constructor(): R|A| {
@@ -1,7 +1,7 @@
FILE: inferenceFromExpectedType.kt
public final fun foo(x: R|kotlin/Function1<kotlin/String, kotlin/Int>|): R|kotlin/Unit| {
public final fun foo(x: R|(kotlin/String) -> kotlin/Int|): R|kotlin/Unit| {
}
public final fun foo2(x: R|kotlin/Function2<A, kotlin/String, kotlin/Int>|): R|kotlin/Unit| {
public final fun foo2(x: R|(A, kotlin/String) -> kotlin/Int|): R|kotlin/Unit| {
}
public final class A : R|kotlin/Any| {
public constructor(): R|A| {
@@ -1,11 +1,11 @@
FILE: main.kt
public final fun foo1(x: R|kotlin/Function1<kotlin/String, kotlin/Int>|): R|kotlin/Unit| {
public final fun foo1(x: R|(kotlin/String) -> kotlin/Int|): R|kotlin/Unit| {
}
public final fun foo2(x: R|kotlin/Function2<JavaClass, kotlin/CharSequence, kotlin/Int>|): R|kotlin/Unit| {
public final fun foo2(x: R|(JavaClass, kotlin/CharSequence) -> kotlin/Int|): R|kotlin/Unit| {
}
public final fun foo3(x: R|kotlin/Function2<JavaClass, kotlin/CharSequence, kotlin/Int>|): R|kotlin/Unit| {
public final fun foo3(x: R|(JavaClass, kotlin/CharSequence) -> kotlin/Int|): R|kotlin/Unit| {
}
public final fun foo3(x: R|kotlin/Function1<kotlin/String, kotlin/Int>|): R|kotlin/Unit| {
public final fun foo3(x: R|(kotlin/String) -> kotlin/Int|): R|kotlin/Unit| {
}
public final fun main(): R|kotlin/Unit| {
R|/foo1|(Q|JavaClass|::R|/JavaClass.bar|)
@@ -1,5 +1,5 @@
FILE: manyCandidatesInference.kt
public final fun <T> foo(x: R|kotlin/Function0<T>|, y: R|kotlin/Int|): R|kotlin/Unit| {
public final fun <T> foo(x: R|() -> T|, y: R|kotlin/Int|): R|kotlin/Unit| {
}
public final fun <E> bar(x: R|E|): R|kotlin/Int| {
^bar Int(1)
@@ -9,7 +9,7 @@ FILE: manyCandidatesInference.kt
^bar Int(1)
}
local final fun foo(x: R|kotlin/Function1<kotlin/String, kotlin/Int>|, y: R|kotlin/String|): R|kotlin/Unit| {
local final fun foo(x: R|(kotlin/String) -> kotlin/Int|, y: R|kotlin/String|): R|kotlin/Unit| {
}
R|/foo|<R|kotlin/Int|>(::R|<local>/bar|, Int(1))
@@ -1,5 +1,5 @@
FILE: manyInnerCandidates.kt
public final fun foo(x: R|kotlin/Function1<kotlin/String, kotlin/Int>|): R|kotlin/Unit| {
public final fun foo(x: R|(kotlin/String) -> kotlin/Int|): R|kotlin/Unit| {
}
public final fun bar(y: R|kotlin/Any|): R|kotlin/Int| {
^bar Int(1)
@@ -1,7 +1,7 @@
FILE: manyInnerManyOuterCandidates.kt
public final fun foo(x: R|kotlin/Function1<kotlin/String, kotlin/Int>|): R|kotlin/Unit| {
public final fun foo(x: R|(kotlin/String) -> kotlin/Int|): R|kotlin/Unit| {
}
public final fun foo(x: R|kotlin/Function0<kotlin/Int>|): R|kotlin/Unit| {
public final fun foo(x: R|() -> kotlin/Int|): R|kotlin/Unit| {
}
public final fun bar(): R|kotlin/Int| {
^bar Int(1)
@@ -1,7 +1,7 @@
FILE: manyInnermanyOuterCandidatesAmbiguity.kt
public final fun foo(x: R|kotlin/Function1<kotlin/String, kotlin/Int>|): R|kotlin/Unit| {
public final fun foo(x: R|(kotlin/String) -> kotlin/Int|): R|kotlin/Unit| {
}
public final fun foo(x: R|kotlin/Function0<kotlin/Int>|): R|kotlin/Unit| {
public final fun foo(x: R|() -> kotlin/Int|): R|kotlin/Unit| {
}
public final fun bar(): R|kotlin/Int| {
^bar Int(1)
@@ -1,7 +1,7 @@
FILE: manyOuterCandidates.kt
public final fun foo(x: R|kotlin/Function1<kotlin/String, kotlin/Int>|): R|kotlin/Unit| {
public final fun foo(x: R|(kotlin/String) -> kotlin/Int|): R|kotlin/Unit| {
}
public final fun foo(x: R|kotlin/Function0<kotlin/Int>|): R|kotlin/Unit| {
public final fun foo(x: R|() -> kotlin/Int|): R|kotlin/Unit| {
}
public final fun bar(): R|kotlin/Int| {
^bar Int(1)
@@ -14,13 +14,13 @@ FILE: properties.kt
public get(): R|kotlin/Int| {
^ Int(1)
}
public final fun foo1(x: R|kotlin/Function0<kotlin/Int>|): R|kotlin/Unit| {
public final fun foo1(x: R|() -> kotlin/Int|): R|kotlin/Unit| {
}
public final fun foo2(x: R|kotlin/Function1<A, kotlin/Int>|): R|kotlin/Unit| {
public final fun foo2(x: R|(A) -> kotlin/Int|): R|kotlin/Unit| {
}
public final fun <R> foo3(x: R|kotlin/Function0<R>|): R|kotlin/Unit| {
public final fun <R> foo3(x: R|() -> R|): R|kotlin/Unit| {
}
public final fun <T, R> foo4(x: R|kotlin/Function1<T, R>|): R|kotlin/Unit| {
public final fun <T, R> foo4(x: R|(T) -> R|): R|kotlin/Unit| {
}
public final fun main(): R|kotlin/Unit| {
R|/foo1|(::R|/bar|)
@@ -8,7 +8,7 @@ FILE: simpleClassReceiver.kt
}
}
public final fun foo(x: R|kotlin/Function2<A, kotlin/String, kotlin/Int>|): R|kotlin/Unit| {
public final fun foo(x: R|(A, kotlin/String) -> kotlin/Int|): R|kotlin/Unit| {
}
public final fun main(): R|kotlin/Unit| {
R|/foo|(Q|A|::R|/A.bar|)
@@ -8,7 +8,7 @@ FILE: simpleExpressionReceiver.kt
}
}
public final fun foo(x: R|kotlin/Function1<kotlin/String, kotlin/Int>|): R|kotlin/Unit| {
public final fun foo(x: R|(kotlin/String) -> kotlin/Int|): R|kotlin/Unit| {
}
public final fun main(): R|kotlin/Unit| {
lval a: R|A| = R|/A.A|()
@@ -1,5 +1,5 @@
FILE: simpleNoReceiver.kt
public final fun foo(x: R|kotlin/Function1<kotlin/String, kotlin/Int>|): R|kotlin/Unit| {
public final fun foo(x: R|(kotlin/String) -> kotlin/Int|): R|kotlin/Unit| {
}
public final fun bar(x: R|kotlin/String|): R|kotlin/Int| {
}
@@ -33,7 +33,7 @@ FILE: callsInPlace.kt
}
)
}
public final inline fun myRun(block1: R|kotlin/Function0<kotlin/Unit>|, block2: R|kotlin/Function0<kotlin/Unit>|): R|kotlin/Unit| {
public final inline fun myRun(block1: R|() -> kotlin/Unit|, block2: R|() -> kotlin/Unit|): R|kotlin/Unit| {
R|<local>/block1|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
R|<local>/block2|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
}
@@ -55,7 +55,7 @@ FILE: callsInPlace.kt
}
)
}
public final fun myDummyRun(block: R|kotlin/Function0<kotlin/Unit>|): R|kotlin/Unit| {
public final fun myDummyRun(block: R|() -> kotlin/Unit|): R|kotlin/Unit| {
R|<local>/block|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
}
public final fun test_8(): R|kotlin/Unit| {
+3 -3
View File
@@ -4,12 +4,12 @@ FILE: functionX.kt
}
public get(): R|kotlin/jvm/functions/Function0<kotlin/Int>|
public final val y: R|kotlin/Function1<kotlin/String, kotlin/String>| = fun <anonymous>(it: R|kotlin/String|): R|kotlin/String| {
public final val y: R|(kotlin/String) -> kotlin/String| = fun <anonymous>(it: R|kotlin/String|): R|kotlin/String| {
R|<local>/it|
}
public get(): R|kotlin/Function1<kotlin/String, kotlin/String>|
public final class MyFunction : R|kotlin/Function2<kotlin/Int, kotlin/String, kotlin/Unit>| {
public get(): R|(kotlin/String) -> kotlin/String|
public final class MyFunction : R|(kotlin/Int, kotlin/String) -> kotlin/Unit| {
public constructor(): R|MyFunction| {
super<R|kotlin/Any|>()
}
@@ -12,7 +12,7 @@ FILE: main.kt
R|<local>/it|.R|kotlin/Int.plus|(Int(3)).R|kotlin/Any.toString|()
}
)
lval y: R|kotlin/Function1<kotlin/Int, kotlin/String>| = fun <anonymous>(x: R|kotlin/Int|): R|kotlin/String| {
lval y: R|(kotlin/Int) -> kotlin/String| = fun <anonymous>(x: R|kotlin/Int|): R|kotlin/String| {
R|<local>/x|.R|kotlin/Any.toString|()
}
+1 -1
View File
@@ -11,6 +11,6 @@ FILE: mapList.kt
}
)
}
public final inline fun <T> R|T|.applyX(block: @R|kotlin/ExtensionFunctionType|() R|kotlin/Function1<T, kotlin/Unit>|): R|T| {
public final inline fun <T> R|T|.applyX(block: R|T.() -> kotlin/Unit|): R|T| {
R|kotlin/TODO|()
}
@@ -1,6 +1,6 @@
FILE: recursiveBug.kt
public final class Foo : R|kotlin/Any| {
public constructor(name: R|kotlin/Function0<kotlin/String>|): R|Foo| {
public constructor(name: R|() -> kotlin/String|): R|Foo| {
super<R|kotlin/Any|>()
}
@@ -14,7 +14,7 @@ FILE: recursiveBug.kt
public get(): R|kotlin/Int|
}
public final fun bar(name: R|kotlin/Function0<kotlin/String>|): R|kotlin/Unit| {
public final fun bar(name: R|() -> kotlin/String|): R|kotlin/Unit| {
lval result: R|kotlin/String| = R|kotlin/run|<R|kotlin/String|>(<L> = run@fun <anonymous>(): R|kotlin/String| <kind=EXACTLY_ONCE> {
R|<local>/name|.R|FakeOverride<kotlin/Function0.invoke: R|kotlin/String|>|()
}
@@ -1,5 +1,5 @@
FILE: typeParameterDerived.kt
public final inline fun <K, V, VA : R|V|> R|kotlin/collections/MutableMap<K, V>|.getOrPut(key: R|K|, defaultValue: R|kotlin/Function1<K, VA>|, postCompute: R|kotlin/Function1<VA, kotlin/Unit>|): R|V| {
public final inline fun <K, V, VA : R|V|> R|kotlin/collections/MutableMap<K, V>|.getOrPut(key: R|K|, defaultValue: R|(K) -> VA|, postCompute: R|(VA) -> kotlin/Unit|): R|V| {
lval value: R|V| = this@R|kotlin/collections/Map|.R|FakeOverride<kotlin/collections/Map.get: R|V|>|(R|<local>/key|)
^getOrPut when () {
==(R|<local>/value|, Null(null)) -> {
+1 -1
View File
@@ -1,5 +1,5 @@
FILE: whenAsReceiver.kt
public final fun <T, R> R|T|.also(block: R|kotlin/Function0<R>|): R|R| {
public final fun <T, R> R|T|.also(block: R|() -> R|): R|R| {
^also when (lval <bangbang>: R|kotlin/Nothing?| = Null(null)) {
==($subj$, Null(null)) -> {
throw <Unresolved name: KotlinNullPointerException>#()
@@ -5,6 +5,8 @@
package org.jetbrains.kotlin.fir
import org.jetbrains.kotlin.builtins.functions.BuiltInFictitiousFunctionClassFactory
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
@@ -736,13 +738,27 @@ class FirRenderer(builder: StringBuilder) : FirVisitorVoid() {
}
override fun visitResolvedTypeRef(resolvedTypeRef: FirResolvedTypeRef) {
resolvedTypeRef.annotations.renderAnnotations()
val kind = resolvedTypeRef.functionTypeKind
val annotations = if (kind.withPrettyRender()) {
resolvedTypeRef.annotations.dropExtensionFunctionAnnotation()
} else {
resolvedTypeRef.annotations
}
annotations.renderAnnotations()
print("R|")
val coneType = resolvedTypeRef.type
print(coneType.render())
print(coneType.renderFunctionType(kind, resolvedTypeRef.isExtensionFunctionType()))
print("|")
}
private val FirResolvedTypeRef.functionTypeKind: FunctionClassDescriptor.Kind?
get() {
val classId = (type as? ConeClassLikeType)?.lookupTag?.classId ?: return null
return BuiltInFictitiousFunctionClassFactory.getFunctionalClassKind(
classId.shortClassName.asString(), classId.packageFqName
)
}
override fun visitUserTypeRef(userTypeRef: FirUserTypeRef) {
userTypeRef.annotations.renderAnnotations()
for ((index, qualifier) in userTypeRef.qualifier.withIndex()) {
@@ -5,6 +5,8 @@
package org.jetbrains.kotlin.fir.types
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef
import org.jetbrains.kotlin.name.ClassId
@@ -32,4 +34,26 @@ val FirFunctionTypeRef.parametersCount: Int
get() = if (receiverTypeRef != null)
valueParameters.size + 1
else
valueParameters.size
valueParameters.size
const val EXTENSION_FUNCTION_ANNOTATION = "kotlin/ExtensionFunctionType"
fun FirTypeRef.isExtensionFunctionType(): Boolean {
return annotations.any {
it.isExtensionFunctionAnnotationCall
}
}
val FirAnnotationCall.isExtensionFunctionAnnotationCall: Boolean
get() = (this as? FirAnnotationCall)?.let {
(it.annotationTypeRef as? FirResolvedTypeRef)?.let {
(it.type as? ConeClassLikeType)?.let {
it.lookupTag.classId.asString() == EXTENSION_FUNCTION_ANNOTATION
}
}
} == true
fun List<FirAnnotationCall>.dropExtensionFunctionAnnotation(): List<FirAnnotationCall> {
return filterNot { it.isExtensionFunctionAnnotationCall }
}