FIR renderer: extract separate ConeTypeRenderer
This commit is contained in:
+1
-1
@@ -161,7 +161,7 @@ internal class KtFirTypeProvider(
|
|||||||
|
|
||||||
require(typeParameterSymbols.size == argumentTypes.size) {
|
require(typeParameterSymbols.size == argumentTypes.size) {
|
||||||
"'${symbol.fir.render(FirRenderer.RenderMode.NoBodies)}' expects '${typeParameterSymbols.size}' type arguments " +
|
"'${symbol.fir.render(FirRenderer.RenderMode.NoBodies)}' expects '${typeParameterSymbols.size}' type arguments " +
|
||||||
"but type '${this.render()}' has ${argumentTypes.size} type arguments."
|
"but type '${this.renderForDebugging()}' has ${argumentTypes.size} type arguments."
|
||||||
}
|
}
|
||||||
|
|
||||||
val substitutor = substitutorByMap(typeParameterSymbols.zip(argumentTypes).toMap(), session)
|
val substitutor = substitutorByMap(typeParameterSymbols.zip(argumentTypes).toMap(), session)
|
||||||
|
|||||||
+1
-1
@@ -77,7 +77,7 @@ internal class ConeTypeIdeRenderer(
|
|||||||
}
|
}
|
||||||
is ConeCapturedType -> {
|
is ConeCapturedType -> {
|
||||||
renderAnnotationList(type)
|
renderAnnotationList(type)
|
||||||
append(type.render())
|
append(type.renderReadableWithFqNames())
|
||||||
renderNullability(type.type)
|
renderNullability(type.type)
|
||||||
}
|
}
|
||||||
is ConeDefinitelyNotNullType -> {
|
is ConeDefinitelyNotNullType -> {
|
||||||
|
|||||||
+2
-2
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
|
|||||||
import org.jetbrains.kotlin.analysis.api.types.KtCapturedType
|
import org.jetbrains.kotlin.analysis.api.types.KtCapturedType
|
||||||
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
|
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
|
||||||
import org.jetbrains.kotlin.fir.types.ConeCapturedType
|
import org.jetbrains.kotlin.fir.types.ConeCapturedType
|
||||||
import org.jetbrains.kotlin.fir.types.render
|
import org.jetbrains.kotlin.fir.types.renderForDebugging
|
||||||
|
|
||||||
internal class KtFirCapturedType(
|
internal class KtFirCapturedType(
|
||||||
override val coneType: ConeCapturedType,
|
override val coneType: ConeCapturedType,
|
||||||
@@ -27,7 +27,7 @@ internal class KtFirCapturedType(
|
|||||||
KtFirAnnotationListForType.create(coneType, builder.rootSession, token)
|
KtFirAnnotationListForType.create(coneType, builder.rootSession, token)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun asStringForDebugging(): String = withValidityAssertion { coneType.render() }
|
override fun asStringForDebugging(): String = withValidityAssertion { coneType.renderForDebugging() }
|
||||||
|
|
||||||
|
|
||||||
override fun equals(other: Any?) = typeEquals(other)
|
override fun equals(other: Any?) = typeEquals(other)
|
||||||
|
|||||||
+2
-2
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.analysis.api.types.KtClassErrorType
|
|||||||
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
|
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.ConeErrorType
|
import org.jetbrains.kotlin.fir.types.ConeErrorType
|
||||||
import org.jetbrains.kotlin.fir.types.render
|
import org.jetbrains.kotlin.fir.types.renderForDebugging
|
||||||
|
|
||||||
internal class KtFirClassErrorType(
|
internal class KtFirClassErrorType(
|
||||||
override val coneType: ConeErrorType,
|
override val coneType: ConeErrorType,
|
||||||
@@ -37,7 +37,7 @@ internal class KtFirClassErrorType(
|
|||||||
symbols.map { builder.classifierBuilder.buildClassLikeSymbol(it) }
|
symbols.map { builder.classifierBuilder.buildClassLikeSymbol(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun asStringForDebugging(): String = withValidityAssertion { coneType.render() }
|
override fun asStringForDebugging(): String = withValidityAssertion { coneType.renderForDebugging() }
|
||||||
override fun equals(other: Any?) = typeEquals(other)
|
override fun equals(other: Any?) = typeEquals(other)
|
||||||
override fun hashCode() = typeHashcode()
|
override fun hashCode() = typeHashcode()
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
|
|||||||
import org.jetbrains.kotlin.analysis.api.types.KtDefinitelyNotNullType
|
import org.jetbrains.kotlin.analysis.api.types.KtDefinitelyNotNullType
|
||||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||||
import org.jetbrains.kotlin.fir.types.ConeDefinitelyNotNullType
|
import org.jetbrains.kotlin.fir.types.ConeDefinitelyNotNullType
|
||||||
import org.jetbrains.kotlin.fir.types.render
|
import org.jetbrains.kotlin.fir.types.renderForDebugging
|
||||||
|
|
||||||
internal class KtFirDefinitelyNotNullType(
|
internal class KtFirDefinitelyNotNullType(
|
||||||
override val coneType: ConeDefinitelyNotNullType,
|
override val coneType: ConeDefinitelyNotNullType,
|
||||||
@@ -26,7 +26,7 @@ internal class KtFirDefinitelyNotNullType(
|
|||||||
KtFirAnnotationListForType.create(coneType, builder.rootSession, token)
|
KtFirAnnotationListForType.create(coneType, builder.rootSession, token)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun asStringForDebugging(): String = withValidityAssertion { coneType.render() }
|
override fun asStringForDebugging(): String = withValidityAssertion { coneType.renderForDebugging() }
|
||||||
override fun equals(other: Any?) = typeEquals(other)
|
override fun equals(other: Any?) = typeEquals(other)
|
||||||
override fun hashCode() = typeHashcode()
|
override fun hashCode() = typeHashcode()
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
|
|||||||
import org.jetbrains.kotlin.analysis.api.types.KtDynamicType
|
import org.jetbrains.kotlin.analysis.api.types.KtDynamicType
|
||||||
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
|
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
|
||||||
import org.jetbrains.kotlin.fir.types.ConeDynamicType
|
import org.jetbrains.kotlin.fir.types.ConeDynamicType
|
||||||
import org.jetbrains.kotlin.fir.types.render
|
import org.jetbrains.kotlin.fir.types.renderForDebugging
|
||||||
|
|
||||||
internal class KtFirDynamicType(
|
internal class KtFirDynamicType(
|
||||||
override val coneType: ConeDynamicType,
|
override val coneType: ConeDynamicType,
|
||||||
@@ -26,7 +26,7 @@ internal class KtFirDynamicType(
|
|||||||
}
|
}
|
||||||
override val nullability: KtTypeNullability get() = withValidityAssertion { coneType.nullability.asKtNullability() }
|
override val nullability: KtTypeNullability get() = withValidityAssertion { coneType.nullability.asKtNullability() }
|
||||||
|
|
||||||
override fun asStringForDebugging(): String = withValidityAssertion { coneType.render() }
|
override fun asStringForDebugging(): String = withValidityAssertion { coneType.renderForDebugging() }
|
||||||
override fun equals(other: Any?) = typeEquals(other)
|
override fun equals(other: Any?) = typeEquals(other)
|
||||||
override fun hashCode() = typeHashcode()
|
override fun hashCode() = typeHashcode()
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.analysis.api.types.KtFlexibleType
|
|||||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||||
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
|
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
|
||||||
import org.jetbrains.kotlin.fir.types.ConeFlexibleType
|
import org.jetbrains.kotlin.fir.types.ConeFlexibleType
|
||||||
import org.jetbrains.kotlin.fir.types.render
|
import org.jetbrains.kotlin.fir.types.renderForDebugging
|
||||||
|
|
||||||
internal class KtFirFlexibleType(
|
internal class KtFirFlexibleType(
|
||||||
override val coneType: ConeFlexibleType,
|
override val coneType: ConeFlexibleType,
|
||||||
@@ -30,7 +30,7 @@ internal class KtFirFlexibleType(
|
|||||||
}
|
}
|
||||||
override val nullability: KtTypeNullability get() = withValidityAssertion { coneType.nullability.asKtNullability() }
|
override val nullability: KtTypeNullability get() = withValidityAssertion { coneType.nullability.asKtNullability() }
|
||||||
|
|
||||||
override fun asStringForDebugging(): String = withValidityAssertion { coneType.render() }
|
override fun asStringForDebugging(): String = withValidityAssertion { coneType.renderForDebugging() }
|
||||||
override fun equals(other: Any?) = typeEquals(other)
|
override fun equals(other: Any?) = typeEquals(other)
|
||||||
override fun hashCode() = typeHashcode()
|
override fun hashCode() = typeHashcode()
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
|||||||
import org.jetbrains.kotlin.fir.types.isExtensionFunctionType
|
import org.jetbrains.kotlin.fir.types.isExtensionFunctionType
|
||||||
import org.jetbrains.kotlin.fir.types.isSuspendFunctionType
|
import org.jetbrains.kotlin.fir.types.isSuspendFunctionType
|
||||||
import org.jetbrains.kotlin.fir.types.receiverType
|
import org.jetbrains.kotlin.fir.types.receiverType
|
||||||
import org.jetbrains.kotlin.fir.types.render
|
import org.jetbrains.kotlin.fir.types.renderForDebugging
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
|
||||||
internal class KtFirFunctionalType(
|
internal class KtFirFunctionalType(
|
||||||
@@ -73,7 +73,7 @@ internal class KtFirFunctionalType(
|
|||||||
override val returnType: KtType
|
override val returnType: KtType
|
||||||
get() = withValidityAssertion { (typeArguments.last() as KtTypeArgumentWithVariance).type }
|
get() = withValidityAssertion { (typeArguments.last() as KtTypeArgumentWithVariance).type }
|
||||||
|
|
||||||
override fun asStringForDebugging(): String = withValidityAssertion { coneType.render() }
|
override fun asStringForDebugging(): String = withValidityAssertion { coneType.renderForDebugging() }
|
||||||
override fun equals(other: Any?) = typeEquals(other)
|
override fun equals(other: Any?) = typeEquals(other)
|
||||||
override fun hashCode() = typeHashcode()
|
override fun hashCode() = typeHashcode()
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.analysis.api.types.KtClassType
|
|||||||
import org.jetbrains.kotlin.analysis.api.types.KtIntegerLiteralType
|
import org.jetbrains.kotlin.analysis.api.types.KtIntegerLiteralType
|
||||||
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
|
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
|
||||||
import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralConstantType
|
import org.jetbrains.kotlin.fir.types.ConeIntegerLiteralConstantType
|
||||||
import org.jetbrains.kotlin.fir.types.render
|
import org.jetbrains.kotlin.fir.types.renderForDebugging
|
||||||
|
|
||||||
internal class KtFirIntegerLiteralType(
|
internal class KtFirIntegerLiteralType(
|
||||||
override val coneType: ConeIntegerLiteralConstantType,
|
override val coneType: ConeIntegerLiteralConstantType,
|
||||||
@@ -38,7 +38,7 @@ internal class KtFirIntegerLiteralType(
|
|||||||
|
|
||||||
override val nullability: KtTypeNullability get() = withValidityAssertion { coneType.nullability.asKtNullability() }
|
override val nullability: KtTypeNullability get() = withValidityAssertion { coneType.nullability.asKtNullability() }
|
||||||
|
|
||||||
override fun asStringForDebugging(): String = withValidityAssertion { coneType.render() }
|
override fun asStringForDebugging(): String = withValidityAssertion { coneType.renderForDebugging() }
|
||||||
override fun equals(other: Any?) = typeEquals(other)
|
override fun equals(other: Any?) = typeEquals(other)
|
||||||
override fun hashCode() = typeHashcode()
|
override fun hashCode() = typeHashcode()
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.analysis.api.types.KtIntersectionType
|
|||||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||||
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
|
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
|
||||||
import org.jetbrains.kotlin.fir.types.ConeIntersectionType
|
import org.jetbrains.kotlin.fir.types.ConeIntersectionType
|
||||||
import org.jetbrains.kotlin.fir.types.render
|
import org.jetbrains.kotlin.fir.types.renderForDebugging
|
||||||
|
|
||||||
internal class KtFirIntersectionType(
|
internal class KtFirIntersectionType(
|
||||||
override val coneType: ConeIntersectionType,
|
override val coneType: ConeIntersectionType,
|
||||||
@@ -30,7 +30,7 @@ internal class KtFirIntersectionType(
|
|||||||
}
|
}
|
||||||
override val nullability: KtTypeNullability get() = withValidityAssertion { coneType.nullability.asKtNullability() }
|
override val nullability: KtTypeNullability get() = withValidityAssertion { coneType.nullability.asKtNullability() }
|
||||||
|
|
||||||
override fun asStringForDebugging(): String = withValidityAssertion { coneType.render() }
|
override fun asStringForDebugging(): String = withValidityAssertion { coneType.renderForDebugging() }
|
||||||
override fun equals(other: Any?) = typeEquals(other)
|
override fun equals(other: Any?) = typeEquals(other)
|
||||||
override fun hashCode() = typeHashcode()
|
override fun hashCode() = typeHashcode()
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtTypeParameterSymbol
|
|||||||
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
|
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
|
||||||
import org.jetbrains.kotlin.analysis.api.types.KtTypeParameterType
|
import org.jetbrains.kotlin.analysis.api.types.KtTypeParameterType
|
||||||
import org.jetbrains.kotlin.fir.types.ConeTypeParameterType
|
import org.jetbrains.kotlin.fir.types.ConeTypeParameterType
|
||||||
import org.jetbrains.kotlin.fir.types.render
|
import org.jetbrains.kotlin.fir.types.renderForDebugging
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
internal class KtFirTypeParameterType(
|
internal class KtFirTypeParameterType(
|
||||||
@@ -35,7 +35,7 @@ internal class KtFirTypeParameterType(
|
|||||||
|
|
||||||
override val nullability: KtTypeNullability get() = withValidityAssertion { coneType.nullability.asKtNullability() }
|
override val nullability: KtTypeNullability get() = withValidityAssertion { coneType.nullability.asKtNullability() }
|
||||||
|
|
||||||
override fun asStringForDebugging(): String = withValidityAssertion { coneType.render() }
|
override fun asStringForDebugging(): String = withValidityAssertion { coneType.renderForDebugging() }
|
||||||
override fun equals(other: Any?) = typeEquals(other)
|
override fun equals(other: Any?) = typeEquals(other)
|
||||||
override fun hashCode() = typeHashcode()
|
override fun hashCode() = typeHashcode()
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtClassLikeSymbol
|
|||||||
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
|
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
|
||||||
import org.jetbrains.kotlin.analysis.api.types.KtUsualClassType
|
import org.jetbrains.kotlin.analysis.api.types.KtUsualClassType
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||||
import org.jetbrains.kotlin.fir.types.render
|
import org.jetbrains.kotlin.fir.types.renderForDebugging
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
|
||||||
internal class KtFirUsualClassType(
|
internal class KtFirUsualClassType(
|
||||||
@@ -40,7 +40,7 @@ internal class KtFirUsualClassType(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override val nullability: KtTypeNullability get() = withValidityAssertion { coneType.nullability.asKtNullability() }
|
override val nullability: KtTypeNullability get() = withValidityAssertion { coneType.nullability.asKtNullability() }
|
||||||
override fun asStringForDebugging(): String = withValidityAssertion { coneType.render() }
|
override fun asStringForDebugging(): String = withValidityAssertion { coneType.renderForDebugging() }
|
||||||
override fun equals(other: Any?) = typeEquals(other)
|
override fun equals(other: Any?) = typeEquals(other)
|
||||||
override fun hashCode() = typeHashcode()
|
override fun hashCode() = typeHashcode()
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -52,8 +52,8 @@ abstract class AbstractFirLazyBodiesCalculatorTest : AbstractLowLevelApiSingleFi
|
|||||||
bodyBuildingMode = BodyBuildingMode.NORMAL
|
bodyBuildingMode = BodyBuildingMode.NORMAL
|
||||||
).buildFirFile(ktFile)
|
).buildFirFile(ktFile)
|
||||||
|
|
||||||
val laziedFirFileDump = StringBuilder().also { FirRenderer(it).visitFile(laziedFirFile) }.toString()
|
val laziedFirFileDump = StringBuilder().also { FirRenderer(it).Visitor().visitFile(laziedFirFile) }.toString()
|
||||||
val fullFirFileDump = StringBuilder().also { FirRenderer(it).visitFile(fullFirFile) }.toString()
|
val fullFirFileDump = StringBuilder().also { FirRenderer(it).Visitor().visitFile(fullFirFile) }.toString()
|
||||||
|
|
||||||
TestCase.assertEquals(laziedFirFileDump, fullFirFileDump)
|
TestCase.assertEquals(laziedFirFileDump, fullFirFileDump)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -37,14 +37,14 @@ abstract class AbstractFirLoadBinariesTest : AbstractFirResolveWithSessionTestCa
|
|||||||
|
|
||||||
for (name in declarationNames) {
|
for (name in declarationNames) {
|
||||||
for (symbol in provider.getTopLevelCallableSymbols(packageFqName, name)) {
|
for (symbol in provider.getTopLevelCallableSymbols(packageFqName, name)) {
|
||||||
symbol.fir.accept(firRenderer)
|
symbol.fir.accept(firRenderer.Visitor())
|
||||||
builder.appendLine()
|
builder.appendLine()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (name in declarationNames) {
|
for (name in declarationNames) {
|
||||||
val classLikeSymbol = provider.getClassLikeSymbolByClassId(ClassId.topLevel(packageFqName.child(name))) ?: continue
|
val classLikeSymbol = provider.getClassLikeSymbolByClassId(ClassId.topLevel(packageFqName.child(name))) ?: continue
|
||||||
classLikeSymbol.fir.accept(firRenderer)
|
classLikeSymbol.fir.accept(firRenderer.Visitor())
|
||||||
builder.appendLine()
|
builder.appendLine()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-3
@@ -24,9 +24,10 @@ fun renderJavaClass(renderer: FirRenderer, javaClass: FirJavaClass, session: Fir
|
|||||||
val memberScope = javaClass.unsubstitutedScope(session, ScopeSession(), withForcedTypeCalculator = true)
|
val memberScope = javaClass.unsubstitutedScope(session, ScopeSession(), withForcedTypeCalculator = true)
|
||||||
|
|
||||||
val staticScope = javaClass.scopeProvider.getStaticScope(javaClass, session, ScopeSession())
|
val staticScope = javaClass.scopeProvider.getStaticScope(javaClass, session, ScopeSession())
|
||||||
|
val visitor = renderer.Visitor()
|
||||||
|
|
||||||
renderer.renderAnnotations(javaClass)
|
renderer.renderAnnotations(javaClass)
|
||||||
renderer.visitMemberDeclaration(javaClass)
|
visitor.visitMemberDeclaration(javaClass)
|
||||||
renderer.renderSupertypes(javaClass)
|
renderer.renderSupertypes(javaClass)
|
||||||
renderer.renderInBraces {
|
renderer.renderInBraces {
|
||||||
val renderedDeclarations = mutableListOf<FirDeclaration>()
|
val renderedDeclarations = mutableListOf<FirDeclaration>()
|
||||||
@@ -34,7 +35,7 @@ fun renderJavaClass(renderer: FirRenderer, javaClass: FirJavaClass, session: Fir
|
|||||||
fun renderAndCache(symbol: FirCallableSymbol<*>) {
|
fun renderAndCache(symbol: FirCallableSymbol<*>) {
|
||||||
val enhanced = symbol.fir
|
val enhanced = symbol.fir
|
||||||
if (enhanced !in renderedDeclarations) {
|
if (enhanced !in renderedDeclarations) {
|
||||||
enhanced.accept(renderer, null)
|
enhanced.accept(visitor, null)
|
||||||
renderer.newLine()
|
renderer.newLine()
|
||||||
renderedDeclarations += enhanced
|
renderedDeclarations += enhanced
|
||||||
}
|
}
|
||||||
@@ -55,7 +56,7 @@ fun renderJavaClass(renderer: FirRenderer, javaClass: FirJavaClass, session: Fir
|
|||||||
is FirJavaField -> scopeToUse!!.processPropertiesByName(declaration.name, ::renderAndCache)
|
is FirJavaField -> scopeToUse!!.processPropertiesByName(declaration.name, ::renderAndCache)
|
||||||
is FirEnumEntry -> scopeToUse!!.processPropertiesByName(declaration.name, ::renderAndCache)
|
is FirEnumEntry -> scopeToUse!!.processPropertiesByName(declaration.name, ::renderAndCache)
|
||||||
else -> {
|
else -> {
|
||||||
declaration.accept(renderer, null)
|
declaration.accept(visitor, null)
|
||||||
renderer.newLine()
|
renderer.newLine()
|
||||||
renderedDeclarations += declaration
|
renderedDeclarations += declaration
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-5
@@ -23,10 +23,7 @@ import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeInapplicableCandidateErr
|
|||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeInapplicableWrongReceiver
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeInapplicableWrongReceiver
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedNameError
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedNameError
|
||||||
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.types.ConeErrorType
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.fir.types.coneType
|
|
||||||
import org.jetbrains.kotlin.fir.types.render
|
|
||||||
import org.jetbrains.kotlin.fir.types.typeContext
|
|
||||||
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
|
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
|
||||||
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
import org.jetbrains.kotlin.types.AbstractTypeChecker
|
||||||
@@ -72,7 +69,7 @@ object FirDelegatedPropertyChecker : FirPropertyChecker() {
|
|||||||
val errorNamedReference = functionCall.calleeReference as? FirErrorNamedReference ?: return false
|
val errorNamedReference = functionCall.calleeReference as? FirErrorNamedReference ?: return false
|
||||||
if (errorNamedReference.source?.kind != KtFakeSourceElementKind.DelegatedPropertyAccessor) return false
|
if (errorNamedReference.source?.kind != KtFakeSourceElementKind.DelegatedPropertyAccessor) return false
|
||||||
val expectedFunctionSignature =
|
val expectedFunctionSignature =
|
||||||
(if (isGet) "getValue" else "setValue") + "(${functionCall.arguments.joinToString(", ") { it.typeRef.coneType.render() }})"
|
(if (isGet) "getValue" else "setValue") + "(${functionCall.arguments.joinToString(", ") { it.typeRef.coneType.renderReadable() }})"
|
||||||
val delegateDescription = if (isGet) "delegate" else "delegate for var (read-write property)"
|
val delegateDescription = if (isGet) "delegate" else "delegate for var (read-write property)"
|
||||||
|
|
||||||
fun reportInapplicableDiagnostics(candidates: Collection<FirBasedSymbol<*>>) {
|
fun reportInapplicableDiagnostics(candidates: Collection<FirBasedSymbol<*>>) {
|
||||||
|
|||||||
+2
-2
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.fir.resolve.diagnostics.*
|
|||||||
import org.jetbrains.kotlin.fir.types.ConeErrorType
|
import org.jetbrains.kotlin.fir.types.ConeErrorType
|
||||||
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
|
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.render
|
import org.jetbrains.kotlin.fir.types.renderForDebugging
|
||||||
|
|
||||||
class ErrorNodeDiagnosticCollectorComponent(
|
class ErrorNodeDiagnosticCollectorComponent(
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
@@ -42,7 +42,7 @@ class ErrorNodeDiagnosticCollectorComponent(
|
|||||||
|
|
||||||
override fun visitResolvedTypeRef(resolvedTypeRef: FirResolvedTypeRef, data: CheckerContext) {
|
override fun visitResolvedTypeRef(resolvedTypeRef: FirResolvedTypeRef, data: CheckerContext) {
|
||||||
assert(resolvedTypeRef.type !is ConeErrorType) {
|
assert(resolvedTypeRef.type !is ConeErrorType) {
|
||||||
"Instead use FirErrorTypeRef for ${resolvedTypeRef.type.render()}"
|
"Instead use FirErrorTypeRef for ${resolvedTypeRef.type.renderForDebugging()}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -19,7 +19,7 @@ import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
|||||||
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.fir.types.render
|
import org.jetbrains.kotlin.fir.types.renderReadableWithFqNames
|
||||||
import org.jetbrains.kotlin.name.CallableId
|
import org.jetbrains.kotlin.name.CallableId
|
||||||
|
|
||||||
object FirDiagnosticRenderers {
|
object FirDiagnosticRenderers {
|
||||||
@@ -89,7 +89,7 @@ object FirDiagnosticRenderers {
|
|||||||
|
|
||||||
val RENDER_TYPE = Renderer { t: ConeKotlinType ->
|
val RENDER_TYPE = Renderer { t: ConeKotlinType ->
|
||||||
// TODO: need a way to tune granuality, e.g., without parameter names in functional types.
|
// TODO: need a way to tune granuality, e.g., without parameter names in functional types.
|
||||||
t.render()
|
t.renderReadableWithFqNames()
|
||||||
}
|
}
|
||||||
|
|
||||||
val FQ_NAMES_IN_TYPES = Renderer { symbol: FirBasedSymbol<*> ->
|
val FQ_NAMES_IN_TYPES = Renderer { symbol: FirBasedSymbol<*> ->
|
||||||
|
|||||||
@@ -0,0 +1,199 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.fir.renderer
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
|
||||||
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
import kotlin.contracts.ExperimentalContracts
|
||||||
|
import kotlin.contracts.contract
|
||||||
|
|
||||||
|
open class ConeTypeRenderer(protected val builder: StringBuilder) {
|
||||||
|
|
||||||
|
open fun renderAsPossibleFunctionType(
|
||||||
|
type: ConeKotlinType, renderType: ConeTypeProjection.() -> Unit = { render() }
|
||||||
|
) {
|
||||||
|
val kind = type.functionTypeKind
|
||||||
|
if (!kind.withPrettyRender()) {
|
||||||
|
type.renderType()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type.isMarkedNullable) {
|
||||||
|
builder.append("(")
|
||||||
|
}
|
||||||
|
if (kind == FunctionClassKind.SuspendFunction) {
|
||||||
|
builder.append("suspend ")
|
||||||
|
}
|
||||||
|
val typeArguments = type.typeArguments
|
||||||
|
val isExtension = type.isExtensionFunctionType
|
||||||
|
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) {
|
||||||
|
receiver.render()
|
||||||
|
builder.append(".")
|
||||||
|
}
|
||||||
|
builder.append("(")
|
||||||
|
for ((index, argument) in arguments.withIndex()) {
|
||||||
|
if (index != 0) {
|
||||||
|
builder.append(", ")
|
||||||
|
}
|
||||||
|
argument.render()
|
||||||
|
}
|
||||||
|
builder.append(") -> ")
|
||||||
|
returnType.render()
|
||||||
|
if (type.isMarkedNullable) {
|
||||||
|
builder.append(")?")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
private fun FunctionClassKind?.withPrettyRender(): Boolean {
|
||||||
|
contract {
|
||||||
|
returns(true) implies (this@withPrettyRender != null)
|
||||||
|
}
|
||||||
|
return this != null && this != FunctionClassKind.KSuspendFunction && this != FunctionClassKind.KFunction
|
||||||
|
}
|
||||||
|
|
||||||
|
fun render(type: ConeKotlinType) {
|
||||||
|
if (type !is ConeFlexibleType && type !is ConeDefinitelyNotNullType) {
|
||||||
|
// We don't render attributes for flexible/definitely not null types here,
|
||||||
|
// because bounds duplicate these attributes often
|
||||||
|
type.renderAttributes()
|
||||||
|
}
|
||||||
|
when (type) {
|
||||||
|
is ConeTypeVariableType -> {
|
||||||
|
builder.append("TypeVariable(")
|
||||||
|
builder.append(type.lookupTag.name)
|
||||||
|
builder.append(")")
|
||||||
|
}
|
||||||
|
is ConeDefinitelyNotNullType -> {
|
||||||
|
render(type.original)
|
||||||
|
builder.append(" & Any")
|
||||||
|
}
|
||||||
|
is ConeErrorType -> {
|
||||||
|
builder.append("ERROR CLASS: ${type.diagnostic.reason}")
|
||||||
|
}
|
||||||
|
is ConeCapturedType -> {
|
||||||
|
builder.append("CapturedType(")
|
||||||
|
type.constructor.projection.render()
|
||||||
|
builder.append(")")
|
||||||
|
}
|
||||||
|
is ConeClassLikeType -> {
|
||||||
|
type.render()
|
||||||
|
}
|
||||||
|
is ConeLookupTagBasedType -> {
|
||||||
|
builder.append(type.lookupTag.name.asString())
|
||||||
|
}
|
||||||
|
is ConeDynamicType -> {
|
||||||
|
builder.append("dynamic")
|
||||||
|
}
|
||||||
|
is ConeFlexibleType -> {
|
||||||
|
type.render()
|
||||||
|
}
|
||||||
|
is ConeIntersectionType -> {
|
||||||
|
builder.append("it(")
|
||||||
|
for ((index, intersected) in type.intersectedTypes.withIndex()) {
|
||||||
|
if (index > 0) {
|
||||||
|
builder.append(" & ")
|
||||||
|
}
|
||||||
|
render(intersected)
|
||||||
|
}
|
||||||
|
builder.append(")")
|
||||||
|
}
|
||||||
|
is ConeStubTypeForSyntheticFixation -> {
|
||||||
|
builder.append("Stub (fixation): ${type.constructor.variable}")
|
||||||
|
}
|
||||||
|
is ConeStubTypeForChainInference -> {
|
||||||
|
builder.append("Stub (chain inference): ${type.constructor.variable}")
|
||||||
|
}
|
||||||
|
is ConeStubType -> {
|
||||||
|
builder.append("Stub (subtyping): ${type.constructor.variable}")
|
||||||
|
}
|
||||||
|
is ConeIntegerLiteralConstantType -> {
|
||||||
|
builder.append("ILT: ${type.value}")
|
||||||
|
}
|
||||||
|
is ConeIntegerConstantOperatorType -> {
|
||||||
|
builder.append("IOT")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (type !is ConeFlexibleType && type !is ConeErrorType) {
|
||||||
|
builder.append(type.nullability.suffix)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ConeClassLikeType.render() {
|
||||||
|
lookupTag.classId.render()
|
||||||
|
if (typeArguments.isEmpty()) return
|
||||||
|
builder.append("<")
|
||||||
|
for ((index, typeArgument) in typeArguments.withIndex()) {
|
||||||
|
if (index > 0) {
|
||||||
|
builder.append(", ")
|
||||||
|
}
|
||||||
|
typeArgument.render()
|
||||||
|
}
|
||||||
|
builder.append(">")
|
||||||
|
}
|
||||||
|
|
||||||
|
protected open fun ClassId.render() {
|
||||||
|
builder.append(relativeClassName.asString())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ConeFlexibleType.render() {
|
||||||
|
val lowerBound = lowerBound
|
||||||
|
val upperBound = upperBound
|
||||||
|
if (lowerBound is ConeLookupTagBasedType && upperBound is ConeLookupTagBasedType &&
|
||||||
|
lowerBound.lookupTag == upperBound.lookupTag &&
|
||||||
|
lowerBound.nullability == ConeNullability.NOT_NULL && upperBound.nullability == ConeNullability.NULLABLE
|
||||||
|
) {
|
||||||
|
if (lowerBound !is ConeClassLikeType || lowerBound.typeArguments.isEmpty()) {
|
||||||
|
if (upperBound !is ConeClassLikeType || upperBound.typeArguments.isEmpty()) {
|
||||||
|
render(lowerBound)
|
||||||
|
builder.append("!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
builder.append("ft<")
|
||||||
|
render(lowerBound)
|
||||||
|
builder.append(", ")
|
||||||
|
render(upperBound)
|
||||||
|
builder.append(">")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ConeKotlinType.renderAttributes() {
|
||||||
|
if (!attributes.any()) return
|
||||||
|
builder.append(attributes.joinToString(" ", postfix = " ") { it.toString() })
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ConeTypeProjection.render() {
|
||||||
|
when (this) {
|
||||||
|
ConeStarProjection -> {
|
||||||
|
builder.append("*")
|
||||||
|
}
|
||||||
|
is ConeKotlinTypeConflictingProjection -> {
|
||||||
|
builder.append("CONFLICTING-PROJECTION ")
|
||||||
|
render(type)
|
||||||
|
}
|
||||||
|
is ConeKotlinTypeProjectionIn -> {
|
||||||
|
builder.append("in ")
|
||||||
|
render(type)
|
||||||
|
}
|
||||||
|
is ConeKotlinTypeProjectionOut -> {
|
||||||
|
builder.append("out ")
|
||||||
|
render(type)
|
||||||
|
}
|
||||||
|
is ConeKotlinType -> {
|
||||||
|
render(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.fir.renderer
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
|
import org.jetbrains.kotlin.fir.types.ConeTypeProjection
|
||||||
|
|
||||||
|
class ConeTypeRendererForDebugging(builder: StringBuilder) : ConeTypeRendererWithFqNames(builder) {
|
||||||
|
override fun renderAsPossibleFunctionType(type: ConeKotlinType, renderType: ConeTypeProjection.() -> Unit) {
|
||||||
|
builder.append("R|")
|
||||||
|
super.renderAsPossibleFunctionType(type, renderType)
|
||||||
|
builder.append("|")
|
||||||
|
}
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.fir.renderer
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
|
|
||||||
|
open class ConeTypeRendererWithFqNames(builder: StringBuilder) : ConeTypeRenderer(builder) {
|
||||||
|
override fun ClassId.render() {
|
||||||
|
builder.append(asString())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,10 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.types
|
package org.jetbrains.kotlin.fir.types
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
|
||||||
|
import org.jetbrains.kotlin.fir.renderer.ConeTypeRenderer
|
||||||
|
import org.jetbrains.kotlin.fir.renderer.ConeTypeRendererForDebugging
|
||||||
|
import org.jetbrains.kotlin.fir.renderer.ConeTypeRendererWithFqNames
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
@@ -107,3 +111,30 @@ fun ConeClassLikeType.replaceArgumentsWithStarProjections(): ConeClassLikeType {
|
|||||||
val newArguments = Array(typeArguments.size) { ConeStarProjection }
|
val newArguments = Array(typeArguments.size) { ConeStarProjection }
|
||||||
return withArguments(newArguments)
|
return withArguments(newArguments)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val ConeKotlinType?.functionTypeKind: FunctionClassKind?
|
||||||
|
get() {
|
||||||
|
val classId = (this as? ConeClassLikeType)?.lookupTag?.classId ?: return null
|
||||||
|
return FunctionClassKind.getFunctionalClassKind(
|
||||||
|
classId.shortClassName.asString(), classId.packageFqName
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ConeKotlinType.renderForDebugging(): String {
|
||||||
|
val builder = StringBuilder()
|
||||||
|
ConeTypeRendererForDebugging(builder).render(this)
|
||||||
|
return builder.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ConeKotlinType.renderReadable(): String {
|
||||||
|
val builder = StringBuilder()
|
||||||
|
ConeTypeRenderer(builder).render(this)
|
||||||
|
return builder.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ConeKotlinType.renderReadableWithFqNames(): String {
|
||||||
|
val builder = StringBuilder()
|
||||||
|
ConeTypeRendererWithFqNames(builder).render(this)
|
||||||
|
return builder.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ sealed class ConeKotlinType : ConeKotlinTypeProjection(), KotlinTypeMarker, Type
|
|||||||
abstract val attributes: ConeAttributes
|
abstract val attributes: ConeAttributes
|
||||||
|
|
||||||
final override fun toString(): String {
|
final override fun toString(): String {
|
||||||
return render()
|
return renderForDebugging()
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract override fun equals(other: Any?): Boolean
|
abstract override fun equals(other: Any?): Boolean
|
||||||
@@ -160,7 +160,7 @@ data class ConeCapturedType(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int {
|
override fun hashCode(): Int {
|
||||||
var result = 0
|
var result = 7
|
||||||
result = 31 * result + (lowerType?.hashCode() ?: 0)
|
result = 31 * result + (lowerType?.hashCode() ?: 0)
|
||||||
result = 31 * result + constructor.projection.hashCode()
|
result = 31 * result + constructor.projection.hashCode()
|
||||||
result = 31 * result + constructor.typeParameterMarker.hashCode()
|
result = 31 * result + constructor.typeParameterMarker.hashCode()
|
||||||
|
|||||||
@@ -1,129 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.fir.types
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
|
|
||||||
import kotlin.contracts.ExperimentalContracts
|
|
||||||
import kotlin.contracts.contract
|
|
||||||
|
|
||||||
fun ConeKotlinType.render(renderFqNames: Boolean = true): String {
|
|
||||||
val nullabilitySuffix = if (this !is ConeFlexibleType && this !is ConeErrorType) nullability.suffix else ""
|
|
||||||
return when (this) {
|
|
||||||
is ConeTypeVariableType -> "${renderAttributes()}TypeVariable(${this.lookupTag.name})"
|
|
||||||
is ConeDefinitelyNotNullType -> "${original.render(renderFqNames)} & Any"
|
|
||||||
is ConeErrorType -> "${renderAttributes()}ERROR CLASS: ${diagnostic.reason}"
|
|
||||||
is ConeCapturedType -> "${renderAttributes()}CapturedType(${constructor.projection.render(renderFqNames)})"
|
|
||||||
is ConeClassLikeType -> {
|
|
||||||
buildString {
|
|
||||||
append(renderAttributes())
|
|
||||||
if (renderFqNames) {
|
|
||||||
append(lookupTag.classId.asString())
|
|
||||||
} else {
|
|
||||||
append(lookupTag.classId.relativeClassName.asString())
|
|
||||||
}
|
|
||||||
if (typeArguments.isNotEmpty()) {
|
|
||||||
append(typeArguments.joinToString(prefix = "<", postfix = ">") {
|
|
||||||
it.render(renderFqNames)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is ConeLookupTagBasedType -> {
|
|
||||||
"${renderAttributes()}${lookupTag.name.asString()}"
|
|
||||||
}
|
|
||||||
is ConeDynamicType -> "dynamic"
|
|
||||||
is ConeFlexibleType -> this.render(renderFqNames)
|
|
||||||
is ConeIntersectionType -> {
|
|
||||||
intersectedTypes.joinToString(
|
|
||||||
separator = " & ",
|
|
||||||
prefix = "${renderAttributes()}it(",
|
|
||||||
postfix = ")"
|
|
||||||
) {
|
|
||||||
it.render(renderFqNames)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is ConeStubTypeForSyntheticFixation -> "${renderAttributes()}Stub (fixation): ${constructor.variable}"
|
|
||||||
is ConeStubTypeForChainInference -> "${renderAttributes()}Stub (chain inference): ${constructor.variable}"
|
|
||||||
is ConeStubType -> "${renderAttributes()}Stub (subtyping): ${constructor.variable}"
|
|
||||||
is ConeIntegerLiteralConstantType -> "${renderAttributes()}ILT: $value"
|
|
||||||
is ConeIntegerConstantOperatorType -> "${renderAttributes()}IOT"
|
|
||||||
} + nullabilitySuffix
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun ConeFlexibleType.render(renderFqNames: Boolean): String {
|
|
||||||
if (lowerBound is ConeLookupTagBasedType && upperBound is ConeLookupTagBasedType &&
|
|
||||||
lowerBound.lookupTag == upperBound.lookupTag &&
|
|
||||||
lowerBound.nullability == ConeNullability.NOT_NULL && upperBound.nullability == ConeNullability.NULLABLE
|
|
||||||
) {
|
|
||||||
if (lowerBound !is ConeClassLikeType || lowerBound.typeArguments.isEmpty()) {
|
|
||||||
if (upperBound !is ConeClassLikeType || upperBound.typeArguments.isEmpty()) {
|
|
||||||
return buildString {
|
|
||||||
append(lowerBound.render(renderFqNames))
|
|
||||||
append("!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return buildString {
|
|
||||||
append("ft<")
|
|
||||||
append(lowerBound.render(renderFqNames))
|
|
||||||
append(", ")
|
|
||||||
append(upperBound.render(renderFqNames))
|
|
||||||
append(">")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun ConeKotlinType.renderAttributes(): String {
|
|
||||||
if (!attributes.any()) return ""
|
|
||||||
return attributes.joinToString(" ", postfix = " ") { it.toString() }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun ConeTypeProjection.render(renderFqNames: Boolean): String {
|
|
||||||
return when (this) {
|
|
||||||
ConeStarProjection -> "*"
|
|
||||||
is ConeKotlinTypeConflictingProjection -> "CONFLICTING-PROJECTION ${type.render(renderFqNames)}"
|
|
||||||
is ConeKotlinTypeProjectionIn -> "in ${type.render(renderFqNames)}"
|
|
||||||
is ConeKotlinTypeProjectionOut -> "out ${type.render(renderFqNames)}"
|
|
||||||
is ConeKotlinType -> render(renderFqNames)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun ConeKotlinType.renderFunctionType(
|
|
||||||
kind: FunctionClassKind?, renderFqNames: Boolean, renderType: ConeTypeProjection.() -> String = { render(renderFqNames) }
|
|
||||||
): String {
|
|
||||||
if (!kind.withPrettyRender()) return renderType()
|
|
||||||
|
|
||||||
val isExtension = isExtensionFunctionType
|
|
||||||
|
|
||||||
val renderedType = buildString {
|
|
||||||
if (kind == FunctionClassKind.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.renderType())
|
|
||||||
append(".")
|
|
||||||
}
|
|
||||||
append(arguments.joinToString(", ", "(", ")") { it.renderType() })
|
|
||||||
append(" -> ")
|
|
||||||
append(returnType.renderType())
|
|
||||||
}
|
|
||||||
return if (isMarkedNullable) "($renderedType)?" else renderedType
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(ExperimentalContracts::class)
|
|
||||||
fun FunctionClassKind?.withPrettyRender(): Boolean {
|
|
||||||
contract {
|
|
||||||
returns(true) implies (this@withPrettyRender != null)
|
|
||||||
}
|
|
||||||
return this != null && this != FunctionClassKind.KSuspendFunction && this != FunctionClassKind.KFunction
|
|
||||||
}
|
|
||||||
+3
-3
@@ -685,15 +685,15 @@ class FirElementSerializer private constructor(
|
|||||||
typeApproximator.approximateToSubType(type, TypeApproximatorConfiguration.PublicDeclaration)
|
typeApproximator.approximateToSubType(type, TypeApproximatorConfiguration.PublicDeclaration)
|
||||||
}
|
}
|
||||||
assert(approximatedType != type && approximatedType is ConeKotlinType) {
|
assert(approximatedType != type && approximatedType is ConeKotlinType) {
|
||||||
"Approximation failed: ${type.render()}"
|
"Approximation failed: ${type.renderForDebugging()}"
|
||||||
}
|
}
|
||||||
return typeProto(approximatedType as ConeKotlinType)
|
return typeProto(approximatedType as ConeKotlinType)
|
||||||
}
|
}
|
||||||
is ConeIntegerLiteralType -> {
|
is ConeIntegerLiteralType -> {
|
||||||
throw IllegalStateException("Integer literal types should not persist up to the serializer: ${type.render()}")
|
throw IllegalStateException("Integer literal types should not persist up to the serializer: ${type.renderForDebugging()}")
|
||||||
}
|
}
|
||||||
is ConeCapturedType -> {
|
is ConeCapturedType -> {
|
||||||
throw IllegalStateException("Captured types should not persist up to the serializer: ${type.render()}")
|
throw IllegalStateException("Captured types should not persist up to the serializer: ${type.renderForDebugging()}")
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
throw AssertionError("Should not be here: ${type::class.java}")
|
throw AssertionError("Should not be here: ${type::class.java}")
|
||||||
|
|||||||
+1
-1
@@ -121,7 +121,7 @@ class FirJvmTypeMapper(val session: FirSession) : TypeMappingContext<JvmSignatur
|
|||||||
val toIndex = firClass.typeParameters.count { it is FirTypeParameter } + index
|
val toIndex = firClass.typeParameters.count { it is FirTypeParameter } + index
|
||||||
if (!firClass.isInner) {
|
if (!firClass.isInner) {
|
||||||
assert(toIndex == typeArguments.size || firClass.isLocal) {
|
assert(toIndex == typeArguments.size || firClass.isLocal) {
|
||||||
"${typeArguments.size - toIndex} trailing arguments were found in this type: ${render()}"
|
"${typeArguments.size - toIndex} trailing arguments were found in this type: ${renderForDebugging()}"
|
||||||
}
|
}
|
||||||
return PossiblyInnerConeType(classifier, typeArguments.toList().subList(index, typeArguments.size), null)
|
return PossiblyInnerConeType(classifier, typeArguments.toList().subList(index, typeArguments.size), null)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -519,7 +519,7 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
|
|||||||
override fun KotlinTypeMarker.getFunctionalTypeFromSupertypes(): KotlinTypeMarker {
|
override fun KotlinTypeMarker.getFunctionalTypeFromSupertypes(): KotlinTypeMarker {
|
||||||
require(this is ConeKotlinType)
|
require(this is ConeKotlinType)
|
||||||
assert(this.isBuiltinFunctionalTypeOrSubtype()) {
|
assert(this.isBuiltinFunctionalTypeOrSubtype()) {
|
||||||
"Not a function type or subtype: ${this.render()}"
|
"Not a function type or subtype: ${this.renderForDebugging()}"
|
||||||
}
|
}
|
||||||
|
|
||||||
return fullyExpandedType(session).let {
|
return fullyExpandedType(session).let {
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ fun <T : ConeKotlinType> T.withArguments(arguments: Array<out ConeTypeProjection
|
|||||||
is ConeErrorType -> this
|
is ConeErrorType -> this
|
||||||
is ConeClassLikeTypeImpl -> ConeClassLikeTypeImpl(lookupTag, arguments, nullability.isNullable) as T
|
is ConeClassLikeTypeImpl -> ConeClassLikeTypeImpl(lookupTag, arguments, nullability.isNullable) as T
|
||||||
is ConeDefinitelyNotNullType -> ConeDefinitelyNotNullType(original.withArguments(arguments)) as T
|
is ConeDefinitelyNotNullType -> ConeDefinitelyNotNullType(original.withArguments(arguments)) as T
|
||||||
else -> error("Not supported: $this: ${this.render()}")
|
else -> error("Not supported: $this: ${this.renderForDebugging()}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,7 +154,7 @@ fun <T : ConeKotlinType> T.withAttributes(attributes: ConeAttributes): T {
|
|||||||
// Attributes for stub types are not supported, and it's not obvious if it should
|
// Attributes for stub types are not supported, and it's not obvious if it should
|
||||||
is ConeStubType -> this
|
is ConeStubType -> this
|
||||||
is ConeIntegerLiteralType -> this
|
is ConeIntegerLiteralType -> this
|
||||||
else -> error("Not supported: $this: ${this.render()}")
|
else -> error("Not supported: $this: ${this.renderForDebugging()}")
|
||||||
} as T
|
} as T
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -33,7 +33,7 @@ class TotalKotlinTest : AbstractRawFirBuilderTestCase() {
|
|||||||
DebugUtil.psiTreeToString(ktFile, false)
|
DebugUtil.psiTreeToString(ktFile, false)
|
||||||
} else {
|
} else {
|
||||||
val firFile = ktFile.toFirFile()
|
val firFile = ktFile.toFirFile()
|
||||||
StringBuilder().also { FirRenderer(it).visitFile(firFile) }.toString()
|
StringBuilder().also { FirRenderer(it).Visitor().visitFile(firFile) }.toString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ class TotalKotlinTest : AbstractRawFirBuilderTestCase() {
|
|||||||
DebugUtil.lightTreeToString(lightTree, false)
|
DebugUtil.lightTreeToString(lightTree, false)
|
||||||
} else {
|
} else {
|
||||||
val firFile = converter.buildFirFile(text, sourceFile, linesMapping)
|
val firFile = converter.buildFirFile(text, sourceFile, linesMapping)
|
||||||
StringBuilder().also { FirRenderer(it).visitFile(firFile) }.toString()
|
StringBuilder().also { FirRenderer(it).Visitor().visitFile(firFile) }.toString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -72,12 +72,12 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
|
|||||||
//psi
|
//psi
|
||||||
val ktFile = createPsiFile(FileUtil.getNameWithoutExtension(PathUtil.getFileName(file.path)), text.toString().trim()) as KtFile
|
val ktFile = createPsiFile(FileUtil.getNameWithoutExtension(PathUtil.getFileName(file.path)), text.toString().trim()) as KtFile
|
||||||
val firFileFromPsi = ktFile.toFirFile()
|
val firFileFromPsi = ktFile.toFirFile()
|
||||||
val treeFromPsi = StringBuilder().also { FirRenderer(it).visitFile(firFileFromPsi) }.toString()
|
val treeFromPsi = StringBuilder().also { FirRenderer(it).Visitor().visitFile(firFileFromPsi) }.toString()
|
||||||
.replace("<ERROR TYPE REF:.*?>".toRegex(), "<ERROR TYPE REF>")
|
.replace("<ERROR TYPE REF:.*?>".toRegex(), "<ERROR TYPE REF>")
|
||||||
|
|
||||||
//light tree
|
//light tree
|
||||||
val firFileFromLightTree = lightTreeConverter.buildFirFile(text, KtIoFileSourceFile(file), linesMapping)
|
val firFileFromLightTree = lightTreeConverter.buildFirFile(text, KtIoFileSourceFile(file), linesMapping)
|
||||||
val treeFromLightTree = StringBuilder().also { FirRenderer(it).visitFile(firFileFromLightTree) }.toString()
|
val treeFromLightTree = StringBuilder().also { FirRenderer(it).Visitor().visitFile(firFileFromLightTree) }.toString()
|
||||||
.replace("<ERROR TYPE REF:.*?>".toRegex(), "<ERROR TYPE REF>")
|
.replace("<ERROR TYPE REF:.*?>".toRegex(), "<ERROR TYPE REF>")
|
||||||
|
|
||||||
return@compareBase treeFromLightTree == treeFromPsi
|
return@compareBase treeFromLightTree == treeFromPsi
|
||||||
@@ -104,7 +104,7 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
|
|||||||
//psi
|
//psi
|
||||||
val ktFile = createPsiFile(FileUtil.getNameWithoutExtension(PathUtil.getFileName(file.path)), text) as KtFile
|
val ktFile = createPsiFile(FileUtil.getNameWithoutExtension(PathUtil.getFileName(file.path)), text) as KtFile
|
||||||
val firFileFromPsi = ktFile.toFirFile()
|
val firFileFromPsi = ktFile.toFirFile()
|
||||||
val treeFromPsi = StringBuilder().also { FirRenderer(it).visitFile(firFileFromPsi) }.toString()
|
val treeFromPsi = StringBuilder().also { FirRenderer(it).Visitor().visitFile(firFileFromPsi) }.toString()
|
||||||
.replace("<Unsupported LValue.*?>".toRegex(), "<Unsupported LValue>")
|
.replace("<Unsupported LValue.*?>".toRegex(), "<Unsupported LValue>")
|
||||||
.replace("<ERROR TYPE REF:.*?>".toRegex(), "<ERROR TYPE REF>")
|
.replace("<ERROR TYPE REF:.*?>".toRegex(), "<ERROR TYPE REF>")
|
||||||
|
|
||||||
@@ -115,7 +115,7 @@ class TreesCompareTest : AbstractRawFirBuilderTestCase() {
|
|||||||
KtInMemoryTextSourceFile(file.name, file.path, text),
|
KtInMemoryTextSourceFile(file.name, file.path, text),
|
||||||
text.toSourceLinesMapping()
|
text.toSourceLinesMapping()
|
||||||
)
|
)
|
||||||
val treeFromLightTree = StringBuilder().also { FirRenderer(it).visitFile(firFileFromLightTree) }.toString()
|
val treeFromLightTree = StringBuilder().also { FirRenderer(it).Visitor().visitFile(firFileFromLightTree) }.toString()
|
||||||
.replace("<Unsupported LValue.*?>".toRegex(), "<Unsupported LValue>")
|
.replace("<Unsupported LValue.*?>".toRegex(), "<Unsupported LValue>")
|
||||||
.replace("<ERROR TYPE REF:.*?>".toRegex(), "<ERROR TYPE REF>")
|
.replace("<ERROR TYPE REF:.*?>".toRegex(), "<ERROR TYPE REF>")
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -13,7 +13,7 @@ abstract class AbstractRawFirBuilderLazyBodiesTestCase : AbstractRawFirBuilderTe
|
|||||||
override fun doRawFirTest(filePath: String) {
|
override fun doRawFirTest(filePath: String) {
|
||||||
val file = createKtFile(filePath)
|
val file = createKtFile(filePath)
|
||||||
val firFile = file.toFirFile(BodyBuildingMode.LAZY_BODIES)
|
val firFile = file.toFirFile(BodyBuildingMode.LAZY_BODIES)
|
||||||
val firFileDump = StringBuilder().also { FirRenderer(it).visitFile(firFile) }.toString()
|
val firFileDump = StringBuilder().also { FirRenderer(it).Visitor().visitFile(firFile) }.toString()
|
||||||
val expectedPath = filePath.replace(".kt", ".lazyBodies.txt")
|
val expectedPath = filePath.replace(".kt", ".lazyBodies.txt")
|
||||||
KotlinTestUtils.assertEqualsToFile(File(expectedPath), firFileDump)
|
KotlinTestUtils.assertEqualsToFile(File(expectedPath), firFileDump)
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-2
@@ -65,7 +65,9 @@ abstract class AbstractRawFirBuilderTestCase : KtParsingTestCase(
|
|||||||
protected open fun doRawFirTest(filePath: String) {
|
protected open fun doRawFirTest(filePath: String) {
|
||||||
val file = createKtFile(filePath)
|
val file = createKtFile(filePath)
|
||||||
val firFile = file.toFirFile(BodyBuildingMode.NORMAL)
|
val firFile = file.toFirFile(BodyBuildingMode.NORMAL)
|
||||||
val firFileDump = StringBuilder().also { FirRenderer(it, mode = FirRenderer.RenderMode.WithDeclarationAttributes).visitFile(firFile) }.toString()
|
val firFileDump = StringBuilder().also {
|
||||||
|
FirRenderer(it, mode = FirRenderer.RenderMode.WithDeclarationAttributes).Visitor().visitFile(firFile)
|
||||||
|
}.toString()
|
||||||
val expectedPath = filePath.replace(".kt", ".txt")
|
val expectedPath = filePath.replace(".kt", ".txt")
|
||||||
KotlinTestUtils.assertEqualsToFile(File(expectedPath), firFileDump)
|
KotlinTestUtils.assertEqualsToFile(File(expectedPath), firFileDump)
|
||||||
}
|
}
|
||||||
@@ -191,7 +193,7 @@ private fun throwTwiceVisitingError(element: FirElement) {
|
|||||||
if (psiParent is KtPropertyDelegate || psiParent?.parent is KtPropertyDelegate) return
|
if (psiParent is KtPropertyDelegate || psiParent?.parent is KtPropertyDelegate) return
|
||||||
}
|
}
|
||||||
|
|
||||||
val elementDump = StringBuilder().also { element.accept(FirRenderer(it)) }.toString()
|
val elementDump = StringBuilder().also { element.accept(FirRenderer(it).Visitor()) }.toString()
|
||||||
throw AssertionError("FirElement ${element.javaClass} is visited twice: $elementDump")
|
throw AssertionError("FirElement ${element.javaClass} is visited twice: $elementDump")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -65,7 +65,7 @@ class RawFirBuilderTotalKotlinTestCase : AbstractRawFirBuilderTestCase() {
|
|||||||
time += measureNanoTime {
|
time += measureNanoTime {
|
||||||
firFile = ktFile.toFirFile()
|
firFile = ktFile.toFirFile()
|
||||||
}
|
}
|
||||||
totalLength += StringBuilder().also { FirRenderer(it).visitFile(firFile) }.length
|
totalLength += StringBuilder().also { FirRenderer(it).Visitor().visitFile(firFile) }.length
|
||||||
counter++
|
counter++
|
||||||
firFile.accept(object : FirVisitorVoid() {
|
firFile.accept(object : FirVisitorVoid() {
|
||||||
override fun visitElement(element: FirElement) {
|
override fun visitElement(element: FirElement) {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ abstract class FirLookupTrackerComponent : FirSessionComponent {
|
|||||||
|
|
||||||
fun FirLookupTrackerComponent.recordCallLookup(callInfo: AbstractCallInfo, inType: ConeKotlinType) {
|
fun FirLookupTrackerComponent.recordCallLookup(callInfo: AbstractCallInfo, inType: ConeKotlinType) {
|
||||||
if (inType.classId?.isLocal == true) return
|
if (inType.classId?.isLocal == true) return
|
||||||
val scopes = SmartList(inType.render().replace('/', '.'))
|
val scopes = SmartList(inType.renderForDebugging().replace('/', '.'))
|
||||||
if (inType.classId?.shortClassName?.asString() == "Companion") {
|
if (inType.classId?.shortClassName?.asString() == "Companion") {
|
||||||
scopes.add(inType.classId!!.outerClassId!!.asString().replace('/', '.'))
|
scopes.add(inType.classId!!.outerClassId!!.asString().replace('/', '.'))
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
|
|||||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||||
|
import org.jetbrains.kotlin.fir.types.renderForDebugging
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
|
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
|
||||||
|
|||||||
+3
-1
@@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.contracts.description
|
package org.jetbrains.kotlin.fir.contracts.description
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.fir.types.renderForDebugging
|
||||||
|
|
||||||
class ConeContractRenderer(private val builder: StringBuilder) : ConeContractDescriptionVisitor<Unit, Nothing?>() {
|
class ConeContractRenderer(private val builder: StringBuilder) : ConeContractDescriptionVisitor<Unit, Nothing?>() {
|
||||||
override fun visitConditionalEffectDeclaration(conditionalEffect: ConeConditionalEffectDeclaration, data: Nothing?) {
|
override fun visitConditionalEffectDeclaration(conditionalEffect: ConeConditionalEffectDeclaration, data: Nothing?) {
|
||||||
conditionalEffect.effect.accept(this, data)
|
conditionalEffect.effect.accept(this, data)
|
||||||
@@ -37,7 +39,7 @@ class ConeContractRenderer(private val builder: StringBuilder) : ConeContractDes
|
|||||||
|
|
||||||
override fun visitIsInstancePredicate(isInstancePredicate: ConeIsInstancePredicate, data: Nothing?) {
|
override fun visitIsInstancePredicate(isInstancePredicate: ConeIsInstancePredicate, data: Nothing?) {
|
||||||
isInstancePredicate.arg.accept(this, data)
|
isInstancePredicate.arg.accept(this, data)
|
||||||
builder.append(" ${if (isInstancePredicate.isNegated) "!" else ""}is ${isInstancePredicate.type}")
|
builder.append(" ${if (isInstancePredicate.isNegated) "!" else ""}is ${isInstancePredicate.type.renderForDebugging()}")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitIsNullPredicate(isNullPredicate: ConeIsNullPredicate, data: Nothing?) {
|
override fun visitIsNullPredicate(isNullPredicate: ConeIsNullPredicate, data: Nothing?) {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ open class FirAnnotationRenderer internal constructor(components: FirRendererCom
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun renderAnnotation(annotation: FirAnnotation) {
|
internal fun renderAnnotation(annotation: FirAnnotation) {
|
||||||
printer.print("@")
|
printer.print("@")
|
||||||
annotation.useSiteTarget?.let {
|
annotation.useSiteTarget?.let {
|
||||||
printer.print(it.name)
|
printer.print(it.name)
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class FirBodyRenderer internal constructor(components: FirRendererComponents) :
|
|||||||
if (block == null) return
|
if (block == null) return
|
||||||
when (block) {
|
when (block) {
|
||||||
is FirLazyBlock -> {
|
is FirLazyBlock -> {
|
||||||
println(" { LAZY_BLOCK }")
|
printer.println(" { LAZY_BLOCK }")
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
annotationRenderer?.render(block)
|
annotationRenderer?.render(block)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.fir.renderer
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.utils.Printer
|
import org.jetbrains.kotlin.utils.Printer
|
||||||
|
|
||||||
abstract class FirPrinter internal constructor(builder: StringBuilder) {
|
open class FirPrinter(builder: StringBuilder) {
|
||||||
private val printer = Printer(builder)
|
private val printer = Printer(builder)
|
||||||
|
|
||||||
private var lineBeginning = true
|
private var lineBeginning = true
|
||||||
|
|||||||
@@ -47,6 +47,8 @@ open class FirRenderer private constructor(
|
|||||||
|
|
||||||
override var bodyRenderer: FirBodyRenderer? = null
|
override var bodyRenderer: FirBodyRenderer? = null
|
||||||
|
|
||||||
|
override lateinit var typeRenderer: ConeTypeRenderer
|
||||||
|
|
||||||
override lateinit var visitor: Visitor
|
override lateinit var visitor: Visitor
|
||||||
|
|
||||||
override lateinit var printer: FirPrinter
|
override lateinit var printer: FirPrinter
|
||||||
@@ -154,12 +156,18 @@ open class FirRenderer private constructor(
|
|||||||
else ->
|
else ->
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
private val bodyRenderer = if (mode.renderBodies) FirBodyRenderer(components) else null
|
private val bodyRenderer =
|
||||||
|
if (mode.renderBodies) FirBodyRenderer(components) else null
|
||||||
|
|
||||||
|
@Suppress("LeakingThis")
|
||||||
|
private val typeRenderer =
|
||||||
|
if (mode.renderDetailedTypeReferences) ConeTypeRendererForDebugging(builder) else ConeTypeRenderer(builder)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
components.visitor = visitor
|
components.visitor = visitor
|
||||||
components.annotationRenderer = annotationRenderer
|
components.annotationRenderer = annotationRenderer
|
||||||
components.bodyRenderer = bodyRenderer
|
components.bodyRenderer = bodyRenderer
|
||||||
|
components.typeRenderer = typeRenderer
|
||||||
@Suppress("LeakingThis")
|
@Suppress("LeakingThis")
|
||||||
components.printer = this
|
components.printer = this
|
||||||
}
|
}
|
||||||
@@ -188,7 +196,7 @@ open class FirRenderer private constructor(
|
|||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
print(", ")
|
print(", ")
|
||||||
}
|
}
|
||||||
print(element.render())
|
print(element.renderForDebugging())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,6 +326,10 @@ open class FirRenderer private constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun renderAnnotations(annotationContainer: FirAnnotationContainer) {
|
||||||
|
annotationRenderer?.render(annotationContainer)
|
||||||
|
}
|
||||||
|
|
||||||
protected open fun renderClassDeclarations(regularClass: FirRegularClass) {
|
protected open fun renderClassDeclarations(regularClass: FirRegularClass) {
|
||||||
if (mode.renderNestedDeclarations) {
|
if (mode.renderNestedDeclarations) {
|
||||||
regularClass.declarations.renderDeclarations()
|
regularClass.declarations.renderDeclarations()
|
||||||
@@ -346,6 +358,14 @@ open class FirRenderer private constructor(
|
|||||||
popIndent()
|
popIndent()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun visitAnnotation(annotation: FirAnnotation) {
|
||||||
|
annotationRenderer?.renderAnnotation(annotation)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitAnnotationCall(annotationCall: FirAnnotationCall) {
|
||||||
|
annotationRenderer?.renderAnnotation(annotationCall)
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitCallableDeclaration(callableDeclaration: FirCallableDeclaration) {
|
override fun visitCallableDeclaration(callableDeclaration: FirCallableDeclaration) {
|
||||||
renderContexts(callableDeclaration.contextReceivers)
|
renderContexts(callableDeclaration.contextReceivers)
|
||||||
annotationRenderer?.render(callableDeclaration)
|
annotationRenderer?.render(callableDeclaration)
|
||||||
@@ -603,7 +623,7 @@ open class FirRenderer private constructor(
|
|||||||
constructor.renderDeclarationData()
|
constructor.renderDeclarationData()
|
||||||
|
|
||||||
constructor.dispatchReceiverType?.let {
|
constructor.dispatchReceiverType?.let {
|
||||||
print(it.render())
|
typeRenderer.render(it)
|
||||||
print(".")
|
print(".")
|
||||||
}
|
}
|
||||||
print("constructor")
|
print("constructor")
|
||||||
@@ -1051,15 +1071,7 @@ open class FirRenderer private constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitResolvedTypeRef(resolvedTypeRef: FirResolvedTypeRef) {
|
override fun visitResolvedTypeRef(resolvedTypeRef: FirResolvedTypeRef) {
|
||||||
val kind = resolvedTypeRef.functionTypeKind
|
typeRenderer.renderAsPossibleFunctionType(resolvedTypeRef.type)
|
||||||
if (mode.renderDetailedTypeReferences) {
|
|
||||||
print("R|")
|
|
||||||
}
|
|
||||||
val coneType = resolvedTypeRef.type
|
|
||||||
print(coneType.renderFunctionType(kind, renderFqNames = mode.renderDetailedTypeReferences))
|
|
||||||
if (mode.renderDetailedTypeReferences) {
|
|
||||||
print("|")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitUserTypeRef(userTypeRef: FirUserTypeRef) {
|
override fun visitUserTypeRef(userTypeRef: FirUserTypeRef) {
|
||||||
|
|||||||
@@ -10,4 +10,5 @@ internal interface FirRendererComponents {
|
|||||||
val printer: FirPrinter
|
val printer: FirPrinter
|
||||||
val annotationRenderer: FirAnnotationRenderer?
|
val annotationRenderer: FirAnnotationRenderer?
|
||||||
val bodyRenderer: FirBodyRenderer?
|
val bodyRenderer: FirBodyRenderer?
|
||||||
|
val typeRenderer: ConeTypeRenderer
|
||||||
}
|
}
|
||||||
@@ -75,13 +75,13 @@ object ConeKotlinTypeComparator : Comparator<ConeKotlinType> {
|
|||||||
when (a) {
|
when (a) {
|
||||||
is ConeErrorType -> {
|
is ConeErrorType -> {
|
||||||
require(b is ConeErrorType) {
|
require(b is ConeErrorType) {
|
||||||
"priority is inconsistent: ${a.render()} v.s. ${b.render()}"
|
"priority is inconsistent: ${a.renderForDebugging()} v.s. ${b.renderForDebugging()}"
|
||||||
}
|
}
|
||||||
return a.hashCode() - b.hashCode()
|
return a.hashCode() - b.hashCode()
|
||||||
}
|
}
|
||||||
is ConeLookupTagBasedType -> {
|
is ConeLookupTagBasedType -> {
|
||||||
require(b is ConeLookupTagBasedType) {
|
require(b is ConeLookupTagBasedType) {
|
||||||
"priority is inconsistent: ${a.render()} v.s. ${b.render()}"
|
"priority is inconsistent: ${a.renderForDebugging()} v.s. ${b.renderForDebugging()}"
|
||||||
}
|
}
|
||||||
val nameDiff = a.lookupTag.name.compareTo(b.lookupTag.name)
|
val nameDiff = a.lookupTag.name.compareTo(b.lookupTag.name)
|
||||||
if (nameDiff != 0) {
|
if (nameDiff != 0) {
|
||||||
@@ -95,7 +95,7 @@ object ConeKotlinTypeComparator : Comparator<ConeKotlinType> {
|
|||||||
}
|
}
|
||||||
is ConeFlexibleType -> {
|
is ConeFlexibleType -> {
|
||||||
require(b is ConeFlexibleType) {
|
require(b is ConeFlexibleType) {
|
||||||
"priority is inconsistent: ${a.render()} v.s. ${b.render()}"
|
"priority is inconsistent: ${a.renderForDebugging()} v.s. ${b.renderForDebugging()}"
|
||||||
}
|
}
|
||||||
val lowerBoundDiff = compare(a.lowerBound, b.lowerBound)
|
val lowerBoundDiff = compare(a.lowerBound, b.lowerBound)
|
||||||
if (lowerBoundDiff != 0) {
|
if (lowerBoundDiff != 0) {
|
||||||
@@ -105,7 +105,7 @@ object ConeKotlinTypeComparator : Comparator<ConeKotlinType> {
|
|||||||
}
|
}
|
||||||
is ConeCapturedType -> {
|
is ConeCapturedType -> {
|
||||||
require(b is ConeCapturedType) {
|
require(b is ConeCapturedType) {
|
||||||
"priority is inconsistent: ${a.render()} v.s. ${b.render()}"
|
"priority is inconsistent: ${a.renderForDebugging()} v.s. ${b.renderForDebugging()}"
|
||||||
}
|
}
|
||||||
val aHasLowerType = if (a.lowerType != null) 1 else 0
|
val aHasLowerType = if (a.lowerType != null) 1 else 0
|
||||||
val bHasLowerType = if (b.lowerType != null) 1 else 0
|
val bHasLowerType = if (b.lowerType != null) 1 else 0
|
||||||
@@ -127,13 +127,13 @@ object ConeKotlinTypeComparator : Comparator<ConeKotlinType> {
|
|||||||
}
|
}
|
||||||
is ConeDefinitelyNotNullType -> {
|
is ConeDefinitelyNotNullType -> {
|
||||||
require(b is ConeDefinitelyNotNullType) {
|
require(b is ConeDefinitelyNotNullType) {
|
||||||
"priority is inconsistent: ${a.render()} v.s. ${b.render()}"
|
"priority is inconsistent: ${a.renderForDebugging()} v.s. ${b.renderForDebugging()}"
|
||||||
}
|
}
|
||||||
return compare(a.original, b.original)
|
return compare(a.original, b.original)
|
||||||
}
|
}
|
||||||
is ConeIntersectionType -> {
|
is ConeIntersectionType -> {
|
||||||
require(b is ConeIntersectionType) {
|
require(b is ConeIntersectionType) {
|
||||||
"priority is inconsistent: ${a.render()} v.s. ${b.render()}"
|
"priority is inconsistent: ${a.renderForDebugging()} v.s. ${b.renderForDebugging()}"
|
||||||
}
|
}
|
||||||
val sizeDiff = a.intersectedTypes.size - b.intersectedTypes.size
|
val sizeDiff = a.intersectedTypes.size - b.intersectedTypes.size
|
||||||
if (sizeDiff != 0) {
|
if (sizeDiff != 0) {
|
||||||
@@ -144,7 +144,7 @@ object ConeKotlinTypeComparator : Comparator<ConeKotlinType> {
|
|||||||
}
|
}
|
||||||
is ConeStubType -> {
|
is ConeStubType -> {
|
||||||
require(b is ConeStubType) {
|
require(b is ConeStubType) {
|
||||||
"priority is inconsistent: ${a.render()} v.s. ${b.render()}"
|
"priority is inconsistent: ${a.renderForDebugging()} v.s. ${b.renderForDebugging()}"
|
||||||
}
|
}
|
||||||
val nameDiff = a.constructor.variable.typeConstructor.name.compareTo(b.constructor.variable.typeConstructor.name)
|
val nameDiff = a.constructor.variable.typeConstructor.name.compareTo(b.constructor.variable.typeConstructor.name)
|
||||||
if (nameDiff != 0) {
|
if (nameDiff != 0) {
|
||||||
@@ -154,7 +154,7 @@ object ConeKotlinTypeComparator : Comparator<ConeKotlinType> {
|
|||||||
}
|
}
|
||||||
is ConeIntegerLiteralConstantType -> {
|
is ConeIntegerLiteralConstantType -> {
|
||||||
require(b is ConeIntegerLiteralConstantType) {
|
require(b is ConeIntegerLiteralConstantType) {
|
||||||
"priority is inconsistent: ${a.render()} v.s. ${b.render()}"
|
"priority is inconsistent: ${a.renderForDebugging()} v.s. ${b.renderForDebugging()}"
|
||||||
}
|
}
|
||||||
val valueDiff = a.value - b.value
|
val valueDiff = a.value - b.value
|
||||||
if (valueDiff != 0L) {
|
if (valueDiff != 0L) {
|
||||||
@@ -171,7 +171,7 @@ object ConeKotlinTypeComparator : Comparator<ConeKotlinType> {
|
|||||||
return compare(a.nullability, b.nullability)
|
return compare(a.nullability, b.nullability)
|
||||||
}
|
}
|
||||||
else ->
|
else ->
|
||||||
error("Unsupported type comparison: ${a.render()} v.s. ${b.render()}")
|
error("Unsupported type comparison: ${a.renderForDebugging()} v.s. ${b.renderForDebugging()}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
package org.jetbrains.kotlin.fir.types
|
package org.jetbrains.kotlin.fir.types
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.StandardNames
|
import org.jetbrains.kotlin.builtins.StandardNames
|
||||||
import org.jetbrains.kotlin.builtins.functions.FunctionClassKind
|
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
|
import org.jetbrains.kotlin.fir.expressions.FirConstExpression
|
||||||
@@ -15,6 +14,8 @@ import org.jetbrains.kotlin.fir.expressions.FirExpressionWithSmartcast
|
|||||||
import org.jetbrains.kotlin.fir.extensions.extensionService
|
import org.jetbrains.kotlin.fir.extensions.extensionService
|
||||||
import org.jetbrains.kotlin.fir.extensions.typeAttributeExtensions
|
import org.jetbrains.kotlin.fir.extensions.typeAttributeExtensions
|
||||||
import org.jetbrains.kotlin.fir.render
|
import org.jetbrains.kotlin.fir.render
|
||||||
|
import org.jetbrains.kotlin.fir.renderer.ConeTypeRenderer
|
||||||
|
import org.jetbrains.kotlin.fir.renderer.ConeTypeRendererForDebugging
|
||||||
import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef
|
import org.jetbrains.kotlin.fir.types.impl.FirImplicitBuiltinTypeRef
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.StandardClassIds
|
import org.jetbrains.kotlin.name.StandardClassIds
|
||||||
@@ -195,13 +196,3 @@ val ConeKotlinType.canBeNull: Boolean
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val ConeKotlinType?.functionTypeKind: FunctionClassKind?
|
|
||||||
get() {
|
|
||||||
val classId = (this as? ConeClassLikeType)?.lookupTag?.classId ?: return null
|
|
||||||
return FunctionClassKind.getFunctionalClassKind(
|
|
||||||
classId.shortClassName.asString(), classId.packageFqName
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
val FirResolvedTypeRef.functionTypeKind: FunctionClassKind?
|
|
||||||
get() = type.functionTypeKind
|
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ abstract class AbstractKtDiagnosticsTest : AbstractFirBaseDiagnosticsTest() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun checkFir(testDataFile: File, firFiles: List<FirFile>) {
|
fun checkFir(testDataFile: File, firFiles: List<FirFile>) {
|
||||||
val firFileDump = StringBuilder().apply { firFiles.forEach { it.accept(FirRenderer(this), null) } }.toString()
|
val firFileDump = StringBuilder().apply { firFiles.forEach { it.accept(FirRenderer(this).Visitor(), null) } }.toString()
|
||||||
val expectedPath = testDataFile.absolutePath.replace(".kt", ".txt")
|
val expectedPath = testDataFile.absolutePath.replace(".kt", ".txt")
|
||||||
KotlinTestUtils.assertEqualsToFile(
|
KotlinTestUtils.assertEqualsToFile(
|
||||||
File(expectedPath),
|
File(expectedPath),
|
||||||
|
|||||||
@@ -5,9 +5,7 @@
|
|||||||
package org.jetbrains.kotlin.fir
|
package org.jetbrains.kotlin.fir
|
||||||
|
|
||||||
import com.intellij.openapi.fileEditor.FileDocumentManager
|
import com.intellij.openapi.fileEditor.FileDocumentManager
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
|
||||||
import com.intellij.openapi.util.text.StringUtil
|
import com.intellij.openapi.util.text.StringUtil
|
||||||
import com.intellij.openapi.vfs.CharsetToolkit
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.KtIoFileSourceFile
|
import org.jetbrains.kotlin.KtIoFileSourceFile
|
||||||
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
|
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
|
||||||
@@ -339,7 +337,7 @@ class FirResolveBench(val withProgress: Boolean, val listener: BenchListener? =
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
val psi = resolvedTypeRef.psi ?: return
|
val psi = resolvedTypeRef.psi ?: return
|
||||||
val problem = "${resolvedTypeRef::class.simpleName} -> ${type::class.simpleName}: ${type.render()}"
|
val problem = "${resolvedTypeRef::class.simpleName} -> ${type::class.simpleName}: ${type.renderForDebugging()}"
|
||||||
reportProblem(problem, psi)
|
reportProblem(problem, psi)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+74
-39
@@ -14,6 +14,8 @@ import org.jetbrains.kotlin.fir.declarations.utils.isLocal
|
|||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
||||||
import org.jetbrains.kotlin.fir.references.*
|
import org.jetbrains.kotlin.fir.references.*
|
||||||
|
import org.jetbrains.kotlin.fir.renderer.ConeTypeRendererForDebugging
|
||||||
|
import org.jetbrains.kotlin.fir.renderer.FirPrinter
|
||||||
import org.jetbrains.kotlin.fir.resolve.defaultType
|
import org.jetbrains.kotlin.fir.resolve.defaultType
|
||||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||||
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
|
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
|
||||||
@@ -322,10 +324,22 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() {
|
|||||||
private val filePackage = firFile.packageFqName.toString()
|
private val filePackage = firFile.packageFqName.toString()
|
||||||
private val filePackageWithSlash = filePackage.replace(".", "/")
|
private val filePackageWithSlash = filePackage.replace(".", "/")
|
||||||
|
|
||||||
private fun ConeTypeProjection.tryToRenderConeAsFunctionType(): String {
|
private fun ConeTypeProjection.tryToRenderConeAsFunctionTypeString(): String {
|
||||||
if (this !is ConeKotlinType) return localTypeRenderer()
|
return buildString {
|
||||||
val functionType = renderFunctionType(functionTypeKind, renderFqNames = true) { localTypeRenderer() }
|
tryToRenderConeAsFunctionType(this@buildString)
|
||||||
return functionType.removeCurrentFilePackage()
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun ConeTypeProjection.tryToRenderConeAsFunctionType(builder: StringBuilder) {
|
||||||
|
if (this !is ConeKotlinType) {
|
||||||
|
localTypeProjectionRenderer(builder)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
val projectionBuilder = StringBuilder()
|
||||||
|
ConeTypeRendererForDebugging(projectionBuilder).renderAsPossibleFunctionType(this) {
|
||||||
|
localTypeProjectionRenderer(projectionBuilder)
|
||||||
|
}
|
||||||
|
builder.append(projectionBuilder.toString().removeCurrentFilePackage())
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO rewrite or extract in common utils
|
// TODO rewrite or extract in common utils
|
||||||
@@ -384,33 +398,49 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ConeTypeProjection.localTypeRenderer(): String {
|
private fun ConeTypeProjection.localTypeProjectionRenderer(builder: StringBuilder) {
|
||||||
val nullabilitySuffix = when {
|
val nullabilitySuffix = when {
|
||||||
this is ConeKotlinType && this !is ConeErrorType && this !is ConeErrorType -> nullability.suffix
|
this is ConeKotlinType && this !is ConeErrorType -> nullability.suffix
|
||||||
else -> ""
|
else -> ""
|
||||||
}
|
}
|
||||||
|
|
||||||
return when (this) {
|
when (this) {
|
||||||
is ConeKotlinTypeProjectionIn -> "in ${type.tryToRenderConeAsFunctionType()}"
|
is ConeKotlinTypeProjectionIn -> {
|
||||||
is ConeKotlinTypeProjectionOut -> "out ${type.tryToRenderConeAsFunctionType()}"
|
builder.append("in ")
|
||||||
|
type.tryToRenderConeAsFunctionType(builder)
|
||||||
|
}
|
||||||
|
is ConeKotlinTypeProjectionOut -> {
|
||||||
|
builder.append("out ")
|
||||||
|
type.tryToRenderConeAsFunctionType(builder)
|
||||||
|
}
|
||||||
|
is ConeStarProjection -> builder.append("*")
|
||||||
is ConeClassLikeType -> {
|
is ConeClassLikeType -> {
|
||||||
val type = this.fullyExpandedType(session)
|
val type = this.fullyExpandedType(session)
|
||||||
if (type != this) return type.tryToRenderConeAsFunctionType()
|
if (type != this) {
|
||||||
val classId = type.lookupTag.classId
|
type.tryToRenderConeAsFunctionType(builder)
|
||||||
buildString {
|
return
|
||||||
when {
|
|
||||||
classId.isLocal -> append(classId.shortClassName.asString().let { stack.getPathByName(it) + it })
|
|
||||||
else -> append(classId.asString())
|
|
||||||
}
|
|
||||||
if (type.typeArguments.isNotEmpty()) {
|
|
||||||
append(type.typeArguments.joinToString(prefix = "<", postfix = ">") { it.tryToRenderConeAsFunctionType() })
|
|
||||||
}
|
|
||||||
append(nullabilitySuffix)
|
|
||||||
}
|
}
|
||||||
|
val classId = type.lookupTag.classId
|
||||||
|
when {
|
||||||
|
classId.isLocal -> builder.append(classId.shortClassName.asString().let { stack.getPathByName(it) + it })
|
||||||
|
else -> builder.append(classId.asString())
|
||||||
|
}
|
||||||
|
if (type.typeArguments.isNotEmpty()) {
|
||||||
|
builder.append("<")
|
||||||
|
for ((index, typeArgument) in type.typeArguments.withIndex()) {
|
||||||
|
if (index != 0) {
|
||||||
|
builder.append(", ")
|
||||||
|
}
|
||||||
|
typeArgument.tryToRenderConeAsFunctionType(builder)
|
||||||
|
}
|
||||||
|
builder.append(">")
|
||||||
|
}
|
||||||
|
builder.append(nullabilitySuffix)
|
||||||
}
|
}
|
||||||
is ConeLookupTagBasedType -> lookupTag.name.asString() + nullabilitySuffix
|
is ConeLookupTagBasedType -> builder.append(lookupTag.name.asString() + nullabilitySuffix)
|
||||||
is ConeFlexibleType -> {
|
is ConeFlexibleType -> {
|
||||||
val lowerRendered = lowerBound.tryToRenderConeAsFunctionType()
|
val lowerBuilder = StringBuilder()
|
||||||
|
lowerBound.tryToRenderConeAsFunctionType(lowerBuilder)
|
||||||
if (lowerBound.nullability == ConeNullability.NOT_NULL && upperBound.nullability == ConeNullability.NULLABLE &&
|
if (lowerBound.nullability == ConeNullability.NOT_NULL && upperBound.nullability == ConeNullability.NULLABLE &&
|
||||||
AbstractStrictEqualityTypeChecker
|
AbstractStrictEqualityTypeChecker
|
||||||
.strictEqualTypes(
|
.strictEqualTypes(
|
||||||
@@ -419,17 +449,20 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() {
|
|||||||
upperBound.withNullability(ConeNullability.NOT_NULL, session.typeContext)
|
upperBound.withNullability(ConeNullability.NOT_NULL, session.typeContext)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
"$lowerRendered!"
|
builder.append(lowerBuilder)
|
||||||
} else {
|
} else {
|
||||||
val upperRendered = upperBound.tryToRenderConeAsFunctionType()
|
val upperBuilder = StringBuilder()
|
||||||
tryToSquashFlexibleType(lowerRendered, upperRendered) ?: "$lowerRendered..$upperRendered"
|
upperBound.tryToRenderConeAsFunctionType(upperBuilder)
|
||||||
|
builder.append(
|
||||||
|
tryToSquashFlexibleType(lowerBuilder.toString(), upperBuilder.toString()) ?: "$lowerBuilder..$upperBuilder"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is ConeIntersectionType -> {
|
is ConeIntersectionType -> {
|
||||||
intersectedTypes.map { it.render().replace("/", ".").replace("kotlin.", "") }.sorted()
|
intersectedTypes.map { it.renderForDebugging().replace("/", ".").replace("kotlin.", "") }.sorted()
|
||||||
.joinToString(separator = " & ", prefix = "{", postfix = "}")
|
.joinToString(separator = " & ", prefix = "{", postfix = "}")
|
||||||
}
|
}
|
||||||
else -> this.render(renderFqNames = true)
|
else -> builder.append((this as ConeKotlinType).renderForDebugging())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -485,11 +518,11 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() {
|
|||||||
if (original.isVal) data.append("val ") else if (original.isVar) data.append("var ")
|
if (original.isVal) data.append("val ") else if (original.isVar) data.append("var ")
|
||||||
|
|
||||||
data.append("(")
|
data.append("(")
|
||||||
.append(original.dispatchReceiverType?.tryToRenderConeAsFunctionType())
|
original.dispatchReceiverType?.tryToRenderConeAsFunctionType(data)
|
||||||
.append(").")
|
data.append(").")
|
||||||
.append(original.name)
|
.append(original.name)
|
||||||
.append(": ")
|
.append(": ")
|
||||||
.append(original.returnTypeRef.coneType.tryToRenderConeAsFunctionType())
|
original.returnTypeRef.coneType.tryToRenderConeAsFunctionType(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun renderVariable(variable: FirVariable, data: StringBuilder) {
|
private fun renderVariable(variable: FirVariable, data: StringBuilder) {
|
||||||
@@ -513,15 +546,15 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val receiver = when (variable) {
|
val receiver = when (variable) {
|
||||||
is FirField -> variable.dispatchReceiverType?.tryToRenderConeAsFunctionType()
|
is FirField -> variable.dispatchReceiverType?.tryToRenderConeAsFunctionTypeString()
|
||||||
else -> getSymbolId(variable.symbol)
|
else -> getSymbolId(variable.symbol)
|
||||||
}
|
}
|
||||||
|
|
||||||
data.append(receiver)
|
data.append(receiver)
|
||||||
.append(variable.symbol.callableId.callableName)
|
.append(variable.symbol.callableId.callableName)
|
||||||
.append(": ")
|
.append(": ")
|
||||||
.append(returnType?.tryToRenderConeAsFunctionType())
|
returnType?.tryToRenderConeAsFunctionType(data)
|
||||||
.append((variable as? FirValueParameter)?.defaultValue?.let { " = ..." } ?: "")
|
data.append((variable as? FirValueParameter)?.defaultValue?.let { " = ..." } ?: "")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun renderPropertySymbol(symbol: FirPropertySymbol, data: StringBuilder) {
|
private fun renderPropertySymbol(symbol: FirPropertySymbol, data: StringBuilder) {
|
||||||
@@ -533,7 +566,7 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() {
|
|||||||
when {
|
when {
|
||||||
receiver != null -> data.append(receiver).append(".").append(symbol.callableId.callableName)
|
receiver != null -> data.append(receiver).append(".").append(symbol.callableId.callableName)
|
||||||
fir.dispatchReceiverType != null -> {
|
fir.dispatchReceiverType != null -> {
|
||||||
val dispatchReceiver = fir.dispatchReceiverType?.tryToRenderConeAsFunctionType()
|
val dispatchReceiver = fir.dispatchReceiverType?.tryToRenderConeAsFunctionTypeString()
|
||||||
data.append("($dispatchReceiver)").append(".").append(symbol.callableId.callableName)
|
data.append("($dispatchReceiver)").append(".").append(symbol.callableId.callableName)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
@@ -578,7 +611,7 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() {
|
|||||||
}
|
}
|
||||||
call.dispatchReceiver !is FirNoReceiverExpression -> {
|
call.dispatchReceiver !is FirNoReceiverExpression -> {
|
||||||
data.append("(")
|
data.append("(")
|
||||||
val dispatch = fir.dispatchReceiverType!!.tryToRenderConeAsFunctionType()
|
val dispatch = fir.dispatchReceiverType!!.tryToRenderConeAsFunctionTypeString()
|
||||||
.let { if (it.endsWith("!")) it.dropLast(1) else it } // this hack drop flexible annotation for receiver
|
.let { if (it.endsWith("!")) it.dropLast(1) else it } // this hack drop flexible annotation for receiver
|
||||||
data.append(dispatch).append(").").append(callableName)
|
data.append(dispatch).append(").").append(callableName)
|
||||||
}
|
}
|
||||||
@@ -654,7 +687,7 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() {
|
|||||||
override fun visitValueParameter(valueParameter: FirValueParameter, data: StringBuilder) {
|
override fun visitValueParameter(valueParameter: FirValueParameter, data: StringBuilder) {
|
||||||
if (valueParameter.isVararg) {
|
if (valueParameter.isVararg) {
|
||||||
data.append("vararg ")
|
data.append("vararg ")
|
||||||
valueParameter.returnTypeRef.coneType.arrayElementType()?.let { data.append(it.localTypeRenderer()) }
|
valueParameter.returnTypeRef.coneType.arrayElementType()?.localTypeProjectionRenderer(data)
|
||||||
} else {
|
} else {
|
||||||
valueParameter.returnTypeRef.accept(this, data)
|
valueParameter.returnTypeRef.accept(this, data)
|
||||||
}
|
}
|
||||||
@@ -683,7 +716,7 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() {
|
|||||||
data.append(stack.getPathByName(resolvedNamedReference.name.asString()))
|
data.append(stack.getPathByName(resolvedNamedReference.name.asString()))
|
||||||
.append(resolvedNamedReference.name)
|
.append(resolvedNamedReference.name)
|
||||||
.append(": ")
|
.append(": ")
|
||||||
.append(fir.dispatchReceiverType?.tryToRenderConeAsFunctionType())
|
fir.dispatchReceiverType?.tryToRenderConeAsFunctionType(data)
|
||||||
}
|
}
|
||||||
symbol is FirFieldSymbol -> renderField(symbol.fir, data)
|
symbol is FirFieldSymbol -> renderField(symbol.fir, data)
|
||||||
else -> (symbol.fir as? FirVariable)?.let { renderVariable(it, data) }
|
else -> (symbol.fir as? FirVariable)?.let { renderVariable(it, data) }
|
||||||
@@ -813,7 +846,7 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitResolvedTypeRef(resolvedTypeRef: FirResolvedTypeRef, data: StringBuilder) {
|
override fun visitResolvedTypeRef(resolvedTypeRef: FirResolvedTypeRef, data: StringBuilder) {
|
||||||
data.append(resolvedTypeRef.type.tryToRenderConeAsFunctionType())
|
resolvedTypeRef.type.tryToRenderConeAsFunctionType(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitErrorTypeRef(errorTypeRef: FirErrorTypeRef, data: StringBuilder) {
|
override fun visitErrorTypeRef(errorTypeRef: FirErrorTypeRef, data: StringBuilder) {
|
||||||
@@ -836,7 +869,9 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() {
|
|||||||
val typeParameters = if (typeArguments.isEmpty()) "" else " <T>"
|
val typeParameters = if (typeArguments.isEmpty()) "" else " <T>"
|
||||||
data.append("fun$typeParameters ${name.replaceFirstChar(Char::lowercaseChar)}Of")
|
data.append("fun$typeParameters ${name.replaceFirstChar(Char::lowercaseChar)}Of")
|
||||||
typeArguments.firstOrNull()?.let {
|
typeArguments.firstOrNull()?.let {
|
||||||
data.append("<").append(it.tryToRenderConeAsFunctionType()).append(">")
|
data.append("<")
|
||||||
|
it.tryToRenderConeAsFunctionType(data)
|
||||||
|
data.append(">")
|
||||||
}
|
}
|
||||||
val valueParameter = name.replace("Array", "").takeIf { it.isNotEmpty() } ?: "T"
|
val valueParameter = name.replace("Array", "").takeIf { it.isNotEmpty() } ?: "T"
|
||||||
data.append("(vararg $valueParameter): $name${typeParameters.trim()}") // TODO change "T" to concrete type is array is primitive
|
data.append("(vararg $valueParameter): $name${typeParameters.trim()}") // TODO change "T" to concrete type is array is primitive
|
||||||
|
|||||||
Reference in New Issue
Block a user