[Tests] Check for duplicate file names in FIR diagnostic tests with IR
The relative path of a test file is just its name, even if it's in a module. Diagnostics in IR are mapped to the file path and so it's reported on all files with the same path, i.e. name. This doesn't happen in production code because no two files can have the same path. The proper fix would be to prefix the test files' paths with the module name. Unfortunately, this breaks a bunch of test runners that rely on the current behavior. Especially, some JS runners turned out to be hard to fix. The linked YouTrack issue contains a WIP, incomplete patch of fixing some runners. #KT-61592 Fixed #KT-63252
This commit is contained in:
committed by
Space Team
parent
159d89b7af
commit
eba1fdec1d
@@ -11,10 +11,10 @@
|
||||
// MODULE: commonJS()()(common)
|
||||
// TARGET_PLATFORM: JS
|
||||
|
||||
// FILE: StringValue.kt
|
||||
actual class Strin<!NO_ACTUAL_FOR_EXPECT{JS}!>gValue(val value: String<!>)
|
||||
<!NO_ACTUAL_FOR_EXPECT{JS}!>
|
||||
actual fun StringValue.plus(other: String) = StringVal<!>ue(this.value + other)
|
||||
// FILE: StringValueJs.kt
|
||||
actual class StringValue(val value: String)
|
||||
|
||||
actual fun StringValue.plus(other: String) = StringValue(this.value + other)
|
||||
|
||||
// MODULE: intermediate()()(common)
|
||||
// TARGET_PLATFORM: Common
|
||||
@@ -31,10 +31,10 @@ interface KotlinXStringDemoInterface {
|
||||
// MODULE: js()()(common, intermediate)
|
||||
// TARGET_PLATFORM: JS
|
||||
|
||||
// FILE: StringDemoInterface.kt
|
||||
// FILE: StringDemoInterfaceJs.kt
|
||||
actual typealias StringDemoInterface = KotlinXStringDemoInterface
|
||||
|
||||
actual fun StringDemoIn<!EXPECT_ACTUAL_INCOMPATIBILITY!>terface.<!ACTUAL_WITHOUT_EXPECT("actual fun StringDemoInterface.plusK(): <ERROR TYPE REF: Unresolved name: value>; The following declaration is incompatible because return type is different: expect fun StringDemoInterface.plusK(): String")!>plusK<!>() = <!EXPECT_CLASS_AS_FUNCTION!>StringValue<!>(value).plus("K")<!>.<!UNRESOLVED_REFERENCE!>value<!>
|
||||
actual fun StringDemoInterface.<!ACTUAL_WITHOUT_EXPECT("actual fun StringDemoInterface.plusK(): <ERROR TYPE REF: Unresolved name: value>; The following declaration is incompatible because return type is different: expect fun StringDemoInterface.plusK(): String")!>plusK<!>() = <!EXPECT_CLASS_AS_FUNCTION!>StringValue<!>(value).plus("K").<!UNRESOLVED_REFERENCE!>value<!>
|
||||
|
||||
// FILE: main.kt
|
||||
class StringDemo(override val value: String) : StringDemoInterface
|
||||
|
||||
@@ -11,7 +11,7 @@ expect fun StringValue.<!NO_ACTUAL_FOR_EXPECT{JS}!>plus<!>(other: String): Strin
|
||||
// MODULE: commonJS()()(common)
|
||||
// TARGET_PLATFORM: JS
|
||||
|
||||
// FILE: StringValue.kt
|
||||
// FILE: StringValueJs.kt
|
||||
actual class StringValue(val value: String)
|
||||
|
||||
actual fun StringValue.plus(other: String) = StringValue(this.value + other)
|
||||
@@ -31,7 +31,7 @@ expect fun StringDemoInterface.plusK(): <!NO_ACTUAL_FOR_EXPECT{JS}!>String<!>
|
||||
// MODULE: js()()(common, intermediate)
|
||||
// TARGET_PLATFORM: JS
|
||||
|
||||
// FILE: StringDemoInterface.kt
|
||||
// FILE: StringDemoInterfaceJs.kt
|
||||
actual typealias StringDemoInterface = KotlinXStringDemoInterface
|
||||
|
||||
actual fun StringDemoInterface.<!ACTUAL_WITHOUT_EXPECT("Actual function 'plusK'; The following declaration is incompatible because return type is different: public expect fun StringDemoInterface /* = KotlinXStringDemoInterface */.plusK(): String")!>plusK<!>() = <!RESOLUTION_TO_CLASSIFIER!>StringValue<!>(value).<!DEBUG_INFO_MISSING_UNRESOLVED!>plus<!>("K").<!DEBUG_INFO_MISSING_UNRESOLVED!>value<!>
|
||||
|
||||
+5
-1
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.test.runners
|
||||
import org.jetbrains.kotlin.config.ExplicitApiMode
|
||||
import org.jetbrains.kotlin.diagnostics.impl.SimpleDiagnosticsCollector
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.SessionConfiguration
|
||||
import org.jetbrains.kotlin.fir.symbols.FirLazyDeclarationResolver
|
||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||
import org.jetbrains.kotlin.test.*
|
||||
@@ -110,6 +111,9 @@ abstract class AbstractFirWithActualizerDiagnosticsTest(val parser: FirParser) :
|
||||
}
|
||||
|
||||
useAdditionalService(::LibraryProvider)
|
||||
|
||||
@OptIn(TestInfrastructureInternals::class)
|
||||
useModuleStructureTransformers(DuplicateFileNameChecker)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -238,7 +242,7 @@ fun TestConfigurationBuilder.baseFirDiagnosticTestConfiguration(
|
||||
class FirLazyDeclarationResolverWithPhaseCheckingSessionComponentRegistrar : FirSessionComponentRegistrar() {
|
||||
private val lazyResolver = FirCompilerLazyDeclarationResolverWithPhaseChecking()
|
||||
|
||||
@OptIn(org.jetbrains.kotlin.fir.SessionConfiguration::class)
|
||||
@OptIn(SessionConfiguration::class)
|
||||
override fun registerAdditionalComponent(session: FirSession) {
|
||||
session.register(FirLazyDeclarationResolver::class, lazyResolver)
|
||||
}
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2010-2023 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
|
||||
|
||||
import org.jetbrains.kotlin.test.TestInfrastructureInternals
|
||||
import org.jetbrains.kotlin.test.services.ModuleStructureTransformer
|
||||
import org.jetbrains.kotlin.test.services.TestModuleStructure
|
||||
|
||||
// TODO remove when duplicate files names are supported by prefix their path with the module name KT-63252
|
||||
@OptIn(TestInfrastructureInternals::class)
|
||||
object DuplicateFileNameChecker : ModuleStructureTransformer() {
|
||||
override fun transformModuleStructure(moduleStructure: TestModuleStructure): TestModuleStructure {
|
||||
val files = mutableSetOf<String>()
|
||||
|
||||
for (module in moduleStructure.modules) {
|
||||
for (file in module.files) {
|
||||
if (!files.add(file.name)) {
|
||||
throw IllegalStateException("Duplicate file name: ${file.name}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return moduleStructure
|
||||
}
|
||||
}
|
||||
+5
@@ -7,12 +7,14 @@ package org.jetbrains.kotlin.test.runners.ir
|
||||
|
||||
import org.jetbrains.kotlin.test.FirParser
|
||||
import org.jetbrains.kotlin.test.TargetBackend
|
||||
import org.jetbrains.kotlin.test.TestInfrastructureInternals
|
||||
import org.jetbrains.kotlin.test.backend.ir.IrDiagnosticsHandler
|
||||
import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder
|
||||
import org.jetbrains.kotlin.test.builders.irHandlersStep
|
||||
import org.jetbrains.kotlin.test.directives.configureFirParser
|
||||
import org.jetbrains.kotlin.test.frontend.fir.Fir2IrResultsConverter
|
||||
import org.jetbrains.kotlin.test.runners.AbstractKotlinCompilerWithTargetBackendTest
|
||||
import org.jetbrains.kotlin.test.runners.DuplicateFileNameChecker
|
||||
import org.jetbrains.kotlin.test.runners.baseFirDiagnosticTestConfiguration
|
||||
|
||||
abstract class AbstractFirWithInterpreterDiagnosticsTest(val parser: FirParser) : AbstractKotlinCompilerWithTargetBackendTest(TargetBackend.JVM_IR) {
|
||||
@@ -26,6 +28,9 @@ abstract class AbstractFirWithInterpreterDiagnosticsTest(val parser: FirParser)
|
||||
::IrDiagnosticsHandler
|
||||
)
|
||||
}
|
||||
|
||||
@OptIn(TestInfrastructureInternals::class)
|
||||
useModuleStructureTransformers(DuplicateFileNameChecker)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user