[FIR] Add ability to specify members in FirScopeDumpHandler
This commit is contained in:
@@ -30,6 +30,10 @@ class HandlersStepBuilder<I : ResultingArtifact<I>>(val artifactKind: TestArtifa
|
|||||||
handlers += constructor
|
handlers += constructor
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun useHandlersAtFirst(vararg constructor: Constructor<AnalysisHandler<I>>) {
|
||||||
|
handlers.addAll(0, constructor.toList())
|
||||||
|
}
|
||||||
|
|
||||||
fun useHandlers(constructors: List<Constructor<AnalysisHandler<I>>>) {
|
fun useHandlers(constructors: List<Constructor<AnalysisHandler<I>>>) {
|
||||||
handlers += constructors
|
handlers += constructors
|
||||||
}
|
}
|
||||||
|
|||||||
+4
@@ -54,6 +54,10 @@ object FirDiagnosticsDirectives : SimpleDirectivesContainer() {
|
|||||||
val SCOPE_DUMP by stringDirective(
|
val SCOPE_DUMP by stringDirective(
|
||||||
description = """
|
description = """
|
||||||
Dump hierarchies of overrides of classes listed in arguments
|
Dump hierarchies of overrides of classes listed in arguments
|
||||||
|
Syntax: SCOPE_DUMP: some.package.ClassName:foo;bar, some.package.OtherClass
|
||||||
|
^^^ ^^^
|
||||||
|
members foo and bar from ClassName |
|
||||||
|
all members from OtherClass
|
||||||
Enables ${FirScopeDumpHandler::class}
|
Enables ${FirScopeDumpHandler::class}
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
)
|
)
|
||||||
|
|||||||
+39
-18
@@ -17,7 +17,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.FirNamedFunctionSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||||
import org.jetbrains.kotlin.fir.types.render
|
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -40,16 +40,39 @@ class FirScopeDumpHandler(testServices: TestServices) : FirAnalysisHandler(testS
|
|||||||
get() = listOf(FirDiagnosticsDirectives)
|
get() = listOf(FirDiagnosticsDirectives)
|
||||||
|
|
||||||
override fun processModule(module: TestModule, info: FirOutputArtifact) {
|
override fun processModule(module: TestModule, info: FirOutputArtifact) {
|
||||||
val fqNames = module.directives[FirDiagnosticsDirectives.SCOPE_DUMP]
|
val fqNamesWithNames = module.directives[FirDiagnosticsDirectives.SCOPE_DUMP]
|
||||||
if (fqNames.isEmpty()) return
|
if (fqNamesWithNames.isEmpty()) return
|
||||||
val printer = SmartPrinter(dumper.builderForModule(module), indent = " ")
|
val printer = SmartPrinter(dumper.builderForModule(module), indent = " ")
|
||||||
for (fqName in fqNames) {
|
for (fqNameWithNames in fqNamesWithNames) {
|
||||||
printer.processClass(fqName, info.session, info.firAnalyzerFacade.scopeSession, module)
|
val (fqName, names) = extractFqNameAndMemberNames(fqNameWithNames)
|
||||||
|
printer.processClass(fqName, names, info.session, info.firAnalyzerFacade.scopeSession, module)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun SmartPrinter.processClass(fqName: String, session: FirSession, scopeSession: ScopeSession, module: TestModule) {
|
private fun extractFqNameAndMemberNames(fqNameWithNames: String): Pair<String, List<String>> {
|
||||||
val classId = ClassId.topLevel(FqName.fromSegments(fqName.split(".")))
|
val (fqName, namesString) = fqNameWithNames.split(":").takeIf { it.size > 1 } ?: return fqNameWithNames to emptyList()
|
||||||
|
return fqName to namesString.split(";")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun SmartPrinter.processClass(
|
||||||
|
fqName: String,
|
||||||
|
namesFromDirective: List<String>,
|
||||||
|
session: FirSession,
|
||||||
|
scopeSession: ScopeSession,
|
||||||
|
module: TestModule
|
||||||
|
) {
|
||||||
|
val (packageFqName, className) = fqName.split(".").let {
|
||||||
|
val packageName = FqName.fromSegments(it.dropLast(1))
|
||||||
|
packageName to it.last()
|
||||||
|
}
|
||||||
|
val classId = className.let {
|
||||||
|
val names = it.split("$")
|
||||||
|
var classId = ClassId(packageFqName, Name.identifier(names.first()))
|
||||||
|
for (name in names.drop(1)) {
|
||||||
|
classId = classId.createNestedClassId(Name.identifier(name))
|
||||||
|
}
|
||||||
|
classId
|
||||||
|
}
|
||||||
val symbol = session.symbolProvider.getClassLikeSymbolByClassId(classId) ?: assertions.fail {
|
val symbol = session.symbolProvider.getClassLikeSymbolByClassId(classId) ?: assertions.fail {
|
||||||
"Class $fqName not found in module ${module.name}"
|
"Class $fqName not found in module ${module.name}"
|
||||||
}
|
}
|
||||||
@@ -57,7 +80,7 @@ class FirScopeDumpHandler(testServices: TestServices) : FirAnalysisHandler(testS
|
|||||||
println("$fqName: ")
|
println("$fqName: ")
|
||||||
|
|
||||||
val scope = firClass.unsubstitutedScope(session, scopeSession, withForcedTypeCalculator = true)
|
val scope = firClass.unsubstitutedScope(session, scopeSession, withForcedTypeCalculator = true)
|
||||||
val names = scope.getCallableNames()
|
val names = namesFromDirective.takeIf { it.isNotEmpty() }?.map { Name.identifier(it) } ?: scope.getCallableNames()
|
||||||
withIndent {
|
withIndent {
|
||||||
for (name in names) {
|
for (name in names) {
|
||||||
processFunctions(name, scope)
|
processFunctions(name, scope)
|
||||||
@@ -80,15 +103,14 @@ class FirScopeDumpHandler(testServices: TestServices) : FirAnalysisHandler(testS
|
|||||||
val functions = scope.getFunctions(name)
|
val functions = scope.getFunctions(name)
|
||||||
for (function in functions) {
|
for (function in functions) {
|
||||||
processFunction(function, scope, SymbolCounter())
|
processFunction(function, scope, SymbolCounter())
|
||||||
println()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun SmartPrinter.processFunction(symbol: FirNamedFunctionSymbol, scope: FirTypeScope, counter: SymbolCounter) {
|
private fun SmartPrinter.processFunction(symbol: FirNamedFunctionSymbol, scope: FirTypeScope, counter: SymbolCounter) {
|
||||||
printInfo(symbol.fir, counter)
|
printInfo(symbol.fir, scope, counter)
|
||||||
scope.processDirectOverriddenFunctionsWithBaseScope(symbol) { overriden, baseScope ->
|
scope.processDirectOverriddenFunctionsWithBaseScope(symbol) { overridden, baseScope ->
|
||||||
withIndent {
|
withIndent {
|
||||||
processFunction(overriden, baseScope, counter)
|
processFunction(overridden, baseScope, counter)
|
||||||
}
|
}
|
||||||
ProcessorAction.NEXT
|
ProcessorAction.NEXT
|
||||||
}
|
}
|
||||||
@@ -97,14 +119,13 @@ class FirScopeDumpHandler(testServices: TestServices) : FirAnalysisHandler(testS
|
|||||||
private fun SmartPrinter.processProperties(name: Name, scope: FirTypeScope) {
|
private fun SmartPrinter.processProperties(name: Name, scope: FirTypeScope) {
|
||||||
val properties = scope.getProperties(name)
|
val properties = scope.getProperties(name)
|
||||||
for (property in properties) {
|
for (property in properties) {
|
||||||
if (property !is FirPropertySymbol) continue
|
|
||||||
processProperty(property, scope, SymbolCounter())
|
processProperty(property, scope, SymbolCounter())
|
||||||
println()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun SmartPrinter.processProperty(symbol: FirPropertySymbol, scope: FirTypeScope, counter: SymbolCounter) {
|
private fun SmartPrinter.processProperty(symbol: FirVariableSymbol<*>, scope: FirTypeScope, counter: SymbolCounter) {
|
||||||
printInfo(symbol.fir, counter)
|
printInfo(symbol.fir, scope, counter)
|
||||||
|
if (symbol !is FirPropertySymbol) return
|
||||||
withIndent {
|
withIndent {
|
||||||
scope.processDirectOverriddenPropertiesWithBaseScope(symbol) { overriden, baseScope ->
|
scope.processDirectOverriddenPropertiesWithBaseScope(symbol) { overriden, baseScope ->
|
||||||
processProperty(overriden, baseScope, counter)
|
processProperty(overriden, baseScope, counter)
|
||||||
@@ -113,10 +134,10 @@ class FirScopeDumpHandler(testServices: TestServices) : FirAnalysisHandler(testS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun SmartPrinter.printInfo(declaration: FirCallableDeclaration, counter: SymbolCounter) {
|
private fun SmartPrinter.printInfo(declaration: FirCallableDeclaration, scope: FirTypeScope, counter: SymbolCounter) {
|
||||||
print("[${declaration.origin}]: ")
|
print("[${declaration.origin}]: ")
|
||||||
print(declaration.render(FirRenderer.RenderMode.NoBodies).trim())
|
print(declaration.render(FirRenderer.RenderMode.NoBodies).trim())
|
||||||
print(" from ${declaration.dispatchReceiverType?.render()}")
|
print(" from $scope")
|
||||||
println(" [id: ${counter.getIndex(declaration.symbol)}]")
|
println(" [id: ${counter.getIndex(declaration.symbol)}]")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
@@ -82,6 +82,7 @@ fun TestConfigurationBuilder.baseFirDiagnosticTestConfiguration(
|
|||||||
::FirCfgDumpHandler,
|
::FirCfgDumpHandler,
|
||||||
::FirCfgConsistencyHandler,
|
::FirCfgConsistencyHandler,
|
||||||
::FirNoImplicitTypesHandler,
|
::FirNoImplicitTypesHandler,
|
||||||
|
::FirScopeDumpHandler,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -52,7 +52,7 @@ open class AbstractFirBlackBoxCodegenTest : AbstractJvmBlackBoxCodegenTestBase<F
|
|||||||
}
|
}
|
||||||
|
|
||||||
configureFirHandlersStep {
|
configureFirHandlersStep {
|
||||||
useHandlers(
|
useHandlersAtFirst(
|
||||||
::FirDumpHandler,
|
::FirDumpHandler,
|
||||||
::FirScopeDumpHandler,
|
::FirScopeDumpHandler,
|
||||||
::FirCfgDumpHandler,
|
::FirCfgDumpHandler,
|
||||||
|
|||||||
Reference in New Issue
Block a user