[JVM] Implement new inlined variable naming format
^KT-65478 fixed
This commit is contained in:
committed by
Alexander Udalov
parent
9ea775cbed
commit
407448d8e3
+13
-3
@@ -11,9 +11,11 @@ import org.jetbrains.kotlin.test.directives.AsmLikeInstructionListingDirectives
|
||||
import org.jetbrains.kotlin.test.directives.AsmLikeInstructionListingDirectives.CHECK_ASM_LIKE_INSTRUCTIONS
|
||||
import org.jetbrains.kotlin.test.directives.AsmLikeInstructionListingDirectives.CURIOUS_ABOUT
|
||||
import org.jetbrains.kotlin.test.directives.AsmLikeInstructionListingDirectives.FIR_DIFFERENCE
|
||||
import org.jetbrains.kotlin.test.directives.AsmLikeInstructionListingDirectives.INLINE_SCOPES_DIFFERENCE
|
||||
import org.jetbrains.kotlin.test.directives.AsmLikeInstructionListingDirectives.IR_DIFFERENCE
|
||||
import org.jetbrains.kotlin.test.directives.AsmLikeInstructionListingDirectives.LOCAL_VARIABLE_TABLE
|
||||
import org.jetbrains.kotlin.test.directives.AsmLikeInstructionListingDirectives.RENDER_ANNOTATIONS
|
||||
import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives.USE_INLINE_SCOPES_NUMBERS
|
||||
import org.jetbrains.kotlin.test.directives.model.Directive
|
||||
import org.jetbrains.kotlin.test.directives.model.DirectivesContainer
|
||||
import org.jetbrains.kotlin.test.model.BinaryArtifacts
|
||||
@@ -38,6 +40,7 @@ class AsmLikeInstructionListingHandler(testServices: TestServices) : JvmBinaryAr
|
||||
companion object {
|
||||
const val DUMP_EXTENSION = "asm.txt"
|
||||
const val IR_DUMP_EXTENSION = "asm.ir.txt"
|
||||
const val INLINE_SCOPES_DUMP_EXTENSION = "asm.scopes.txt"
|
||||
const val FIR_DUMP_EXTENSION = "asm.fir.txt"
|
||||
const val LINE_SEPARATOR = "\n"
|
||||
|
||||
@@ -388,13 +391,20 @@ class AsmLikeInstructionListingHandler(testServices: TestServices) : JvmBinaryAr
|
||||
|
||||
val irDifference = IR_DIFFERENCE in testServices.moduleStructure.allDirectives
|
||||
val firDifference = FIR_DIFFERENCE in testServices.moduleStructure.allDirectives
|
||||
val inlineScopesDifference = INLINE_SCOPES_DIFFERENCE in testServices.moduleStructure.allDirectives
|
||||
|
||||
val firstModule = testServices.moduleStructure.modules.first()
|
||||
|
||||
val inlineScopesNumbersEnabled = firstModule.directives.contains(USE_INLINE_SCOPES_NUMBERS)
|
||||
val extension = when {
|
||||
firDifference && firstModule.frontendKind == FrontendKinds.FIR -> FIR_DUMP_EXTENSION
|
||||
irDifference && firstModule.targetBackend?.isIR == true -> IR_DUMP_EXTENSION
|
||||
else -> DUMP_EXTENSION
|
||||
inlineScopesNumbersEnabled && inlineScopesDifference && firstModule.targetBackend?.isIR == true ->
|
||||
INLINE_SCOPES_DUMP_EXTENSION
|
||||
firDifference && firstModule.frontendKind == FrontendKinds.FIR ->
|
||||
FIR_DUMP_EXTENSION
|
||||
irDifference && firstModule.targetBackend?.isIR == true ->
|
||||
IR_DUMP_EXTENSION
|
||||
else ->
|
||||
DUMP_EXTENSION
|
||||
}
|
||||
|
||||
val testDataFile = testServices.moduleStructure.originalTestDataFiles.first()
|
||||
|
||||
+30
-3
@@ -11,11 +11,13 @@ import org.jetbrains.kotlin.test.backend.codegenSuppressionChecker
|
||||
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives
|
||||
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.CHECK_BYTECODE_TEXT
|
||||
import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.TREAT_AS_ONE_FILE
|
||||
import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives
|
||||
import org.jetbrains.kotlin.test.directives.model.DirectivesContainer
|
||||
import org.jetbrains.kotlin.test.model.BinaryArtifacts
|
||||
import org.jetbrains.kotlin.test.model.TestFile
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
import org.jetbrains.kotlin.test.services.defaultDirectives
|
||||
import org.jetbrains.kotlin.test.services.isKtFile
|
||||
|
||||
class BytecodeTextHandler(testServices: TestServices, private val shouldEnableExplicitly: Boolean = false) :
|
||||
@@ -40,7 +42,14 @@ class BytecodeTextHandler(testServices: TestServices, private val shouldEnableEx
|
||||
val file = files.first { !it.isAdditional }
|
||||
val expected = readExpectedOccurrences(file.originalContent.split("\n"))
|
||||
val actual = info.classFileFactory.createText(IGNORED_PREFIX)
|
||||
checkGeneratedTextAgainstExpectedOccurrences(actual, expected, targetBackend, !isIgnored, assertions)
|
||||
checkGeneratedTextAgainstExpectedOccurrences(
|
||||
actual,
|
||||
expected,
|
||||
targetBackend,
|
||||
!isIgnored,
|
||||
assertions,
|
||||
inlineScopesNumbersEnabled()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +67,14 @@ class BytecodeTextHandler(testServices: TestServices, private val shouldEnableEx
|
||||
|
||||
if (globalOccurrences.isNotEmpty()) {
|
||||
val generatedText = info.classFileFactory.createText()
|
||||
checkGeneratedTextAgainstExpectedOccurrences(generatedText, globalOccurrences, targetBackend, reportProblems, assertions)
|
||||
checkGeneratedTextAgainstExpectedOccurrences(
|
||||
generatedText,
|
||||
globalOccurrences,
|
||||
targetBackend,
|
||||
reportProblems,
|
||||
assertions,
|
||||
inlineScopesNumbersEnabled()
|
||||
)
|
||||
}
|
||||
|
||||
val generatedByFile = info.classFileFactory.createTextForEachFile()
|
||||
@@ -66,9 +82,20 @@ class BytecodeTextHandler(testServices: TestServices, private val shouldEnableEx
|
||||
assertTextWasGenerated(expectedOutputFile, generatedByFile, assertions)
|
||||
val generatedText = generatedByFile[expectedOutputFile]!!
|
||||
val expectedOccurrences = expectedOccurrencesByOutputFile[expectedOutputFile]!!
|
||||
checkGeneratedTextAgainstExpectedOccurrences(generatedText, expectedOccurrences, targetBackend, reportProblems, assertions)
|
||||
checkGeneratedTextAgainstExpectedOccurrences(
|
||||
generatedText,
|
||||
expectedOccurrences,
|
||||
targetBackend,
|
||||
reportProblems,
|
||||
assertions,
|
||||
inlineScopesNumbersEnabled()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun inlineScopesNumbersEnabled(): Boolean {
|
||||
return LanguageSettingsDirectives.USE_INLINE_SCOPES_NUMBERS in testServices.defaultDirectives
|
||||
}
|
||||
|
||||
override fun processAfterAllModules(someAssertionWasFailed: Boolean) {}
|
||||
}
|
||||
|
||||
+2
-1
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.test.TargetBackend
|
||||
import org.jetbrains.kotlin.test.model.FrontendKind
|
||||
import org.jetbrains.kotlin.test.model.TestModule
|
||||
import org.jetbrains.kotlin.test.services.TestServices
|
||||
import org.jetbrains.kotlin.test.services.defaultDirectives
|
||||
import org.jetbrains.kotlin.test.services.sourceProviders.MainFunctionForBlackBoxTestsSourceProvider.Companion.BOX_MAIN_FILE_NAME
|
||||
import org.jetbrains.kotlin.test.utils.*
|
||||
import java.io.File
|
||||
@@ -155,7 +156,7 @@ abstract class DebugRunner(testServices: TestServices) : JvmBoxRunner(testServic
|
||||
}
|
||||
eventSet.resume()
|
||||
}
|
||||
checkSteppingTestResult(frontend, backend, wholeFile, loggedItems)
|
||||
checkSteppingTestResult(frontend, backend, wholeFile, loggedItems, testServices.defaultDirectives)
|
||||
virtualMachine.resume()
|
||||
}
|
||||
|
||||
|
||||
+4
@@ -17,6 +17,10 @@ object AsmLikeInstructionListingDirectives : SimpleDirectivesContainer() {
|
||||
"If present then saves dump for IR backend in asm.ir.txt file"
|
||||
)
|
||||
|
||||
val INLINE_SCOPES_DIFFERENCE by directive(
|
||||
"If present and if inline scopes are enabled then saves dump for IR backend in asm.scopes.txt file"
|
||||
)
|
||||
|
||||
val FIR_DIFFERENCE by directive(
|
||||
"If present then saves dump for IR backend in asm.fir.txt file"
|
||||
)
|
||||
|
||||
+6
@@ -97,6 +97,12 @@ fun TestConfigurationBuilder.useIrInliner() {
|
||||
}
|
||||
}
|
||||
|
||||
fun TestConfigurationBuilder.useInlineScopesNumbers() {
|
||||
defaultDirectives {
|
||||
+LanguageSettingsDirectives.USE_INLINE_SCOPES_NUMBERS
|
||||
}
|
||||
}
|
||||
|
||||
fun TestConfigurationBuilder.applyDumpSmapDirective() {
|
||||
forTestsMatching("compiler/testData/codegen/boxInline/smap/*") {
|
||||
defaultDirectives {
|
||||
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 2010-2024 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.test.runners.codegen.inlineScopes
|
||||
|
||||
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||
import org.jetbrains.kotlin.test.runners.codegen.*
|
||||
|
||||
/*
|
||||
* All tests in this file are Fir Light Tree tests because they are meant to test inline scopes numbers
|
||||
* in the JVM backend and their execution result shouldn't be affected by the parser.
|
||||
*/
|
||||
|
||||
open class AbstractFirBlackBoxInlineCodegenWithBytecodeInlinerTestWithInlineScopes :
|
||||
AbstractFirLightTreeBlackBoxInlineCodegenWithBytecodeInlinerTest() {
|
||||
override fun configure(builder: TestConfigurationBuilder) {
|
||||
super.configure(builder)
|
||||
builder.useInlineScopesNumbers()
|
||||
}
|
||||
}
|
||||
|
||||
open class AbstractFirBlackBoxInlineCodegenWithIrInlinerTestWithInlineScopes : AbstractFirLightTreeBlackBoxInlineCodegenWithIrInlinerTest() {
|
||||
override fun configure(builder: TestConfigurationBuilder) {
|
||||
super.configure(builder)
|
||||
builder.useInlineScopesNumbers()
|
||||
}
|
||||
}
|
||||
|
||||
// Adding this test will result in test failures.
|
||||
// TODO: Decide what to do with this test
|
||||
open class AbstractFirAsmLikeInstructionListingTestWithInlineScopes : AbstractFirLightTreeAsmLikeInstructionListingTest() {
|
||||
override fun configure(builder: TestConfigurationBuilder) {
|
||||
super.configure(builder)
|
||||
builder.useInlineScopesNumbers()
|
||||
}
|
||||
}
|
||||
|
||||
open class AbstractFirBlackBoxCodegenTestWithInlineScopes : AbstractFirLightTreeBlackBoxCodegenTest() {
|
||||
override fun configure(builder: TestConfigurationBuilder) {
|
||||
super.configure(builder)
|
||||
builder.useInlineScopesNumbers()
|
||||
}
|
||||
}
|
||||
|
||||
// Adding this test will result in test failures.
|
||||
// TODO: Add or remove when the fate of the IR inliner is decided.
|
||||
open class AbstractFirBlackBoxCodegenWithIrInlinerTestWithInlineScopes : AbstractFirLightTreeBlackBoxCodegenTest() {
|
||||
override fun configure(builder: TestConfigurationBuilder) {
|
||||
super.configure(builder)
|
||||
builder.useInlineScopesNumbers()
|
||||
builder.useIrInliner()
|
||||
}
|
||||
}
|
||||
|
||||
open class AbstractFirBytecodeTextTestWithInlineScopes : AbstractFirLightTreeBytecodeTextTest() {
|
||||
override fun configure(builder: TestConfigurationBuilder) {
|
||||
super.configure(builder)
|
||||
builder.useInlineScopesNumbers()
|
||||
}
|
||||
}
|
||||
|
||||
open class AbstractFirLocalVariableBytecodeInlinerTestWithInlineScopes : AbstractFirLightTreeLocalVariableTest() {
|
||||
override fun configure(builder: TestConfigurationBuilder) {
|
||||
super.configure(builder)
|
||||
builder.useInlineScopesNumbers()
|
||||
}
|
||||
}
|
||||
|
||||
open class AbstractFirLocalVariableIrInlinerTestWithInlineScopes : AbstractFirLightTreeLocalVariableTest() {
|
||||
override fun configure(builder: TestConfigurationBuilder) {
|
||||
super.configure(builder)
|
||||
builder.useInlineScopesNumbers()
|
||||
builder.useIrInliner()
|
||||
}
|
||||
}
|
||||
|
||||
open class AbstractFirSerializeCompileKotlinAgainstInlineKotlinTestWithInlineScopes :
|
||||
AbstractFirLightTreeSerializeCompileKotlinAgainstInlineKotlinTest() {
|
||||
override fun configure(builder: TestConfigurationBuilder) {
|
||||
super.configure(builder)
|
||||
builder.useInlineScopesNumbers()
|
||||
}
|
||||
}
|
||||
|
||||
open class AbstractFirSteppingWithBytecodeInlinerTestWithInlineScopes : AbstractFirLightTreeSteppingTest() {
|
||||
override fun configure(builder: TestConfigurationBuilder) {
|
||||
super.configure(builder)
|
||||
builder.useInlineScopesNumbers()
|
||||
}
|
||||
}
|
||||
|
||||
open class AbstractFirSteppingWithIrInlinerTestWithInlineScopes : AbstractFirLightTreeSteppingTest() {
|
||||
override fun configure(builder: TestConfigurationBuilder) {
|
||||
super.configure(builder)
|
||||
builder.useInlineScopesNumbers()
|
||||
builder.useIrInliner()
|
||||
}
|
||||
}
|
||||
+2
@@ -41,6 +41,7 @@ import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives
|
||||
import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives.DISABLE_CALL_ASSERTIONS
|
||||
import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives.DISABLE_PARAM_ASSERTIONS
|
||||
import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives.EMIT_JVM_TYPE_ANNOTATIONS
|
||||
import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives.USE_INLINE_SCOPES_NUMBERS
|
||||
import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives.ENABLE_JVM_IR_INLINER
|
||||
import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives.ENABLE_JVM_PREVIEW
|
||||
import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives.JDK_RELEASE
|
||||
@@ -180,6 +181,7 @@ open class JvmEnvironmentConfigurator(testServices: TestServices) : EnvironmentC
|
||||
register(OLD_INNER_CLASSES_LOGIC, JVMConfigurationKeys.OLD_INNER_CLASSES_LOGIC)
|
||||
register(LINK_VIA_SIGNATURES_K1, JVMConfigurationKeys.LINK_VIA_SIGNATURES)
|
||||
register(ENABLE_JVM_IR_INLINER, JVMConfigurationKeys.ENABLE_IR_INLINER)
|
||||
register(USE_INLINE_SCOPES_NUMBERS, JVMConfigurationKeys.USE_INLINE_SCOPES_NUMBERS)
|
||||
}
|
||||
|
||||
override fun configureCompilerConfiguration(configuration: CompilerConfiguration, module: TestModule) {
|
||||
|
||||
+74
-16
@@ -6,6 +6,9 @@
|
||||
package org.jetbrains.kotlin.test.utils
|
||||
|
||||
import org.jetbrains.kotlin.test.TargetBackend
|
||||
import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives
|
||||
import org.jetbrains.kotlin.test.directives.model.Directive
|
||||
import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives
|
||||
import org.jetbrains.kotlin.test.model.FrontendKind
|
||||
import org.jetbrains.kotlin.test.model.FrontendKinds
|
||||
import org.jetbrains.kotlin.test.services.JUnit5Assertions.assertEqualsToFile
|
||||
@@ -56,16 +59,46 @@ private fun String.normalizeIndyLambdas(): String =
|
||||
|
||||
private const val EXPECTATIONS_MARKER = "// EXPECTATIONS"
|
||||
private const val FORCE_STEP_INTO_MARKER = "// FORCE_STEP_INTO"
|
||||
private const val DIRECTIVE_MARKER = "+"
|
||||
|
||||
data class BackendWithDirectives(val backend: TargetBackend) {
|
||||
companion object {
|
||||
private val directivesToConsider = mutableSetOf(LanguageSettingsDirectives.USE_INLINE_SCOPES_NUMBERS)
|
||||
}
|
||||
|
||||
private val directives = mutableSetOf<Directive>()
|
||||
|
||||
fun addDirectiveIfConsidered(directive: Directive) {
|
||||
if (directive in directivesToConsider) {
|
||||
directives += directive
|
||||
}
|
||||
}
|
||||
|
||||
fun contains(registeredDirectives: RegisteredDirectives, directivesInTestFile: Set<Directive>): Boolean {
|
||||
if (directivesInTestFile.isEmpty()) return true
|
||||
return registeredDirectives.filter { it in directivesToConsider && it in directivesInTestFile }.toSet() == directives
|
||||
}
|
||||
}
|
||||
|
||||
fun checkSteppingTestResult(
|
||||
frontendKind: FrontendKind<*>,
|
||||
targetBackend: TargetBackend,
|
||||
wholeFile: File,
|
||||
loggedItems: List<SteppingTestLoggedData>
|
||||
loggedItems: List<SteppingTestLoggedData>,
|
||||
directives: RegisteredDirectives
|
||||
) {
|
||||
val actual = mutableListOf<String>()
|
||||
val lines = wholeFile.readLines()
|
||||
val forceStepInto = lines.any { it.startsWith(FORCE_STEP_INTO_MARKER) }
|
||||
val directivesInTestFile = mutableSetOf<Directive>()
|
||||
var forceStepInto = false
|
||||
for (line in lines) {
|
||||
if (line.contains(DIRECTIVE_MARKER)) {
|
||||
directivesInTestFile.addAll(line.getDeclaredDirectives())
|
||||
}
|
||||
if (line.startsWith(FORCE_STEP_INTO_MARKER)) {
|
||||
forceStepInto = true
|
||||
}
|
||||
}
|
||||
|
||||
val actualLineNumbers = compressSequencesWithoutLineNumber(loggedItems)
|
||||
.filter {
|
||||
@@ -86,8 +119,8 @@ fun checkSteppingTestResult(
|
||||
if (line.startsWith(FORCE_STEP_INTO_MARKER)) break
|
||||
}
|
||||
|
||||
var currentBackends = setOf(TargetBackend.ANY)
|
||||
var currentFrontends = setOf(frontendKind)
|
||||
var currentBackends = listOf(BackendWithDirectives(TargetBackend.ANY))
|
||||
var currentFrontends = listOf(frontendKind)
|
||||
for (line in lineIterator) {
|
||||
if (line.isEmpty()) {
|
||||
actual.add(line)
|
||||
@@ -95,20 +128,41 @@ fun checkSteppingTestResult(
|
||||
}
|
||||
if (line.startsWith(EXPECTATIONS_MARKER)) {
|
||||
actual.add(line)
|
||||
val backendsAndFrontends = line.removePrefix(EXPECTATIONS_MARKER).splitToSequence(Regex("\\s+")).filter { it.isNotEmpty() }
|
||||
currentBackends = backendsAndFrontends
|
||||
.mapNotNullTo(mutableSetOf()) { valueOfOrNull<TargetBackend>(it) }
|
||||
.takeIf { it.isNotEmpty() }
|
||||
?: setOf(TargetBackend.ANY)
|
||||
currentFrontends = backendsAndFrontends
|
||||
.mapNotNullTo(mutableSetOf(), FrontendKinds::fromString)
|
||||
.takeIf { it.isNotEmpty() }
|
||||
?: setOf(frontendKind)
|
||||
val options = line.removePrefix(EXPECTATIONS_MARKER).splitToSequence(Regex("\\s+")).filter { it.isNotEmpty() }
|
||||
val backends = mutableListOf<BackendWithDirectives>()
|
||||
val frontends = mutableListOf<FrontendKind<*>>()
|
||||
var currentBackendWithDirectives: BackendWithDirectives? = null
|
||||
for (option in options) {
|
||||
val backend = valueOfOrNull<TargetBackend>(option)
|
||||
if (backend != null) {
|
||||
val backendWithDirectives = BackendWithDirectives(backend)
|
||||
currentBackendWithDirectives = backendWithDirectives
|
||||
backends += backendWithDirectives
|
||||
continue
|
||||
}
|
||||
|
||||
val frontend = FrontendKinds.fromString(option)
|
||||
if (frontend != null) {
|
||||
frontends += frontend
|
||||
continue
|
||||
}
|
||||
|
||||
val directive = LanguageSettingsDirectives[option.substringAfter(DIRECTIVE_MARKER)]
|
||||
if (directive != null && currentBackendWithDirectives != null) {
|
||||
currentBackendWithDirectives.addDirectiveIfConsidered(directive)
|
||||
}
|
||||
}
|
||||
|
||||
currentBackends = backends.takeIf { it.isNotEmpty() } ?: listOf(BackendWithDirectives(TargetBackend.ANY))
|
||||
currentFrontends = frontends.takeIf { it.isNotEmpty() } ?: listOf(frontendKind)
|
||||
continue
|
||||
}
|
||||
if ((currentBackends.contains(TargetBackend.ANY) || currentBackends.contains(targetBackend)) &&
|
||||
currentFrontends.contains(frontendKind)
|
||||
) {
|
||||
|
||||
val containsBackend =
|
||||
currentBackends.any {
|
||||
it.backend == TargetBackend.ANY || (it.backend == targetBackend && it.contains(directives, directivesInTestFile))
|
||||
}
|
||||
if (containsBackend && currentFrontends.contains(frontendKind)) {
|
||||
if (actualLineNumbersIterator.hasNext()) {
|
||||
actual.add(actualLineNumbersIterator.next())
|
||||
}
|
||||
@@ -125,6 +179,10 @@ fun checkSteppingTestResult(
|
||||
assertEqualsToFile(wholeFile, actual.joinToString("\n"))
|
||||
}
|
||||
|
||||
private fun String.getDeclaredDirectives(): List<Directive> {
|
||||
return split(Regex("\\s+")).mapNotNull { LanguageSettingsDirectives[it.substringAfter(DIRECTIVE_MARKER)] }
|
||||
}
|
||||
|
||||
/**
|
||||
* Compresses sequences of the same location without line number in the log:
|
||||
* specifically removes locations without linenumber, that would otherwise
|
||||
|
||||
Reference in New Issue
Block a user