From ca424a94ef623ade41b53a7ac5fdcd4a8adf25b3 Mon Sep 17 00:00:00 2001 From: Ivan Kylchik Date: Fri, 19 Feb 2021 15:42:07 +0300 Subject: [PATCH] [VISUALIZER] Add local path to local declarations in fir --- .../compiler/visualizer/FirVisualizer.kt | 82 +++++++++++-------- 1 file changed, 49 insertions(+), 33 deletions(-) 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 761a80cd494..3716967566a 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 @@ -10,13 +10,12 @@ import org.jetbrains.kotlin.KtNodeTypes import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirLabel import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.dispatchReceiverClassOrNull import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression import org.jetbrains.kotlin.fir.psi import org.jetbrains.kotlin.fir.references.* -import org.jetbrains.kotlin.fir.resolve.directExpansionType -import org.jetbrains.kotlin.fir.resolve.symbolProvider -import org.jetbrains.kotlin.fir.resolve.getSymbolByLookupTag +import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.firUnsafe import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.impl.* @@ -25,9 +24,7 @@ import org.jetbrains.kotlin.fir.visitors.FirVisitor import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.getChildOfType import org.jetbrains.kotlin.psi.psiUtil.getChildrenOfType -import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue import org.jetbrains.kotlin.types.ConstantValueKind import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly @@ -38,6 +35,30 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() { private fun FirElement.render(): String = buildString { this@render.accept(FirRenderer(), this) } + private val stack = mutableListOf("" to mutableListOf()) + + private fun Stack.push( + levelName: String, + defaultValues: MutableList = mutableListOf() + ) = this.add(levelName to defaultValues) + + private fun Stack.pop() = this.removeAt(this.size - 1) + private fun Stack.addName(name: String) = this.last().second.add(name) + private fun Stack.addName(name: Name) = this.addName(name.asString()) + private fun Stack.getPathByName(name: String): String { + for ((reversedIndex, names) in this.asReversed().map { it.second }.withIndex()) { + if (names.contains(name)) { + return this.filterIndexed { index, _ -> index < this.size - reversedIndex && index > 0 } + .joinToString(separator = ".", postfix = ".") { it.first } + } + } + if (name == "it") { + return this.subList(1, this.size) + .joinToString(separator = ".", postfix = ".") { it.first } + } + return "[NOT FOUND]." + } + override fun addAnnotation(annotationText: String, element: PsiElement?, deleteDuplicate: Boolean) { super.addAnnotation(annotationText, element, false) } @@ -51,30 +72,6 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() { inner class PsiVisitor(private val map: Map>) : KtVisitorVoid() { private var lastCallWithLambda: String? = null - private val stack = mutableListOf("" to mutableListOf()) - - private fun Stack.push( - levelName: String, - defaultValues: MutableList = mutableListOf() - ) = this.add(levelName to defaultValues) - - private fun Stack.pop() = this.removeAt(this.size - 1) - private fun Stack.addName(name: String) = this.last().second.add(name) - private fun Stack.addName(name: Name) = this.addName(name.asString()) - private fun Stack.getPathByName(name: String): String { - for ((reversedIndex, names) in this.asReversed().map { it.second }.withIndex()) { - if (names.contains(name)) { - return this.filterIndexed { index, _ -> index < this.size - reversedIndex && index > 0 } - .joinToString(separator = ".", postfix = ".") { it.first } - } - } - if (name == "it") { - return this.subList(1, this.size) - .joinToString(separator = ".", postfix = ".") { it.first } - } - return "[NOT FOUND]." - } - private inline fun KtElement.firstOfType(): T? { val firList = map[this] return firList?.filterIsInstance()?.firstOrNull() @@ -133,6 +130,7 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() { stack.pop() } is KtClassOrObject -> { + if (element.isLocal) stack.addName((element.name ?: "")) stack.push((element.name ?: "")) element.acceptChildren(this) stack.pop() @@ -154,6 +152,7 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() { } override fun visitNamedFunction(function: KtNamedFunction) { + if (function.isLocal) stack.addName(function.name ?: "") stack.push((function.name ?: "")) if (function.equalsToken != null) { function.bodyExpression!!.firstOfTypeWithRender(function.equalsToken) { this.result.typeRef } @@ -304,7 +303,7 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() { private fun FirTypeRef.renderWithNativeRenderer(): String { var result = buildString { - val nativeRenderer = org.jetbrains.kotlin.fir.FirRenderer(this) + val nativeRenderer = org.jetbrains.kotlin.fir.FirRenderer(this, org.jetbrains.kotlin.fir.FirRenderer.RenderMode.WithFqNamesExceptAnnotation) this@renderWithNativeRenderer.accept(nativeRenderer) } if (result.startsWith("R|")) result = result.substring(2) @@ -410,8 +409,9 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() { when { call.dispatchReceiver !is FirNoReceiverExpression -> { data.append("(") - call.dispatchReceiver.typeRef.accept(this, data) - data.append(").").append(symbol.callableId.callableName) + val dispatch = buildString { call.dispatchReceiver.typeRef.accept(this@FirRenderer, this) } + val localPath = if (symbol.isLocalDeclaration()) stack.getPathByName(dispatch) else "" + data.append(localPath).append(dispatch).append(").").append(symbol.callableId.callableName) } call.extensionReceiver !is FirNoReceiverExpression -> { // render type from symbol because this way it will be consistent with psi render @@ -642,13 +642,29 @@ class FirVisualizer(private val firFile: FirFile) : BaseRenderer() { } } + private fun AbstractFirBasedSymbol<*>.isLocalDeclaration(): Boolean { + return when (val fir = this.fir) { + is FirConstructor -> { + val firClass = fir.returnTypeRef.coneTypeUnsafe().lookupTag.toFirRegularClass(session) + firClass?.isLocal ?: false + } + is FirCallableDeclaration<*> -> { + fir.dispatchReceiverClassOrNull()?.toFirRegularClass(session)?.isLocal ?: false + } + else -> false + } + } + private fun getSymbolId(symbol: AbstractFirBasedSymbol<*>?): String { return when (symbol) { is FirCallableSymbol<*> -> { val callableId = symbol.callableId - callableId.toString() + val isLocal = symbol.isLocalDeclaration() + val trimmedCallableId = callableId.toString() .replaceFirst(".${callableId.callableName}", "") .removeCurrentFilePackage() + val localPath = if (isLocal) stack.getPathByName(trimmedCallableId) else "" + localPath + trimmedCallableId } is FirClassLikeSymbol<*> -> symbol.classId.getWithoutCurrentPackage() else -> ""