[K/JS] Throw error when a module contains file with the same name and package (ignoring case)

This commit is contained in:
Artem Kobzar
2023-07-07 13:50:04 +00:00
committed by Space Team
parent 0e6930e7ef
commit 7c7aa98875
9 changed files with 94 additions and 4 deletions
@@ -15,9 +15,24 @@ import org.jetbrains.kotlin.ir.declarations.path
private const val EXPORTER_FILE_POSTFIX = ".export"
class ModuleFragmentToExternalName(private val jsOutputNamesMapping: Map<IrModuleFragment, String>) {
private val externalNameToItsFile = hashMapOf<String, IrFile>()
fun getExternalNameFor(file: IrFile, granularity: JsGenerationGranularity): String {
assert(granularity == JsGenerationGranularity.PER_FILE) { "This method should be used only for PER_FILE granularity" }
return file.module.getJsOutputName().getExternalModuleNameForPerFile(file)
return file.module.getJsOutputName().getExternalModuleNameForPerFile(file).also {
val alreadyReservedBy = externalNameToItsFile.putIfAbsent(it.lowercase(), file)
if (alreadyReservedBy != null && alreadyReservedBy != file) {
error(
"""
|There are two files in module '${file.module.name}' that have the similar package and file names.
| - Package "${file.packageFqName.asString()}" and path "${file.path}"
| - Package "${alreadyReservedBy.packageFqName.asString()}" and path "${alreadyReservedBy.path}"
|Note, that if the difference is only in letter cases, it also could lead to a clash of the compiled artifacts
""".trimMargin()
)
}
}
}
fun getExternalNameForExporterFile(file: IrFile, granularity: JsGenerationGranularity): String {
@@ -359,6 +359,27 @@ class Kotlin2JsIrGradlePluginIT : AbstractKotlin2JsGradlePluginIT(true) {
}
}
@DisplayName("per-file with the declarations validation")
@GradleTest
fun testPerFileProjectWithResultFilesClash(gradleVersion: GradleVersion) {
project("kotlin-js-invalid-per-file-project", gradleVersion) {
buildAndFail("compileDevelopmentExecutableKotlinJs") {
assertTasksFailed(":compileDevelopmentExecutableKotlinJs")
assertOutputContains("""
|There are two files in module '<kotlin-js-invalid-per-file-project>' that have the similar package and file names.
| - Package "com.example" and
""".trimMargin())
}
buildAndFail("compileProductionExecutableKotlinJs") {
assertTasksFailed(":compileProductionExecutableKotlinJs")
assertOutputContains("""
|There are two files in module '<kotlin-js-invalid-per-file-project>' that have the similar package and file names.
| - Package "com.example" and path
""".trimMargin())
}
}
}
@DisplayName("fully qualified names can be used in the sourcemap")
@GradleTest
fun testKotlinJsSourceMapGenerateFqNames(gradleVersion: GradleVersion) {
@@ -0,0 +1,16 @@
plugins {
kotlin("js")
}
repositories {
mavenLocal()
mavenCentral()
}
kotlin {
js(IR) {
useEsModules()
binaries.executable()
nodejs()
}
}
@@ -0,0 +1,8 @@
kotlin.tests.individualTaskReports=true
kotlin.js.ir.output.granularity=per-file
kotlin.incremental=false
kotlin.incremental.js=false
kotlin.incremental.js.ir=false
kotlin.incremental.js.klib=false
kotlin.incremental.multiplatform=false
kotlin.incremental.useClasspathSnapshot=false
@@ -0,0 +1,16 @@
/*
* Copyright 2010-2019 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 com.example
@JsExport
fun best(): Int {
return 42
}
@JsExport
fun simpleBest(): Int {
return 73
}
@@ -0,0 +1,9 @@
/*
* Copyright 2010-2019 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 com.example
@JsExport
public val foo = 44
@@ -24,6 +24,7 @@ internal const val MINIMIZED_MEMBER_NAMES = "-Xir-minimized-member-names"
internal const val KLIB_MODULE_NAME = "-Xir-module-name"
internal const val PER_FILE = "-Xir-per-file"
internal const val PER_MODULE = "-Xir-per-module"
internal const val PER_MODULE_OUTPUT_NAME = "-Xir-per-module-output-name"
@@ -7,7 +7,8 @@ package org.jetbrains.kotlin.gradle.targets.js.ir
enum class KotlinJsIrOutputGranularity {
WHOLE_PROGRAM,
PER_MODULE;
PER_MODULE,
PER_FILE;
companion object {
fun byArgument(argument: String): KotlinJsIrOutputGranularity? =
@@ -17,6 +18,9 @@ enum class KotlinJsIrOutputGranularity {
}
fun KotlinJsIrOutputGranularity.toCompilerArgument(): String {
val perModule = this == KotlinJsIrOutputGranularity.PER_MODULE
return "$PER_MODULE=$perModule"
return when (this) {
KotlinJsIrOutputGranularity.PER_FILE -> PER_FILE
KotlinJsIrOutputGranularity.PER_MODULE -> PER_MODULE
KotlinJsIrOutputGranularity.WHOLE_PROGRAM -> ""
}
}