From 31ec10142b497f8ce1f14356a933709abb90bc3c Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Fri, 24 Jun 2022 10:21:21 +0200 Subject: [PATCH] FirRenderer: add renderAllModifiers and renderDetailedTypeReferences Related to KT-52020 --- .../callResolver/resolveCall/ambiguous.txt | 2 +- .../resolveCall/ambiguousImplicitInvoke.txt | 2 +- .../ambiguousWithExplicitTypeParameters.txt | 2 +- .../ambiguousWithInferredTypeParameters.txt | 2 +- ...legatedConstructorCall_this_unresolved.txt | 2 +- .../resolveCall/hiddenConstructor.txt | 2 +- .../resolveCall/privateMember.txt | 2 +- .../consecutiveImplicitInvoke1.txt | 4 +- .../consecutiveImplicitInvoke2.txt | 4 +- .../consecutiveImplicitInvoke3.txt | 4 +- .../singleCandidate/hiddenConstructor.txt | 2 +- .../singleCandidate/privateMember.txt | 2 +- .../kotlin/fir/types/TypeRenderer.kt | 38 +++++----- .../org/jetbrains/kotlin/fir/FirRenderer.kt | 71 +++++++++++-------- .../testData/cli/jvm/firDeprecationJava.out | 6 +- .../compiler/visualizer/FirVisualizer.kt | 4 +- 16 files changed, 83 insertions(+), 66 deletions(-) diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/ambiguous.txt b/analysis/analysis-api/testData/components/callResolver/resolveCall/ambiguous.txt index 6ac299f93f5..f8687c9efb2 100644 --- a/analysis/analysis-api/testData/components/callResolver/resolveCall/ambiguous.txt +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/ambiguous.txt @@ -82,4 +82,4 @@ KtErrorCallInfo: callableIdIfNonLocal = null) } ] - diagnostic = ERROR + diagnostic = ERROR \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/ambiguousImplicitInvoke.txt b/analysis/analysis-api/testData/components/callResolver/resolveCall/ambiguousImplicitInvoke.txt index 9334d149956..00079570c4a 100644 --- a/analysis/analysis-api/testData/components/callResolver/resolveCall/ambiguousImplicitInvoke.txt +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/ambiguousImplicitInvoke.txt @@ -47,4 +47,4 @@ KtErrorCallInfo: typeArgumentsMapping = {} argumentMapping = {} ] - diagnostic = ERROR + diagnostic = ERROR \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/ambiguousWithExplicitTypeParameters.txt b/analysis/analysis-api/testData/components/callResolver/resolveCall/ambiguousWithExplicitTypeParameters.txt index 8b50a3a8481..3719eb34a94 100644 --- a/analysis/analysis-api/testData/components/callResolver/resolveCall/ambiguousWithExplicitTypeParameters.txt +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/ambiguousWithExplicitTypeParameters.txt @@ -106,4 +106,4 @@ KtErrorCallInfo: callableIdIfNonLocal = null) } ] - diagnostic = ERROR function(t: R|T|, a: R|kotlin/Char|): R|kotlin/Unit|, public final fun function(u: R|U|, b: R|kotlin/Boolean|): R|kotlin/Unit|, public final fun function(v: R|V|, c: R|kotlin/String|): R|kotlin/Unit|]> + diagnostic = ERROR function(t: T, a: Char): Unit, fun function(u: U, b: Boolean): Unit, fun function(v: V, c: String): Unit]> \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/ambiguousWithInferredTypeParameters.txt b/analysis/analysis-api/testData/components/callResolver/resolveCall/ambiguousWithInferredTypeParameters.txt index dd3ba02e580..afa1e6287f6 100644 --- a/analysis/analysis-api/testData/components/callResolver/resolveCall/ambiguousWithInferredTypeParameters.txt +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/ambiguousWithInferredTypeParameters.txt @@ -100,4 +100,4 @@ KtErrorCallInfo: callableIdIfNonLocal = null) } ] - diagnostic = ERROR function(t: R|T|, a: R|kotlin/Char|): R|kotlin/Unit|, public final fun function(u: R|U|, b: R|kotlin/Boolean|): R|kotlin/Unit|, public final fun function(v: R|V|, c: R|kotlin/String|): R|kotlin/Unit|]> + diagnostic = ERROR function(t: T, a: Char): Unit, fun function(u: U, b: Boolean): Unit, fun function(v: V, c: String): Unit]> \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/delegatedConstructorCall_this_unresolved.txt b/analysis/analysis-api/testData/components/callResolver/resolveCall/delegatedConstructorCall_this_unresolved.txt index 923fc767126..741361f9057 100644 --- a/analysis/analysis-api/testData/components/callResolver/resolveCall/delegatedConstructorCall_this_unresolved.txt +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/delegatedConstructorCall_this_unresolved.txt @@ -47,4 +47,4 @@ KtErrorCallInfo: typeArgumentsMapping = {} argumentMapping = {} ] - diagnostic = ERROR + diagnostic = ERROR \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/hiddenConstructor.txt b/analysis/analysis-api/testData/components/callResolver/resolveCall/hiddenConstructor.txt index 7fcd213acf0..cbde5b2772e 100644 --- a/analysis/analysis-api/testData/components/callResolver/resolveCall/hiddenConstructor.txt +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/hiddenConstructor.txt @@ -14,4 +14,4 @@ KtErrorCallInfo: typeArgumentsMapping = {} argumentMapping = {} ] - diagnostic = ERROR + diagnostic = ERROR \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCall/privateMember.txt b/analysis/analysis-api/testData/components/callResolver/resolveCall/privateMember.txt index df3d175053a..70cd2209ba8 100644 --- a/analysis/analysis-api/testData/components/callResolver/resolveCall/privateMember.txt +++ b/analysis/analysis-api/testData/components/callResolver/resolveCall/privateMember.txt @@ -17,4 +17,4 @@ KtErrorCallInfo: typeArgumentsMapping = {} argumentMapping = {} ] - diagnostic = ERROR + diagnostic = ERROR \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/consecutiveImplicitInvoke1.txt b/analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/consecutiveImplicitInvoke1.txt index 3354e364f77..9056998275b 100644 --- a/analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/consecutiveImplicitInvoke1.txt +++ b/analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/consecutiveImplicitInvoke1.txt @@ -1,5 +1,5 @@ KtInapplicableCallCandidateInfo: - diagnostic = ERROR + diagnostic = ERROR candidate = KtSimpleFunctionCall: isImplicitInvoke = true partiallyAppliedSymbol = KtPartiallyAppliedSymbol: @@ -38,7 +38,7 @@ KtApplicableCallCandidateInfo: isInBestCandidates = true KtInapplicableCallCandidateInfo: - diagnostic = ERROR + diagnostic = ERROR candidate = KtSimpleFunctionCall: isImplicitInvoke = true partiallyAppliedSymbol = KtPartiallyAppliedSymbol: diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/consecutiveImplicitInvoke2.txt b/analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/consecutiveImplicitInvoke2.txt index 281a20404c8..ed0d1e248a6 100644 --- a/analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/consecutiveImplicitInvoke2.txt +++ b/analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/consecutiveImplicitInvoke2.txt @@ -1,5 +1,5 @@ KtInapplicableCallCandidateInfo: - diagnostic = ERROR + diagnostic = ERROR candidate = KtSimpleFunctionCall: isImplicitInvoke = true partiallyAppliedSymbol = KtPartiallyAppliedSymbol: @@ -19,7 +19,7 @@ KtInapplicableCallCandidateInfo: isInBestCandidates = false KtInapplicableCallCandidateInfo: - diagnostic = ERROR + diagnostic = ERROR candidate = KtSimpleFunctionCall: isImplicitInvoke = true partiallyAppliedSymbol = KtPartiallyAppliedSymbol: diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/consecutiveImplicitInvoke3.txt b/analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/consecutiveImplicitInvoke3.txt index 8e1f638d428..75c5a2b254b 100644 --- a/analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/consecutiveImplicitInvoke3.txt +++ b/analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/consecutiveImplicitInvoke3.txt @@ -18,7 +18,7 @@ KtApplicableCallCandidateInfo: isInBestCandidates = true KtInapplicableCallCandidateInfo: - diagnostic = ERROR + diagnostic = ERROR candidate = KtSimpleFunctionCall: isImplicitInvoke = true partiallyAppliedSymbol = KtPartiallyAppliedSymbol: @@ -38,7 +38,7 @@ KtInapplicableCallCandidateInfo: isInBestCandidates = false KtInapplicableCallCandidateInfo: - diagnostic = ERROR + diagnostic = ERROR candidate = KtSimpleFunctionCall: isImplicitInvoke = true partiallyAppliedSymbol = KtPartiallyAppliedSymbol: diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/hiddenConstructor.txt b/analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/hiddenConstructor.txt index d0a734220f9..18f680bdd58 100644 --- a/analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/hiddenConstructor.txt +++ b/analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/hiddenConstructor.txt @@ -1,5 +1,5 @@ KtInapplicableCallCandidateInfo: - diagnostic = ERROR + diagnostic = ERROR candidate = KtSimpleFunctionCall: isImplicitInvoke = false partiallyAppliedSymbol = KtPartiallyAppliedSymbol: diff --git a/analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/privateMember.txt b/analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/privateMember.txt index 5290f8a5e39..803c2954927 100644 --- a/analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/privateMember.txt +++ b/analysis/analysis-api/testData/components/callResolver/resolveCandidates/singleCandidate/privateMember.txt @@ -1,5 +1,5 @@ KtInapplicableCallCandidateInfo: - diagnostic = ERROR + diagnostic = ERROR candidate = KtSimpleFunctionCall: isImplicitInvoke = false partiallyAppliedSymbol = KtPartiallyAppliedSymbol: diff --git a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/TypeRenderer.kt b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/TypeRenderer.kt index f1e729135de..816ec106df1 100644 --- a/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/TypeRenderer.kt +++ b/compiler/fir/cones/src/org/jetbrains/kotlin/fir/types/TypeRenderer.kt @@ -9,20 +9,24 @@ import org.jetbrains.kotlin.builtins.functions.FunctionClassKind import kotlin.contracts.ExperimentalContracts import kotlin.contracts.contract -fun ConeKotlinType.render(): String { +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()} & Any" + is ConeDefinitelyNotNullType -> "${original.render(renderFqNames)} & Any" is ConeErrorType -> "${renderAttributes()}ERROR CLASS: ${diagnostic.reason}" - is ConeCapturedType -> "${renderAttributes()}CapturedType(${constructor.projection.render()})" + is ConeCapturedType -> "${renderAttributes()}CapturedType(${constructor.projection.render(renderFqNames)})" is ConeClassLikeType -> { buildString { append(renderAttributes()) - append(lookupTag.classId.asString()) + if (renderFqNames) { + append(lookupTag.classId.asString()) + } else { + append(lookupTag.classId.relativeClassName.asString()) + } if (typeArguments.isNotEmpty()) { append(typeArguments.joinToString(prefix = "<", postfix = ">") { - it.render() + it.render(renderFqNames) }) } } @@ -31,13 +35,15 @@ fun ConeKotlinType.render(): String { "${renderAttributes()}${lookupTag.name.asString()}" } is ConeDynamicType -> "dynamic" - is ConeFlexibleType -> this.render() + 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}" @@ -47,12 +53,12 @@ fun ConeKotlinType.render(): String { } + nullabilitySuffix } -private fun ConeFlexibleType.render(): String = +private fun ConeFlexibleType.render(renderFqNames: Boolean): String = buildString { append("ft<") - append(lowerBound.render()) + append(lowerBound.render(renderFqNames)) append(", ") - append(upperBound.render()) + append(upperBound.render(renderFqNames)) append(">") } @@ -61,18 +67,18 @@ private fun ConeKotlinType.renderAttributes(): String { return attributes.joinToString(" ", postfix = " ") { it.toString() } } -fun ConeTypeProjection.render(): String { +fun ConeTypeProjection.render(renderFqNames: Boolean): String { return when (this) { ConeStarProjection -> "*" - is ConeKotlinTypeConflictingProjection -> "CONFLICTING-PROJECTION ${type.render()}" - is ConeKotlinTypeProjectionIn -> "in ${type.render()}" - is ConeKotlinTypeProjectionOut -> "out ${type.render()}" - is ConeKotlinType -> render() + 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?, renderType: ConeTypeProjection.() -> String = { render() } + kind: FunctionClassKind?, renderFqNames: Boolean, renderType: ConeTypeProjection.() -> String = { render(renderFqNames) } ): String { if (!kind.withPrettyRender()) return renderType() diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt index 7b1362ca59c..90347f60a45 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt @@ -66,6 +66,8 @@ open class FirRenderer(builder: StringBuilder, protected val mode: RenderMode = val renderPackageDirective: Boolean = false, val renderNestedDeclarations: Boolean = true, val renderDefaultParameterValues: Boolean = true, + val renderDetailedTypeReferences: Boolean = true, + val renderAllModifiers: Boolean = true, ) { companion object { val Normal = RenderMode( @@ -124,6 +126,8 @@ open class FirRenderer(builder: StringBuilder, protected val mode: RenderMode = renderPackageDirective = false, renderNestedDeclarations = false, renderDefaultParameterValues = false, + renderDetailedTypeReferences = false, + renderAllModifiers = false, ) val WithDeclarationAttributes = RenderMode( @@ -236,7 +240,6 @@ open class FirRenderer(builder: StringBuilder, protected val mode: RenderMode = override fun visitCallableDeclaration(callableDeclaration: FirCallableDeclaration) { renderContexts(callableDeclaration.contextReceivers) - callableDeclaration.contextReceivers callableDeclaration.annotations.renderAnnotations() visitMemberDeclaration(callableDeclaration) val receiverType = callableDeclaration.receiverTypeRef @@ -338,7 +341,7 @@ open class FirRenderer(builder: StringBuilder, protected val mode: RenderMode = } override fun visitMemberDeclaration(memberDeclaration: FirMemberDeclaration) { - if (memberDeclaration !is FirProperty || !memberDeclaration.isLocal) { + if (mode.renderAllModifiers && (memberDeclaration !is FirProperty || !memberDeclaration.isLocal)) { // we can't access session.effectiveVisibilityResolver from here! // print(memberDeclaration.visibility.asString(memberDeclaration.getEffectiveVisibility(...)) + " ") print(memberDeclaration.visibility.asString() + " ") @@ -350,11 +353,13 @@ open class FirRenderer(builder: StringBuilder, protected val mode: RenderMode = if (memberDeclaration.isActual) { print("actual ") } - if (memberDeclaration.isExternal) { - print("external ") - } - if (memberDeclaration.isOverride) { - print("override ") + if (mode.renderAllModifiers) { + if (memberDeclaration.isExternal) { + print("external ") + } + if (memberDeclaration.isOverride) { + print("override ") + } } if (memberDeclaration.isStatic) { print("static ") @@ -379,26 +384,28 @@ open class FirRenderer(builder: StringBuilder, protected val mode: RenderMode = print("fun ") } - if (memberDeclaration.isInline) { - print("inline ") - } - if (memberDeclaration.isOperator) { - print("operator ") - } - if (memberDeclaration.isInfix) { - print("infix ") - } - if (memberDeclaration.isTailRec) { - print("tailrec ") - } - if (memberDeclaration.isSuspend) { - print("suspend ") - } - if (memberDeclaration.isConst) { - print("const ") - } - if (memberDeclaration.isLateInit) { - print("lateinit ") + if (mode.renderAllModifiers) { + if (memberDeclaration.isInline) { + print("inline ") + } + if (memberDeclaration.isOperator) { + print("operator ") + } + if (memberDeclaration.isInfix) { + print("infix ") + } + if (memberDeclaration.isTailRec) { + print("tailrec ") + } + if (memberDeclaration.isSuspend) { + print("suspend ") + } + if (memberDeclaration.isConst) { + print("const ") + } + if (memberDeclaration.isLateInit) { + print("lateinit ") + } } visitDeclaration(memberDeclaration as FirDeclaration) @@ -1128,10 +1135,14 @@ open class FirRenderer(builder: StringBuilder, protected val mode: RenderMode = override fun visitResolvedTypeRef(resolvedTypeRef: FirResolvedTypeRef) { val kind = resolvedTypeRef.functionTypeKind - print("R|") + if (mode.renderDetailedTypeReferences) { + print("R|") + } val coneType = resolvedTypeRef.type - print(coneType.renderFunctionType(kind)) - print("|") + print(coneType.renderFunctionType(kind, renderFqNames = mode.renderDetailedTypeReferences)) + if (mode.renderDetailedTypeReferences) { + print("|") + } } override fun visitUserTypeRef(userTypeRef: FirUserTypeRef) { diff --git a/compiler/testData/cli/jvm/firDeprecationJava.out b/compiler/testData/cli/jvm/firDeprecationJava.out index 4f8d2c6f3d3..246e0bea996 100644 --- a/compiler/testData/cli/jvm/firDeprecationJava.out +++ b/compiler/testData/cli/jvm/firDeprecationJava.out @@ -1,15 +1,15 @@ warning: ATTENTION! This build uses experimental K2 compiler: -Xuse-k2 -compiler/testData/cli/jvm/firDeprecationJava.kt:3:12: warning: '@R|kotlin/Deprecated|(...) public final fun stop(): R|kotlin/Unit| +compiler/testData/cli/jvm/firDeprecationJava.kt:3:12: warning: '@Deprecated(...) fun stop(): Unit ' is deprecated. Deprecated in Java thread.stop() ^ -compiler/testData/cli/jvm/firDeprecationJava.kt:4:17: warning: '@R|kotlin/Deprecated|(...) public open fun bar(a: R|ft|, b: R|kotlin/Int|, c: R|kotlin/Double|): R|ft| +compiler/testData/cli/jvm/firDeprecationJava.kt:4:17: warning: '@Deprecated(...) fun bar(a: ft, b: Int, c: Double): ft ' is deprecated. Deprecated in Java JavaClass().bar("", 1, 2.0) ^ -compiler/testData/cli/jvm/firDeprecationJava.kt:5:27: warning: '@R|kotlin/Deprecated|(...) public open field baz: R|ft| +compiler/testData/cli/jvm/firDeprecationJava.kt:5:27: warning: '@Deprecated(...) field baz: ft ' is deprecated. Deprecated in Java val baz = JavaClass().baz ^ diff --git a/compiler/visualizer/render-fir/src/org/jetbrains/kotlin/compiler/visualizer/FirVisualizer.kt b/compiler/visualizer/render-fir/src/org/jetbrains/kotlin/compiler/visualizer/FirVisualizer.kt index ad7a6096a51..17609b3dcbe 100644 --- a/compiler/visualizer/render-fir/src/org/jetbrains/kotlin/compiler/visualizer/FirVisualizer.kt +++ b/compiler/visualizer/render-fir/src/org/jetbrains/kotlin/compiler/visualizer/FirVisualizer.kt @@ -324,7 +324,7 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() { private fun ConeTypeProjection.tryToRenderConeAsFunctionType(): String { if (this !is ConeKotlinType) return localTypeRenderer() - val functionType = renderFunctionType(functionTypeKind) { localTypeRenderer() } + val functionType = renderFunctionType(functionTypeKind, renderFqNames = true) { localTypeRenderer() } return functionType.removeCurrentFilePackage() } @@ -429,7 +429,7 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() { intersectedTypes.map { it.render().replace("/", ".").replace("kotlin.", "") }.sorted() .joinToString(separator = " & ", prefix = "{", postfix = "}") } - else -> this.render() + else -> this.render(renderFqNames = true) } }