JS: Use the same output paths for JPS and Maven-based builds
#KT-22586 Fixed
This commit is contained in:
@@ -22,11 +22,14 @@ import com.intellij.openapi.components.Storage
|
||||
import com.intellij.openapi.components.StoragePathMacros
|
||||
import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.roots.CompilerModuleExtension
|
||||
import com.intellij.openapi.roots.ModifiableRootModel
|
||||
import com.intellij.openapi.roots.OrderEnumerator
|
||||
import com.intellij.openapi.roots.OrderRootType
|
||||
import com.intellij.openapi.roots.impl.libraries.LibraryEx
|
||||
import com.intellij.openapi.roots.libraries.Library
|
||||
import com.intellij.openapi.util.AsyncResult
|
||||
import com.intellij.util.PathUtil
|
||||
import org.jdom.Element
|
||||
import org.jdom.Text
|
||||
import org.jetbrains.idea.maven.importing.MavenImporter
|
||||
@@ -139,6 +142,39 @@ class KotlinMavenImporter : MavenImporter(KOTLIN_PLUGIN_GROUP_ID, KOTLIN_PLUGIN_
|
||||
}
|
||||
}
|
||||
|
||||
private fun configureJSOutputPaths(
|
||||
mavenProject: MavenProject,
|
||||
modifiableRootModel: ModifiableRootModel,
|
||||
facetSettings: KotlinFacetSettings,
|
||||
mavenPlugin: MavenPlugin
|
||||
) {
|
||||
fun parentPath(path: String): String =
|
||||
File(path).absoluteFile.parentFile.absolutePath
|
||||
|
||||
val sharedOutputFile = mavenPlugin.configurationElement?.getChild("outputFile")?.text
|
||||
|
||||
val compilerModuleExtension = modifiableRootModel.getModuleExtension(CompilerModuleExtension::class.java) ?: return
|
||||
val buildDirectory = mavenProject.buildDirectory
|
||||
|
||||
val executions = mavenPlugin.executions
|
||||
|
||||
executions.forEach {
|
||||
val explicitOutputFile = it.configurationElement?.getChild("outputFile")?.text ?: sharedOutputFile
|
||||
if (PomFile.KotlinGoals.Js in it.goals) {
|
||||
// see org.jetbrains.kotlin.maven.K2JSCompilerMojo
|
||||
val outputFilePath = PathUtil.toSystemDependentName(explicitOutputFile ?: "$buildDirectory/js/${mavenProject.mavenId.artifactId}.js")
|
||||
compilerModuleExtension.setCompilerOutputPath(parentPath(outputFilePath))
|
||||
facetSettings.productionOutputPath = outputFilePath
|
||||
}
|
||||
if (PomFile.KotlinGoals.TestJs in it.goals) {
|
||||
// see org.jetbrains.kotlin.maven.KotlinTestJSCompilerMojo
|
||||
val outputFilePath = PathUtil.toSystemDependentName(explicitOutputFile ?: "$buildDirectory/test-js/${mavenProject.mavenId.artifactId}-tests.js")
|
||||
compilerModuleExtension.setCompilerOutputPathForTests(parentPath(outputFilePath))
|
||||
facetSettings.testOutputPath = outputFilePath
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getCompilerArgumentsByConfigurationElement(
|
||||
mavenProject: MavenProject,
|
||||
configuration: Element?,
|
||||
@@ -215,6 +251,7 @@ class KotlinMavenImporter : MavenImporter(KOTLIN_PLUGIN_GROUP_ID, KOTLIN_PLUGIN_
|
||||
val platform = detectPlatform(mavenProject)
|
||||
|
||||
kotlinFacet.configureFacet(compilerVersion, LanguageFeature.Coroutines.defaultState, platform, modifiableModelsProvider)
|
||||
val facetSettings = kotlinFacet.configuration.settings
|
||||
val configuredPlatform = kotlinFacet.configuration.settings.targetPlatformKind!!
|
||||
val configuration = mavenPlugin.configurationElement
|
||||
val sharedArguments = getCompilerArgumentsByConfigurationElement(mavenProject, configuration, configuredPlatform)
|
||||
@@ -225,6 +262,9 @@ class KotlinMavenImporter : MavenImporter(KOTLIN_PLUGIN_GROUP_ID, KOTLIN_PLUGIN_
|
||||
if (executionArguments != null) {
|
||||
parseCompilerArgumentsToFacet(executionArguments, emptyList(), kotlinFacet, modifiableModelsProvider)
|
||||
}
|
||||
if (facetSettings.compilerArguments is K2JSCompilerArguments) {
|
||||
configureJSOutputPaths(mavenProject, modifiableModelsProvider.getModifiableRootModel(module), facetSettings, mavenPlugin)
|
||||
}
|
||||
MavenProjectImportHandler.getInstances(module.project).forEach { it(kotlinFacet, mavenProject) }
|
||||
setImplementedModuleName(kotlinFacet, mavenProject, module)
|
||||
kotlinFacet.noVersionAutoAdvance()
|
||||
|
||||
@@ -20,9 +20,11 @@ import com.intellij.openapi.application.Result
|
||||
import com.intellij.openapi.application.WriteAction
|
||||
import com.intellij.openapi.projectRoots.JavaSdk
|
||||
import com.intellij.openapi.projectRoots.ProjectJdkTable
|
||||
import com.intellij.openapi.roots.CompilerModuleExtension
|
||||
import com.intellij.openapi.roots.LibraryOrderEntry
|
||||
import com.intellij.openapi.roots.ModuleRootManager
|
||||
import com.intellij.openapi.roots.impl.libraries.LibraryEx
|
||||
import com.intellij.util.PathUtil
|
||||
import junit.framework.TestCase
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
||||
@@ -632,6 +634,75 @@ class KotlinMavenImporterTest : MavenImportingTestCase() {
|
||||
Assert.assertTrue(ModuleRootManager.getInstance(getModule("project")).sdk!!.sdkType is KotlinSdkType)
|
||||
}
|
||||
|
||||
fun testJsCustomOutputPaths() {
|
||||
createProjectSubDirs("src/main/kotlin", "src/test/kotlin")
|
||||
importProject(
|
||||
"""
|
||||
<groupId>test</groupId>
|
||||
<artifactId>project</artifactId>
|
||||
<version>1.0.0</version>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib-js</artifactId>
|
||||
<version>$kotlinVersion</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<sourceDirectory>src/main/kotlin</sourceDirectory>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<version>$kotlinVersion</version>
|
||||
|
||||
<executions>
|
||||
<execution>
|
||||
<id>compile</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>js</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputFile>${'$'}{project.basedir}/prod/main.js</outputFile>
|
||||
</configuration>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>test-compile</id>
|
||||
<phase>test-compile</phase>
|
||||
<goals>
|
||||
<goal>test-js</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputFile>${'$'}{project.basedir}/test/test.js</outputFile>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
"""
|
||||
)
|
||||
|
||||
assertModules("project")
|
||||
assertImporterStatePresent()
|
||||
|
||||
val projectBasePath = myProjectsManager.projects.first().file.parent.path
|
||||
|
||||
with(facetSettings) {
|
||||
Assert.assertEquals("$projectBasePath/prod/main.js", PathUtil.toSystemIndependentName(productionOutputPath))
|
||||
Assert.assertEquals("$projectBasePath/test/test.js", PathUtil.toSystemIndependentName(testOutputPath))
|
||||
}
|
||||
|
||||
with (CompilerModuleExtension.getInstance(getModule("project"))!!) {
|
||||
Assert.assertEquals("$projectBasePath/prod", PathUtil.toSystemIndependentName(compilerOutputUrl))
|
||||
Assert.assertEquals("$projectBasePath/test", PathUtil.toSystemIndependentName(compilerOutputUrlForTests))
|
||||
}
|
||||
}
|
||||
|
||||
fun testFacetSplitConfiguration() {
|
||||
createProjectSubDirs("src/main/kotlin", "src/main/kotlin.jvm", "src/test/kotlin", "src/test/kotlin.jvm")
|
||||
|
||||
|
||||
@@ -262,6 +262,13 @@ open class KotlinJpsBuildTest : AbstractKotlinJpsBuildTestCase() {
|
||||
return list.toTypedArray()
|
||||
}
|
||||
|
||||
fun testKotlinJavaScriptProjectWithCustomOutputPaths() {
|
||||
initProject(JS_STDLIB)
|
||||
buildAllModules().assertSuccessful()
|
||||
|
||||
checkOutputFilesList(File(workDir, "target"))
|
||||
}
|
||||
|
||||
fun testKotlinJavaScriptProjectWithSourceMap() {
|
||||
initProject(JS_STDLIB)
|
||||
buildAllModules().assertSuccessful()
|
||||
@@ -686,7 +693,7 @@ open class KotlinJpsBuildTest : AbstractKotlinJpsBuildTestCase() {
|
||||
|
||||
}
|
||||
|
||||
private fun checkOutputFilesList() {
|
||||
private fun checkOutputFilesList(outputDir: File = productionOutputDir) {
|
||||
if (!expectedOutputFile.exists()) {
|
||||
expectedOutputFile.writeText("")
|
||||
throw IllegalStateException("$expectedOutputFile did not exist. Created empty file.")
|
||||
@@ -694,7 +701,7 @@ open class KotlinJpsBuildTest : AbstractKotlinJpsBuildTestCase() {
|
||||
|
||||
val sb = StringBuilder()
|
||||
val p = Printer(sb, " ")
|
||||
productionOutputDir.printFilesRecursively(p)
|
||||
outputDir.printFilesRecursively(p)
|
||||
|
||||
UsefulTestCase.assertSameLinesWithFile(expectedOutputFile.canonicalPath, sb.toString(), true)
|
||||
}
|
||||
|
||||
@@ -115,4 +115,18 @@ class JpsKotlinCompilerSettings : JpsElementBase<JpsKotlinCompilerSettings>() {
|
||||
}
|
||||
|
||||
val JpsModule.targetPlatform: TargetPlatformKind<*>?
|
||||
get() = kotlinFacetExtension?.settings?.targetPlatformKind
|
||||
get() = kotlinFacetExtension?.settings?.targetPlatformKind
|
||||
|
||||
val JpsModule.productionOutputFilePath: String?
|
||||
get() {
|
||||
val facetSettings = kotlinFacetExtension?.settings ?: return null
|
||||
if (facetSettings.useProjectSettings) return null
|
||||
return facetSettings.productionOutputPath
|
||||
}
|
||||
|
||||
val JpsModule.testOutputFilePath: String?
|
||||
get() {
|
||||
val facetSettings = kotlinFacetExtension?.settings ?: return null
|
||||
if (facetSettings.useProjectSettings) return null
|
||||
return facetSettings.testOutputPath
|
||||
}
|
||||
@@ -56,6 +56,8 @@ import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.jps.JpsKotlinCompilerSettings
|
||||
import org.jetbrains.kotlin.jps.build.JpsJsModuleUtils.getOutputMetaFile
|
||||
import org.jetbrains.kotlin.jps.incremental.*
|
||||
import org.jetbrains.kotlin.jps.productionOutputFilePath
|
||||
import org.jetbrains.kotlin.jps.testOutputFilePath
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
|
||||
import org.jetbrains.kotlin.modules.TargetId
|
||||
@@ -681,7 +683,9 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
||||
|
||||
val representativeModule = representativeTarget.module
|
||||
val moduleName = representativeModule.name
|
||||
val outputFile = JpsJsModuleUtils.getOutputFile(outputDir, moduleName, representativeTarget.isTests)
|
||||
val isTests = representativeTarget.isTests
|
||||
val explicitOutputPath = if (isTests) representativeModule.testOutputFilePath else representativeModule.productionOutputFilePath
|
||||
val outputFile = explicitOutputPath?.let { File(it) } ?: JpsJsModuleUtils.getOutputFile(outputDir, moduleName, isTests)
|
||||
val libraries = JpsJsModuleUtils.getLibraryFilesAndDependencies(representativeTarget)
|
||||
val compilerSettings = JpsKotlinCompilerSettings.getCompilerSettings(representativeModule)
|
||||
val k2JsArguments = JpsKotlinCompilerSettings.getK2JsCompilerArguments(representativeModule)
|
||||
|
||||
@@ -34,6 +34,8 @@ import org.jetbrains.jps.model.module.JpsSdkDependency
|
||||
import org.jetbrains.kotlin.build.JvmSourceRoot
|
||||
import org.jetbrains.kotlin.config.IncrementalCompilation
|
||||
import org.jetbrains.kotlin.jps.build.JpsUtils.getAllDependencies
|
||||
import org.jetbrains.kotlin.jps.productionOutputFilePath
|
||||
import org.jetbrains.kotlin.jps.testOutputFilePath
|
||||
import org.jetbrains.kotlin.modules.KotlinModuleXmlBuilder
|
||||
import org.jetbrains.kotlin.modules.TargetId
|
||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
@@ -161,8 +163,11 @@ object KotlinBuilderModuleScriptGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
fun getOutputDirSafe(target: ModuleBuildTarget): File =
|
||||
target.outputDir ?: throw ProjectBuildException("No output directory found for " + target)
|
||||
fun getOutputDirSafe(target: ModuleBuildTarget): File {
|
||||
val explicitOutputPath = if (target.isTests) target.module.testOutputFilePath else target.module.productionOutputFilePath
|
||||
val explicitOutputDir = explicitOutputPath?.let { File(it).absoluteFile.parentFile }
|
||||
return explicitOutputDir ?: target.outputDir ?: throw ProjectBuildException("No output directory found for " + target)
|
||||
}
|
||||
|
||||
fun getProductionModulesWhichInternalsAreVisible(from: ModuleBuildTarget): List<JpsModule> {
|
||||
if (!from.isTests) return emptyList()
|
||||
|
||||
Vendored
+16
@@ -0,0 +1,16 @@
|
||||
my_js/
|
||||
lib/
|
||||
kotlin.js
|
||||
kotlin.meta.js
|
||||
myproject/
|
||||
root-package.kjsm
|
||||
myproject.js
|
||||
myproject.meta.js
|
||||
my_test-js/
|
||||
lib/
|
||||
kotlin.js
|
||||
kotlin.meta.js
|
||||
myproject-tests/
|
||||
root-package.kjsm
|
||||
myproject-tests.js
|
||||
myproject-tests.meta.js
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="kotlin-language" name="Kotlin">
|
||||
<configuration version="3" platform="JavaScript " useProjectSettings="false">
|
||||
<productionOutputPath>$MODULE_DIR$/target/my_js/myproject.js</productionOutputPath>
|
||||
<testOutputPath>$MODULE_DIR$/target/my_test-js/myproject-tests.js</testOutputPath>
|
||||
<compilerSettings />
|
||||
<compilerArguments>
|
||||
<option name="sourceMapPrefix" value="" />
|
||||
<option name="sourceMapEmbedSources" value="inlining" />
|
||||
<option name="pluginOptions">
|
||||
<array />
|
||||
</option>
|
||||
<option name="pluginClasspaths">
|
||||
<array />
|
||||
</option>
|
||||
</compilerArguments>
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/kotlin" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/kotlin" isTestSource="true" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="IDEA_JDK" jdkType="JavaSDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="kotlinProject" />
|
||||
</component>
|
||||
</module>
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<option name="DEFAULT_COMPILER" value="Javac" />
|
||||
</component>
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/kotlinProject.iml" filepath="$PROJECT_DIR$/kotlinProject.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="IDEA_JDK" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
fun main(args: Array<String>) {
|
||||
|
||||
}
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
fun main(args: Array<String>) {
|
||||
|
||||
}
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
fun test() {
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user