[FIR] Add ability to specify members in FirScopeDumpHandler

This commit is contained in:
Dmitriy Novozhilov
2021-12-09 12:13:12 +03:00
parent d588b2e654
commit 09a7a1c09f
5 changed files with 49 additions and 19 deletions
@@ -30,6 +30,10 @@ class HandlersStepBuilder<I : ResultingArtifact<I>>(val artifactKind: TestArtifa
handlers += constructor
}
fun useHandlersAtFirst(vararg constructor: Constructor<AnalysisHandler<I>>) {
handlers.addAll(0, constructor.toList())
}
fun useHandlers(constructors: List<Constructor<AnalysisHandler<I>>>) {
handlers += constructors
}
@@ -54,6 +54,10 @@ object FirDiagnosticsDirectives : SimpleDirectivesContainer() {
val SCOPE_DUMP by stringDirective(
description = """
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}
""".trimIndent()
)
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
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.FqName
import org.jetbrains.kotlin.name.Name
@@ -40,16 +40,39 @@ class FirScopeDumpHandler(testServices: TestServices) : FirAnalysisHandler(testS
get() = listOf(FirDiagnosticsDirectives)
override fun processModule(module: TestModule, info: FirOutputArtifact) {
val fqNames = module.directives[FirDiagnosticsDirectives.SCOPE_DUMP]
if (fqNames.isEmpty()) return
val fqNamesWithNames = module.directives[FirDiagnosticsDirectives.SCOPE_DUMP]
if (fqNamesWithNames.isEmpty()) return
val printer = SmartPrinter(dumper.builderForModule(module), indent = " ")
for (fqName in fqNames) {
printer.processClass(fqName, info.session, info.firAnalyzerFacade.scopeSession, module)
for (fqNameWithNames in fqNamesWithNames) {
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) {
val classId = ClassId.topLevel(FqName.fromSegments(fqName.split(".")))
private fun extractFqNameAndMemberNames(fqNameWithNames: String): Pair<String, List<String>> {
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 {
"Class $fqName not found in module ${module.name}"
}
@@ -57,7 +80,7 @@ class FirScopeDumpHandler(testServices: TestServices) : FirAnalysisHandler(testS
println("$fqName: ")
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 {
for (name in names) {
processFunctions(name, scope)
@@ -80,15 +103,14 @@ class FirScopeDumpHandler(testServices: TestServices) : FirAnalysisHandler(testS
val functions = scope.getFunctions(name)
for (function in functions) {
processFunction(function, scope, SymbolCounter())
println()
}
}
private fun SmartPrinter.processFunction(symbol: FirNamedFunctionSymbol, scope: FirTypeScope, counter: SymbolCounter) {
printInfo(symbol.fir, counter)
scope.processDirectOverriddenFunctionsWithBaseScope(symbol) { overriden, baseScope ->
printInfo(symbol.fir, scope, counter)
scope.processDirectOverriddenFunctionsWithBaseScope(symbol) { overridden, baseScope ->
withIndent {
processFunction(overriden, baseScope, counter)
processFunction(overridden, baseScope, counter)
}
ProcessorAction.NEXT
}
@@ -97,14 +119,13 @@ class FirScopeDumpHandler(testServices: TestServices) : FirAnalysisHandler(testS
private fun SmartPrinter.processProperties(name: Name, scope: FirTypeScope) {
val properties = scope.getProperties(name)
for (property in properties) {
if (property !is FirPropertySymbol) continue
processProperty(property, scope, SymbolCounter())
println()
}
}
private fun SmartPrinter.processProperty(symbol: FirPropertySymbol, scope: FirTypeScope, counter: SymbolCounter) {
printInfo(symbol.fir, counter)
private fun SmartPrinter.processProperty(symbol: FirVariableSymbol<*>, scope: FirTypeScope, counter: SymbolCounter) {
printInfo(symbol.fir, scope, counter)
if (symbol !is FirPropertySymbol) return
withIndent {
scope.processDirectOverriddenPropertiesWithBaseScope(symbol) { overriden, baseScope ->
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.render(FirRenderer.RenderMode.NoBodies).trim())
print(" from ${declaration.dispatchReceiverType?.render()}")
print(" from $scope")
println(" [id: ${counter.getIndex(declaration.symbol)}]")
}
@@ -82,6 +82,7 @@ fun TestConfigurationBuilder.baseFirDiagnosticTestConfiguration(
::FirCfgDumpHandler,
::FirCfgConsistencyHandler,
::FirNoImplicitTypesHandler,
::FirScopeDumpHandler,
)
}
@@ -52,7 +52,7 @@ open class AbstractFirBlackBoxCodegenTest : AbstractJvmBlackBoxCodegenTestBase<F
}
configureFirHandlersStep {
useHandlers(
useHandlersAtFirst(
::FirDumpHandler,
::FirScopeDumpHandler,
::FirCfgDumpHandler,