Merge Kotlin JPS plugin
Kotlin JPS plugin existed in Kotlin repo before but was migrated to intellij-community together with entire Kotlin plugin. Now I return Kotlin JPS plugin back because it turned out that it's easier to develop JPS in KT release cycle. Also I need to unbundle Kotlin JPS plugin in scope of KTIJ-11633
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
id("jps-compatible")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile(kotlinStdlib())
|
||||
compileOnly(project(":kotlin-reflect-api"))
|
||||
compile(project(":compiler:util"))
|
||||
compile(project(":compiler:cli-common"))
|
||||
compile(project(":compiler:frontend.java"))
|
||||
compile(project(":js:js.frontend"))
|
||||
compile(project(":native:frontend.native"))
|
||||
compileOnly(intellijDep())
|
||||
compileOnly(jpsStandalone()) { includeJars("jps-model") }
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
"main" { projectDefault() }
|
||||
"test" {}
|
||||
}
|
||||
|
||||
runtimeJar()
|
||||
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.config;
|
||||
|
||||
public class CompilerRunnerConstants {
|
||||
public static final String KOTLIN_COMPILER_NAME = "Kotlin";
|
||||
public static final String INTERNAL_ERROR_PREFIX = "[Internal Error] ";
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.config
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import org.jetbrains.kotlin.cli.common.arguments.Freezable
|
||||
|
||||
class CompilerSettings : Freezable() {
|
||||
var additionalArguments: String by FreezableVar(DEFAULT_ADDITIONAL_ARGUMENTS)
|
||||
var scriptTemplates: String by FreezableVar("")
|
||||
var scriptTemplatesClasspath: String by FreezableVar("")
|
||||
var copyJsLibraryFiles: Boolean by FreezableVar(true)
|
||||
var outputDirectoryForJsLibraryFiles: String by FreezableVar(DEFAULT_OUTPUT_DIRECTORY)
|
||||
|
||||
companion object {
|
||||
val DEFAULT_ADDITIONAL_ARGUMENTS = "-version"
|
||||
private val DEFAULT_OUTPUT_DIRECTORY = "lib"
|
||||
}
|
||||
}
|
||||
|
||||
val CompilerSettings.additionalArgumentsAsList: List<String>
|
||||
get() = splitArgumentString(additionalArguments)
|
||||
|
||||
fun splitArgumentString(arguments: String) = StringUtil.splitHonorQuotes(arguments, ' ').map {
|
||||
if (it.startsWith('"')) StringUtil.unescapeChar(StringUtil.unquoteString(it), '"') else it
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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.config
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
|
||||
private const val APPLICATION_MANAGER_CLASS_NAME = "com.intellij.openapi.application.ApplicationManager"
|
||||
|
||||
val isJps: Boolean by lazy {
|
||||
/*
|
||||
Normally, JPS shouldn't have an ApplicationManager class in the classpath,
|
||||
but that's not true for JPS inside IDEA right now.
|
||||
Though Application is not properly initialized inside JPS so we can use it as a check.
|
||||
*/
|
||||
return@lazy if (doesClassExist(APPLICATION_MANAGER_CLASS_NAME)) {
|
||||
ApplicationManager.getApplication() == null
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
private fun doesClassExist(fqName: String): Boolean {
|
||||
val classPath = fqName.replace('.', '/') + ".class"
|
||||
return {}.javaClass.classLoader.getResource(classPath) != null
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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.config;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.model.serialization.JpsModelSerializerExtension;
|
||||
import org.jetbrains.jps.model.serialization.module.JpsModuleSourceRootPropertiesSerializer;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class KotlinCommonJpsModelSerializerExtension extends JpsModelSerializerExtension {
|
||||
@NotNull
|
||||
@Override
|
||||
public List<? extends JpsModuleSourceRootPropertiesSerializer<?>> getModuleSourceRootPropertiesSerializers() {
|
||||
return Arrays.asList(
|
||||
KotlinSourceRootPropertiesSerializer.Source.INSTANCE,
|
||||
KotlinSourceRootPropertiesSerializer.TestSource.INSTANCE,
|
||||
KotlinResourceRootPropertiesSerializer.Resource.INSTANCE,
|
||||
KotlinResourceRootPropertiesSerializer.TestResource.INSTANCE
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
* 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 org.jetbrains.kotlin.config
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.module.Module
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.cli.common.arguments.Argument
|
||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.arguments.copyBean
|
||||
import org.jetbrains.kotlin.cli.common.arguments.parseCommandLineArguments
|
||||
import org.jetbrains.kotlin.platform.IdePlatformKind
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.platform.TargetPlatformVersion
|
||||
import org.jetbrains.kotlin.platform.compat.toIdePlatform
|
||||
import org.jetbrains.kotlin.platform.isCommon
|
||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||
import org.jetbrains.kotlin.utils.DescriptionAware
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import kotlin.reflect.KProperty1
|
||||
import kotlin.reflect.full.findAnnotation
|
||||
|
||||
@Deprecated("Use IdePlatformKind instead.", level = DeprecationLevel.ERROR)
|
||||
sealed class TargetPlatformKind<out Version : TargetPlatformVersion>(
|
||||
val version: Version,
|
||||
val name: String
|
||||
) : DescriptionAware {
|
||||
override val description = "$name ${version.description}"
|
||||
|
||||
class Jvm(version: JvmTarget) : @Suppress("DEPRECATION_ERROR") TargetPlatformKind<JvmTarget>(version, "JVM") {
|
||||
companion object {
|
||||
private val JVM_PLATFORMS by lazy { JvmTarget.values().map(::Jvm) }
|
||||
operator fun get(version: JvmTarget) = JVM_PLATFORMS[version.ordinal]
|
||||
}
|
||||
}
|
||||
|
||||
object JavaScript : @Suppress("DEPRECATION_ERROR") TargetPlatformKind<TargetPlatformVersion.NoVersion>(
|
||||
TargetPlatformVersion.NoVersion,
|
||||
"JavaScript"
|
||||
)
|
||||
|
||||
object Common : @Suppress("DEPRECATION_ERROR") TargetPlatformKind<TargetPlatformVersion.NoVersion>(
|
||||
TargetPlatformVersion.NoVersion,
|
||||
"Common (experimental)"
|
||||
)
|
||||
}
|
||||
|
||||
sealed class VersionView : DescriptionAware {
|
||||
abstract val version: LanguageVersion
|
||||
|
||||
object LatestStable : VersionView() {
|
||||
override val version: LanguageVersion = RELEASED_VERSION
|
||||
|
||||
override val description: String
|
||||
get() = "Latest stable (${version.versionString})"
|
||||
}
|
||||
|
||||
class Specific(override val version: LanguageVersion) : VersionView() {
|
||||
override val description: String
|
||||
get() = version.description
|
||||
|
||||
override fun equals(other: Any?) = other is Specific && version == other.version
|
||||
|
||||
override fun hashCode() = version.hashCode()
|
||||
}
|
||||
|
||||
companion object {
|
||||
val RELEASED_VERSION = LanguageVersion.LATEST_STABLE
|
||||
|
||||
fun deserialize(value: String?, isAutoAdvance: Boolean): VersionView {
|
||||
if (isAutoAdvance) return LatestStable
|
||||
val languageVersion = LanguageVersion.fromVersionString(value)
|
||||
return if (languageVersion != null) Specific(languageVersion) else LatestStable
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var CommonCompilerArguments.languageVersionView: VersionView
|
||||
get() = VersionView.deserialize(languageVersion, autoAdvanceLanguageVersion)
|
||||
set(value) {
|
||||
languageVersion = value.version.versionString
|
||||
autoAdvanceLanguageVersion = value == VersionView.LatestStable
|
||||
}
|
||||
|
||||
var CommonCompilerArguments.apiVersionView: VersionView
|
||||
get() = VersionView.deserialize(apiVersion, autoAdvanceApiVersion)
|
||||
set(value) {
|
||||
apiVersion = value.version.versionString
|
||||
autoAdvanceApiVersion = value == VersionView.LatestStable
|
||||
}
|
||||
|
||||
enum class KotlinModuleKind {
|
||||
DEFAULT,
|
||||
SOURCE_SET_HOLDER,
|
||||
COMPILATION_AND_SOURCE_SET_HOLDER;
|
||||
|
||||
@Deprecated("Use KotlinFacetSettings.mppVersion.isNewMpp")
|
||||
val isNewMPP: Boolean
|
||||
get() = this != DEFAULT
|
||||
}
|
||||
|
||||
enum class KotlinMultiplatformVersion(val version: Int) {
|
||||
M1(1), // the first implementation of MPP. Aka 1.2.0 MPP
|
||||
M2(2), // the "New" MPP. Aka 1.3.0 MPP
|
||||
M3(3) // the "Hierarchical" MPP.
|
||||
}
|
||||
|
||||
val KotlinMultiplatformVersion?.isOldMpp: Boolean
|
||||
get() = this == KotlinMultiplatformVersion.M1
|
||||
|
||||
val KotlinMultiplatformVersion?.isNewMPP: Boolean
|
||||
get() = this == KotlinMultiplatformVersion.M2
|
||||
|
||||
val KotlinMultiplatformVersion?.isHmpp: Boolean
|
||||
get() = this == KotlinMultiplatformVersion.M3
|
||||
|
||||
interface ExternalSystemRunTask {
|
||||
val taskName: String
|
||||
val externalSystemProjectId: String
|
||||
val targetName: String?
|
||||
}
|
||||
|
||||
data class ExternalSystemTestRunTask(
|
||||
override val taskName: String,
|
||||
override val externalSystemProjectId: String,
|
||||
override val targetName: String?
|
||||
) : ExternalSystemRunTask {
|
||||
|
||||
fun toStringRepresentation() = "$taskName|$externalSystemProjectId|$targetName"
|
||||
|
||||
companion object {
|
||||
fun fromStringRepresentation(line: String) =
|
||||
line.split("|").let { if (it.size == 3) ExternalSystemTestRunTask(it[0], it[1], it[2]) else null }
|
||||
}
|
||||
|
||||
override fun toString() = "$taskName@$externalSystemProjectId [$targetName]"
|
||||
}
|
||||
|
||||
data class ExternalSystemNativeMainRunTask(
|
||||
override val taskName: String,
|
||||
override val externalSystemProjectId: String,
|
||||
override val targetName: String?,
|
||||
val entryPoint: String,
|
||||
val debuggable: Boolean,
|
||||
) : ExternalSystemRunTask {
|
||||
|
||||
fun toStringRepresentation() = "$taskName|$externalSystemProjectId|$targetName|$entryPoint|$debuggable"
|
||||
|
||||
companion object {
|
||||
fun fromStringRepresentation(line: String): ExternalSystemNativeMainRunTask? =
|
||||
line.split("|").let {
|
||||
if (it.size == 5) ExternalSystemNativeMainRunTask(it[0], it[1], it[2], it[3], it[4].toBoolean()) else null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class KotlinFacetSettings {
|
||||
companion object {
|
||||
// Increment this when making serialization-incompatible changes to configuration data
|
||||
val CURRENT_VERSION = 4
|
||||
val DEFAULT_VERSION = 0
|
||||
}
|
||||
|
||||
var version = CURRENT_VERSION
|
||||
var useProjectSettings: Boolean = true
|
||||
|
||||
var mergedCompilerArguments: CommonCompilerArguments? = null
|
||||
private set
|
||||
|
||||
// TODO: Workaround for unwanted facet settings modification on code analysis
|
||||
// To be replaced with proper API for settings update (see BaseKotlinCompilerSettings as an example)
|
||||
fun updateMergedArguments() {
|
||||
val compilerArguments = compilerArguments
|
||||
val compilerSettings = compilerSettings
|
||||
|
||||
mergedCompilerArguments = if (compilerArguments != null) {
|
||||
copyBean(compilerArguments).apply {
|
||||
if (compilerSettings != null) {
|
||||
parseCommandLineArguments(compilerSettings.additionalArgumentsAsList, this)
|
||||
}
|
||||
}
|
||||
} else null
|
||||
}
|
||||
|
||||
var compilerArguments: CommonCompilerArguments? = null
|
||||
set(value) {
|
||||
field = value?.unfrozen() as CommonCompilerArguments?
|
||||
updateMergedArguments()
|
||||
}
|
||||
|
||||
var compilerSettings: CompilerSettings? = null
|
||||
set(value) {
|
||||
field = value?.unfrozen() as CompilerSettings?
|
||||
updateMergedArguments()
|
||||
}
|
||||
|
||||
/*
|
||||
This function is needed as some setting values may not be present in compilerArguments
|
||||
but present in additional arguments instead, so we have to check both cases manually
|
||||
*/
|
||||
inline fun <reified A : CommonCompilerArguments> isCompilerSettingPresent(settingReference: KProperty1<A, Boolean>): Boolean {
|
||||
val isEnabledByCompilerArgument = compilerArguments?.safeAs<A>()?.let(settingReference::get)
|
||||
if (isEnabledByCompilerArgument == true) return true
|
||||
val isEnabledByAdditionalSettings = run {
|
||||
val stringArgumentName = settingReference.findAnnotation<Argument>()?.value ?: return@run null
|
||||
compilerSettings?.additionalArguments?.contains(stringArgumentName, ignoreCase = true)
|
||||
}
|
||||
return isEnabledByAdditionalSettings ?: false
|
||||
}
|
||||
|
||||
var languageLevel: LanguageVersion?
|
||||
get() = compilerArguments?.languageVersion?.let { LanguageVersion.fromFullVersionString(it) }
|
||||
set(value) {
|
||||
compilerArguments?.apply {
|
||||
languageVersion = value?.versionString
|
||||
}
|
||||
}
|
||||
|
||||
var apiLevel: LanguageVersion?
|
||||
get() = compilerArguments?.apiVersion?.let { LanguageVersion.fromFullVersionString(it) }
|
||||
set(value) {
|
||||
compilerArguments?.apply {
|
||||
apiVersion = value?.versionString
|
||||
}
|
||||
}
|
||||
|
||||
var targetPlatform: TargetPlatform? = null
|
||||
get() {
|
||||
// This work-around is required in order to fix importing of the proper JVM target version and works only
|
||||
// for fully actualized JVM target platform
|
||||
//TODO(auskov): this hack should be removed after fixing equals in SimplePlatform
|
||||
val args = compilerArguments
|
||||
val singleSimplePlatform = field?.componentPlatforms?.singleOrNull()
|
||||
if (singleSimplePlatform == JvmPlatforms.defaultJvmPlatform.singleOrNull() && args != null) {
|
||||
return IdePlatformKind.platformByCompilerArguments(args)
|
||||
}
|
||||
return field
|
||||
}
|
||||
|
||||
var externalSystemRunTasks: List<ExternalSystemRunTask> = emptyList()
|
||||
|
||||
@Suppress("DEPRECATION_ERROR")
|
||||
@Deprecated(
|
||||
message = "This accessor is deprecated and will be removed soon, use API from 'org.jetbrains.kotlin.platform.*' packages instead",
|
||||
replaceWith = ReplaceWith("targetPlatform"),
|
||||
level = DeprecationLevel.ERROR
|
||||
)
|
||||
fun getPlatform(): org.jetbrains.kotlin.platform.IdePlatform<*, *>? {
|
||||
return targetPlatform?.toIdePlatform()
|
||||
}
|
||||
|
||||
var implementedModuleNames: List<String> = emptyList() // used for first implementation of MPP, aka 'old' MPP
|
||||
var dependsOnModuleNames: List<String> = emptyList() // used for New MPP and later implementations
|
||||
|
||||
var productionOutputPath: String? = null
|
||||
var testOutputPath: String? = null
|
||||
|
||||
var kind: KotlinModuleKind = KotlinModuleKind.DEFAULT
|
||||
var sourceSetNames: List<String> = emptyList()
|
||||
var isTestModule: Boolean = false
|
||||
|
||||
var externalProjectId: String = ""
|
||||
|
||||
@Deprecated(message = "Use mppVersion.isHmppEnabled")
|
||||
var isHmppEnabled: Boolean = false
|
||||
|
||||
val mppVersion: KotlinMultiplatformVersion?
|
||||
get() = when {
|
||||
isHmppEnabled -> KotlinMultiplatformVersion.M3
|
||||
kind.isNewMPP -> KotlinMultiplatformVersion.M2
|
||||
targetPlatform.isCommon() || implementedModuleNames.isNotEmpty() -> KotlinMultiplatformVersion.M1
|
||||
else -> null
|
||||
}
|
||||
|
||||
var pureKotlinSourceFolders: List<String> = emptyList()
|
||||
}
|
||||
|
||||
interface KotlinFacetSettingsProvider {
|
||||
fun getSettings(module: Module): KotlinFacetSettings?
|
||||
fun getInitializedSettings(module: Module): KotlinFacetSettings
|
||||
|
||||
companion object {
|
||||
fun getInstance(project: Project): KotlinFacetSettingsProvider? {
|
||||
if (project.isDisposed) {
|
||||
return null
|
||||
}
|
||||
return ServiceManager.getService(project, KotlinFacetSettingsProvider::class.java)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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.config
|
||||
|
||||
import org.jetbrains.jps.model.ex.JpsElementTypeBase
|
||||
import org.jetbrains.jps.model.java.JavaResourceRootProperties
|
||||
import org.jetbrains.jps.model.java.JavaResourceRootType
|
||||
import org.jetbrains.jps.model.java.JpsJavaExtensionService
|
||||
import org.jetbrains.jps.model.module.JpsModuleSourceRootType
|
||||
|
||||
sealed class KotlinResourceRootType() : JpsElementTypeBase<JavaResourceRootProperties>(),
|
||||
JpsModuleSourceRootType<JavaResourceRootProperties> {
|
||||
|
||||
override fun createDefaultProperties() =
|
||||
JpsJavaExtensionService.getInstance().createResourceRootProperties("", false)
|
||||
}
|
||||
|
||||
object ResourceKotlinRootType : KotlinResourceRootType()
|
||||
|
||||
object TestResourceKotlinRootType : KotlinResourceRootType() {
|
||||
override fun isForTests() = true
|
||||
}
|
||||
|
||||
val ALL_KOTLIN_RESOURCE_ROOT_TYPES = setOf(ResourceKotlinRootType, TestResourceKotlinRootType)
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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.config
|
||||
|
||||
import org.jetbrains.jps.model.ex.JpsElementTypeBase
|
||||
import org.jetbrains.jps.model.java.JavaSourceRootProperties
|
||||
import org.jetbrains.jps.model.java.JavaSourceRootType
|
||||
import org.jetbrains.jps.model.java.JpsJavaExtensionService
|
||||
import org.jetbrains.jps.model.module.JpsModuleSourceRootType
|
||||
|
||||
sealed class KotlinSourceRootType() : JpsElementTypeBase<JavaSourceRootProperties>(), JpsModuleSourceRootType<JavaSourceRootProperties> {
|
||||
|
||||
override fun createDefaultProperties() = JpsJavaExtensionService.getInstance().createSourceRootProperties("")
|
||||
|
||||
}
|
||||
|
||||
object SourceKotlinRootType : KotlinSourceRootType()
|
||||
|
||||
object TestSourceKotlinRootType : KotlinSourceRootType() {
|
||||
override fun isForTests() = true
|
||||
}
|
||||
|
||||
val ALL_KOTLIN_SOURCE_ROOT_TYPES = setOf(SourceKotlinRootType, TestSourceKotlinRootType)
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.config;
|
||||
|
||||
public class SettingConstants {
|
||||
private SettingConstants() {}
|
||||
|
||||
public static final String KOTLIN_COMMON_COMPILER_ARGUMENTS_SECTION = "KotlinCommonCompilerArguments";
|
||||
public static final String KOTLIN_TO_JS_COMPILER_ARGUMENTS_SECTION = "Kotlin2JsCompilerArguments";
|
||||
public static final String KOTLIN_TO_JVM_COMPILER_ARGUMENTS_SECTION = "Kotlin2JvmCompilerArguments";
|
||||
public static final String KOTLIN_COMPILER_SETTINGS_SECTION = "KotlinCompilerSettings";
|
||||
|
||||
public static final String KOTLIN_COMPILER_SETTINGS_FILE = "kotlinc.xml";
|
||||
}
|
||||
@@ -0,0 +1,457 @@
|
||||
/*
|
||||
* 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 org.jetbrains.kotlin.config
|
||||
|
||||
import com.intellij.util.PathUtil
|
||||
import com.intellij.util.xmlb.SerializationFilter
|
||||
import com.intellij.util.xmlb.SkipDefaultsSerializationFilter
|
||||
import com.intellij.util.xmlb.XmlSerializer
|
||||
import org.jdom.DataConversionException
|
||||
import org.jdom.Element
|
||||
import org.jdom.Text
|
||||
import org.jetbrains.kotlin.cli.common.arguments.*
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.platform.*
|
||||
import org.jetbrains.kotlin.platform.impl.FakeK2NativeCompilerArguments
|
||||
import org.jetbrains.kotlin.platform.impl.JvmIdePlatformKind
|
||||
import org.jetbrains.kotlin.platform.js.isJs
|
||||
import org.jetbrains.kotlin.platform.jvm.JdkPlatform
|
||||
import org.jetbrains.kotlin.platform.jvm.isJvm
|
||||
import org.jetbrains.kotlin.platform.konan.*
|
||||
import java.lang.reflect.Modifier
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.full.superclasses
|
||||
|
||||
fun Element.getOption(name: String) = getChildren("option").firstOrNull { it.getAttribute("name").value == name }
|
||||
|
||||
private fun Element.getOptionValue(name: String) = getOption(name)?.getAttribute("value")?.value
|
||||
|
||||
private fun Element.getOptionBody(name: String) = getOption(name)?.children?.firstOrNull()
|
||||
|
||||
fun TargetPlatform.createArguments(init: (CommonCompilerArguments).() -> Unit = {}): CommonCompilerArguments {
|
||||
return when {
|
||||
isCommon() -> K2MetadataCompilerArguments().apply { init() }
|
||||
isJvm() -> K2JVMCompilerArguments().apply {
|
||||
init()
|
||||
// TODO(dsavvinov): review this
|
||||
jvmTarget = (single() as? JdkPlatform)?.targetVersion?.description ?: JvmTarget.DEFAULT.description
|
||||
}
|
||||
isJs() -> K2JSCompilerArguments().apply { init() }
|
||||
isNative() -> FakeK2NativeCompilerArguments().apply { init() }
|
||||
else -> error("Unknown platform $this")
|
||||
}
|
||||
}
|
||||
|
||||
private fun readV1Config(element: Element): KotlinFacetSettings {
|
||||
return KotlinFacetSettings().apply {
|
||||
val useProjectSettings = element.getOptionValue("useProjectSettings")?.toBoolean()
|
||||
|
||||
val versionInfoElement = element.getOptionBody("versionInfo")
|
||||
val targetPlatformName = versionInfoElement?.getOptionValue("targetPlatformName")
|
||||
val languageLevel = versionInfoElement?.getOptionValue("languageLevel")
|
||||
val apiLevel = versionInfoElement?.getOptionValue("apiLevel")
|
||||
val targetPlatform = CommonPlatforms.allSimplePlatforms.union(setOf(CommonPlatforms.defaultCommonPlatform))
|
||||
.firstOrNull { it.oldFashionedDescription == targetPlatformName }
|
||||
?: JvmIdePlatformKind.defaultPlatform // FIXME(dsavvinov): choose proper default
|
||||
|
||||
val compilerInfoElement = element.getOptionBody("compilerInfo")
|
||||
|
||||
val compilerSettings = CompilerSettings().apply {
|
||||
compilerInfoElement?.getOptionBody("compilerSettings")?.let { compilerSettingsElement ->
|
||||
XmlSerializer.deserializeInto(this, compilerSettingsElement)
|
||||
}
|
||||
}
|
||||
|
||||
val commonArgumentsElement = compilerInfoElement?.getOptionBody("_commonCompilerArguments")
|
||||
val jvmArgumentsElement = compilerInfoElement?.getOptionBody("k2jvmCompilerArguments")
|
||||
val jsArgumentsElement = compilerInfoElement?.getOptionBody("k2jsCompilerArguments")
|
||||
|
||||
val compilerArguments = targetPlatform.createArguments { freeArgs = arrayListOf() }
|
||||
|
||||
commonArgumentsElement?.let { XmlSerializer.deserializeInto(compilerArguments, it) }
|
||||
when (compilerArguments) {
|
||||
is K2JVMCompilerArguments -> jvmArgumentsElement?.let { XmlSerializer.deserializeInto(compilerArguments, it) }
|
||||
is K2JSCompilerArguments -> jsArgumentsElement?.let { XmlSerializer.deserializeInto(compilerArguments, it) }
|
||||
}
|
||||
|
||||
if (languageLevel != null) {
|
||||
compilerArguments.languageVersion = languageLevel
|
||||
}
|
||||
|
||||
if (apiLevel != null) {
|
||||
compilerArguments.apiVersion = apiLevel
|
||||
}
|
||||
|
||||
compilerArguments.detectVersionAutoAdvance()
|
||||
|
||||
if (useProjectSettings != null) {
|
||||
this.useProjectSettings = useProjectSettings
|
||||
} else {
|
||||
// Migration problem workaround for pre-1.1-beta releases (mainly 1.0.6) -> 1.1-rc+
|
||||
// Problematic cases: 1.1-beta/1.1-beta2 -> 1.1-rc+ (useProjectSettings gets reset to false)
|
||||
// This heuristic detects old enough configurations:
|
||||
if (jvmArgumentsElement == null) {
|
||||
this.useProjectSettings = false
|
||||
}
|
||||
}
|
||||
|
||||
this.compilerSettings = compilerSettings
|
||||
this.compilerArguments = compilerArguments
|
||||
this.targetPlatform = IdePlatformKind.platformByCompilerArguments(compilerArguments)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Introduce new version of facet serialization. See https://youtrack.jetbrains.com/issue/KT-38235
|
||||
// This is necessary to avoid having too much custom logic for platform serialization.
|
||||
fun Element.getFacetPlatformByConfigurationElement(): TargetPlatform {
|
||||
val targetPlatform = getAttributeValue("allPlatforms").deserializeTargetPlatformByComponentPlatforms()
|
||||
if (targetPlatform != null) return targetPlatform
|
||||
|
||||
// failed to read list of all platforms. Fallback to legacy algorithm
|
||||
val platformName = getAttributeValue("platform") ?: return DefaultIdeTargetPlatformKindProvider.defaultPlatform
|
||||
|
||||
return CommonPlatforms.allSimplePlatforms.firstOrNull {
|
||||
// first, look for exact match through all simple platforms
|
||||
it.oldFashionedDescription == platformName
|
||||
} ?: CommonPlatforms.defaultCommonPlatform.takeIf {
|
||||
// then, check exact match for the default common platform
|
||||
it.oldFashionedDescription == platformName
|
||||
} ?: NativePlatforms.unspecifiedNativePlatform.takeIf {
|
||||
// if none of the above succeeded, check if it's an old-style record about native platform (without suffix with target name)
|
||||
it.oldFashionedDescription.startsWith(platformName)
|
||||
}.orDefault() // finally, fallback to the default platform
|
||||
}
|
||||
|
||||
private fun readV2AndLaterConfig(element: Element): KotlinFacetSettings {
|
||||
return KotlinFacetSettings().apply {
|
||||
element.getAttributeValue("useProjectSettings")?.let { useProjectSettings = it.toBoolean() }
|
||||
val targetPlatform = element.getFacetPlatformByConfigurationElement()
|
||||
this.targetPlatform = targetPlatform
|
||||
readElementsList(element, "implements", "implement")?.let { implementedModuleNames = it }
|
||||
readElementsList(element, "dependsOnModuleNames", "dependsOn")?.let { dependsOnModuleNames = it }
|
||||
element.getChild("externalSystemTestTasks")?.let {
|
||||
val testRunTasks = it.getChildren("externalSystemTestTask")
|
||||
.mapNotNull { (it.content.firstOrNull() as? Text)?.textTrim }
|
||||
.mapNotNull { ExternalSystemTestRunTask.fromStringRepresentation(it) }
|
||||
val nativeMainRunTasks = it.getChildren("externalSystemNativeMainRunTask")
|
||||
.mapNotNull { (it.content.firstOrNull() as? Text)?.textTrim }
|
||||
.mapNotNull { ExternalSystemNativeMainRunTask.fromStringRepresentation(it) }
|
||||
|
||||
externalSystemRunTasks = testRunTasks + nativeMainRunTasks
|
||||
}
|
||||
|
||||
element.getChild("sourceSets")?.let {
|
||||
val items = it.getChildren("sourceSet")
|
||||
sourceSetNames = items.mapNotNull { (it.content.firstOrNull() as? Text)?.textTrim }
|
||||
}
|
||||
kind = element.getChild("newMppModelJpsModuleKind")?.let {
|
||||
val kindName = (it.content.firstOrNull() as? Text)?.textTrim
|
||||
if (kindName != null) {
|
||||
try {
|
||||
KotlinModuleKind.valueOf(kindName)
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
} else null
|
||||
} ?: KotlinModuleKind.DEFAULT
|
||||
isTestModule = element.getAttributeValue("isTestModule")?.toBoolean() ?: false
|
||||
externalProjectId = element.getAttributeValue("externalProjectId") ?: ""
|
||||
isHmppEnabled = element.getAttribute("isHmppProject")?.booleanValue ?: false
|
||||
pureKotlinSourceFolders = element.getAttributeValue("pureKotlinSourceFolders")?.split(";")?.toList() ?: emptyList()
|
||||
element.getChild("compilerSettings")?.let {
|
||||
compilerSettings = CompilerSettings()
|
||||
XmlSerializer.deserializeInto(compilerSettings!!, it)
|
||||
}
|
||||
element.getChild("compilerArguments")?.let {
|
||||
compilerArguments = targetPlatform.createArguments {
|
||||
freeArgs = mutableListOf()
|
||||
internalArguments = mutableListOf()
|
||||
}
|
||||
XmlSerializer.deserializeInto(compilerArguments!!, it)
|
||||
compilerArguments!!.detectVersionAutoAdvance()
|
||||
}
|
||||
productionOutputPath = element.getChild("productionOutputPath")?.let {
|
||||
PathUtil.toSystemDependentName((it.content.firstOrNull() as? Text)?.textTrim)
|
||||
} ?: (compilerArguments as? K2JSCompilerArguments)?.outputFile
|
||||
testOutputPath = element.getChild("testOutputPath")?.let {
|
||||
PathUtil.toSystemDependentName((it.content.firstOrNull() as? Text)?.textTrim)
|
||||
} ?: (compilerArguments as? K2JSCompilerArguments)?.outputFile
|
||||
}
|
||||
}
|
||||
|
||||
private fun readElementsList(element: Element, rootElementName: String, elementName: String): List<String>? {
|
||||
element.getChild(rootElementName)?.let {
|
||||
val items = it.getChildren(elementName)
|
||||
return if (items.isNotEmpty()) {
|
||||
items.mapNotNull { (it.content.firstOrNull() as? Text)?.textTrim }
|
||||
} else {
|
||||
listOfNotNull((it.content.firstOrNull() as? Text)?.textTrim)
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun readV3Config(element: Element): KotlinFacetSettings {
|
||||
return readV2AndLaterConfig(element)
|
||||
}
|
||||
|
||||
private fun readV2Config(element: Element): KotlinFacetSettings {
|
||||
return readV2AndLaterConfig(element)
|
||||
}
|
||||
|
||||
private fun readLatestConfig(element: Element): KotlinFacetSettings {
|
||||
return readV2AndLaterConfig(element)
|
||||
}
|
||||
|
||||
fun deserializeFacetSettings(element: Element): KotlinFacetSettings {
|
||||
val version = try {
|
||||
element.getAttribute("version")?.intValue
|
||||
} catch (e: DataConversionException) {
|
||||
null
|
||||
} ?: KotlinFacetSettings.DEFAULT_VERSION
|
||||
return when (version) {
|
||||
1 -> readV1Config(element)
|
||||
2 -> readV2Config(element)
|
||||
3 -> readV3Config(element)
|
||||
KotlinFacetSettings.CURRENT_VERSION -> readLatestConfig(element)
|
||||
else -> return KotlinFacetSettings() // Reset facet configuration if versions don't match
|
||||
}.apply { this.version = version }
|
||||
}
|
||||
|
||||
fun CommonCompilerArguments.convertPathsToSystemIndependent() {
|
||||
pluginClasspaths?.forEachIndexed { index, s -> pluginClasspaths!![index] = PathUtil.toSystemIndependentName(s) }
|
||||
|
||||
when (this) {
|
||||
is K2JVMCompilerArguments -> {
|
||||
destination = PathUtil.toSystemIndependentName(destination)
|
||||
classpath = PathUtil.toSystemIndependentName(classpath)
|
||||
jdkHome = PathUtil.toSystemIndependentName(jdkHome)
|
||||
kotlinHome = PathUtil.toSystemIndependentName(kotlinHome)
|
||||
friendPaths?.forEachIndexed { index, s -> friendPaths!![index] = PathUtil.toSystemIndependentName(s) }
|
||||
declarationsOutputPath = PathUtil.toSystemIndependentName(declarationsOutputPath)
|
||||
}
|
||||
|
||||
is K2JSCompilerArguments -> {
|
||||
outputFile = PathUtil.toSystemIndependentName(outputFile)
|
||||
libraries = PathUtil.toSystemIndependentName(libraries)
|
||||
}
|
||||
|
||||
is K2MetadataCompilerArguments -> {
|
||||
destination = PathUtil.toSystemIndependentName(destination)
|
||||
classpath = PathUtil.toSystemIndependentName(classpath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun CompilerSettings.convertPathsToSystemIndependent() {
|
||||
scriptTemplatesClasspath = PathUtil.toSystemIndependentName(scriptTemplatesClasspath)
|
||||
outputDirectoryForJsLibraryFiles = PathUtil.toSystemIndependentName(outputDirectoryForJsLibraryFiles)
|
||||
}
|
||||
|
||||
private fun KClass<*>.superClass() = superclasses.firstOrNull { !it.java.isInterface }
|
||||
|
||||
private fun Class<*>.computeNormalPropertyOrdering(): Map<String, Int> {
|
||||
val result = LinkedHashMap<String, Int>()
|
||||
var count = 0
|
||||
generateSequence(this) { it.superclass }.forEach { clazz ->
|
||||
for (field in clazz.declaredFields) {
|
||||
if (field.modifiers and Modifier.STATIC != 0) continue
|
||||
|
||||
var propertyName = field.name
|
||||
if (propertyName.endsWith(JvmAbi.DELEGATED_PROPERTY_NAME_SUFFIX)) {
|
||||
propertyName = propertyName.dropLast(JvmAbi.DELEGATED_PROPERTY_NAME_SUFFIX.length)
|
||||
}
|
||||
|
||||
result[propertyName] = count++
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
private val allNormalOrderings = HashMap<Class<*>, Map<String, Int>>()
|
||||
|
||||
private val Class<*>.normalOrdering
|
||||
get() = synchronized(allNormalOrderings) { allNormalOrderings.getOrPut(this) { computeNormalPropertyOrdering() } }
|
||||
|
||||
// Replacing fields with delegated properties leads to unexpected reordering of entries in facet configuration XML
|
||||
// It happens due to XmlSerializer using different orderings for field- and method-based accessors
|
||||
// This code restores the original ordering
|
||||
private fun Element.restoreNormalOrdering(bean: Any) {
|
||||
val normalOrdering = bean.javaClass.normalOrdering
|
||||
val elementsToReorder = this.getContent<Element> { it is Element && it.getAttribute("name")?.value in normalOrdering }
|
||||
elementsToReorder.sortedBy { normalOrdering[it.getAttribute("name")?.value!!] }
|
||||
.forEachIndexed { index, element -> elementsToReorder[index] = element.clone() }
|
||||
}
|
||||
|
||||
private fun buildChildElement(element: Element, tag: String, bean: Any, filter: SerializationFilter): Element {
|
||||
return Element(tag).apply {
|
||||
XmlSerializer.serializeInto(bean, this, filter)
|
||||
restoreNormalOrdering(bean)
|
||||
element.addContent(this)
|
||||
}
|
||||
}
|
||||
|
||||
private fun KotlinFacetSettings.writeLatestConfig(element: Element) {
|
||||
val filter = SkipDefaultsSerializationFilter()
|
||||
|
||||
// TODO: Introduce new version of facet serialization. See https://youtrack.jetbrains.com/issue/KT-38235
|
||||
// This is necessary to avoid having too much custom logic for platform serialization.
|
||||
targetPlatform?.let { targetPlatform ->
|
||||
element.setAttribute("platform", targetPlatform.oldFashionedDescription)
|
||||
element.setAttribute("allPlatforms", targetPlatform.serializeComponentPlatforms())
|
||||
}
|
||||
if (!useProjectSettings) {
|
||||
element.setAttribute("useProjectSettings", useProjectSettings.toString())
|
||||
}
|
||||
saveElementsList(element, implementedModuleNames, "implements", "implement")
|
||||
saveElementsList(element, dependsOnModuleNames, "dependsOnModuleNames", "dependsOn")
|
||||
|
||||
if (sourceSetNames.isNotEmpty()) {
|
||||
element.addContent(
|
||||
Element("sourceSets").apply {
|
||||
sourceSetNames.map { addContent(Element("sourceSet").apply { addContent(it) }) }
|
||||
}
|
||||
)
|
||||
}
|
||||
if (kind != KotlinModuleKind.DEFAULT) {
|
||||
element.addContent(Element("newMppModelJpsModuleKind").apply { addContent(kind.name) })
|
||||
element.setAttribute("isTestModule", isTestModule.toString())
|
||||
}
|
||||
if (externalProjectId.isNotEmpty()) {
|
||||
element.setAttribute("externalProjectId", externalProjectId)
|
||||
}
|
||||
if (isHmppEnabled) {
|
||||
element.setAttribute("isHmppProject", mppVersion.isHmpp.toString())
|
||||
}
|
||||
if (externalSystemRunTasks.isNotEmpty()) {
|
||||
element.addContent(
|
||||
Element("externalSystemTestTasks").apply {
|
||||
externalSystemRunTasks.forEach { task ->
|
||||
when(task) {
|
||||
is ExternalSystemTestRunTask -> {
|
||||
addContent(
|
||||
Element("externalSystemTestTask").apply { addContent(task.toStringRepresentation()) }
|
||||
)
|
||||
}
|
||||
is ExternalSystemNativeMainRunTask -> {
|
||||
addContent(
|
||||
Element("externalSystemNativeMainRunTask").apply { addContent(task.toStringRepresentation()) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
if (pureKotlinSourceFolders.isNotEmpty()) {
|
||||
element.setAttribute("pureKotlinSourceFolders", pureKotlinSourceFolders.joinToString(";"))
|
||||
}
|
||||
productionOutputPath?.let {
|
||||
if (it != (compilerArguments as? K2JSCompilerArguments)?.outputFile) {
|
||||
element.addContent(Element("productionOutputPath").apply { addContent(PathUtil.toSystemIndependentName(it)) })
|
||||
}
|
||||
}
|
||||
testOutputPath?.let {
|
||||
if (it != (compilerArguments as? K2JSCompilerArguments)?.outputFile) {
|
||||
element.addContent(Element("testOutputPath").apply { addContent(PathUtil.toSystemIndependentName(it)) })
|
||||
}
|
||||
}
|
||||
compilerSettings?.let { copyBean(it) }?.let {
|
||||
it.convertPathsToSystemIndependent()
|
||||
buildChildElement(element, "compilerSettings", it, filter)
|
||||
}
|
||||
compilerArguments?.let { copyBean(it) }?.let {
|
||||
it.convertPathsToSystemIndependent()
|
||||
val compilerArgumentsXml = buildChildElement(element, "compilerArguments", it, filter)
|
||||
compilerArgumentsXml.dropVersionsIfNecessary(it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveElementsList(element: Element, elementsList: List<String>, rootElementName: String, elementName: String) {
|
||||
if (elementsList.isNotEmpty()) {
|
||||
element.addContent(
|
||||
Element(rootElementName).apply {
|
||||
val singleModule = elementsList.singleOrNull()
|
||||
if (singleModule != null) {
|
||||
addContent(singleModule)
|
||||
} else {
|
||||
elementsList.map { addContent(Element(elementName).apply { addContent(it) }) }
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun CommonCompilerArguments.detectVersionAutoAdvance() {
|
||||
autoAdvanceLanguageVersion = languageVersion == null
|
||||
autoAdvanceApiVersion = apiVersion == null
|
||||
}
|
||||
|
||||
fun Element.dropVersionsIfNecessary(settings: CommonCompilerArguments) {
|
||||
// Do not serialize language/api version if they correspond to the default language version
|
||||
if (settings.autoAdvanceLanguageVersion) {
|
||||
getOption("languageVersion")?.detach()
|
||||
}
|
||||
|
||||
if (settings.autoAdvanceApiVersion) {
|
||||
getOption("apiVersion")?.detach()
|
||||
}
|
||||
}
|
||||
|
||||
fun KotlinFacetSettings.serializeFacetSettings(element: Element) {
|
||||
val versionToWrite = when (version) {
|
||||
2, 3 -> version
|
||||
else -> KotlinFacetSettings.CURRENT_VERSION
|
||||
}
|
||||
element.setAttribute("version", versionToWrite.toString())
|
||||
writeLatestConfig(element)
|
||||
}
|
||||
|
||||
private fun TargetPlatform.serializeComponentPlatforms(): String {
|
||||
val componentPlatforms = componentPlatforms
|
||||
val componentPlatformNames = componentPlatforms.mapTo(ArrayList()) { it.serializeToString() }
|
||||
|
||||
// workaround for old Kotlin IDE plugins, KT-38634
|
||||
if (componentPlatforms.any { it is NativePlatform })
|
||||
componentPlatformNames.add(NativePlatformUnspecifiedTarget.legacySerializeToString())
|
||||
|
||||
return componentPlatformNames.sorted().joinToString("/")
|
||||
}
|
||||
|
||||
private fun String?.deserializeTargetPlatformByComponentPlatforms(): TargetPlatform? {
|
||||
val componentPlatformNames = this?.split('/')?.toSet()
|
||||
if (componentPlatformNames == null || componentPlatformNames.isEmpty())
|
||||
return null
|
||||
|
||||
val knownComponentPlatforms = HashMap<String, SimplePlatform>() // "serialization presentation" to "simple platform name"
|
||||
|
||||
// first, collect serialization presentations for every known simple platform
|
||||
CommonPlatforms.allSimplePlatforms
|
||||
.flatMap { it.componentPlatforms }
|
||||
.forEach { knownComponentPlatforms[it.serializeToString()] = it }
|
||||
|
||||
// next, add legacy aliases for some of the simple platforms; ex: unspecifiedNativePlatform
|
||||
NativePlatformUnspecifiedTarget.let { knownComponentPlatforms[it.legacySerializeToString()] = it }
|
||||
|
||||
val componentPlatforms = componentPlatformNames.mapNotNull(knownComponentPlatforms::get).toSet()
|
||||
return when (componentPlatforms.size) {
|
||||
0 -> {
|
||||
// empty set of component platforms is not allowed, in such case fallback to legacy algorithm
|
||||
null
|
||||
}
|
||||
1 -> TargetPlatform(componentPlatforms)
|
||||
else -> {
|
||||
// workaround for old Kotlin IDE plugins, KT-38634
|
||||
if (componentPlatforms.any { it is NativePlatformUnspecifiedTarget }
|
||||
&& componentPlatforms.any { it is NativePlatformWithTarget }
|
||||
) {
|
||||
TargetPlatform(componentPlatforms - NativePlatformUnspecifiedTarget)
|
||||
} else {
|
||||
TargetPlatform(componentPlatforms)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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 org.jetbrains.kotlin.config
|
||||
|
||||
import org.jdom.Element
|
||||
import org.jetbrains.jps.model.java.JavaResourceRootProperties
|
||||
import org.jetbrains.jps.model.java.JavaSourceRootProperties
|
||||
import org.jetbrains.jps.model.java.JpsJavaExtensionService
|
||||
import org.jetbrains.jps.model.module.JpsModuleSourceRootType
|
||||
import org.jetbrains.jps.model.serialization.module.JpsModuleRootModelSerializer
|
||||
import org.jetbrains.jps.model.serialization.module.JpsModuleSourceRootPropertiesSerializer
|
||||
|
||||
private const val IS_GENERATED_ATTRIBUTE = "generated"
|
||||
private const val RELATIVE_OUTPUT_PATH_ATTRIBUTE = "relativeOutputPath"
|
||||
|
||||
const val KOTLIN_SOURCE_ROOT_TYPE_ID = "kotlin-source"
|
||||
const val KOTLIN_TEST_ROOT_TYPE_ID = "kotlin-test"
|
||||
const val KOTLIN_RESOURCE_ROOT_TYPE_ID = "kotlin-resource"
|
||||
const val KOTLIN_TEST_RESOURCE_ROOT_TYPE_ID = "kotlin-test-resource"
|
||||
|
||||
// Based on org.jetbrains.jps.model.serialization.java.JpsJavaModelSerializerExtension.JavaSourceRootPropertiesSerializer class
|
||||
sealed class KotlinSourceRootPropertiesSerializer(
|
||||
type: JpsModuleSourceRootType<JavaSourceRootProperties>,
|
||||
typeId: String
|
||||
) : JpsModuleSourceRootPropertiesSerializer<JavaSourceRootProperties>(type, typeId) {
|
||||
object Source : KotlinSourceRootPropertiesSerializer(
|
||||
SourceKotlinRootType,
|
||||
KOTLIN_SOURCE_ROOT_TYPE_ID
|
||||
)
|
||||
|
||||
object TestSource : KotlinSourceRootPropertiesSerializer(
|
||||
TestSourceKotlinRootType,
|
||||
KOTLIN_TEST_ROOT_TYPE_ID
|
||||
)
|
||||
|
||||
override fun loadProperties(sourceRootTag: Element): JavaSourceRootProperties {
|
||||
val packagePrefix = sourceRootTag.getAttributeValue(JpsModuleRootModelSerializer.PACKAGE_PREFIX_ATTRIBUTE) ?: ""
|
||||
val isGenerated = sourceRootTag.getAttributeValue(IS_GENERATED_ATTRIBUTE)?.toBoolean() ?: false
|
||||
return JpsJavaExtensionService.getInstance().createSourceRootProperties(packagePrefix, isGenerated)
|
||||
}
|
||||
|
||||
override fun saveProperties(properties: JavaSourceRootProperties, sourceRootTag: Element) {
|
||||
val packagePrefix = properties.packagePrefix
|
||||
if (packagePrefix.isNotEmpty()) {
|
||||
sourceRootTag.setAttribute(JpsModuleRootModelSerializer.PACKAGE_PREFIX_ATTRIBUTE, packagePrefix)
|
||||
}
|
||||
if (properties.isForGeneratedSources) {
|
||||
sourceRootTag.setAttribute(IS_GENERATED_ATTRIBUTE, "true")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Based on org.jetbrains.jps.model.serialization.java.JpsJavaModelSerializerExtension.JavaResourceRootPropertiesSerializer
|
||||
sealed class KotlinResourceRootPropertiesSerializer(
|
||||
type: JpsModuleSourceRootType<JavaResourceRootProperties>,
|
||||
typeId: String
|
||||
) : JpsModuleSourceRootPropertiesSerializer<JavaResourceRootProperties>(type, typeId) {
|
||||
object Resource : KotlinResourceRootPropertiesSerializer(
|
||||
ResourceKotlinRootType,
|
||||
KOTLIN_RESOURCE_ROOT_TYPE_ID
|
||||
)
|
||||
|
||||
object TestResource : KotlinResourceRootPropertiesSerializer(
|
||||
TestResourceKotlinRootType,
|
||||
KOTLIN_TEST_RESOURCE_ROOT_TYPE_ID
|
||||
)
|
||||
|
||||
override fun loadProperties(sourceRootTag: Element): JavaResourceRootProperties {
|
||||
val relativeOutputPath = sourceRootTag.getAttributeValue(RELATIVE_OUTPUT_PATH_ATTRIBUTE) ?: ""
|
||||
val isGenerated = sourceRootTag.getAttributeValue(IS_GENERATED_ATTRIBUTE)?.toBoolean() ?: false
|
||||
return JpsJavaExtensionService.getInstance().createResourceRootProperties(relativeOutputPath, isGenerated)
|
||||
}
|
||||
|
||||
override fun saveProperties(properties: JavaResourceRootProperties, sourceRootTag: Element) {
|
||||
val relativeOutputPath = properties.relativeOutputPath
|
||||
if (relativeOutputPath.isNotEmpty()) {
|
||||
sourceRootTag.setAttribute(RELATIVE_OUTPUT_PATH_ATTRIBUTE, relativeOutputPath)
|
||||
}
|
||||
if (properties.isForGeneratedSources) {
|
||||
sourceRootTag.setAttribute(IS_GENERATED_ATTRIBUTE, "true")
|
||||
}
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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.platform
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import org.jetbrains.kotlin.config.isJps
|
||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
|
||||
interface DefaultIdeTargetPlatformKindProvider {
|
||||
val defaultPlatform: TargetPlatform
|
||||
|
||||
companion object {
|
||||
val defaultPlatform: TargetPlatform
|
||||
get() {
|
||||
if (isJps) {
|
||||
// TODO support passing custom platforms in JPS
|
||||
return JvmPlatforms.defaultJvmPlatform
|
||||
}
|
||||
|
||||
return ServiceManager.getService(DefaultIdeTargetPlatformKindProvider::class.java).defaultPlatform
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun TargetPlatform?.orDefault(): TargetPlatform {
|
||||
return this ?: DefaultIdeTargetPlatformKindProvider.defaultPlatform
|
||||
}
|
||||
|
||||
fun IdePlatformKind<*>?.orDefault(): IdePlatformKind<*> {
|
||||
return this ?: DefaultIdeTargetPlatformKindProvider.defaultPlatform.idePlatformKind
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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 org.jetbrains.kotlin.platform
|
||||
|
||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||
import org.jetbrains.kotlin.utils.DescriptionAware
|
||||
|
||||
@Suppress("DEPRECATION_ERROR")
|
||||
@Deprecated(
|
||||
message = "This interface is deprecated and will be removed soon, use API from 'org.jetbrains.kotlin.platform.*' packages instead",
|
||||
replaceWith = ReplaceWith("TargetPlatform", "org.jetbrains.kotlin.platform.TargetPlatform"),
|
||||
level = DeprecationLevel.ERROR
|
||||
)
|
||||
abstract class IdePlatform<Kind : IdePlatformKind<Kind>, out Arguments : CommonCompilerArguments> : DescriptionAware {
|
||||
abstract val kind: Kind
|
||||
abstract val version: TargetPlatformVersion
|
||||
|
||||
abstract fun createArguments(init: Arguments.() -> Unit = {}): Arguments
|
||||
|
||||
override val description
|
||||
get() = kind.name + " " + version.description
|
||||
|
||||
override fun toString() = description
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@file:JvmName("IdePlatformKindUtil")
|
||||
|
||||
package org.jetbrains.kotlin.platform
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||
import org.jetbrains.kotlin.config.isJps
|
||||
import org.jetbrains.kotlin.extensions.ApplicationExtensionDescriptor
|
||||
import org.jetbrains.kotlin.platform.impl.CommonIdePlatformKind
|
||||
import org.jetbrains.kotlin.platform.impl.JsIdePlatformKind
|
||||
import org.jetbrains.kotlin.platform.impl.JvmIdePlatformKind
|
||||
import org.jetbrains.kotlin.platform.impl.NativeIdePlatformKind
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||
|
||||
abstract class IdePlatformKind<Kind : IdePlatformKind<Kind>> {
|
||||
abstract fun supportsTargetPlatform(platform: TargetPlatform): Boolean
|
||||
|
||||
abstract val defaultPlatform: TargetPlatform
|
||||
|
||||
@Suppress("DEPRECATION_ERROR", "DeprecatedCallableAddReplaceWith")
|
||||
@Deprecated(
|
||||
message = "IdePlatform is deprecated and will be removed soon, please, migrate to org.jetbrains.kotlin.platform.TargetPlatform",
|
||||
level = DeprecationLevel.ERROR
|
||||
)
|
||||
abstract fun getDefaultPlatform(): IdePlatform<*, *>
|
||||
|
||||
abstract fun platformByCompilerArguments(arguments: CommonCompilerArguments): TargetPlatform?
|
||||
|
||||
abstract val argumentsClass: Class<out CommonCompilerArguments>
|
||||
|
||||
abstract val name: String
|
||||
|
||||
abstract fun createArguments(): CommonCompilerArguments
|
||||
|
||||
override fun equals(other: Any?): Boolean = javaClass == other?.javaClass
|
||||
override fun hashCode(): Int = javaClass.hashCode()
|
||||
|
||||
override fun toString() = name
|
||||
|
||||
companion object {
|
||||
// We can't use the ApplicationExtensionDescriptor class directly because it's missing in the JPS process
|
||||
private val extension = run {
|
||||
if (isJps) return@run null
|
||||
ApplicationExtensionDescriptor("org.jetbrains.kotlin.idePlatformKind", IdePlatformKind::class.java)
|
||||
}
|
||||
|
||||
// For using only in JPS
|
||||
private val JPS_KINDS
|
||||
get() = listOf(
|
||||
JvmIdePlatformKind,
|
||||
JsIdePlatformKind,
|
||||
CommonIdePlatformKind,
|
||||
NativeIdePlatformKind
|
||||
)
|
||||
|
||||
val ALL_KINDS by lazy {
|
||||
val kinds = extension?.getInstances() ?: return@lazy JPS_KINDS
|
||||
require(kinds.isNotEmpty()) { "Platform kind list is empty" }
|
||||
kinds
|
||||
}
|
||||
|
||||
|
||||
fun <Args : CommonCompilerArguments> platformByCompilerArguments(arguments: Args): TargetPlatform? =
|
||||
ALL_KINDS.firstNotNullResult { it.platformByCompilerArguments(arguments) }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
val TargetPlatform.idePlatformKind: IdePlatformKind<*>
|
||||
get() = IdePlatformKind.ALL_KINDS.filter { it.supportsTargetPlatform(this) }.let { list ->
|
||||
when {
|
||||
list.size == 1 -> list.first()
|
||||
list.size > 1 -> list.first().also {
|
||||
Logger.getInstance(IdePlatformKind.javaClass).warn("Found more than one IdePlatformKind [$list] for target [$this].")
|
||||
}
|
||||
else -> error("Unknown platform $this")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@file:Suppress("DEPRECATION_ERROR", "TYPEALIAS_EXPANSION_DEPRECATION_ERROR")
|
||||
|
||||
package org.jetbrains.kotlin.platform.compat
|
||||
|
||||
import org.jetbrains.kotlin.config.JvmTarget
|
||||
import org.jetbrains.kotlin.platform.CommonPlatforms
|
||||
import org.jetbrains.kotlin.platform.IdePlatform
|
||||
import org.jetbrains.kotlin.platform.impl.CommonIdePlatformKind
|
||||
import org.jetbrains.kotlin.platform.impl.JsIdePlatformKind
|
||||
import org.jetbrains.kotlin.platform.impl.JvmIdePlatformKind
|
||||
import org.jetbrains.kotlin.platform.impl.NativeIdePlatformKind
|
||||
import org.jetbrains.kotlin.platform.js.JsPlatform
|
||||
import org.jetbrains.kotlin.platform.js.JsPlatforms
|
||||
import org.jetbrains.kotlin.platform.jvm.JdkPlatform
|
||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatform
|
||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||
import org.jetbrains.kotlin.platform.konan.NativePlatforms
|
||||
import org.jetbrains.kotlin.platform.konan.NativePlatform
|
||||
|
||||
typealias OldPlatform = org.jetbrains.kotlin.resolve.TargetPlatform
|
||||
typealias NewPlatform = org.jetbrains.kotlin.platform.TargetPlatform
|
||||
|
||||
fun NewPlatform.toOldPlatform(): OldPlatform = when (val single = singleOrNull()) {
|
||||
null -> CommonPlatforms.CompatCommonPlatform
|
||||
is JvmPlatform -> JvmPlatforms.CompatJvmPlatform
|
||||
is JsPlatform -> JsPlatforms.CompatJsPlatform
|
||||
is NativePlatform -> NativePlatforms.CompatNativePlatform
|
||||
else -> error("Unknown platform $single")
|
||||
}
|
||||
|
||||
fun OldPlatform.toNewPlatform(): NewPlatform = when (this) {
|
||||
is CommonPlatforms.CompatCommonPlatform -> this
|
||||
is JvmPlatforms.CompatJvmPlatform -> this
|
||||
is JsPlatforms.CompatJsPlatform -> this
|
||||
is NativePlatforms.CompatNativePlatform -> this
|
||||
else -> error(
|
||||
"Can't convert org.jetbrains.kotlin.resolve.TargetPlatform to org.jetbrains.kotlin.platform.TargetPlatform: " +
|
||||
"non-Compat instance passed\n" +
|
||||
"toString: $this\n" +
|
||||
"class: ${this::class}\n" +
|
||||
"hashCode: ${this.hashCode().toString(16)}"
|
||||
)
|
||||
}
|
||||
|
||||
fun IdePlatform<*, *>.toNewPlatform(): NewPlatform = when (this) {
|
||||
is CommonIdePlatformKind.Platform -> CommonPlatforms.defaultCommonPlatform
|
||||
is JvmIdePlatformKind.Platform -> JvmPlatforms.jvmPlatformByTargetVersion(this.version)
|
||||
is JsIdePlatformKind.Platform -> JsPlatforms.defaultJsPlatform
|
||||
is NativeIdePlatformKind.Platform -> NativePlatforms.unspecifiedNativePlatform
|
||||
else -> error("Unknown platform $this")
|
||||
}
|
||||
|
||||
fun NewPlatform.toIdePlatform(): IdePlatform<*, *> = when (val single = singleOrNull()) {
|
||||
null -> CommonIdePlatformKind.Platform
|
||||
is JdkPlatform -> JvmIdePlatformKind.Platform(single.targetVersion)
|
||||
is JvmPlatform -> JvmIdePlatformKind.Platform(JvmTarget.DEFAULT)
|
||||
is JsPlatform -> JsIdePlatformKind.Platform
|
||||
is NativePlatform -> NativeIdePlatformKind.Platform
|
||||
else -> error("Unknown platform $single")
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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.
|
||||
*/
|
||||
|
||||
@file:JvmName("CommonIdePlatformUtil")
|
||||
@file:Suppress("DEPRECATION_ERROR", "DeprecatedCallableAddReplaceWith")
|
||||
|
||||
package org.jetbrains.kotlin.platform.impl
|
||||
|
||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2MetadataCompilerArguments
|
||||
import org.jetbrains.kotlin.platform.*
|
||||
|
||||
object CommonIdePlatformKind : IdePlatformKind<CommonIdePlatformKind>() {
|
||||
override fun supportsTargetPlatform(platform: TargetPlatform) = platform.isCommon()
|
||||
|
||||
override fun platformByCompilerArguments(arguments: CommonCompilerArguments): TargetPlatform? {
|
||||
return if (arguments is K2MetadataCompilerArguments)
|
||||
CommonPlatforms.defaultCommonPlatform
|
||||
else
|
||||
null
|
||||
}
|
||||
|
||||
@Deprecated(
|
||||
message = "IdePlatform is deprecated and will be removed soon, please, migrate to org.jetbrains.kotlin.platform.TargetPlatform",
|
||||
level = DeprecationLevel.ERROR
|
||||
)
|
||||
override fun getDefaultPlatform(): IdePlatform<*, *> = Platform
|
||||
|
||||
override fun createArguments(): CommonCompilerArguments {
|
||||
return K2MetadataCompilerArguments() // TODO(dsavvinov): review that, as now MPP !== K2Metadata
|
||||
}
|
||||
|
||||
override val defaultPlatform get() = CommonPlatforms.defaultCommonPlatform
|
||||
|
||||
override val argumentsClass get() = K2MetadataCompilerArguments::class.java
|
||||
|
||||
override val name get() = "Common (experimental)"
|
||||
|
||||
@Deprecated(
|
||||
message = "IdePlatform is deprecated and will be removed soon, please, migrate to org.jetbrains.kotlin.platform.TargetPlatform",
|
||||
level = DeprecationLevel.ERROR
|
||||
)
|
||||
object Platform : IdePlatform<CommonIdePlatformKind, CommonCompilerArguments>() {
|
||||
override val kind get() = CommonIdePlatformKind
|
||||
override val version get() = TargetPlatformVersion.NoVersion
|
||||
override fun createArguments(init: CommonCompilerArguments.() -> Unit) = K2MetadataCompilerArguments().apply(init)
|
||||
}
|
||||
}
|
||||
|
||||
val IdePlatformKind<*>?.isCommon
|
||||
get() = this is CommonIdePlatformKind
|
||||
|
||||
@Deprecated(
|
||||
message = "IdePlatform is deprecated and will be removed soon, please, migrate to org.jetbrains.kotlin.platform.TargetPlatform",
|
||||
level = DeprecationLevel.ERROR
|
||||
)
|
||||
val IdePlatform<*, *>.isCommon: Boolean
|
||||
get() = this is CommonIdePlatformKind.Platform
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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.platform.impl
|
||||
|
||||
import org.jetbrains.kotlin.platform.DefaultIdeTargetPlatformKindProvider
|
||||
|
||||
class IdeaDefaultIdeTargetPlatformKindProvider private constructor() : DefaultIdeTargetPlatformKindProvider {
|
||||
override val defaultPlatform = JvmIdePlatformKind.defaultPlatform
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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.
|
||||
*/
|
||||
|
||||
@file:JvmName("JsIdePlatformUtil")
|
||||
@file:Suppress("DEPRECATION_ERROR", "DeprecatedCallableAddReplaceWith")
|
||||
|
||||
package org.jetbrains.kotlin.platform.impl
|
||||
|
||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
|
||||
import org.jetbrains.kotlin.platform.IdePlatform
|
||||
import org.jetbrains.kotlin.platform.IdePlatformKind
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.platform.TargetPlatformVersion
|
||||
import org.jetbrains.kotlin.platform.js.JsPlatforms
|
||||
import org.jetbrains.kotlin.platform.js.isJs
|
||||
|
||||
object JsIdePlatformKind : IdePlatformKind<JsIdePlatformKind>() {
|
||||
override fun supportsTargetPlatform(platform: TargetPlatform): Boolean = platform.isJs()
|
||||
|
||||
override fun platformByCompilerArguments(arguments: CommonCompilerArguments): TargetPlatform? {
|
||||
return if (arguments is K2JSCompilerArguments)
|
||||
JsPlatforms.defaultJsPlatform
|
||||
else
|
||||
null
|
||||
}
|
||||
|
||||
val platforms get() = listOf(JsPlatforms.defaultJsPlatform)
|
||||
override val defaultPlatform get() = JsPlatforms.defaultJsPlatform
|
||||
|
||||
@Deprecated(
|
||||
message = "IdePlatform is deprecated and will be removed soon, please, migrate to org.jetbrains.kotlin.platform.TargetPlatform",
|
||||
level = DeprecationLevel.ERROR
|
||||
)
|
||||
override fun getDefaultPlatform(): IdePlatform<*, *> = Platform
|
||||
|
||||
override fun createArguments(): CommonCompilerArguments {
|
||||
return K2JSCompilerArguments()
|
||||
}
|
||||
|
||||
override val argumentsClass get() = K2JSCompilerArguments::class.java
|
||||
|
||||
override val name get() = "JavaScript"
|
||||
|
||||
@Deprecated(
|
||||
message = "IdePlatform is deprecated and will be removed soon, please, migrate to org.jetbrains.kotlin.platform.TargetPlatform",
|
||||
level = DeprecationLevel.ERROR
|
||||
)
|
||||
object Platform : IdePlatform<JsIdePlatformKind, K2JSCompilerArguments>() {
|
||||
override val kind get() = JsIdePlatformKind
|
||||
override val version get() = TargetPlatformVersion.NoVersion
|
||||
override fun createArguments(init: K2JSCompilerArguments.() -> Unit) = K2JSCompilerArguments().apply(init)
|
||||
}
|
||||
}
|
||||
|
||||
val IdePlatformKind<*>?.isJavaScript
|
||||
get() = this is JsIdePlatformKind
|
||||
|
||||
@Deprecated(
|
||||
message = "IdePlatform is deprecated and will be removed soon, please, migrate to org.jetbrains.kotlin.platform.TargetPlatform",
|
||||
level = DeprecationLevel.ERROR
|
||||
)
|
||||
val IdePlatform<*, *>?.isJavaScript
|
||||
get() = this is JsIdePlatformKind.Platform
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@file:JvmName("JvmIdePlatformUtil")
|
||||
@file:Suppress("DEPRECATION_ERROR", "DeprecatedCallableAddReplaceWith")
|
||||
|
||||
package org.jetbrains.kotlin.platform.impl
|
||||
|
||||
import com.intellij.util.text.VersionComparatorUtil
|
||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
||||
import org.jetbrains.kotlin.config.JvmTarget
|
||||
import org.jetbrains.kotlin.platform.IdePlatform
|
||||
import org.jetbrains.kotlin.platform.IdePlatformKind
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||
import org.jetbrains.kotlin.platform.jvm.isJvm
|
||||
|
||||
object JvmIdePlatformKind : IdePlatformKind<JvmIdePlatformKind>() {
|
||||
override fun supportsTargetPlatform(platform: TargetPlatform): Boolean = platform.isJvm()
|
||||
|
||||
override fun platformByCompilerArguments(arguments: CommonCompilerArguments): TargetPlatform? {
|
||||
if (arguments !is K2JVMCompilerArguments) return null
|
||||
|
||||
val jvmTargetDescription = arguments.jvmTarget
|
||||
?: return JvmPlatforms.defaultJvmPlatform
|
||||
|
||||
val jvmTarget = JvmTarget.values()
|
||||
.firstOrNull { VersionComparatorUtil.COMPARATOR.compare(it.description, jvmTargetDescription) >= 0 }
|
||||
?: return JvmPlatforms.defaultJvmPlatform
|
||||
|
||||
return JvmPlatforms.jvmPlatformByTargetVersion(jvmTarget)
|
||||
}
|
||||
|
||||
@Deprecated(
|
||||
message = "IdePlatform is deprecated and will be removed soon, please, migrate to org.jetbrains.kotlin.platform.TargetPlatform",
|
||||
level = DeprecationLevel.ERROR
|
||||
)
|
||||
override fun getDefaultPlatform(): Platform = Platform(JvmTarget.DEFAULT)
|
||||
|
||||
override fun createArguments(): CommonCompilerArguments {
|
||||
return K2JVMCompilerArguments()
|
||||
}
|
||||
|
||||
val platforms: List<TargetPlatform> = JvmTarget.values()
|
||||
.map { ver -> JvmPlatforms.jvmPlatformByTargetVersion(ver) } + listOf(JvmPlatforms.unspecifiedJvmPlatform)
|
||||
|
||||
override val defaultPlatform get() = JvmPlatforms.defaultJvmPlatform
|
||||
|
||||
override val argumentsClass get() = K2JVMCompilerArguments::class.java
|
||||
|
||||
override val name get() = "JVM"
|
||||
|
||||
@Deprecated(
|
||||
message = "IdePlatform is deprecated and will be removed soon, please, migrate to org.jetbrains.kotlin.platform.TargetPlatform",
|
||||
level = DeprecationLevel.ERROR
|
||||
)
|
||||
data class Platform(override val version: JvmTarget) : IdePlatform<JvmIdePlatformKind, K2JVMCompilerArguments>() {
|
||||
override val kind get() = JvmIdePlatformKind
|
||||
|
||||
override fun createArguments(init: K2JVMCompilerArguments.() -> Unit) = K2JVMCompilerArguments()
|
||||
.apply(init)
|
||||
.apply { jvmTarget = this@Platform.version.description }
|
||||
}
|
||||
}
|
||||
|
||||
val IdePlatformKind<*>?.isJvm
|
||||
get() = this is JvmIdePlatformKind
|
||||
|
||||
@Deprecated(
|
||||
message = "IdePlatform is deprecated and will be removed soon, please, migrate to org.jetbrains.kotlin.platform.TargetPlatform",
|
||||
level = DeprecationLevel.ERROR
|
||||
)
|
||||
val IdePlatform<*, *>.isJvm: Boolean
|
||||
get() = this is JvmIdePlatformKind.Platform
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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.
|
||||
*/
|
||||
|
||||
@file:JvmName("NativeIdePlatformUtil")
|
||||
@file:Suppress("DEPRECATION_ERROR", "DeprecatedCallableAddReplaceWith")
|
||||
|
||||
package org.jetbrains.kotlin.platform.impl
|
||||
|
||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||
import org.jetbrains.kotlin.platform.IdePlatform
|
||||
import org.jetbrains.kotlin.platform.IdePlatformKind
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.platform.TargetPlatformVersion
|
||||
import org.jetbrains.kotlin.platform.konan.NativePlatforms
|
||||
import org.jetbrains.kotlin.platform.konan.isNative
|
||||
|
||||
object NativeIdePlatformKind : IdePlatformKind<NativeIdePlatformKind>() {
|
||||
override fun supportsTargetPlatform(platform: TargetPlatform): Boolean = platform.isNative()
|
||||
|
||||
override fun platformByCompilerArguments(arguments: CommonCompilerArguments): TargetPlatform? {
|
||||
return if (arguments is FakeK2NativeCompilerArguments)
|
||||
NativePlatforms.unspecifiedNativePlatform
|
||||
else
|
||||
null
|
||||
}
|
||||
|
||||
override fun createArguments(): CommonCompilerArguments {
|
||||
return FakeK2NativeCompilerArguments()
|
||||
}
|
||||
|
||||
override val defaultPlatform: TargetPlatform
|
||||
get() = NativePlatforms.unspecifiedNativePlatform
|
||||
|
||||
@Deprecated(
|
||||
message = "IdePlatform is deprecated and will be removed soon, please, migrate to org.jetbrains.kotlin.platform.TargetPlatform",
|
||||
level = DeprecationLevel.ERROR
|
||||
)
|
||||
override fun getDefaultPlatform(): IdePlatform<*, *> = Platform
|
||||
|
||||
override val argumentsClass
|
||||
get() = FakeK2NativeCompilerArguments::class.java
|
||||
|
||||
override val name
|
||||
get() = "Native"
|
||||
|
||||
@Deprecated(
|
||||
message = "IdePlatform is deprecated and will be removed soon, please, migrate to org.jetbrains.kotlin.platform.TargetPlatform",
|
||||
level = DeprecationLevel.ERROR
|
||||
)
|
||||
object Platform : IdePlatform<NativeIdePlatformKind, FakeK2NativeCompilerArguments>() {
|
||||
override val kind get() = NativeIdePlatformKind
|
||||
override val version get() = TargetPlatformVersion.NoVersion
|
||||
override fun createArguments(init: FakeK2NativeCompilerArguments.() -> Unit) = FakeK2NativeCompilerArguments().apply(init)
|
||||
}
|
||||
}
|
||||
|
||||
// These are fake compiler arguments for Kotlin/Native - only for usage within IDEA plugin:
|
||||
class FakeK2NativeCompilerArguments : CommonCompilerArguments()
|
||||
|
||||
val IdePlatformKind<*>?.isKotlinNative
|
||||
get() = this is NativeIdePlatformKind
|
||||
|
||||
@Deprecated(
|
||||
message = "IdePlatform is deprecated and will be removed soon, please, migrate to org.jetbrains.kotlin.platform.TargetPlatform",
|
||||
level = DeprecationLevel.ERROR
|
||||
)
|
||||
val IdePlatform<*, *>?.isKotlinNative
|
||||
get() = this is NativeIdePlatformKind.Platform
|
||||
@@ -0,0 +1,71 @@
|
||||
plugins {
|
||||
kotlin("jvm")
|
||||
id("jps-compatible")
|
||||
}
|
||||
|
||||
val compilerModules: Array<String> by rootProject.extra
|
||||
|
||||
dependencies {
|
||||
compile(project(":kotlin-build-common"))
|
||||
compile(project(":core:descriptors"))
|
||||
compile(project(":core:descriptors.jvm"))
|
||||
compile(project(":kotlin-compiler-runner"))
|
||||
compile(project(":daemon-common"))
|
||||
compile(project(":daemon-common-new"))
|
||||
compile(projectRuntimeJar(":kotlin-daemon-client"))
|
||||
compile(projectRuntimeJar(":kotlin-daemon"))
|
||||
compile(project(":compiler:frontend.java"))
|
||||
compile(project(":js:js.frontend"))
|
||||
compile(projectRuntimeJar(":kotlin-preloader"))
|
||||
compile(project(":idea:idea-jps-common"))
|
||||
Platform[193].orLower {
|
||||
compileOnly(intellijDep()) { includeJars("openapi", rootProject = rootProject) }
|
||||
}
|
||||
compileOnly(intellijDep()) {
|
||||
includeJars("jdom", "trove4j", "jps-model", "platform-api", "util", "asm-all", rootProject = rootProject)
|
||||
}
|
||||
compileOnly(jpsStandalone()) { includeJars("jps-builders", "jps-builders-6") }
|
||||
testCompileOnly(project(":kotlin-reflect-api"))
|
||||
testCompile(project(":compiler:incremental-compilation-impl"))
|
||||
testCompile(projectTests(":compiler:tests-common"))
|
||||
testCompile(projectTests(":compiler:incremental-compilation-impl"))
|
||||
testCompile(commonDep("junit:junit"))
|
||||
testCompile(project(":kotlin-test:kotlin-test-jvm"))
|
||||
testCompile(projectTests(":kotlin-build-common"))
|
||||
testCompileOnly(jpsStandalone()) { includeJars("jps-builders", "jps-builders-6") }
|
||||
Ide.IJ {
|
||||
testCompile(intellijDep("devkit"))
|
||||
}
|
||||
|
||||
testCompile(intellijDep())
|
||||
|
||||
testCompile(jpsBuildTest())
|
||||
compilerModules.forEach {
|
||||
testRuntime(project(it))
|
||||
}
|
||||
|
||||
testRuntimeOnly(intellijPluginDep("java"))
|
||||
|
||||
testRuntimeOnly(toolsJar())
|
||||
testRuntime(project(":kotlin-reflect"))
|
||||
testRuntime(project(":kotlin-script-runtime"))
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
"main" { projectDefault() }
|
||||
"test" {
|
||||
Ide.IJ {
|
||||
java.srcDirs("jps-tests/test")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
projectTest(parallel = true) {
|
||||
// do not replace with compile/runtime dependency,
|
||||
// because it forces Intellij reindexing after each compiler change
|
||||
dependsOn(":kotlin-compiler:dist")
|
||||
dependsOn(":kotlin-stdlib-js-ir:packFullRuntimeKLib")
|
||||
workingDir = rootDir
|
||||
}
|
||||
|
||||
testsJar {}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.build
|
||||
|
||||
import org.jetbrains.kotlin.incremental.testingUtils.BuildLogFinder
|
||||
import org.jetbrains.kotlin.jps.targets.KotlinModuleBuildTarget
|
||||
|
||||
/**
|
||||
* @see [jps-plugin/testData/incremental/cacheVersionChanged/README.md]
|
||||
*/
|
||||
abstract class AbstractDataContainerVersionChangedTest : AbstractIncrementalCacheVersionChangedTest() {
|
||||
override val buildLogFinder: BuildLogFinder
|
||||
get() = BuildLogFinder(isDataContainerBuildLogEnabled = true)
|
||||
|
||||
override fun getVersionManagersToTest(target: KotlinModuleBuildTarget<*>) =
|
||||
listOf(kotlinCompileContext.lookupsCacheAttributesManager.versionManagerForTesting)
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.build
|
||||
|
||||
import org.jetbrains.kotlin.incremental.testingUtils.Modification
|
||||
import org.jetbrains.kotlin.incremental.testingUtils.ModifyContent
|
||||
import org.jetbrains.kotlin.jps.incremental.CacheVersionManager
|
||||
import org.jetbrains.kotlin.jps.targets.KotlinModuleBuildTarget
|
||||
|
||||
/**
|
||||
* @see [jps-plugin/testData/incremental/cacheVersionChanged/README.md]
|
||||
*/
|
||||
abstract class AbstractIncrementalCacheVersionChangedTest : AbstractIncrementalJvmJpsTest(allowNoFilesWithSuffixInTestData = true) {
|
||||
override fun performAdditionalModifications(modifications: List<Modification>) {
|
||||
val modifiedFiles = modifications.filterIsInstance<ModifyContent>().map { it.path }
|
||||
val targets = projectDescriptor.allModuleTargets
|
||||
val hasKotlin = HasKotlinMarker(projectDescriptor.dataManager)
|
||||
|
||||
if (modifiedFiles.any { it.endsWith("clear-has-kotlin") }) {
|
||||
targets.forEach { hasKotlin.clean(it) }
|
||||
}
|
||||
|
||||
if (modifiedFiles.none { it.endsWith("do-not-change-cache-versions") }) {
|
||||
val versions = targets.flatMap {
|
||||
getVersionManagersToTest(kotlinCompileContext.targetsBinding[it]!!)
|
||||
}
|
||||
|
||||
versions.forEach {
|
||||
if (it.versionFileForTesting.exists()) {
|
||||
it.versionFileForTesting.writeText("777")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun getVersionManagersToTest(target: KotlinModuleBuildTarget<*>): List<CacheVersionManager> =
|
||||
listOf(target.localCacheVersionManager)
|
||||
}
|
||||
+683
@@ -0,0 +1,683 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.build
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.util.io.FileUtilRt
|
||||
import com.intellij.testFramework.TestLoggerFactory
|
||||
import com.intellij.testFramework.UsefulTestCase
|
||||
import junit.framework.TestCase
|
||||
import org.apache.log4j.ConsoleAppender
|
||||
import org.apache.log4j.Level
|
||||
import org.apache.log4j.Logger
|
||||
import org.apache.log4j.PatternLayout
|
||||
import org.jetbrains.jps.ModuleChunk
|
||||
import org.jetbrains.jps.api.CanceledStatus
|
||||
import org.jetbrains.jps.builders.BuildResult
|
||||
import org.jetbrains.jps.builders.CompileScopeTestBuilder
|
||||
import org.jetbrains.jps.builders.impl.BuildDataPathsImpl
|
||||
import org.jetbrains.jps.builders.impl.logging.ProjectBuilderLoggerBase
|
||||
import org.jetbrains.jps.builders.java.dependencyView.Callbacks
|
||||
import org.jetbrains.jps.builders.logging.BuildLoggingManager
|
||||
import org.jetbrains.jps.cmdline.ProjectDescriptor
|
||||
import org.jetbrains.jps.incremental.*
|
||||
import org.jetbrains.jps.incremental.messages.BuildMessage
|
||||
import org.jetbrains.jps.model.JpsDummyElement
|
||||
import org.jetbrains.jps.model.JpsModuleRootModificationUtil
|
||||
import org.jetbrains.jps.model.java.JpsJavaExtensionService
|
||||
import org.jetbrains.jps.model.library.sdk.JpsSdk
|
||||
import org.jetbrains.jps.util.JpsPathUtil
|
||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2MetadataCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.arguments.parseCommandLineArguments
|
||||
import org.jetbrains.kotlin.incremental.LookupSymbol
|
||||
import org.jetbrains.kotlin.incremental.testingUtils.*
|
||||
import org.jetbrains.kotlin.jps.build.dependeciestxt.ModulesTxt
|
||||
import org.jetbrains.kotlin.jps.build.dependeciestxt.ModulesTxtBuilder
|
||||
import org.jetbrains.kotlin.jps.build.fixtures.EnableICFixture
|
||||
import org.jetbrains.kotlin.jps.incremental.CacheAttributesDiff
|
||||
import org.jetbrains.kotlin.jps.incremental.CacheVersionManager
|
||||
import org.jetbrains.kotlin.jps.incremental.CompositeLookupsCacheAttributesManager
|
||||
import org.jetbrains.kotlin.jps.incremental.getKotlinCache
|
||||
import org.jetbrains.kotlin.jps.model.JpsKotlinFacetModuleExtension
|
||||
import org.jetbrains.kotlin.jps.model.kotlinCommonCompilerArguments
|
||||
import org.jetbrains.kotlin.jps.model.kotlinFacet
|
||||
import org.jetbrains.kotlin.jps.targets.KotlinModuleBuildTarget
|
||||
import org.jetbrains.kotlin.platform.idePlatformKind
|
||||
import org.jetbrains.kotlin.platform.impl.isJavaScript
|
||||
import org.jetbrains.kotlin.platform.impl.isJvm
|
||||
import org.jetbrains.kotlin.platform.orDefault
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.File
|
||||
import java.io.PrintStream
|
||||
import java.util.*
|
||||
import kotlin.reflect.jvm.javaField
|
||||
|
||||
abstract class AbstractIncrementalJpsTest(
|
||||
private val allowNoFilesWithSuffixInTestData: Boolean = false,
|
||||
private val checkDumpsCaseInsensitively: Boolean = false
|
||||
) : BaseKotlinJpsBuildTestCase() {
|
||||
companion object {
|
||||
private val COMPILATION_FAILED = "COMPILATION FAILED"
|
||||
|
||||
// change to "/tmp" or anything when default is too long (for easier debugging)
|
||||
private val TEMP_DIRECTORY_TO_USE = File(FileUtilRt.getTempDirectory())
|
||||
|
||||
private val DEBUG_LOGGING_ENABLED = System.getProperty("debug.logging.enabled") == "true"
|
||||
|
||||
private const val ARGUMENTS_FILE_NAME = "args.txt"
|
||||
|
||||
private fun parseAdditionalArgs(testDir: File): List<String> {
|
||||
return File(testDir, ARGUMENTS_FILE_NAME)
|
||||
.takeIf { it.exists() }
|
||||
?.readText()
|
||||
?.split(" ", "\n")
|
||||
?.filter { it.isNotBlank() }
|
||||
?: emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
protected lateinit var testDataDir: File
|
||||
protected lateinit var workDir: File
|
||||
protected lateinit var projectDescriptor: ProjectDescriptor
|
||||
protected lateinit var additionalCommandLineArguments: List<String>
|
||||
// is used to compare lookup dumps in a human readable way (lookup symbols are hashed in an actual lookup storage)
|
||||
protected lateinit var lookupsDuringTest: MutableSet<LookupSymbol>
|
||||
private var isJvmICEnabledBackup: Boolean = false
|
||||
private var isJsICEnabledBackup: Boolean = false
|
||||
|
||||
protected var mapWorkingToOriginalFile: MutableMap<File, File> = hashMapOf()
|
||||
|
||||
lateinit var kotlinCompileContext: KotlinCompileContext
|
||||
|
||||
protected open val buildLogFinder: BuildLogFinder
|
||||
get() = BuildLogFinder()
|
||||
|
||||
private fun enableDebugLogging() {
|
||||
com.intellij.openapi.diagnostic.Logger.setFactory(TestLoggerFactory::class.java)
|
||||
TestLoggerFactory.dumpLogToStdout("")
|
||||
TestLoggerFactory.enableDebugLogging(testRootDisposable, "#org")
|
||||
|
||||
val console = ConsoleAppender()
|
||||
console.layout = PatternLayout("%d [%p|%c|%C{1}] %m%n")
|
||||
console.threshold = Level.ALL
|
||||
console.activateOptions()
|
||||
Logger.getRootLogger().addAppender(console)
|
||||
}
|
||||
|
||||
private var systemPropertiesBackup = run {
|
||||
val props = System.getProperties()
|
||||
val output = ByteArrayOutputStream()
|
||||
props.store(output, "System properties backup")
|
||||
output.toByteArray()
|
||||
}
|
||||
|
||||
private fun restoreSystemProperties() {
|
||||
val input = ByteArrayInputStream(systemPropertiesBackup)
|
||||
val props = Properties()
|
||||
props.load(input)
|
||||
System.setProperties(props)
|
||||
}
|
||||
|
||||
private val enableICFixture = EnableICFixture()
|
||||
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
|
||||
enableICFixture.setUp()
|
||||
lookupsDuringTest = hashSetOf()
|
||||
|
||||
if (DEBUG_LOGGING_ENABLED) {
|
||||
enableDebugLogging()
|
||||
}
|
||||
}
|
||||
|
||||
override fun tearDown() {
|
||||
restoreSystemProperties()
|
||||
|
||||
(AbstractIncrementalJpsTest::myProject).javaField!![this] = null
|
||||
(AbstractIncrementalJpsTest::projectDescriptor).javaField!![this] = null
|
||||
(AbstractIncrementalJpsTest::systemPropertiesBackup).javaField!![this] = null
|
||||
|
||||
lookupsDuringTest.clear()
|
||||
enableICFixture.tearDown()
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
// JPS forces rebuild of all files when JVM constant has been changed and Callbacks.ConstantAffectionResolver
|
||||
// is not provided, so ConstantAffectionResolver is mocked with empty implementation
|
||||
// Usages in Kotlin files are expected to be found by KotlinLookupConstantSearch
|
||||
protected open val mockConstantSearch: Callbacks.ConstantAffectionResolver?
|
||||
get() = MockJavaConstantSearch(workDir)
|
||||
|
||||
private fun build(
|
||||
name: String?,
|
||||
scope: CompileScopeTestBuilder = CompileScopeTestBuilder.make().allModules()
|
||||
): MakeResult {
|
||||
val workDirPath = FileUtil.toSystemIndependentName(workDir.absolutePath)
|
||||
|
||||
val logger = MyLogger(workDirPath)
|
||||
projectDescriptor = createProjectDescriptor(BuildLoggingManager(logger))
|
||||
|
||||
val lookupTracker = TestLookupTracker()
|
||||
val testingContext = TestingContext(lookupTracker, logger)
|
||||
projectDescriptor.project.setTestingContext(testingContext)
|
||||
|
||||
try {
|
||||
val builder = IncProjectBuilder(
|
||||
projectDescriptor,
|
||||
BuilderRegistry.getInstance(),
|
||||
myBuildParams,
|
||||
CanceledStatus.NULL,
|
||||
true
|
||||
)
|
||||
val buildResult = BuildResult()
|
||||
builder.addMessageHandler(buildResult)
|
||||
val finalScope = scope.build()
|
||||
projectDescriptor.project.kotlinCommonCompilerArguments = projectDescriptor.project.kotlinCommonCompilerArguments.apply {
|
||||
updateCommandLineArguments(this)
|
||||
}
|
||||
|
||||
builder.build(finalScope, false)
|
||||
|
||||
// testingContext.kotlinCompileContext is initialized in KotlinBuilder.initializeKotlinContext
|
||||
kotlinCompileContext = testingContext.kotlinCompileContext!!
|
||||
|
||||
lookupTracker.lookups.mapTo(lookupsDuringTest) { LookupSymbol(it.name, it.scopeFqName) }
|
||||
|
||||
if (!buildResult.isSuccessful) {
|
||||
val errorMessages =
|
||||
buildResult
|
||||
.getMessages(BuildMessage.Kind.ERROR)
|
||||
.map { it.messageText }
|
||||
.map { it.replace("^.+:\\d+:\\s+".toRegex(), "").trim() }
|
||||
.joinToString("\n")
|
||||
return MakeResult(
|
||||
log = logger.log + "$COMPILATION_FAILED\n" + errorMessages + "\n",
|
||||
makeFailed = true,
|
||||
mappingsDump = null,
|
||||
name = name
|
||||
)
|
||||
} else {
|
||||
return MakeResult(
|
||||
log = logger.log,
|
||||
makeFailed = false,
|
||||
mappingsDump = createMappingsDump(projectDescriptor, kotlinCompileContext, lookupsDuringTest),
|
||||
name = name
|
||||
)
|
||||
}
|
||||
} finally {
|
||||
projectDescriptor.dataManager.flush(false)
|
||||
projectDescriptor.release()
|
||||
}
|
||||
}
|
||||
|
||||
private fun initialMake(): MakeResult {
|
||||
val makeResult = build(null)
|
||||
|
||||
val initBuildLogFile = File(testDataDir, "init-build.log")
|
||||
if (initBuildLogFile.exists()) {
|
||||
UsefulTestCase.assertSameLinesWithFile(initBuildLogFile.absolutePath, makeResult.log)
|
||||
} else {
|
||||
assertFalse("Initial make failed:\n$makeResult", makeResult.makeFailed)
|
||||
}
|
||||
|
||||
return makeResult
|
||||
}
|
||||
|
||||
private fun make(name: String?): MakeResult {
|
||||
return build(name)
|
||||
}
|
||||
|
||||
private fun rebuild(): MakeResult {
|
||||
return build(null, CompileScopeTestBuilder.rebuild().allModules())
|
||||
}
|
||||
|
||||
private fun updateCommandLineArguments(arguments: CommonCompilerArguments) {
|
||||
parseCommandLineArguments(additionalCommandLineArguments, arguments)
|
||||
}
|
||||
|
||||
private fun rebuildAndCheckOutput(makeOverallResult: MakeResult) {
|
||||
val outDir = File(getAbsolutePath("out"))
|
||||
val outAfterMake = File(getAbsolutePath("out-after-make"))
|
||||
|
||||
if (outDir.exists()) {
|
||||
FileUtil.copyDir(outDir, outAfterMake)
|
||||
}
|
||||
|
||||
val rebuildResult = rebuild()
|
||||
assertEquals(
|
||||
"Rebuild failed: ${rebuildResult.makeFailed}, last make failed: ${makeOverallResult.makeFailed}. Rebuild result: $rebuildResult",
|
||||
rebuildResult.makeFailed, makeOverallResult.makeFailed
|
||||
)
|
||||
|
||||
if (!outAfterMake.exists()) {
|
||||
assertFalse(outDir.exists())
|
||||
} else {
|
||||
assertEqualDirectories(outDir, outAfterMake, makeOverallResult.makeFailed)
|
||||
}
|
||||
|
||||
if (!makeOverallResult.makeFailed) {
|
||||
if (checkDumpsCaseInsensitively && rebuildResult.mappingsDump?.toLowerCase() == makeOverallResult.mappingsDump?.toLowerCase()) {
|
||||
// do nothing
|
||||
} else {
|
||||
TestCase.assertEquals(rebuildResult.mappingsDump, makeOverallResult.mappingsDump)
|
||||
}
|
||||
}
|
||||
|
||||
FileUtil.delete(outAfterMake)
|
||||
}
|
||||
|
||||
private fun clearCachesRebuildAndCheckOutput(makeOverallResult: MakeResult) {
|
||||
FileUtil.delete(BuildDataPathsImpl(myDataStorageRoot).dataStorageRoot!!)
|
||||
|
||||
rebuildAndCheckOutput(makeOverallResult)
|
||||
}
|
||||
|
||||
open val modulesTxtFile
|
||||
get() = File(testDataDir, "dependencies.txt")
|
||||
|
||||
private fun readModulesTxt(): ModulesTxt? {
|
||||
var actualModulesTxtFile = modulesTxtFile
|
||||
|
||||
if (!actualModulesTxtFile.exists()) {
|
||||
// also try `"_${fileName}.txt"`. Useful for sorting files in IDE.
|
||||
actualModulesTxtFile = modulesTxtFile.parentFile.resolve("_" + modulesTxtFile.name)
|
||||
if (!actualModulesTxtFile.exists()) return null
|
||||
}
|
||||
|
||||
return ModulesTxtBuilder().readFile(actualModulesTxtFile)
|
||||
}
|
||||
|
||||
protected open fun createBuildLog(incrementalMakeResults: List<AbstractIncrementalJpsTest.MakeResult>): String =
|
||||
buildString {
|
||||
incrementalMakeResults.forEachIndexed { i, makeResult ->
|
||||
if (i > 0) append("\n")
|
||||
if (makeResult.name != null) {
|
||||
append("================ Step #${i + 1} ${makeResult.name} =================\n\n")
|
||||
} else {
|
||||
append("================ Step #${i + 1} =================\n\n")
|
||||
}
|
||||
append(makeResult.log)
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun doTest(testDataPath: String) {
|
||||
testDataDir = File(testDataPath)
|
||||
workDir = FileUtilRt.createTempDirectory(TEMP_DIRECTORY_TO_USE, "aijt-jps-build", null)
|
||||
additionalCommandLineArguments = parseAdditionalArgs(File(testDataPath))
|
||||
val buildLogFile = buildLogFinder.findBuildLog(testDataDir)
|
||||
Disposer.register(testRootDisposable, Disposable { FileUtilRt.delete(workDir) })
|
||||
|
||||
val modulesTxt = configureModules()
|
||||
if (modulesTxt?.muted == true) return
|
||||
|
||||
initialMake()
|
||||
|
||||
val otherMakeResults = performModificationsAndMake(
|
||||
modulesTxt?.modules?.map { it.name },
|
||||
hasBuildLog = buildLogFile != null
|
||||
)
|
||||
|
||||
buildLogFile?.let {
|
||||
val logs = createBuildLog(otherMakeResults)
|
||||
UsefulTestCase.assertSameLinesWithFile(buildLogFile.absolutePath, logs)
|
||||
|
||||
val lastMakeResult = otherMakeResults.last()
|
||||
clearCachesRebuildAndCheckOutput(lastMakeResult)
|
||||
}
|
||||
}
|
||||
|
||||
protected data class MakeResult(
|
||||
val log: String,
|
||||
val makeFailed: Boolean,
|
||||
val mappingsDump: String?,
|
||||
val name: String? = null
|
||||
)
|
||||
|
||||
open val testDataSrc: File
|
||||
get() = testDataDir
|
||||
|
||||
private fun performModificationsAndMake(
|
||||
moduleNames: Collection<String>?,
|
||||
hasBuildLog: Boolean
|
||||
): List<MakeResult> {
|
||||
val results = arrayListOf<MakeResult>()
|
||||
val modifications = getModificationsToPerform(
|
||||
testDataSrc,
|
||||
moduleNames,
|
||||
allowNoFilesWithSuffixInTestData = allowNoFilesWithSuffixInTestData || !hasBuildLog,
|
||||
touchPolicy = TouchPolicy.TIMESTAMP
|
||||
)
|
||||
|
||||
if (!hasBuildLog) {
|
||||
check(modifications.size == 1 && modifications.single().isEmpty()) {
|
||||
"Bad test data: build steps are provided, but there is no `build.log` file"
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
val stepsTxt = File(testDataSrc, "_steps.txt")
|
||||
val modificationNames = if (stepsTxt.exists()) stepsTxt.readLines() else null
|
||||
|
||||
modifications.forEachIndexed { index, step ->
|
||||
step.forEach { it.perform(workDir, mapWorkingToOriginalFile) }
|
||||
performAdditionalModifications(step)
|
||||
if (moduleNames == null) {
|
||||
preProcessSources(File(workDir, "src"))
|
||||
} else {
|
||||
moduleNames.forEach { preProcessSources(File(workDir, "$it/src")) }
|
||||
}
|
||||
|
||||
val name = modificationNames?.getOrNull(index)
|
||||
val makeResult = make(name)
|
||||
results.add(makeResult)
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
protected open fun performAdditionalModifications(modifications: List<Modification>) {
|
||||
}
|
||||
|
||||
protected open fun generateModuleSources(modulesTxt: ModulesTxt) = Unit
|
||||
|
||||
// null means one module
|
||||
private fun configureModules(): ModulesTxt? {
|
||||
JpsJavaExtensionService.getInstance().getOrCreateProjectExtension(myProject).outputUrl =
|
||||
JpsPathUtil.pathToUrl(getAbsolutePath("out"))
|
||||
|
||||
val jdk = addJdk("my jdk")
|
||||
val modulesTxt = readModulesTxt()
|
||||
mapWorkingToOriginalFile = hashMapOf()
|
||||
|
||||
if (modulesTxt == null) configureSingleModuleProject(jdk)
|
||||
else configureMultiModuleProject(modulesTxt, jdk)
|
||||
|
||||
overrideModuleSettings()
|
||||
configureRequiredLibraries()
|
||||
|
||||
return modulesTxt
|
||||
}
|
||||
|
||||
open fun overrideModuleSettings() {
|
||||
}
|
||||
|
||||
private fun configureSingleModuleProject(jdk: JpsSdk<JpsDummyElement>?) {
|
||||
addModule("module", arrayOf(getAbsolutePath("src")), null, null, jdk)
|
||||
|
||||
val sourceDestinationDir = File(workDir, "src")
|
||||
val sourcesMapping = copyTestSources(testDataDir, File(workDir, "src"), "")
|
||||
mapWorkingToOriginalFile.putAll(sourcesMapping)
|
||||
|
||||
preProcessSources(sourceDestinationDir)
|
||||
}
|
||||
|
||||
protected open val ModulesTxt.Module.sourceFilePrefix: String
|
||||
get() = "${name}_"
|
||||
|
||||
private fun configureMultiModuleProject(
|
||||
modulesTxt: ModulesTxt,
|
||||
jdk: JpsSdk<JpsDummyElement>?
|
||||
) {
|
||||
modulesTxt.modules.forEach { module ->
|
||||
module.jpsModule = addModule(
|
||||
module.name,
|
||||
arrayOf(getAbsolutePath("${module.name}/src")),
|
||||
null,
|
||||
null,
|
||||
jdk
|
||||
)!!
|
||||
|
||||
val kotlinFacetSettings = module.kotlinFacetSettings
|
||||
if (kotlinFacetSettings != null) {
|
||||
val compilerArguments = kotlinFacetSettings.compilerArguments
|
||||
if (compilerArguments is K2MetadataCompilerArguments) {
|
||||
val out = getAbsolutePath("${module.name}/out")
|
||||
File(out).mkdirs()
|
||||
compilerArguments.destination = out
|
||||
} else if (compilerArguments is K2JVMCompilerArguments) {
|
||||
compilerArguments.disableDefaultScriptingPlugin = true
|
||||
}
|
||||
|
||||
module.jpsModule.container.setChild(
|
||||
JpsKotlinFacetModuleExtension.KIND,
|
||||
JpsKotlinFacetModuleExtension(kotlinFacetSettings)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
modulesTxt.dependencies.forEach {
|
||||
JpsModuleRootModificationUtil.addDependency(
|
||||
it.from.jpsModule, it.to.jpsModule,
|
||||
it.scope, it.exported
|
||||
)
|
||||
}
|
||||
|
||||
// configure module contents
|
||||
generateModuleSources(modulesTxt)
|
||||
modulesTxt.modules.forEach { module ->
|
||||
val sourceDirName = "${module.name}/src"
|
||||
val sourceDestinationDir = File(workDir, sourceDirName)
|
||||
val sourcesMapping = copyTestSources(testDataSrc, sourceDestinationDir, module.sourceFilePrefix)
|
||||
mapWorkingToOriginalFile.putAll(sourcesMapping)
|
||||
|
||||
preProcessSources(sourceDestinationDir)
|
||||
}
|
||||
}
|
||||
|
||||
private fun configureRequiredLibraries() {
|
||||
myProject.modules.forEach { module ->
|
||||
val platformKind = module.kotlinFacet?.settings?.targetPlatform?.idePlatformKind.orDefault()
|
||||
|
||||
when {
|
||||
platformKind.isJvm -> {
|
||||
JpsModuleRootModificationUtil.addDependency(module, requireLibrary(KotlinJpsLibrary.JvmStdLib))
|
||||
JpsModuleRootModificationUtil.addDependency(module, requireLibrary(KotlinJpsLibrary.JvmTest))
|
||||
}
|
||||
platformKind.isJavaScript -> {
|
||||
JpsModuleRootModificationUtil.addDependency(module, requireLibrary(KotlinJpsLibrary.JsStdLib))
|
||||
JpsModuleRootModificationUtil.addDependency(module, requireLibrary(KotlinJpsLibrary.JsTest))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun preProcessSources(srcDir: File) {
|
||||
}
|
||||
|
||||
override fun doGetProjectDir(): File? = workDir
|
||||
|
||||
internal class MyLogger(val rootPath: String) : ProjectBuilderLoggerBase(), TestingBuildLogger {
|
||||
private val markedDirtyBeforeRound = ArrayList<File>()
|
||||
private val markedDirtyAfterRound = ArrayList<File>()
|
||||
private val customMessages = mutableListOf<String>()
|
||||
|
||||
override fun invalidOrUnusedCache(
|
||||
chunk: KotlinChunk?,
|
||||
target: KotlinModuleBuildTarget<*>?,
|
||||
attributesDiff: CacheAttributesDiff<*>
|
||||
) {
|
||||
val cacheManager = attributesDiff.manager
|
||||
val cacheTitle = when (cacheManager) {
|
||||
is CacheVersionManager -> "Local cache for ${chunk ?: target}"
|
||||
is CompositeLookupsCacheAttributesManager -> "Lookups cache"
|
||||
else -> error("Unknown cache manager $cacheManager")
|
||||
}
|
||||
|
||||
logLine("$cacheTitle are ${attributesDiff.status}")
|
||||
}
|
||||
|
||||
override fun markedAsDirtyBeforeRound(files: Iterable<File>) {
|
||||
markedDirtyBeforeRound.addAll(files)
|
||||
}
|
||||
|
||||
override fun markedAsDirtyAfterRound(files: Iterable<File>) {
|
||||
markedDirtyAfterRound.addAll(files)
|
||||
}
|
||||
|
||||
override fun chunkBuildStarted(context: CompileContext, chunk: ModuleChunk) {
|
||||
logDirtyFiles(markedDirtyBeforeRound) // files can be marked as dirty during build start (KotlinCompileContext initialization)
|
||||
|
||||
if (!chunk.isDummy(context) && context.projectDescriptor.project.modules.size > 1) {
|
||||
logLine("Building ${chunk.modules.sortedBy { it.name }.joinToString { it.name }}")
|
||||
}
|
||||
}
|
||||
|
||||
override fun afterChunkBuildStarted(context: CompileContext, chunk: ModuleChunk) {
|
||||
logDirtyFiles(markedDirtyBeforeRound)
|
||||
}
|
||||
|
||||
override fun addCustomMessage(message: String) {
|
||||
customMessages.add(message)
|
||||
}
|
||||
|
||||
override fun buildFinished(exitCode: ModuleLevelBuilder.ExitCode) {
|
||||
customMessages.forEach {
|
||||
logLine(it)
|
||||
}
|
||||
customMessages.clear()
|
||||
logDirtyFiles(markedDirtyAfterRound)
|
||||
logLine("Exit code: $exitCode")
|
||||
logLine("------------------------------------------")
|
||||
}
|
||||
|
||||
private fun logDirtyFiles(files: MutableList<File>) {
|
||||
if (files.isEmpty()) return
|
||||
|
||||
logLine("Marked as dirty by Kotlin:")
|
||||
files.apply {
|
||||
map { FileUtil.toSystemIndependentName(it.path) }
|
||||
.sorted()
|
||||
.forEach { logLine(it) }
|
||||
|
||||
clear()
|
||||
}
|
||||
}
|
||||
|
||||
private val logBuf = StringBuilder()
|
||||
val log: String
|
||||
get() = logBuf.toString()
|
||||
|
||||
val compiledFiles = hashSetOf<File>()
|
||||
|
||||
override fun isEnabled(): Boolean = true
|
||||
|
||||
override fun logCompiledFiles(files: MutableCollection<File>?, builderName: String?, description: String?) {
|
||||
super.logCompiledFiles(files, builderName, description)
|
||||
|
||||
if (builderName == KotlinBuilder.KOTLIN_BUILDER_NAME) {
|
||||
compiledFiles.addAll(files!!)
|
||||
}
|
||||
}
|
||||
|
||||
override fun logLine(message: String?) {
|
||||
logBuf.append(message!!.replace("^$rootPath/".toRegex(), " ")).append('\n')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createMappingsDump(
|
||||
project: ProjectDescriptor,
|
||||
kotlinContext: KotlinCompileContext,
|
||||
lookupsDuringTest: Set<LookupSymbol>
|
||||
) = createKotlinCachesDump(project, kotlinContext, lookupsDuringTest) + "\n\n\n" +
|
||||
createCommonMappingsDump(project) + "\n\n\n" +
|
||||
createJavaMappingsDump(project)
|
||||
|
||||
internal fun createKotlinCachesDump(
|
||||
project: ProjectDescriptor,
|
||||
kotlinContext: KotlinCompileContext,
|
||||
lookupsDuringTest: Set<LookupSymbol>
|
||||
) = createKotlinIncrementalCacheDump(project, kotlinContext) + "\n\n\n" +
|
||||
createLookupCacheDump(kotlinContext, lookupsDuringTest)
|
||||
|
||||
private fun createKotlinIncrementalCacheDump(
|
||||
project: ProjectDescriptor,
|
||||
kotlinContext: KotlinCompileContext
|
||||
): String {
|
||||
return buildString {
|
||||
for (target in project.allModuleTargets.sortedBy { it.presentableName }) {
|
||||
val kotlinCache = project.dataManager.getKotlinCache(kotlinContext.targetsBinding[target])
|
||||
if (kotlinCache != null) {
|
||||
append("<target $target>\n")
|
||||
append(kotlinCache.dump())
|
||||
append("</target $target>\n\n\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createLookupCacheDump(kotlinContext: KotlinCompileContext, lookupsDuringTest: Set<LookupSymbol>): String {
|
||||
val sb = StringBuilder()
|
||||
val p = Printer(sb)
|
||||
p.println("Begin of Lookup Maps")
|
||||
p.println()
|
||||
|
||||
kotlinContext.lookupStorageManager.withLookupStorage { lookupStorage ->
|
||||
lookupStorage.forceGC()
|
||||
p.print(lookupStorage.dump(lookupsDuringTest))
|
||||
}
|
||||
|
||||
p.println()
|
||||
p.println("End of Lookup Maps")
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
private fun createCommonMappingsDump(project: ProjectDescriptor): String {
|
||||
val resultBuf = StringBuilder()
|
||||
val result = Printer(resultBuf)
|
||||
|
||||
result.println("Begin of SourceToOutputMap")
|
||||
result.pushIndent()
|
||||
|
||||
for (target in project.allModuleTargets) {
|
||||
result.println(target)
|
||||
result.pushIndent()
|
||||
|
||||
val mapping = project.dataManager.getSourceToOutputMap(target)
|
||||
mapping.sources.sorted().forEach {
|
||||
val outputs = mapping.getOutputs(it)!!.sorted()
|
||||
if (outputs.isNotEmpty()) {
|
||||
result.println("source $it -> $outputs")
|
||||
}
|
||||
}
|
||||
|
||||
result.popIndent()
|
||||
}
|
||||
|
||||
result.popIndent()
|
||||
result.println("End of SourceToOutputMap")
|
||||
|
||||
return resultBuf.toString()
|
||||
}
|
||||
|
||||
private fun createJavaMappingsDump(project: ProjectDescriptor): String {
|
||||
val byteArrayOutputStream = ByteArrayOutputStream()
|
||||
PrintStream(byteArrayOutputStream).use {
|
||||
project.dataManager.mappings.toStream(it)
|
||||
}
|
||||
return byteArrayOutputStream.toString()
|
||||
}
|
||||
|
||||
internal val ProjectDescriptor.allModuleTargets: Collection<ModuleBuildTarget>
|
||||
get() = buildTargetIndex.allTargets.filterIsInstance<ModuleBuildTarget>()
|
||||
|
||||
private val EXPORTED_SUFFIX = "[exported]"
|
||||
+681
@@ -0,0 +1,681 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.build
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.util.io.FileUtilRt
|
||||
import com.intellij.testFramework.TestLoggerFactory
|
||||
import com.intellij.testFramework.UsefulTestCase
|
||||
import junit.framework.TestCase
|
||||
import org.apache.log4j.ConsoleAppender
|
||||
import org.apache.log4j.Level
|
||||
import org.apache.log4j.Logger
|
||||
import org.apache.log4j.PatternLayout
|
||||
import org.jetbrains.jps.ModuleChunk
|
||||
import org.jetbrains.jps.api.CanceledStatus
|
||||
import org.jetbrains.jps.builders.BuildResult
|
||||
import org.jetbrains.jps.builders.CompileScopeTestBuilder
|
||||
import org.jetbrains.jps.builders.impl.BuildDataPathsImpl
|
||||
import org.jetbrains.jps.builders.impl.logging.ProjectBuilderLoggerBase
|
||||
import org.jetbrains.jps.builders.java.dependencyView.Callbacks
|
||||
import org.jetbrains.jps.builders.logging.BuildLoggingManager
|
||||
import org.jetbrains.jps.cmdline.ProjectDescriptor
|
||||
import org.jetbrains.jps.incremental.*
|
||||
import org.jetbrains.jps.incremental.messages.BuildMessage
|
||||
import org.jetbrains.jps.model.JpsDummyElement
|
||||
import org.jetbrains.jps.model.JpsModuleRootModificationUtil
|
||||
import org.jetbrains.jps.model.java.JpsJavaExtensionService
|
||||
import org.jetbrains.jps.model.library.sdk.JpsSdk
|
||||
import org.jetbrains.jps.util.JpsPathUtil
|
||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2MetadataCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.arguments.parseCommandLineArguments
|
||||
import org.jetbrains.kotlin.incremental.LookupSymbol
|
||||
import org.jetbrains.kotlin.incremental.testingUtils.*
|
||||
import org.jetbrains.kotlin.jps.build.dependeciestxt.ModulesTxt
|
||||
import org.jetbrains.kotlin.jps.build.dependeciestxt.ModulesTxtBuilder
|
||||
import org.jetbrains.kotlin.jps.build.fixtures.EnableICFixture
|
||||
import org.jetbrains.kotlin.jps.incremental.*
|
||||
import org.jetbrains.kotlin.jps.model.JpsKotlinFacetModuleExtension
|
||||
import org.jetbrains.kotlin.jps.model.kotlinCommonCompilerArguments
|
||||
import org.jetbrains.kotlin.jps.model.kotlinFacet
|
||||
import org.jetbrains.kotlin.jps.targets.KotlinModuleBuildTarget
|
||||
import org.jetbrains.kotlin.platform.idePlatformKind
|
||||
import org.jetbrains.kotlin.platform.impl.isJavaScript
|
||||
import org.jetbrains.kotlin.platform.impl.isJvm
|
||||
import org.jetbrains.kotlin.platform.orDefault
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
import java.io.ByteArrayInputStream
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.File
|
||||
import java.io.PrintStream
|
||||
import java.util.*
|
||||
import kotlin.reflect.jvm.javaField
|
||||
|
||||
abstract class AbstractIncrementalJpsTest(
|
||||
private val allowNoFilesWithSuffixInTestData: Boolean = false,
|
||||
private val checkDumpsCaseInsensitively: Boolean = false
|
||||
) : BaseKotlinJpsBuildTestCase() {
|
||||
companion object {
|
||||
private val COMPILATION_FAILED = "COMPILATION FAILED"
|
||||
|
||||
// change to "/tmp" or anything when default is too long (for easier debugging)
|
||||
private val TEMP_DIRECTORY_TO_USE = File(FileUtilRt.getTempDirectory())
|
||||
|
||||
private val DEBUG_LOGGING_ENABLED = System.getProperty("debug.logging.enabled") == "true"
|
||||
|
||||
private const val ARGUMENTS_FILE_NAME = "args.txt"
|
||||
|
||||
private fun parseAdditionalArgs(testDir: File): List<String> {
|
||||
return File(testDir, ARGUMENTS_FILE_NAME)
|
||||
.takeIf { it.exists() }
|
||||
?.readText()
|
||||
?.split(" ", "\n")
|
||||
?.filter { it.isNotBlank() }
|
||||
?: emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
protected lateinit var testDataDir: File
|
||||
protected lateinit var workDir: File
|
||||
protected lateinit var projectDescriptor: ProjectDescriptor
|
||||
protected lateinit var additionalCommandLineArguments: List<String>
|
||||
// is used to compare lookup dumps in a human readable way (lookup symbols are hashed in an actual lookup storage)
|
||||
protected lateinit var lookupsDuringTest: MutableSet<LookupSymbol>
|
||||
private var isJvmICEnabledBackup: Boolean = false
|
||||
private var isJsICEnabledBackup: Boolean = false
|
||||
|
||||
protected var mapWorkingToOriginalFile: MutableMap<File, File> = hashMapOf()
|
||||
|
||||
lateinit var kotlinCompileContext: KotlinCompileContext
|
||||
|
||||
protected open val buildLogFinder: BuildLogFinder
|
||||
get() = BuildLogFinder()
|
||||
|
||||
private fun enableDebugLogging() {
|
||||
com.intellij.openapi.diagnostic.Logger.setFactory(TestLoggerFactory::class.java)
|
||||
TestLoggerFactory.dumpLogToStdout("")
|
||||
TestLoggerFactory.enableDebugLogging(testRootDisposable, "#org")
|
||||
|
||||
val console = ConsoleAppender()
|
||||
console.layout = PatternLayout("%d [%p|%c|%C{1}] %m%n")
|
||||
console.threshold = Level.ALL
|
||||
console.activateOptions()
|
||||
Logger.getRootLogger().addAppender(console)
|
||||
}
|
||||
|
||||
private var systemPropertiesBackup = run {
|
||||
val props = System.getProperties()
|
||||
val output = ByteArrayOutputStream()
|
||||
props.store(output, "System properties backup")
|
||||
output.toByteArray()
|
||||
}
|
||||
|
||||
private fun restoreSystemProperties() {
|
||||
val input = ByteArrayInputStream(systemPropertiesBackup)
|
||||
val props = Properties()
|
||||
props.load(input)
|
||||
System.setProperties(props)
|
||||
}
|
||||
|
||||
private val enableICFixture = EnableICFixture()
|
||||
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
|
||||
enableICFixture.setUp()
|
||||
lookupsDuringTest = hashSetOf()
|
||||
|
||||
if (DEBUG_LOGGING_ENABLED) {
|
||||
enableDebugLogging()
|
||||
}
|
||||
}
|
||||
|
||||
override fun tearDown() {
|
||||
restoreSystemProperties()
|
||||
|
||||
(AbstractIncrementalJpsTest::myProject).javaField!![this] = null
|
||||
(AbstractIncrementalJpsTest::projectDescriptor).javaField!![this] = null
|
||||
(AbstractIncrementalJpsTest::systemPropertiesBackup).javaField!![this] = null
|
||||
|
||||
lookupsDuringTest.clear()
|
||||
enableICFixture.tearDown()
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
// JPS forces rebuild of all files when JVM constant has been changed and Callbacks.ConstantAffectionResolver
|
||||
// is not provided, so ConstantAffectionResolver is mocked with empty implementation
|
||||
// Usages in Kotlin files are expected to be found by KotlinLookupConstantSearch
|
||||
protected open val mockConstantSearch: Callbacks.ConstantAffectionResolver?
|
||||
get() = MockJavaConstantSearch(workDir)
|
||||
|
||||
private fun build(
|
||||
name: String?,
|
||||
scope: CompileScopeTestBuilder = CompileScopeTestBuilder.make().allModules()
|
||||
): MakeResult {
|
||||
val workDirPath = FileUtil.toSystemIndependentName(workDir.absolutePath)
|
||||
|
||||
val logger = MyLogger(workDirPath)
|
||||
projectDescriptor = createProjectDescriptor(BuildLoggingManager(logger))
|
||||
|
||||
val lookupTracker = TestLookupTracker()
|
||||
val testingContext = TestingContext(lookupTracker, logger)
|
||||
projectDescriptor.project.setTestingContext(testingContext)
|
||||
|
||||
try {
|
||||
val builder = IncProjectBuilder(
|
||||
projectDescriptor,
|
||||
BuilderRegistry.getInstance(),
|
||||
myBuildParams,
|
||||
CanceledStatus.NULL,
|
||||
mockConstantSearch,
|
||||
true
|
||||
)
|
||||
val buildResult = BuildResult()
|
||||
builder.addMessageHandler(buildResult)
|
||||
val finalScope = scope.build()
|
||||
projectDescriptor.project.kotlinCommonCompilerArguments = projectDescriptor.project.kotlinCommonCompilerArguments.apply {
|
||||
updateCommandLineArguments(this)
|
||||
}
|
||||
|
||||
builder.build(finalScope, false)
|
||||
|
||||
// testingContext.kotlinCompileContext is initialized in KotlinBuilder.initializeKotlinContext
|
||||
kotlinCompileContext = testingContext.kotlinCompileContext!!
|
||||
|
||||
lookupTracker.lookups.mapTo(lookupsDuringTest) { LookupSymbol(it.name, it.scopeFqName) }
|
||||
|
||||
if (!buildResult.isSuccessful) {
|
||||
val errorMessages =
|
||||
buildResult
|
||||
.getMessages(BuildMessage.Kind.ERROR)
|
||||
.map { it.messageText }
|
||||
.map { it.replace("^.+:\\d+:\\s+".toRegex(), "").trim() }
|
||||
.joinToString("\n")
|
||||
return MakeResult(
|
||||
log = logger.log + "$COMPILATION_FAILED\n" + errorMessages + "\n",
|
||||
makeFailed = true,
|
||||
mappingsDump = null,
|
||||
name = name
|
||||
)
|
||||
} else {
|
||||
return MakeResult(
|
||||
log = logger.log,
|
||||
makeFailed = false,
|
||||
mappingsDump = createMappingsDump(projectDescriptor, kotlinCompileContext, lookupsDuringTest),
|
||||
name = name
|
||||
)
|
||||
}
|
||||
} finally {
|
||||
projectDescriptor.dataManager.flush(false)
|
||||
projectDescriptor.release()
|
||||
}
|
||||
}
|
||||
|
||||
private fun initialMake(): MakeResult {
|
||||
val makeResult = build(null)
|
||||
|
||||
val initBuildLogFile = File(testDataDir, "init-build.log")
|
||||
if (initBuildLogFile.exists()) {
|
||||
UsefulTestCase.assertSameLinesWithFile(initBuildLogFile.absolutePath, makeResult.log)
|
||||
} else {
|
||||
assertFalse("Initial make failed:\n$makeResult", makeResult.makeFailed)
|
||||
}
|
||||
|
||||
return makeResult
|
||||
}
|
||||
|
||||
private fun make(name: String?): MakeResult {
|
||||
return build(name)
|
||||
}
|
||||
|
||||
private fun rebuild(): MakeResult {
|
||||
return build(null, CompileScopeTestBuilder.rebuild().allModules())
|
||||
}
|
||||
|
||||
private fun updateCommandLineArguments(arguments: CommonCompilerArguments) {
|
||||
parseCommandLineArguments(additionalCommandLineArguments, arguments)
|
||||
}
|
||||
|
||||
private fun rebuildAndCheckOutput(makeOverallResult: MakeResult) {
|
||||
val outDir = File(getAbsolutePath("out"))
|
||||
val outAfterMake = File(getAbsolutePath("out-after-make"))
|
||||
|
||||
if (outDir.exists()) {
|
||||
FileUtil.copyDir(outDir, outAfterMake)
|
||||
}
|
||||
|
||||
val rebuildResult = rebuild()
|
||||
assertEquals(
|
||||
"Rebuild failed: ${rebuildResult.makeFailed}, last make failed: ${makeOverallResult.makeFailed}. Rebuild result: $rebuildResult",
|
||||
rebuildResult.makeFailed, makeOverallResult.makeFailed
|
||||
)
|
||||
|
||||
if (!outAfterMake.exists()) {
|
||||
assertFalse(outDir.exists())
|
||||
} else {
|
||||
assertEqualDirectories(outDir, outAfterMake, makeOverallResult.makeFailed)
|
||||
}
|
||||
|
||||
if (!makeOverallResult.makeFailed) {
|
||||
if (checkDumpsCaseInsensitively && rebuildResult.mappingsDump?.toLowerCase() == makeOverallResult.mappingsDump?.toLowerCase()) {
|
||||
// do nothing
|
||||
} else {
|
||||
TestCase.assertEquals(rebuildResult.mappingsDump, makeOverallResult.mappingsDump)
|
||||
}
|
||||
}
|
||||
|
||||
FileUtil.delete(outAfterMake)
|
||||
}
|
||||
|
||||
private fun clearCachesRebuildAndCheckOutput(makeOverallResult: MakeResult) {
|
||||
FileUtil.delete(BuildDataPathsImpl(myDataStorageRoot).dataStorageRoot!!)
|
||||
|
||||
rebuildAndCheckOutput(makeOverallResult)
|
||||
}
|
||||
|
||||
open val modulesTxtFile
|
||||
get() = File(testDataDir, "dependencies.txt")
|
||||
|
||||
private fun readModulesTxt(): ModulesTxt? {
|
||||
var actualModulesTxtFile = modulesTxtFile
|
||||
|
||||
if (!actualModulesTxtFile.exists()) {
|
||||
// also try `"_${fileName}.txt"`. Useful for sorting files in IDE.
|
||||
actualModulesTxtFile = modulesTxtFile.parentFile.resolve("_" + modulesTxtFile.name)
|
||||
if (!actualModulesTxtFile.exists()) return null
|
||||
}
|
||||
|
||||
return ModulesTxtBuilder().readFile(actualModulesTxtFile)
|
||||
}
|
||||
|
||||
protected open fun createBuildLog(incrementalMakeResults: List<AbstractIncrementalJpsTest.MakeResult>): String =
|
||||
buildString {
|
||||
incrementalMakeResults.forEachIndexed { i, makeResult ->
|
||||
if (i > 0) append("\n")
|
||||
if (makeResult.name != null) {
|
||||
append("================ Step #${i + 1} ${makeResult.name} =================\n\n")
|
||||
} else {
|
||||
append("================ Step #${i + 1} =================\n\n")
|
||||
}
|
||||
append(makeResult.log)
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun doTest(testDataPath: String) {
|
||||
testDataDir = File(testDataPath)
|
||||
workDir = FileUtilRt.createTempDirectory(TEMP_DIRECTORY_TO_USE, "aijt-jps-build", null)
|
||||
additionalCommandLineArguments = parseAdditionalArgs(File(testDataPath))
|
||||
val buildLogFile = buildLogFinder.findBuildLog(testDataDir)
|
||||
Disposer.register(testRootDisposable, Disposable { FileUtilRt.delete(workDir) })
|
||||
|
||||
val modulesTxt = configureModules()
|
||||
if (modulesTxt?.muted == true) return
|
||||
|
||||
initialMake()
|
||||
|
||||
val otherMakeResults = performModificationsAndMake(
|
||||
modulesTxt?.modules?.map { it.name },
|
||||
hasBuildLog = buildLogFile != null
|
||||
)
|
||||
|
||||
buildLogFile?.let {
|
||||
val logs = createBuildLog(otherMakeResults)
|
||||
UsefulTestCase.assertSameLinesWithFile(buildLogFile.absolutePath, logs)
|
||||
|
||||
val lastMakeResult = otherMakeResults.last()
|
||||
clearCachesRebuildAndCheckOutput(lastMakeResult)
|
||||
}
|
||||
}
|
||||
|
||||
protected data class MakeResult(
|
||||
val log: String,
|
||||
val makeFailed: Boolean,
|
||||
val mappingsDump: String?,
|
||||
val name: String? = null
|
||||
)
|
||||
|
||||
open val testDataSrc: File
|
||||
get() = testDataDir
|
||||
|
||||
private fun performModificationsAndMake(
|
||||
moduleNames: Collection<String>?,
|
||||
hasBuildLog: Boolean
|
||||
): List<MakeResult> {
|
||||
val results = arrayListOf<MakeResult>()
|
||||
val modifications = getModificationsToPerform(
|
||||
testDataSrc,
|
||||
moduleNames,
|
||||
allowNoFilesWithSuffixInTestData = allowNoFilesWithSuffixInTestData || !hasBuildLog,
|
||||
touchPolicy = TouchPolicy.TIMESTAMP
|
||||
)
|
||||
|
||||
if (!hasBuildLog) {
|
||||
check(modifications.size == 1 && modifications.single().isEmpty()) {
|
||||
"Bad test data: build steps are provided, but there is no `build.log` file"
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
val stepsTxt = File(testDataSrc, "_steps.txt")
|
||||
val modificationNames = if (stepsTxt.exists()) stepsTxt.readLines() else null
|
||||
|
||||
modifications.forEachIndexed { index, step ->
|
||||
step.forEach { it.perform(workDir, mapWorkingToOriginalFile) }
|
||||
performAdditionalModifications(step)
|
||||
if (moduleNames == null) {
|
||||
preProcessSources(File(workDir, "src"))
|
||||
} else {
|
||||
moduleNames.forEach { preProcessSources(File(workDir, "$it/src")) }
|
||||
}
|
||||
|
||||
val name = modificationNames?.getOrNull(index)
|
||||
val makeResult = make(name)
|
||||
results.add(makeResult)
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
protected open fun performAdditionalModifications(modifications: List<Modification>) {
|
||||
}
|
||||
|
||||
protected open fun generateModuleSources(modulesTxt: ModulesTxt) = Unit
|
||||
|
||||
// null means one module
|
||||
private fun configureModules(): ModulesTxt? {
|
||||
JpsJavaExtensionService.getInstance().getOrCreateProjectExtension(myProject).outputUrl =
|
||||
JpsPathUtil.pathToUrl(getAbsolutePath("out"))
|
||||
|
||||
val jdk = addJdk("my jdk")
|
||||
val modulesTxt = readModulesTxt()
|
||||
mapWorkingToOriginalFile = hashMapOf()
|
||||
|
||||
if (modulesTxt == null) configureSingleModuleProject(jdk)
|
||||
else configureMultiModuleProject(modulesTxt, jdk)
|
||||
|
||||
overrideModuleSettings()
|
||||
configureRequiredLibraries()
|
||||
|
||||
return modulesTxt
|
||||
}
|
||||
|
||||
open fun overrideModuleSettings() {
|
||||
}
|
||||
|
||||
private fun configureSingleModuleProject(jdk: JpsSdk<JpsDummyElement>?) {
|
||||
addModule("module", arrayOf(getAbsolutePath("src")), null, null, jdk)
|
||||
|
||||
val sourceDestinationDir = File(workDir, "src")
|
||||
val sourcesMapping = copyTestSources(testDataDir, File(workDir, "src"), "")
|
||||
mapWorkingToOriginalFile.putAll(sourcesMapping)
|
||||
|
||||
preProcessSources(sourceDestinationDir)
|
||||
}
|
||||
|
||||
protected open val ModulesTxt.Module.sourceFilePrefix: String
|
||||
get() = "${name}_"
|
||||
|
||||
private fun configureMultiModuleProject(
|
||||
modulesTxt: ModulesTxt,
|
||||
jdk: JpsSdk<JpsDummyElement>?
|
||||
) {
|
||||
modulesTxt.modules.forEach { module ->
|
||||
module.jpsModule = addModule(
|
||||
module.name,
|
||||
arrayOf(getAbsolutePath("${module.name}/src")),
|
||||
null,
|
||||
null,
|
||||
jdk
|
||||
)!!
|
||||
|
||||
val kotlinFacetSettings = module.kotlinFacetSettings
|
||||
if (kotlinFacetSettings != null) {
|
||||
val compilerArguments = kotlinFacetSettings.compilerArguments
|
||||
if (compilerArguments is K2MetadataCompilerArguments) {
|
||||
val out = getAbsolutePath("${module.name}/out")
|
||||
File(out).mkdirs()
|
||||
compilerArguments.destination = out
|
||||
} else if (compilerArguments is K2JVMCompilerArguments) {
|
||||
compilerArguments.disableDefaultScriptingPlugin = true
|
||||
}
|
||||
|
||||
module.jpsModule.container.setChild(
|
||||
JpsKotlinFacetModuleExtension.KIND,
|
||||
JpsKotlinFacetModuleExtension(kotlinFacetSettings)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
modulesTxt.dependencies.forEach {
|
||||
JpsModuleRootModificationUtil.addDependency(
|
||||
it.from.jpsModule, it.to.jpsModule,
|
||||
it.scope, it.exported
|
||||
)
|
||||
}
|
||||
|
||||
// configure module contents
|
||||
generateModuleSources(modulesTxt)
|
||||
modulesTxt.modules.forEach { module ->
|
||||
val sourceDirName = "${module.name}/src"
|
||||
val sourceDestinationDir = File(workDir, sourceDirName)
|
||||
val sourcesMapping = copyTestSources(testDataSrc, sourceDestinationDir, module.sourceFilePrefix)
|
||||
mapWorkingToOriginalFile.putAll(sourcesMapping)
|
||||
|
||||
preProcessSources(sourceDestinationDir)
|
||||
}
|
||||
}
|
||||
|
||||
private fun configureRequiredLibraries() {
|
||||
myProject.modules.forEach { module ->
|
||||
val platformKind = module.kotlinFacet?.settings?.targetPlatform?.idePlatformKind.orDefault()
|
||||
|
||||
when {
|
||||
platformKind.isJvm -> {
|
||||
JpsModuleRootModificationUtil.addDependency(module, requireLibrary(KotlinJpsLibrary.JvmStdLib))
|
||||
JpsModuleRootModificationUtil.addDependency(module, requireLibrary(KotlinJpsLibrary.JvmTest))
|
||||
}
|
||||
platformKind.isJavaScript -> {
|
||||
JpsModuleRootModificationUtil.addDependency(module, requireLibrary(KotlinJpsLibrary.JsStdLib))
|
||||
JpsModuleRootModificationUtil.addDependency(module, requireLibrary(KotlinJpsLibrary.JsTest))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun preProcessSources(srcDir: File) {
|
||||
}
|
||||
|
||||
override fun doGetProjectDir(): File? = workDir
|
||||
|
||||
internal class MyLogger(val rootPath: String) : ProjectBuilderLoggerBase(), TestingBuildLogger {
|
||||
private val markedDirtyBeforeRound = ArrayList<File>()
|
||||
private val markedDirtyAfterRound = ArrayList<File>()
|
||||
private val customMessages = mutableListOf<String>()
|
||||
|
||||
override fun invalidOrUnusedCache(
|
||||
chunk: KotlinChunk?,
|
||||
target: KotlinModuleBuildTarget<*>?,
|
||||
attributesDiff: CacheAttributesDiff<*>
|
||||
) {
|
||||
val cacheManager = attributesDiff.manager
|
||||
val cacheTitle = when (cacheManager) {
|
||||
is CacheVersionManager -> "Local cache for ${chunk ?: target}"
|
||||
is CompositeLookupsCacheAttributesManager -> "Lookups cache"
|
||||
else -> error("Unknown cache manager $cacheManager")
|
||||
}
|
||||
|
||||
logLine("$cacheTitle are ${attributesDiff.status}")
|
||||
}
|
||||
|
||||
override fun markedAsDirtyBeforeRound(files: Iterable<File>) {
|
||||
markedDirtyBeforeRound.addAll(files)
|
||||
}
|
||||
|
||||
override fun markedAsDirtyAfterRound(files: Iterable<File>) {
|
||||
markedDirtyAfterRound.addAll(files)
|
||||
}
|
||||
|
||||
override fun chunkBuildStarted(context: CompileContext, chunk: ModuleChunk) {
|
||||
logDirtyFiles(markedDirtyBeforeRound) // files can be marked as dirty during build start (KotlinCompileContext initialization)
|
||||
|
||||
if (!chunk.isDummy(context) && context.projectDescriptor.project.modules.size > 1) {
|
||||
logLine("Building ${chunk.modules.sortedBy { it.name }.joinToString { it.name }}")
|
||||
}
|
||||
}
|
||||
|
||||
override fun afterChunkBuildStarted(context: CompileContext, chunk: ModuleChunk) {
|
||||
logDirtyFiles(markedDirtyBeforeRound)
|
||||
}
|
||||
|
||||
override fun addCustomMessage(message: String) {
|
||||
customMessages.add(message)
|
||||
}
|
||||
|
||||
override fun buildFinished(exitCode: ModuleLevelBuilder.ExitCode) {
|
||||
customMessages.forEach {
|
||||
logLine(it)
|
||||
}
|
||||
customMessages.clear()
|
||||
logDirtyFiles(markedDirtyAfterRound)
|
||||
logLine("Exit code: $exitCode")
|
||||
logLine("------------------------------------------")
|
||||
}
|
||||
|
||||
private fun logDirtyFiles(files: MutableList<File>) {
|
||||
if (files.isEmpty()) return
|
||||
|
||||
logLine("Marked as dirty by Kotlin:")
|
||||
files.apply {
|
||||
map { FileUtil.toSystemIndependentName(it.path) }
|
||||
.sorted()
|
||||
.forEach { logLine(it) }
|
||||
|
||||
clear()
|
||||
}
|
||||
}
|
||||
|
||||
private val logBuf = StringBuilder()
|
||||
val log: String
|
||||
get() = logBuf.toString()
|
||||
|
||||
val compiledFiles = hashSetOf<File>()
|
||||
|
||||
override fun isEnabled(): Boolean = true
|
||||
|
||||
override fun logCompiledFiles(files: MutableCollection<File>?, builderName: String?, description: String?) {
|
||||
super.logCompiledFiles(files, builderName, description)
|
||||
|
||||
if (builderName == KotlinBuilder.KOTLIN_BUILDER_NAME) {
|
||||
compiledFiles.addAll(files!!)
|
||||
}
|
||||
}
|
||||
|
||||
override fun logLine(message: String?) {
|
||||
logBuf.append(message!!.replace("^$rootPath/".toRegex(), " ")).append('\n')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createMappingsDump(
|
||||
project: ProjectDescriptor,
|
||||
kotlinContext: KotlinCompileContext,
|
||||
lookupsDuringTest: Set<LookupSymbol>
|
||||
) = createKotlinCachesDump(project, kotlinContext, lookupsDuringTest) + "\n\n\n" +
|
||||
createCommonMappingsDump(project) + "\n\n\n" +
|
||||
createJavaMappingsDump(project)
|
||||
|
||||
internal fun createKotlinCachesDump(
|
||||
project: ProjectDescriptor,
|
||||
kotlinContext: KotlinCompileContext,
|
||||
lookupsDuringTest: Set<LookupSymbol>
|
||||
) = createKotlinIncrementalCacheDump(project, kotlinContext) + "\n\n\n" +
|
||||
createLookupCacheDump(kotlinContext, lookupsDuringTest)
|
||||
|
||||
private fun createKotlinIncrementalCacheDump(
|
||||
project: ProjectDescriptor,
|
||||
kotlinContext: KotlinCompileContext
|
||||
): String {
|
||||
return buildString {
|
||||
for (target in project.allModuleTargets.sortedBy { it.presentableName }) {
|
||||
val kotlinCache = project.dataManager.getKotlinCache(kotlinContext.targetsBinding[target])
|
||||
if (kotlinCache != null) {
|
||||
append("<target $target>\n")
|
||||
append(kotlinCache.dump())
|
||||
append("</target $target>\n\n\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createLookupCacheDump(kotlinContext: KotlinCompileContext, lookupsDuringTest: Set<LookupSymbol>): String {
|
||||
val sb = StringBuilder()
|
||||
val p = Printer(sb)
|
||||
p.println("Begin of Lookup Maps")
|
||||
p.println()
|
||||
|
||||
kotlinContext.lookupStorageManager.withLookupStorage { lookupStorage ->
|
||||
lookupStorage.forceGC()
|
||||
p.print(lookupStorage.dump(lookupsDuringTest))
|
||||
}
|
||||
|
||||
p.println()
|
||||
p.println("End of Lookup Maps")
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
private fun createCommonMappingsDump(project: ProjectDescriptor): String {
|
||||
val resultBuf = StringBuilder()
|
||||
val result = Printer(resultBuf)
|
||||
|
||||
result.println("Begin of SourceToOutputMap")
|
||||
result.pushIndent()
|
||||
|
||||
for (target in project.allModuleTargets) {
|
||||
result.println(target)
|
||||
result.pushIndent()
|
||||
|
||||
val mapping = project.dataManager.getSourceToOutputMap(target)
|
||||
mapping.sources.sorted().forEach {
|
||||
val outputs = mapping.getOutputs(it)!!.sorted()
|
||||
if (outputs.isNotEmpty()) {
|
||||
result.println("source $it -> $outputs")
|
||||
}
|
||||
}
|
||||
|
||||
result.popIndent()
|
||||
}
|
||||
|
||||
result.popIndent()
|
||||
result.println("End of SourceToOutputMap")
|
||||
|
||||
return resultBuf.toString()
|
||||
}
|
||||
|
||||
private fun createJavaMappingsDump(project: ProjectDescriptor): String {
|
||||
val byteArrayOutputStream = ByteArrayOutputStream()
|
||||
PrintStream(byteArrayOutputStream).use {
|
||||
project.dataManager.mappings.toStream(it)
|
||||
}
|
||||
return byteArrayOutputStream.toString()
|
||||
}
|
||||
|
||||
internal val ProjectDescriptor.allModuleTargets: Collection<ModuleBuildTarget>
|
||||
get() = buildTargetIndex.allTargets.filterIsInstance<ModuleBuildTarget>()
|
||||
|
||||
private val EXPORTED_SUFFIX = "[exported]"
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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.jps.build
|
||||
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
|
||||
import org.jetbrains.kotlin.config.KotlinFacetSettings
|
||||
import org.jetbrains.kotlin.incremental.testingUtils.BuildLogFinder
|
||||
import org.jetbrains.kotlin.incremental.testingUtils.BuildLogFinder.Companion.JS_JPS_LOG
|
||||
import org.jetbrains.kotlin.jps.model.JpsKotlinFacetModuleExtension
|
||||
import org.jetbrains.kotlin.platform.js.JsPlatforms
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractIncrementalJsJpsTest : AbstractIncrementalJpsTest() {
|
||||
override val buildLogFinder: BuildLogFinder
|
||||
get() = super.buildLogFinder.copy(isJsEnabled = true)
|
||||
|
||||
override fun doTest(testDataPath: String) {
|
||||
val buildLogFile = File(testDataPath).resolve(JS_JPS_LOG)
|
||||
if (!buildLogFile.exists()) {
|
||||
buildLogFile.writeText("JPS JS LOG PLACEHOLDER")
|
||||
}
|
||||
super.doTest(testDataPath)
|
||||
}
|
||||
|
||||
override fun overrideModuleSettings() {
|
||||
myProject.modules.forEach {
|
||||
val facet = KotlinFacetSettings()
|
||||
facet.compilerArguments = K2JSCompilerArguments()
|
||||
facet.targetPlatform = JsPlatforms.defaultJsPlatform
|
||||
|
||||
it.container.setChild(
|
||||
JpsKotlinFacetModuleExtension.KIND,
|
||||
JpsKotlinFacetModuleExtension(facet)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* 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 org.jetbrains.kotlin.jps.build
|
||||
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
||||
import org.jetbrains.kotlin.jps.model.k2JvmCompilerArguments
|
||||
|
||||
abstract class AbstractIncrementalJvmJpsTest(
|
||||
allowNoFilesWithSuffixInTestData: Boolean = false
|
||||
) : AbstractIncrementalJpsTest(allowNoFilesWithSuffixInTestData = allowNoFilesWithSuffixInTestData) {
|
||||
override fun overrideModuleSettings() {
|
||||
myProject.k2JvmCompilerArguments = K2JVMCompilerArguments().also {
|
||||
it.disableDefaultScriptingPlugin = true
|
||||
}
|
||||
}
|
||||
}
|
||||
+151
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.build
|
||||
|
||||
import com.intellij.testFramework.UsefulTestCase
|
||||
import org.jetbrains.jps.builders.BuildTarget
|
||||
import org.jetbrains.jps.builders.storage.BuildDataPaths
|
||||
import org.jetbrains.kotlin.config.IncrementalCompilation
|
||||
import org.jetbrains.kotlin.incremental.KOTLIN_CACHE_DIRECTORY_NAME
|
||||
import org.jetbrains.kotlin.incremental.storage.BasicMapsOwner
|
||||
import org.jetbrains.kotlin.incremental.testingUtils.Modification
|
||||
import org.jetbrains.kotlin.incremental.testingUtils.ModifyContent
|
||||
import org.jetbrains.kotlin.jps.build.fixtures.EnableICFixture
|
||||
import org.jetbrains.kotlin.jps.incremental.KotlinDataContainerTarget
|
||||
import org.jetbrains.kotlin.jps.targets.KotlinModuleBuildTarget
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractIncrementalLazyCachesTest : AbstractIncrementalJpsTest() {
|
||||
private val expectedCachesFileName: String
|
||||
get() = "expected-kotlin-caches.txt"
|
||||
|
||||
private val enableICFixture = EnableICFixture()
|
||||
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
enableICFixture.setUp()
|
||||
}
|
||||
|
||||
override fun tearDown() {
|
||||
enableICFixture.tearDown()
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
override fun doTest(testDataPath: String) {
|
||||
super.doTest(testDataPath)
|
||||
|
||||
val actual = dumpKotlinCachesFileNames()
|
||||
val expectedFile = File(testDataPath, expectedCachesFileName)
|
||||
UsefulTestCase.assertSameLinesWithFile(expectedFile.canonicalPath, actual)
|
||||
}
|
||||
|
||||
override fun performAdditionalModifications(modifications: List<Modification>) {
|
||||
super.performAdditionalModifications(modifications)
|
||||
|
||||
for (modification in modifications) {
|
||||
if (modification !is ModifyContent) continue
|
||||
|
||||
val name = File(modification.path).name
|
||||
|
||||
when {
|
||||
name.endsWith("incremental-compilation") -> {
|
||||
IncrementalCompilation.setIsEnabledForJvm(modification.dataFile.readAsBool())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun File.readAsBool(): Boolean {
|
||||
val content = this.readText()
|
||||
|
||||
return when (content.trim()) {
|
||||
"on" -> true
|
||||
"off" -> false
|
||||
else -> throw IllegalStateException("$this content is expected to be 'on' or 'off'")
|
||||
}
|
||||
}
|
||||
|
||||
private fun dumpKotlinCachesFileNames(): String {
|
||||
val sb = StringBuilder()
|
||||
val printer = Printer(sb)
|
||||
val chunks = kotlinCompileContext.targetsIndex.chunks
|
||||
val dataManager = projectDescriptor.dataManager
|
||||
val paths = dataManager.dataPaths
|
||||
|
||||
dumpCachesForTarget(
|
||||
printer,
|
||||
paths,
|
||||
KotlinDataContainerTarget,
|
||||
kotlinCompileContext.lookupsCacheAttributesManager.versionManagerForTesting.versionFileForTesting
|
||||
)
|
||||
|
||||
data class TargetInChunk(val chunk: KotlinChunk, val target: KotlinModuleBuildTarget<*>)
|
||||
|
||||
val allTargets = chunks.flatMap { chunk ->
|
||||
chunk.targets.map { target ->
|
||||
TargetInChunk(chunk, target)
|
||||
}
|
||||
}.sortedBy { it.target.jpsModuleBuildTarget.presentableName }
|
||||
|
||||
allTargets.forEach { (chunk, target) ->
|
||||
val metaBuildInfo = chunk.buildMetaInfoFile(target.jpsModuleBuildTarget)
|
||||
dumpCachesForTarget(
|
||||
printer, paths, target.jpsModuleBuildTarget,
|
||||
target.localCacheVersionManager.versionFileForTesting,
|
||||
metaBuildInfo,
|
||||
subdirectory = KOTLIN_CACHE_DIRECTORY_NAME
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
private fun dumpCachesForTarget(
|
||||
p: Printer,
|
||||
paths: BuildDataPaths,
|
||||
target: BuildTarget<*>,
|
||||
vararg cacheVersionsFiles: File,
|
||||
subdirectory: String? = null
|
||||
) {
|
||||
p.println(target)
|
||||
p.pushIndent()
|
||||
|
||||
val dataRoot = paths.getTargetDataRoot(target).let { if (subdirectory != null) File(it, subdirectory) else it }
|
||||
cacheVersionsFiles
|
||||
.filter(File::exists)
|
||||
.sortedBy { it.name }
|
||||
.forEach { p.println(it.name) }
|
||||
|
||||
kotlinCacheNames(dataRoot).sorted().forEach { p.println(it) }
|
||||
|
||||
p.popIndent()
|
||||
}
|
||||
|
||||
private fun kotlinCacheNames(dir: File): List<String> {
|
||||
val result = arrayListOf<String>()
|
||||
|
||||
for (file in dir.walk()) {
|
||||
if (file.isFile && file.extension == BasicMapsOwner.CACHE_EXTENSION) {
|
||||
result.add(file.name)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.build
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import org.jetbrains.jps.model.JpsDummyElement
|
||||
import org.jetbrains.jps.model.JpsModuleRootModificationUtil
|
||||
import org.jetbrains.jps.model.JpsProject
|
||||
import org.jetbrains.jps.model.java.JpsJavaDependencyScope
|
||||
import org.jetbrains.jps.model.java.JpsJavaLibraryType
|
||||
import org.jetbrains.jps.model.java.JpsJavaSdkType
|
||||
import org.jetbrains.jps.model.library.JpsLibrary
|
||||
import org.jetbrains.jps.model.library.JpsOrderRootType
|
||||
import org.jetbrains.jps.model.library.sdk.JpsSdk
|
||||
import org.jetbrains.jps.model.module.JpsModule
|
||||
import org.jetbrains.jps.util.JpsPathUtil
|
||||
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
|
||||
import org.jetbrains.kotlin.utils.PathUtil
|
||||
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
|
||||
abstract class AbstractKotlinJpsBuildTestCase : BaseKotlinJpsBuildTestCase() {
|
||||
protected lateinit var workDir: File
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun doGetProjectDir(): File? {
|
||||
return workDir
|
||||
}
|
||||
|
||||
override fun addJdk(name: String, path: String?): JpsSdk<JpsDummyElement> {
|
||||
val homePath = System.getProperty("java.home")
|
||||
val versionString = System.getProperty("java.version")
|
||||
val jdk = myModel.global.addSdk(name, homePath, versionString, JpsJavaSdkType.INSTANCE)
|
||||
jdk.addRoot(JpsPathUtil.pathToUrl(path), JpsOrderRootType.COMPILED)
|
||||
return jdk.properties
|
||||
}
|
||||
|
||||
protected fun addKotlinMockRuntimeDependency(): JpsLibrary {
|
||||
return addDependency(KotlinJpsLibrary.MockRuntime)
|
||||
}
|
||||
|
||||
protected fun addKotlinStdlibDependency(): JpsLibrary {
|
||||
return addDependency(KotlinJpsLibrary.JvmStdLib)
|
||||
}
|
||||
|
||||
protected fun addKotlinJavaScriptStdlibDependency(): JpsLibrary {
|
||||
return addDependency(KotlinJpsLibrary.JsStdLib)
|
||||
}
|
||||
|
||||
private fun addDependency(library: KotlinJpsLibrary): JpsLibrary {
|
||||
return addDependency(myProject, library)
|
||||
}
|
||||
|
||||
protected fun addDependency(libraryName: String, libraryFile: File): JpsLibrary {
|
||||
return addDependency(myProject, libraryName, libraryFile)
|
||||
}
|
||||
|
||||
companion object {
|
||||
val TEST_DATA_PATH = "jps-plugin/testData/"
|
||||
|
||||
@JvmStatic
|
||||
protected fun addKotlinStdlibDependency(modules: Collection<JpsModule>, exported: Boolean = false): JpsLibrary {
|
||||
return addDependency(modules, KotlinJpsLibrary.JvmStdLib, exported)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
private fun addDependency(project: JpsProject, library: KotlinJpsLibrary, exported: Boolean = false): JpsLibrary {
|
||||
return addDependency(JpsJavaDependencyScope.COMPILE, project.modules, exported, library.id, *library.roots)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
private fun addDependency(modules: Collection<JpsModule>, library: KotlinJpsLibrary, exported: Boolean = false): JpsLibrary {
|
||||
return addDependency(JpsJavaDependencyScope.COMPILE, modules, exported, library.id, *library.roots)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
private fun addDependency(project: JpsProject, libraryName: String, libraryFile: File): JpsLibrary {
|
||||
return addDependency(JpsJavaDependencyScope.COMPILE, project.modules, false, libraryName, libraryFile)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
protected fun addDependency(
|
||||
type: JpsJavaDependencyScope,
|
||||
modules: Collection<JpsModule>,
|
||||
exported: Boolean,
|
||||
libraryName: String,
|
||||
vararg file: File
|
||||
): JpsLibrary {
|
||||
val library = modules.iterator().next().project.addLibrary(libraryName, JpsJavaLibraryType.INSTANCE)
|
||||
|
||||
for (fileRoot in file) {
|
||||
library.addRoot(fileRoot, JpsOrderRootType.COMPILED)
|
||||
}
|
||||
|
||||
for (module in modules) {
|
||||
JpsModuleRootModificationUtil.addDependency(module, library, type, exported)
|
||||
}
|
||||
return library
|
||||
}
|
||||
}
|
||||
}
|
||||
+368
@@ -0,0 +1,368 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.build
|
||||
|
||||
import com.intellij.testFramework.UsefulTestCase
|
||||
import com.intellij.util.containers.StringInterner
|
||||
import org.jetbrains.kotlin.TestWithWorkingDir
|
||||
import org.jetbrains.kotlin.build.JvmSourceRoot
|
||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
|
||||
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
|
||||
import org.jetbrains.kotlin.compilerRunner.*
|
||||
import org.jetbrains.kotlin.config.Services
|
||||
import org.jetbrains.kotlin.incremental.components.LookupInfo
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.incremental.components.Position
|
||||
import org.jetbrains.kotlin.incremental.components.ScopeKind
|
||||
import org.jetbrains.kotlin.incremental.isKotlinFile
|
||||
import org.jetbrains.kotlin.incremental.js.*
|
||||
import org.jetbrains.kotlin.incremental.makeModuleFile
|
||||
import org.jetbrains.kotlin.incremental.testingUtils.TouchPolicy
|
||||
import org.jetbrains.kotlin.incremental.testingUtils.copyTestSources
|
||||
import org.jetbrains.kotlin.incremental.testingUtils.getModificationsToPerform
|
||||
import org.jetbrains.kotlin.incremental.utils.TestMessageCollector
|
||||
import org.jetbrains.kotlin.jps.build.fixtures.EnableICFixture
|
||||
import org.jetbrains.kotlin.jps.incremental.createTestingCompilerEnvironment
|
||||
import org.jetbrains.kotlin.jps.incremental.runJSCompiler
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import org.jetbrains.kotlin.utils.JsMetadataVersion
|
||||
import org.jetbrains.kotlin.utils.PathUtil
|
||||
import java.io.*
|
||||
import java.util.*
|
||||
|
||||
abstract class AbstractJvmLookupTrackerTest : AbstractLookupTrackerTest() {
|
||||
|
||||
private val sourceToOutputMapping = hashMapOf<File, MutableSet<File>>()
|
||||
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
sourceToOutputMapping.clear()
|
||||
}
|
||||
|
||||
override fun markDirty(removedAndModifiedSources: Iterable<File>) {
|
||||
for (sourceFile in removedAndModifiedSources) {
|
||||
val outputs = sourceToOutputMapping.remove(sourceFile) ?: continue
|
||||
for (output in outputs) {
|
||||
output.delete()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun processCompilationResults(outputItemsCollector: OutputItemsCollectorImpl, services: Services) {
|
||||
for ((sourceFiles, outputFile) in outputItemsCollector.outputs) {
|
||||
if (outputFile.extension == "kotlin_module") continue
|
||||
|
||||
for (sourceFile in sourceFiles) {
|
||||
val outputsForSource = sourceToOutputMapping.getOrPut(sourceFile) { hashSetOf() }
|
||||
outputsForSource.add(outputFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun runCompiler(filesToCompile: Iterable<File>, env: JpsCompilerEnvironment): Any? {
|
||||
val moduleFile = makeModuleFile(
|
||||
name = "test",
|
||||
isTest = true,
|
||||
outputDir = outDir,
|
||||
sourcesToCompile = filesToCompile.toList(),
|
||||
commonSources = emptyList(),
|
||||
javaSourceRoots = listOf(JvmSourceRoot(srcDir, null)),
|
||||
classpath = listOf(outDir, ForTestCompileRuntime.runtimeJarForTests()).filter { it.exists() },
|
||||
friendDirs = emptyList()
|
||||
)
|
||||
|
||||
val args = K2JVMCompilerArguments().apply {
|
||||
disableDefaultScriptingPlugin = true
|
||||
buildFile = moduleFile.canonicalPath
|
||||
reportOutputFiles = true
|
||||
}
|
||||
val argsArray = ArgumentUtils.convertArgumentsToStringList(args).toTypedArray()
|
||||
|
||||
try {
|
||||
val stream = ByteArrayOutputStream()
|
||||
val out = PrintStream(stream)
|
||||
val exitCode = CompilerRunnerUtil.invokeExecMethod(K2JVMCompiler::class.java.name, argsArray, env, out)
|
||||
val reader = BufferedReader(StringReader(stream.toString()))
|
||||
CompilerOutputParser.parseCompilerMessagesFromReader(env.messageCollector, reader, env.outputItemsCollector)
|
||||
|
||||
return exitCode
|
||||
}
|
||||
finally {
|
||||
moduleFile.delete()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AbstractJsKlibLookupTrackerTest : AbstractJsLookupTrackerTest() {
|
||||
override val jsStdlibFile: File
|
||||
get() = File("build/js-ir-runtime/full-runtime.klib")
|
||||
|
||||
override fun configureAdditionalArgs(args: K2JSCompilerArguments) {
|
||||
args.irProduceKlibDir = true
|
||||
args.irOnly = true
|
||||
args.outputFile = outDir.resolve("out.klib").absolutePath
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AbstractJsLookupTrackerTest : AbstractLookupTrackerTest() {
|
||||
private var header: ByteArray? = null
|
||||
private val packageParts: MutableMap<File, TranslationResultValue> = hashMapOf()
|
||||
private val serializedIrFiles: MutableMap<File, IrTranslationResultValue> = hashMapOf()
|
||||
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
header = null
|
||||
packageParts.clear()
|
||||
serializedIrFiles.clear()
|
||||
}
|
||||
|
||||
override fun Services.Builder.registerAdditionalServices() {
|
||||
if (header != null) {
|
||||
register(
|
||||
IncrementalDataProvider::class.java,
|
||||
IncrementalDataProviderImpl(
|
||||
headerMetadata = header!!,
|
||||
compiledPackageParts = packageParts,
|
||||
metadataVersion = JsMetadataVersion.INSTANCE.toArray(),
|
||||
packageMetadata = emptyMap(), // TODO pass correct metadata
|
||||
serializedIrFiles = serializedIrFiles
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
register(IncrementalResultsConsumer::class.java, IncrementalResultsConsumerImpl())
|
||||
}
|
||||
|
||||
override fun markDirty(removedAndModifiedSources: Iterable<File>) {
|
||||
removedAndModifiedSources.forEach {
|
||||
packageParts.remove(it)
|
||||
serializedIrFiles.remove(it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun processCompilationResults(outputItemsCollector: OutputItemsCollectorImpl, services: Services) {
|
||||
val incrementalResults = services.get(IncrementalResultsConsumer::class.java) as IncrementalResultsConsumerImpl
|
||||
header = incrementalResults.headerMetadata
|
||||
packageParts.putAll(incrementalResults.packageParts)
|
||||
serializedIrFiles.putAll(incrementalResults.irFileData)
|
||||
}
|
||||
|
||||
protected open val jsStdlibFile: File
|
||||
get() = PathUtil.kotlinPathsForDistDirectory.jsStdLibJarPath
|
||||
|
||||
protected open fun configureAdditionalArgs(args: K2JSCompilerArguments) {
|
||||
args.outputFile = File(outDir, "out.js").canonicalPath
|
||||
}
|
||||
|
||||
override fun runCompiler(filesToCompile: Iterable<File>, env: JpsCompilerEnvironment): Any? {
|
||||
val args = K2JSCompilerArguments().apply {
|
||||
val libPaths = arrayListOf(jsStdlibFile.absolutePath) + (libraries ?: "").split(File.pathSeparator)
|
||||
libraries = libPaths.joinToString(File.pathSeparator)
|
||||
reportOutputFiles = true
|
||||
freeArgs = filesToCompile.map { it.canonicalPath }
|
||||
}
|
||||
configureAdditionalArgs(args)
|
||||
return runJSCompiler(args, env)
|
||||
}
|
||||
}
|
||||
|
||||
abstract class AbstractLookupTrackerTest : TestWithWorkingDir() {
|
||||
private val DECLARATION_KEYWORDS = listOf("interface", "class", "enum class", "object", "fun", "operator fun", "val", "var")
|
||||
private val DECLARATION_STARTS_WITH = DECLARATION_KEYWORDS.map { it + " " }
|
||||
// ignore KDoc like comments which starts with `/**`, example: /** text */
|
||||
private val COMMENT_WITH_LOOKUP_INFO = "/\\*[^*]+\\*/".toRegex()
|
||||
|
||||
protected lateinit var srcDir: File
|
||||
protected lateinit var outDir: File
|
||||
private val enableICFixture = EnableICFixture()
|
||||
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
srcDir = File(workingDir, "src").apply { mkdirs() }
|
||||
outDir = File(workingDir, "out")
|
||||
enableICFixture.setUp()
|
||||
}
|
||||
|
||||
override fun tearDown() {
|
||||
enableICFixture.tearDown()
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
protected abstract fun markDirty(removedAndModifiedSources: Iterable<File>)
|
||||
protected abstract fun processCompilationResults(outputItemsCollector: OutputItemsCollectorImpl, services: Services)
|
||||
protected abstract fun runCompiler(filesToCompile: Iterable<File>, env: JpsCompilerEnvironment): Any?
|
||||
|
||||
fun doTest(path: String) {
|
||||
val sb = StringBuilder()
|
||||
fun StringBuilder.indentln(string: String) {
|
||||
appendLine(" $string")
|
||||
}
|
||||
fun CompilerOutput.logOutput(stepName: String) {
|
||||
sb.appendLine("==== $stepName ====")
|
||||
|
||||
sb.appendLine("Compiling files:")
|
||||
for (compiledFile in compiledFiles.sortedBy { it.canonicalPath }) {
|
||||
val lookupsFromFile = lookups[compiledFile]
|
||||
val lookupStatus = when {
|
||||
lookupsFromFile == null -> "(unknown)"
|
||||
lookupsFromFile.isEmpty() -> "(no lookups)"
|
||||
else -> ""
|
||||
}
|
||||
val relativePath = compiledFile.toRelativeString(workingDir).replace("\\", "/")
|
||||
sb.indentln("$relativePath$lookupStatus")
|
||||
}
|
||||
|
||||
sb.appendLine("Exit code: $exitCode")
|
||||
errors.forEach(sb::indentln)
|
||||
|
||||
sb.appendLine()
|
||||
}
|
||||
|
||||
val testDir = File(path)
|
||||
val workToOriginalFileMap = HashMap(copyTestSources(testDir, srcDir, filePrefix = ""))
|
||||
var dirtyFiles = srcDir.walk().filterTo(HashSet()) { it.isKotlinFile(listOf("kt", "kts")) }
|
||||
val steps = getModificationsToPerform(testDir, moduleNames = null, allowNoFilesWithSuffixInTestData = true, touchPolicy = TouchPolicy.CHECKSUM)
|
||||
.filter { it.isNotEmpty() }
|
||||
|
||||
val filesToLookups = arrayListOf<Map<File, List<LookupInfo>>>()
|
||||
fun CompilerOutput.originalFilesToLookups() =
|
||||
compiledFiles.associateBy({ workToOriginalFileMap[it]!! }, { lookups[it] ?: emptyList() })
|
||||
|
||||
make(dirtyFiles).apply {
|
||||
logOutput("INITIAL BUILD")
|
||||
filesToLookups.add(originalFilesToLookups())
|
||||
|
||||
}
|
||||
for ((i, modifications) in steps.withIndex()) {
|
||||
dirtyFiles = modifications.mapNotNullTo(HashSet()) { it.perform(workingDir, workToOriginalFileMap) }
|
||||
make(dirtyFiles).apply {
|
||||
logOutput("STEP ${i + 1}")
|
||||
filesToLookups.add(originalFilesToLookups())
|
||||
}
|
||||
}
|
||||
|
||||
val expectedBuildLog = File(testDir, "build.log")
|
||||
UsefulTestCase.assertSameLinesWithFile(expectedBuildLog.canonicalPath, sb.toString())
|
||||
|
||||
assertEquals(steps.size + 1, filesToLookups.size)
|
||||
for ((i, lookupsAtStepI) in filesToLookups.withIndex()) {
|
||||
val step = if (i == 0) "INITIAL BUILD" else "STEP $i"
|
||||
for ((file, lookups) in lookupsAtStepI) {
|
||||
checkLookupsInFile(step, file, lookups)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class CompilerOutput(
|
||||
val exitCode: String,
|
||||
val errors: List<String>,
|
||||
val compiledFiles: Iterable<File>,
|
||||
val lookups: Map<File, List<LookupInfo>>
|
||||
)
|
||||
|
||||
private fun make(filesToCompile: Iterable<File>): CompilerOutput {
|
||||
filesToCompile.forEach {
|
||||
it.writeText(it.readText().replace(COMMENT_WITH_LOOKUP_INFO, ""))
|
||||
}
|
||||
|
||||
markDirty(filesToCompile)
|
||||
val lookupTracker = TestLookupTracker()
|
||||
val messageCollector = TestMessageCollector()
|
||||
val outputItemsCollector = OutputItemsCollectorImpl()
|
||||
val services = Services.Builder().run {
|
||||
register(LookupTracker::class.java, lookupTracker)
|
||||
registerAdditionalServices()
|
||||
build()
|
||||
}
|
||||
val environment = createTestingCompilerEnvironment(messageCollector, outputItemsCollector, services)
|
||||
val exitCode = runCompiler(filesToCompile, environment) as? ExitCode
|
||||
if (exitCode == ExitCode.OK) {
|
||||
processCompilationResults(outputItemsCollector, environment.services)
|
||||
}
|
||||
|
||||
val lookups = lookupTracker.lookups.groupBy { File(it.filePath) }
|
||||
val lookupsFromCompiledFiles = filesToCompile.associate { it to (lookups[it] ?: emptyList()) }
|
||||
return CompilerOutput(exitCode.toString(), messageCollector.errors, filesToCompile, lookupsFromCompiledFiles)
|
||||
}
|
||||
|
||||
protected open fun Services.Builder.registerAdditionalServices() {}
|
||||
|
||||
private fun checkLookupsInFile(step: String, expectedFile: File, lookupsFromFile: List<LookupInfo>) {
|
||||
val text = expectedFile.readText().replace(COMMENT_WITH_LOOKUP_INFO, "")
|
||||
val lines = text.lines().toMutableList()
|
||||
|
||||
for ((line, lookupsFromLine) in lookupsFromFile.groupBy { it.position.line }) {
|
||||
val columnToLookups = lookupsFromLine.groupBy { it.position.column }.toList().sortedBy { it.first }
|
||||
|
||||
val lineContent = lines[line - 1]
|
||||
val parts = ArrayList<CharSequence>(columnToLookups.size * 2)
|
||||
|
||||
var start = 0
|
||||
|
||||
for ((column, lookupsFromColumn) in columnToLookups) {
|
||||
val end = column - 1
|
||||
parts.add(lineContent.subSequence(start, end))
|
||||
|
||||
val lookups = lookupsFromColumn.mapTo(sortedSetOf()) {
|
||||
val rest = lineContent.substring(end)
|
||||
|
||||
val name =
|
||||
when {
|
||||
rest.startsWith(it.name) || // same name
|
||||
rest.startsWith("$" + it.name) || // backing field
|
||||
DECLARATION_STARTS_WITH.any { rest.startsWith(it) } // it's declaration
|
||||
-> ""
|
||||
else -> "(" + it.name + ")"
|
||||
}
|
||||
|
||||
it.scopeKind.toString()[0].toLowerCase()
|
||||
.toString() + ":" + it.scopeFqName.let { if (it.isNotEmpty()) it else "<root>" } + name
|
||||
}.joinToString(separator = " ", prefix = "/*", postfix = "*/")
|
||||
|
||||
parts.add(lookups)
|
||||
|
||||
start = end
|
||||
}
|
||||
|
||||
lines[line - 1] = parts.joinToString("") + lineContent.subSequence(start, lineContent.length)
|
||||
}
|
||||
|
||||
val actual = lines.joinToString("\n")
|
||||
KotlinTestUtils.assertEqualsToFile("Lookups do not match after $step", expectedFile, actual)
|
||||
}
|
||||
}
|
||||
|
||||
class TestLookupTracker : LookupTracker {
|
||||
val lookups = arrayListOf<LookupInfo>()
|
||||
private val interner = StringInterner()
|
||||
|
||||
override val requiresPosition: Boolean
|
||||
get() = true
|
||||
|
||||
override fun record(filePath: String, position: Position, scopeFqName: String, scopeKind: ScopeKind, name: String) {
|
||||
val internedFilePath = interner.intern(filePath)
|
||||
val internedScopeFqName = interner.intern(scopeFqName)
|
||||
val internedName = interner.intern(name)
|
||||
|
||||
lookups.add(LookupInfo(internedFilePath, position, internedScopeFqName, scopeKind, internedName))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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.jps.build
|
||||
|
||||
import org.jetbrains.kotlin.jps.build.dependeciestxt.ModulesTxt
|
||||
import org.jetbrains.kotlin.jps.build.dependeciestxt.MppJpsIncTestsGenerator
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractMultiplatformJpsTestWithGeneratedContent : AbstractIncrementalJpsTest() {
|
||||
override val modulesTxtFile: File
|
||||
get() = File(testDataDir.parent, "dependencies.txt").also {
|
||||
check(it.exists()) {
|
||||
"`dependencies.txt` should be in parent dir. " +
|
||||
"See `jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/README.md` for details"
|
||||
}
|
||||
}
|
||||
|
||||
override val testDataSrc: File
|
||||
get() = File(workDir, "generatedTestDataSources")
|
||||
|
||||
override fun generateModuleSources(modulesTxt: ModulesTxt) {
|
||||
testDataSrc.mkdirs()
|
||||
|
||||
val testCaseName = testDataDir.name
|
||||
|
||||
val generator = MppJpsIncTestsGenerator(modulesTxt) { testDataSrc }
|
||||
val testCase = generator.testCases.find { it.name == testCaseName }
|
||||
?: error("Test case `$testCaseName` is not configured in ${modulesTxt.fileName}")
|
||||
testCase.generate()
|
||||
}
|
||||
|
||||
override val ModulesTxt.Module.sourceFilePrefix: String
|
||||
get() = "${indexedName}_"
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.build
|
||||
|
||||
import org.jetbrains.jps.builders.JpsBuildTestCase
|
||||
import org.jetbrains.jps.model.library.JpsLibrary
|
||||
import org.jetbrains.kotlin.compilerRunner.JpsKotlinCompilerRunner
|
||||
import org.jetbrains.kotlin.test.WithMutedInDatabaseRunTest
|
||||
import org.jetbrains.kotlin.test.runTest
|
||||
|
||||
@WithMutedInDatabaseRunTest
|
||||
abstract class BaseKotlinJpsBuildTestCase : JpsBuildTestCase() {
|
||||
@Throws(Exception::class)
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
System.setProperty("kotlin.jps.tests", "true")
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
override fun tearDown() {
|
||||
System.clearProperty("kotlin.jps.tests")
|
||||
myModel = null
|
||||
myBuildParams.clear()
|
||||
JpsKotlinCompilerRunner.releaseCompileServiceSession()
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
private val libraries = mutableMapOf<String, JpsLibrary>()
|
||||
|
||||
protected fun requireLibrary(library: KotlinJpsLibrary) = libraries.getOrPut(library.id) {
|
||||
library.create(myProject)
|
||||
}
|
||||
|
||||
override fun runTest() {
|
||||
runTest {
|
||||
super.runTest()
|
||||
}
|
||||
}
|
||||
}
|
||||
+229
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.jps.build;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("jps-plugin/testData/incremental/cacheVersionChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class DataContainerVersionChangedTestGenerated extends AbstractDataContainerVersionChangedTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInCacheVersionChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/cacheVersionChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("clearedHasKotlin")
|
||||
public void testClearedHasKotlin() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/cacheVersionChanged/clearedHasKotlin/");
|
||||
}
|
||||
|
||||
@TestMetadata("exportedModule")
|
||||
public void testExportedModule() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/cacheVersionChanged/exportedModule/");
|
||||
}
|
||||
|
||||
@TestMetadata("javaOnlyModulesAreNotAffected")
|
||||
public void testJavaOnlyModulesAreNotAffected() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/cacheVersionChanged/javaOnlyModulesAreNotAffected/");
|
||||
}
|
||||
|
||||
@TestMetadata("module1Modified")
|
||||
public void testModule1Modified() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/cacheVersionChanged/module1Modified/");
|
||||
}
|
||||
|
||||
@TestMetadata("module2Modified")
|
||||
public void testModule2Modified() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/cacheVersionChanged/module2Modified/");
|
||||
}
|
||||
|
||||
@TestMetadata("moduleWithConstantModified")
|
||||
public void testModuleWithConstantModified() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/cacheVersionChanged/moduleWithConstantModified/");
|
||||
}
|
||||
|
||||
@TestMetadata("moduleWithInlineModified")
|
||||
public void testModuleWithInlineModified() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/cacheVersionChanged/moduleWithInlineModified/");
|
||||
}
|
||||
|
||||
@TestMetadata("touchedFile")
|
||||
public void testTouchedFile() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/cacheVersionChanged/touchedFile/");
|
||||
}
|
||||
|
||||
@TestMetadata("touchedOnlyJavaFile")
|
||||
public void testTouchedOnlyJavaFile() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/cacheVersionChanged/touchedOnlyJavaFile/");
|
||||
}
|
||||
|
||||
@TestMetadata("untouchedFiles")
|
||||
public void testUntouchedFiles() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/cacheVersionChanged/untouchedFiles/");
|
||||
}
|
||||
|
||||
@TestMetadata("withError")
|
||||
public void testWithError() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/cacheVersionChanged/withError/");
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/cacheVersionChanged/clearedHasKotlin")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClearedHasKotlin extends AbstractDataContainerVersionChangedTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClearedHasKotlin() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/cacheVersionChanged/clearedHasKotlin"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/cacheVersionChanged/exportedModule")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ExportedModule extends AbstractDataContainerVersionChangedTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInExportedModule() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/cacheVersionChanged/exportedModule"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/cacheVersionChanged/javaOnlyModulesAreNotAffected")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class JavaOnlyModulesAreNotAffected extends AbstractDataContainerVersionChangedTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInJavaOnlyModulesAreNotAffected() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/cacheVersionChanged/javaOnlyModulesAreNotAffected"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/cacheVersionChanged/module1Modified")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Module1Modified extends AbstractDataContainerVersionChangedTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInModule1Modified() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/cacheVersionChanged/module1Modified"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/cacheVersionChanged/module2Modified")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Module2Modified extends AbstractDataContainerVersionChangedTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInModule2Modified() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/cacheVersionChanged/module2Modified"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/cacheVersionChanged/moduleWithConstantModified")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ModuleWithConstantModified extends AbstractDataContainerVersionChangedTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInModuleWithConstantModified() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/cacheVersionChanged/moduleWithConstantModified"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/cacheVersionChanged/moduleWithInlineModified")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ModuleWithInlineModified extends AbstractDataContainerVersionChangedTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInModuleWithInlineModified() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/cacheVersionChanged/moduleWithInlineModified"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/cacheVersionChanged/touchedFile")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class TouchedFile extends AbstractDataContainerVersionChangedTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInTouchedFile() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/cacheVersionChanged/touchedFile"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/cacheVersionChanged/touchedOnlyJavaFile")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class TouchedOnlyJavaFile extends AbstractDataContainerVersionChangedTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInTouchedOnlyJavaFile() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/cacheVersionChanged/touchedOnlyJavaFile"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/cacheVersionChanged/untouchedFiles")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class UntouchedFiles extends AbstractDataContainerVersionChangedTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInUntouchedFiles() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/cacheVersionChanged/untouchedFiles"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/cacheVersionChanged/withError")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class WithError extends AbstractDataContainerVersionChangedTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInWithError() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/cacheVersionChanged/withError"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
+229
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.jps.build;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("jps-plugin/testData/incremental/cacheVersionChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class IncrementalCacheVersionChangedTestGenerated extends AbstractIncrementalCacheVersionChangedTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInCacheVersionChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/cacheVersionChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("clearedHasKotlin")
|
||||
public void testClearedHasKotlin() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/cacheVersionChanged/clearedHasKotlin/");
|
||||
}
|
||||
|
||||
@TestMetadata("exportedModule")
|
||||
public void testExportedModule() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/cacheVersionChanged/exportedModule/");
|
||||
}
|
||||
|
||||
@TestMetadata("javaOnlyModulesAreNotAffected")
|
||||
public void testJavaOnlyModulesAreNotAffected() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/cacheVersionChanged/javaOnlyModulesAreNotAffected/");
|
||||
}
|
||||
|
||||
@TestMetadata("module1Modified")
|
||||
public void testModule1Modified() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/cacheVersionChanged/module1Modified/");
|
||||
}
|
||||
|
||||
@TestMetadata("module2Modified")
|
||||
public void testModule2Modified() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/cacheVersionChanged/module2Modified/");
|
||||
}
|
||||
|
||||
@TestMetadata("moduleWithConstantModified")
|
||||
public void testModuleWithConstantModified() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/cacheVersionChanged/moduleWithConstantModified/");
|
||||
}
|
||||
|
||||
@TestMetadata("moduleWithInlineModified")
|
||||
public void testModuleWithInlineModified() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/cacheVersionChanged/moduleWithInlineModified/");
|
||||
}
|
||||
|
||||
@TestMetadata("touchedFile")
|
||||
public void testTouchedFile() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/cacheVersionChanged/touchedFile/");
|
||||
}
|
||||
|
||||
@TestMetadata("touchedOnlyJavaFile")
|
||||
public void testTouchedOnlyJavaFile() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/cacheVersionChanged/touchedOnlyJavaFile/");
|
||||
}
|
||||
|
||||
@TestMetadata("untouchedFiles")
|
||||
public void testUntouchedFiles() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/cacheVersionChanged/untouchedFiles/");
|
||||
}
|
||||
|
||||
@TestMetadata("withError")
|
||||
public void testWithError() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/cacheVersionChanged/withError/");
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/cacheVersionChanged/clearedHasKotlin")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClearedHasKotlin extends AbstractIncrementalCacheVersionChangedTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClearedHasKotlin() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/cacheVersionChanged/clearedHasKotlin"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/cacheVersionChanged/exportedModule")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ExportedModule extends AbstractIncrementalCacheVersionChangedTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInExportedModule() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/cacheVersionChanged/exportedModule"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/cacheVersionChanged/javaOnlyModulesAreNotAffected")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class JavaOnlyModulesAreNotAffected extends AbstractIncrementalCacheVersionChangedTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInJavaOnlyModulesAreNotAffected() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/cacheVersionChanged/javaOnlyModulesAreNotAffected"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/cacheVersionChanged/module1Modified")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Module1Modified extends AbstractIncrementalCacheVersionChangedTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInModule1Modified() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/cacheVersionChanged/module1Modified"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/cacheVersionChanged/module2Modified")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Module2Modified extends AbstractIncrementalCacheVersionChangedTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInModule2Modified() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/cacheVersionChanged/module2Modified"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/cacheVersionChanged/moduleWithConstantModified")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ModuleWithConstantModified extends AbstractIncrementalCacheVersionChangedTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInModuleWithConstantModified() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/cacheVersionChanged/moduleWithConstantModified"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/cacheVersionChanged/moduleWithInlineModified")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ModuleWithInlineModified extends AbstractIncrementalCacheVersionChangedTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInModuleWithInlineModified() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/cacheVersionChanged/moduleWithInlineModified"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/cacheVersionChanged/touchedFile")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class TouchedFile extends AbstractIncrementalCacheVersionChangedTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInTouchedFile() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/cacheVersionChanged/touchedFile"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/cacheVersionChanged/touchedOnlyJavaFile")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class TouchedOnlyJavaFile extends AbstractIncrementalCacheVersionChangedTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInTouchedOnlyJavaFile() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/cacheVersionChanged/touchedOnlyJavaFile"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/cacheVersionChanged/untouchedFiles")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class UntouchedFiles extends AbstractIncrementalCacheVersionChangedTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInUntouchedFiles() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/cacheVersionChanged/untouchedFiles"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/cacheVersionChanged/withError")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class WithError extends AbstractIncrementalCacheVersionChangedTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInWithError() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/cacheVersionChanged/withError"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.build
|
||||
|
||||
class IncrementalConstantSearchTest : AbstractIncrementalJpsTest() {
|
||||
fun testJavaConstantChangedUsedInKotlin() {
|
||||
doTest("jps-plugin/testData/incremental/custom/javaConstantChangedUsedInKotlin/")
|
||||
}
|
||||
|
||||
fun testJavaConstantUnchangedUsedInKotlin() {
|
||||
doTest("jps-plugin/testData/incremental/custom/javaConstantUnchangedUsedInKotlin/")
|
||||
}
|
||||
|
||||
fun testKotlinConstantChangedUsedInJava() {
|
||||
doTest("jps-plugin/testData/incremental/custom/kotlinConstantChangedUsedInJava/")
|
||||
}
|
||||
|
||||
fun testKotlinJvmFieldChangedUsedInJava() {
|
||||
doTest("jps-plugin/testData/incremental/custom/kotlinJvmFieldChangedUsedInJava/")
|
||||
}
|
||||
|
||||
fun testKotlinConstantUnchangedUsedInJava() {
|
||||
doTest("jps-plugin/testData/incremental/custom/kotlinConstantUnchangedUsedInJava/")
|
||||
}
|
||||
|
||||
fun testKotlinJvmFieldUnchangedUsedInJava() {
|
||||
doTest("jps-plugin/testData/incremental/custom/kotlinJvmFieldUnchangedUsedInJava/")
|
||||
}
|
||||
}
|
||||
Generated
+463
@@ -0,0 +1,463 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.jps.build;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/common")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class IncrementalJsJpsTestGenerated extends AbstractIncrementalJsJpsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInCommon() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/common"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("classAdded")
|
||||
public void testClassAdded() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/common/classAdded/");
|
||||
}
|
||||
|
||||
@TestMetadata("classRemoved")
|
||||
public void testClassRemoved() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/common/classRemoved/");
|
||||
}
|
||||
|
||||
@TestMetadata("constantValueChanged")
|
||||
public void testConstantValueChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/common/constantValueChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("copyFileToAnotherModule")
|
||||
public void testCopyFileToAnotherModule() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/common/copyFileToAnotherModule/");
|
||||
}
|
||||
|
||||
@TestMetadata("defaultArgumentInConstructorRemoved")
|
||||
public void testDefaultArgumentInConstructorRemoved() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/common/defaultArgumentInConstructorRemoved/");
|
||||
}
|
||||
|
||||
@TestMetadata("defaultParameterAdded")
|
||||
public void testDefaultParameterAdded() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/common/defaultParameterAdded/");
|
||||
}
|
||||
|
||||
@TestMetadata("defaultParameterAddedForTopLevelFun")
|
||||
public void testDefaultParameterAddedForTopLevelFun() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/common/defaultParameterAddedForTopLevelFun/");
|
||||
}
|
||||
|
||||
@TestMetadata("defaultParameterRemoved")
|
||||
public void testDefaultParameterRemoved() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/common/defaultParameterRemoved/");
|
||||
}
|
||||
|
||||
@TestMetadata("defaultParameterRemovedForTopLevelFun")
|
||||
public void testDefaultParameterRemovedForTopLevelFun() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/common/defaultParameterRemovedForTopLevelFun/");
|
||||
}
|
||||
|
||||
@TestMetadata("defaultValueInConstructorRemoved")
|
||||
public void testDefaultValueInConstructorRemoved() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/common/defaultValueInConstructorRemoved/");
|
||||
}
|
||||
|
||||
@TestMetadata("duplicatedClass")
|
||||
public void testDuplicatedClass() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/common/duplicatedClass/");
|
||||
}
|
||||
|
||||
@TestMetadata("exportedDependency")
|
||||
public void testExportedDependency() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/common/exportedDependency/");
|
||||
}
|
||||
|
||||
@TestMetadata("functionFromDifferentPackageChanged")
|
||||
public void testFunctionFromDifferentPackageChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/common/functionFromDifferentPackageChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineFunctionInlined")
|
||||
public void testInlineFunctionInlined() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/common/inlineFunctionInlined/");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineFunctionTwoPackageParts")
|
||||
public void testInlineFunctionTwoPackageParts() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/common/inlineFunctionTwoPackageParts/");
|
||||
}
|
||||
|
||||
@TestMetadata("moveFileToAnotherModule")
|
||||
public void testMoveFileToAnotherModule() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/common/moveFileToAnotherModule/");
|
||||
}
|
||||
|
||||
@TestMetadata("simple")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/common/simple/");
|
||||
}
|
||||
|
||||
@TestMetadata("simpleDependency")
|
||||
public void testSimpleDependency() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/common/simpleDependency/");
|
||||
}
|
||||
|
||||
@TestMetadata("simpleDependencyErrorOnAccessToInternal1")
|
||||
public void testSimpleDependencyErrorOnAccessToInternal1() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/common/simpleDependencyErrorOnAccessToInternal1/");
|
||||
}
|
||||
|
||||
@TestMetadata("simpleDependencyErrorOnAccessToInternal2")
|
||||
public void testSimpleDependencyErrorOnAccessToInternal2() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/common/simpleDependencyErrorOnAccessToInternal2/");
|
||||
}
|
||||
|
||||
@TestMetadata("simpleDependencyUnchanged")
|
||||
public void testSimpleDependencyUnchanged() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/common/simpleDependencyUnchanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("transitiveDependency")
|
||||
public void testTransitiveDependency() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/common/transitiveDependency/");
|
||||
}
|
||||
|
||||
@TestMetadata("transitiveInlining")
|
||||
public void testTransitiveInlining() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/common/transitiveInlining/");
|
||||
}
|
||||
|
||||
@TestMetadata("twoDependants")
|
||||
public void testTwoDependants() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/common/twoDependants/");
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/common/classAdded")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassAdded extends AbstractIncrementalJsJpsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassAdded() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/common/classAdded"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/common/classRemoved")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassRemoved extends AbstractIncrementalJsJpsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassRemoved() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/common/classRemoved"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/common/constantValueChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ConstantValueChanged extends AbstractIncrementalJsJpsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInConstantValueChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/common/constantValueChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/common/copyFileToAnotherModule")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class CopyFileToAnotherModule extends AbstractIncrementalJsJpsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInCopyFileToAnotherModule() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/common/copyFileToAnotherModule"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/common/defaultArgumentInConstructorRemoved")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class DefaultArgumentInConstructorRemoved extends AbstractIncrementalJsJpsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInDefaultArgumentInConstructorRemoved() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/common/defaultArgumentInConstructorRemoved"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/common/defaultParameterAdded")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class DefaultParameterAdded extends AbstractIncrementalJsJpsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInDefaultParameterAdded() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/common/defaultParameterAdded"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/common/defaultParameterAddedForTopLevelFun")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class DefaultParameterAddedForTopLevelFun extends AbstractIncrementalJsJpsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInDefaultParameterAddedForTopLevelFun() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/common/defaultParameterAddedForTopLevelFun"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/common/defaultParameterRemoved")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class DefaultParameterRemoved extends AbstractIncrementalJsJpsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInDefaultParameterRemoved() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/common/defaultParameterRemoved"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/common/defaultParameterRemovedForTopLevelFun")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class DefaultParameterRemovedForTopLevelFun extends AbstractIncrementalJsJpsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInDefaultParameterRemovedForTopLevelFun() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/common/defaultParameterRemovedForTopLevelFun"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/common/defaultValueInConstructorRemoved")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class DefaultValueInConstructorRemoved extends AbstractIncrementalJsJpsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInDefaultValueInConstructorRemoved() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/common/defaultValueInConstructorRemoved"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/common/duplicatedClass")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class DuplicatedClass extends AbstractIncrementalJsJpsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInDuplicatedClass() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/common/duplicatedClass"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/common/exportedDependency")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ExportedDependency extends AbstractIncrementalJsJpsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInExportedDependency() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/common/exportedDependency"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/common/functionFromDifferentPackageChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class FunctionFromDifferentPackageChanged extends AbstractIncrementalJsJpsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInFunctionFromDifferentPackageChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/common/functionFromDifferentPackageChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/common/inlineFunctionInlined")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class InlineFunctionInlined extends AbstractIncrementalJsJpsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInInlineFunctionInlined() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/common/inlineFunctionInlined"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/common/inlineFunctionTwoPackageParts")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class InlineFunctionTwoPackageParts extends AbstractIncrementalJsJpsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInInlineFunctionTwoPackageParts() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/common/inlineFunctionTwoPackageParts"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/common/moveFileToAnotherModule")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class MoveFileToAnotherModule extends AbstractIncrementalJsJpsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInMoveFileToAnotherModule() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/common/moveFileToAnotherModule"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/common/simple")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Simple extends AbstractIncrementalJsJpsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInSimple() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/common/simple"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/common/simpleDependency")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class SimpleDependency extends AbstractIncrementalJsJpsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInSimpleDependency() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/common/simpleDependency"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/common/simpleDependencyErrorOnAccessToInternal1")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class SimpleDependencyErrorOnAccessToInternal1 extends AbstractIncrementalJsJpsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInSimpleDependencyErrorOnAccessToInternal1() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/common/simpleDependencyErrorOnAccessToInternal1"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/common/simpleDependencyErrorOnAccessToInternal2")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class SimpleDependencyErrorOnAccessToInternal2 extends AbstractIncrementalJsJpsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInSimpleDependencyErrorOnAccessToInternal2() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/common/simpleDependencyErrorOnAccessToInternal2"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/common/simpleDependencyUnchanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class SimpleDependencyUnchanged extends AbstractIncrementalJsJpsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInSimpleDependencyUnchanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/common/simpleDependencyUnchanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/common/transitiveDependency")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class TransitiveDependency extends AbstractIncrementalJsJpsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInTransitiveDependency() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/common/transitiveDependency"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/common/transitiveInlining")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class TransitiveInlining extends AbstractIncrementalJsJpsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInTransitiveInlining() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/common/transitiveInlining"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/common/twoDependants")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class TwoDependants extends AbstractIncrementalJsJpsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInTwoDependants() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/common/twoDependants"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
Generated
+3693
File diff suppressed because it is too large
Load Diff
jps/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/build/IncrementalLazyCachesTestGenerated.java
Generated
+263
@@ -0,0 +1,263 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.jps.build;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class IncrementalLazyCachesTestGenerated extends AbstractIncrementalLazyCachesTest {
|
||||
@TestMetadata("jps-plugin/testData/incremental/lazyKotlinCaches")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class LazyKotlinCaches extends AbstractIncrementalLazyCachesTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInLazyKotlinCaches() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/lazyKotlinCaches"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("class")
|
||||
public void testClass() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/lazyKotlinCaches/class/");
|
||||
}
|
||||
|
||||
@TestMetadata("classInheritance")
|
||||
public void testClassInheritance() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/lazyKotlinCaches/classInheritance/");
|
||||
}
|
||||
|
||||
@TestMetadata("constant")
|
||||
public void testConstant() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/lazyKotlinCaches/constant/");
|
||||
}
|
||||
|
||||
@TestMetadata("function")
|
||||
public void testFunction() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/lazyKotlinCaches/function/");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineFunctionWithUsage")
|
||||
public void testInlineFunctionWithUsage() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/lazyKotlinCaches/inlineFunctionWithUsage/");
|
||||
}
|
||||
|
||||
@TestMetadata("inlineFunctionWithoutUsage")
|
||||
public void testInlineFunctionWithoutUsage() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/lazyKotlinCaches/inlineFunctionWithoutUsage/");
|
||||
}
|
||||
|
||||
@TestMetadata("noKotlin")
|
||||
public void testNoKotlin() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/lazyKotlinCaches/noKotlin/");
|
||||
}
|
||||
|
||||
@TestMetadata("topLevelPropertyAccess")
|
||||
public void testTopLevelPropertyAccess() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/lazyKotlinCaches/topLevelPropertyAccess/");
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/lazyKotlinCaches/class")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Class extends AbstractIncrementalLazyCachesTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClass() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/lazyKotlinCaches/class"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/lazyKotlinCaches/classInheritance")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassInheritance extends AbstractIncrementalLazyCachesTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassInheritance() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/lazyKotlinCaches/classInheritance"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/lazyKotlinCaches/constant")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Constant extends AbstractIncrementalLazyCachesTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInConstant() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/lazyKotlinCaches/constant"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/lazyKotlinCaches/function")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Function extends AbstractIncrementalLazyCachesTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInFunction() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/lazyKotlinCaches/function"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/lazyKotlinCaches/inlineFunctionWithUsage")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class InlineFunctionWithUsage extends AbstractIncrementalLazyCachesTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInInlineFunctionWithUsage() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/lazyKotlinCaches/inlineFunctionWithUsage"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/lazyKotlinCaches/inlineFunctionWithoutUsage")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class InlineFunctionWithoutUsage extends AbstractIncrementalLazyCachesTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInInlineFunctionWithoutUsage() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/lazyKotlinCaches/inlineFunctionWithoutUsage"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/lazyKotlinCaches/noKotlin")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class NoKotlin extends AbstractIncrementalLazyCachesTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInNoKotlin() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/lazyKotlinCaches/noKotlin"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/lazyKotlinCaches/topLevelPropertyAccess")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class TopLevelPropertyAccess extends AbstractIncrementalLazyCachesTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInTopLevelPropertyAccess() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/lazyKotlinCaches/topLevelPropertyAccess"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/changeIncrementalOption")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ChangeIncrementalOption extends AbstractIncrementalLazyCachesTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInChangeIncrementalOption() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/changeIncrementalOption"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("incrementalOff")
|
||||
public void testIncrementalOff() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/changeIncrementalOption/incrementalOff/");
|
||||
}
|
||||
|
||||
@TestMetadata("incrementalOffOn")
|
||||
public void testIncrementalOffOn() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/changeIncrementalOption/incrementalOffOn/");
|
||||
}
|
||||
|
||||
@TestMetadata("incrementalOffOnJavaChanged")
|
||||
public void testIncrementalOffOnJavaChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/changeIncrementalOption/incrementalOffOnJavaChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("incrementalOffOnJavaOnly")
|
||||
public void testIncrementalOffOnJavaOnly() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/changeIncrementalOption/incrementalOffOnJavaOnly/");
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/changeIncrementalOption/incrementalOff")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class IncrementalOff extends AbstractIncrementalLazyCachesTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInIncrementalOff() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/changeIncrementalOption/incrementalOff"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/changeIncrementalOption/incrementalOffOn")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class IncrementalOffOn extends AbstractIncrementalLazyCachesTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInIncrementalOffOn() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/changeIncrementalOption/incrementalOffOn"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/changeIncrementalOption/incrementalOffOnJavaChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class IncrementalOffOnJavaChanged extends AbstractIncrementalLazyCachesTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInIncrementalOffOnJavaChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/changeIncrementalOption/incrementalOffOnJavaChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/changeIncrementalOption/incrementalOffOnJavaOnly")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class IncrementalOffOnJavaOnly extends AbstractIncrementalLazyCachesTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInIncrementalOffOnJavaOnly() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/changeIncrementalOption/incrementalOffOnJavaOnly"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.build
|
||||
|
||||
import com.intellij.openapi.util.SystemInfoRt
|
||||
import org.jetbrains.jps.model.java.JavaSourceRootType
|
||||
import org.jetbrains.kotlin.incremental.testingUtils.Modification
|
||||
|
||||
class IncrementalProjectPathCaseChangedTest : AbstractIncrementalJpsTest(checkDumpsCaseInsensitively = true) {
|
||||
fun testProjectPathCaseChanged() {
|
||||
doTest("jps-plugin/testData/incremental/custom/projectPathCaseChanged/")
|
||||
}
|
||||
|
||||
fun testProjectPathCaseChangedMultiFile() {
|
||||
doTest("jps-plugin/testData/incremental/custom/projectPathCaseChangedMultiFile/")
|
||||
}
|
||||
|
||||
override fun doTest(testDataPath: String) {
|
||||
if (SystemInfoRt.isFileSystemCaseSensitive) {
|
||||
return
|
||||
}
|
||||
|
||||
super.doTest(testDataPath)
|
||||
}
|
||||
|
||||
override fun performAdditionalModifications(modifications: List<Modification>) {
|
||||
val module = myProject.modules[0]
|
||||
val sourceRoot = module.sourceRoots[0].url
|
||||
assert(sourceRoot.endsWith("/src"))
|
||||
val newSourceRoot = sourceRoot.replace("/src", "/SRC")
|
||||
module.removeSourceRoot(sourceRoot, JavaSourceRootType.SOURCE)
|
||||
module.addSourceRoot(newSourceRoot, JavaSourceRootType.SOURCE)
|
||||
}
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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.jps.build
|
||||
|
||||
import junit.framework.TestCase
|
||||
|
||||
class JoinToReadableStringTest : TestCase() {
|
||||
fun test0() {
|
||||
assertEquals(
|
||||
"",
|
||||
listOf<String>().joinToReadableString()
|
||||
)
|
||||
}
|
||||
|
||||
fun test1() {
|
||||
assertEquals(
|
||||
"a",
|
||||
listOf("a").joinToReadableString()
|
||||
)
|
||||
}
|
||||
|
||||
fun test2() {
|
||||
assertEquals(
|
||||
"a and b",
|
||||
listOf("a", "b").joinToReadableString()
|
||||
)
|
||||
}
|
||||
|
||||
fun test3() {
|
||||
assertEquals(
|
||||
"a, b and c",
|
||||
listOf("a", "b", "c").joinToReadableString()
|
||||
)
|
||||
}
|
||||
|
||||
fun test4() {
|
||||
assertEquals(
|
||||
"a, b, c and d",
|
||||
listOf("a", "b", "c", "d").joinToReadableString()
|
||||
)
|
||||
}
|
||||
|
||||
fun test5() {
|
||||
assertEquals(
|
||||
"a, b, c, d and e",
|
||||
listOf("a", "b", "c", "d", "e").joinToReadableString()
|
||||
)
|
||||
}
|
||||
|
||||
fun test6() {
|
||||
assertEquals(
|
||||
"a, b, c, d, e and 1 more",
|
||||
listOf("a", "b", "c", "d", "e", "f").joinToReadableString()
|
||||
)
|
||||
}
|
||||
}
|
||||
Generated
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.jps.build;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("jps-plugin/testData/incremental/lookupTracker/jsKlib")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class JsKlibLookupTrackerTestGenerated extends AbstractJsKlibLookupTrackerTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInJsKlib() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/lookupTracker/jsKlib"), Pattern.compile("^([^\\.]+)$"), null, false);
|
||||
}
|
||||
|
||||
@TestMetadata("classifierMembers")
|
||||
public void testClassifierMembers() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/lookupTracker/jsKlib/classifierMembers/");
|
||||
}
|
||||
|
||||
@TestMetadata("conventions")
|
||||
public void testConventions() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/lookupTracker/jsKlib/conventions/");
|
||||
}
|
||||
|
||||
@TestMetadata("expressionType")
|
||||
public void testExpressionType() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/lookupTracker/jsKlib/expressionType/");
|
||||
}
|
||||
|
||||
@TestMetadata("localDeclarations")
|
||||
public void testLocalDeclarations() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/lookupTracker/jsKlib/localDeclarations/");
|
||||
}
|
||||
|
||||
@TestMetadata("packageDeclarations")
|
||||
public void testPackageDeclarations() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/lookupTracker/jsKlib/packageDeclarations/");
|
||||
}
|
||||
|
||||
@TestMetadata("simple")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/lookupTracker/jsKlib/simple/");
|
||||
}
|
||||
}
|
||||
Generated
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.jps.build;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("jps-plugin/testData/incremental/lookupTracker/js")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class JsLookupTrackerTestGenerated extends AbstractJsLookupTrackerTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInJs() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/lookupTracker/js"), Pattern.compile("^([^\\.]+)$"), null, false);
|
||||
}
|
||||
|
||||
@TestMetadata("classifierMembers")
|
||||
public void testClassifierMembers() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/lookupTracker/js/classifierMembers/");
|
||||
}
|
||||
|
||||
@TestMetadata("conventions")
|
||||
public void testConventions() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/lookupTracker/js/conventions/");
|
||||
}
|
||||
|
||||
@TestMetadata("expressionType")
|
||||
public void testExpressionType() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/lookupTracker/js/expressionType/");
|
||||
}
|
||||
|
||||
@TestMetadata("localDeclarations")
|
||||
public void testLocalDeclarations() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/lookupTracker/js/localDeclarations/");
|
||||
}
|
||||
|
||||
@TestMetadata("packageDeclarations")
|
||||
public void testPackageDeclarations() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/lookupTracker/js/packageDeclarations/");
|
||||
}
|
||||
|
||||
@TestMetadata("simple")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/lookupTracker/js/simple/");
|
||||
}
|
||||
}
|
||||
Generated
+76
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.jps.build;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("jps-plugin/testData/incremental/lookupTracker/jvm")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class JvmLookupTrackerTestGenerated extends AbstractJvmLookupTrackerTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInJvm() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/lookupTracker/jvm"), Pattern.compile("^([^\\.]+)$"), null, false);
|
||||
}
|
||||
|
||||
@TestMetadata("classifierMembers")
|
||||
public void testClassifierMembers() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/lookupTracker/jvm/classifierMembers/");
|
||||
}
|
||||
|
||||
@TestMetadata("conventions")
|
||||
public void testConventions() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/lookupTracker/jvm/conventions/");
|
||||
}
|
||||
|
||||
@TestMetadata("expressionType")
|
||||
public void testExpressionType() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/lookupTracker/jvm/expressionType/");
|
||||
}
|
||||
|
||||
@TestMetadata("java")
|
||||
public void testJava() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/lookupTracker/jvm/java/");
|
||||
}
|
||||
|
||||
@TestMetadata("localDeclarations")
|
||||
public void testLocalDeclarations() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/lookupTracker/jvm/localDeclarations/");
|
||||
}
|
||||
|
||||
@TestMetadata("packageDeclarations")
|
||||
public void testPackageDeclarations() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/lookupTracker/jvm/packageDeclarations/");
|
||||
}
|
||||
|
||||
@TestMetadata("SAM")
|
||||
public void testSAM() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/lookupTracker/jvm/SAM/");
|
||||
}
|
||||
|
||||
@TestMetadata("simple")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/lookupTracker/jvm/simple/");
|
||||
}
|
||||
|
||||
@TestMetadata("syntheticProperties")
|
||||
public void testSyntheticProperties() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/lookupTracker/jvm/syntheticProperties/");
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
+1120
File diff suppressed because it is too large
Load Diff
+111
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* 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 org.jetbrains.kotlin.jps.build
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import org.jetbrains.jps.model.java.JpsJavaExtensionService
|
||||
import org.jetbrains.jps.model.module.JpsModule
|
||||
import org.jetbrains.jps.util.JpsPathUtil
|
||||
import java.io.File
|
||||
import java.nio.file.Paths
|
||||
|
||||
abstract class KotlinJpsBuildTestBase : AbstractKotlinJpsBuildTestCase() {
|
||||
protected lateinit var originalProjectDir: File
|
||||
protected val expectedOutputFile: File
|
||||
get() = File(originalProjectDir, "expected-output.txt")
|
||||
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
val currentTestMethod = this::class.members.firstOrNull { it.name == "test" + getTestName(false) }
|
||||
val workingDirFromAnnotation = currentTestMethod?.annotations?.filterIsInstance<WorkingDir>()?.firstOrNull()?.name
|
||||
val projDirPath = Paths.get(
|
||||
TEST_DATA_PATH,
|
||||
"general",
|
||||
workingDirFromAnnotation ?: getTestName(false)
|
||||
)
|
||||
originalProjectDir = projDirPath.toFile()
|
||||
workDir = copyTestDataToTmpDir(originalProjectDir)
|
||||
orCreateProjectDir
|
||||
}
|
||||
|
||||
protected open fun copyTestDataToTmpDir(testDataDir: File): File {
|
||||
assert(testDataDir.exists()) { "Cannot find source folder " + testDataDir.absolutePath }
|
||||
val tmpDir = FileUtil.createTempDirectory("kjbtb-jps-build", null)
|
||||
FileUtil.copyDir(testDataDir, tmpDir)
|
||||
return tmpDir
|
||||
}
|
||||
|
||||
override fun tearDown() {
|
||||
workDir.deleteRecursively()
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
override fun doGetProjectDir(): File = workDir
|
||||
|
||||
annotation class WorkingDir(val name: String)
|
||||
|
||||
enum class LibraryDependency {
|
||||
NONE,
|
||||
JVM_MOCK_RUNTIME,
|
||||
JVM_FULL_RUNTIME,
|
||||
JS_STDLIB,
|
||||
}
|
||||
|
||||
protected fun initProject(libraryDependency: LibraryDependency = LibraryDependency.NONE) {
|
||||
addJdk(JDK_NAME)
|
||||
loadProject(workDir.absolutePath + File.separator + PROJECT_NAME + ".ipr")
|
||||
|
||||
when (libraryDependency) {
|
||||
LibraryDependency.NONE -> {}
|
||||
LibraryDependency.JVM_MOCK_RUNTIME -> addKotlinMockRuntimeDependency()
|
||||
LibraryDependency.JVM_FULL_RUNTIME -> addKotlinStdlibDependency()
|
||||
LibraryDependency.JS_STDLIB -> addKotlinJavaScriptStdlibDependency()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val JDK_NAME = "IDEA_JDK"
|
||||
const val PROJECT_NAME = "kotlinProject"
|
||||
|
||||
@JvmStatic
|
||||
protected fun assertFilesExistInOutput(module: JpsModule, vararg relativePaths: String) {
|
||||
for (path in relativePaths) {
|
||||
val outputFile = findFileInOutputDir(module, path)
|
||||
assertTrue("Output not written: " + outputFile.absolutePath + "\n Directory contents: \n" + dirContents(
|
||||
outputFile.parentFile
|
||||
), outputFile.exists())
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
protected fun findFileInOutputDir(module: JpsModule, relativePath: String): File {
|
||||
val outputUrl = JpsJavaExtensionService.getInstance().getOutputUrl(module, false)
|
||||
assertNotNull(outputUrl)
|
||||
val outputDir = File(JpsPathUtil.urlToPath(outputUrl))
|
||||
return File(outputDir, relativePath)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
protected fun assertFilesNotExistInOutput(module: JpsModule, vararg relativePaths: String) {
|
||||
val outputUrl = JpsJavaExtensionService.getInstance().getOutputUrl(module, false)
|
||||
assertNotNull(outputUrl)
|
||||
val outputDir = File(JpsPathUtil.urlToPath(outputUrl))
|
||||
for (path in relativePaths) {
|
||||
val outputFile = File(outputDir, path)
|
||||
assertFalse("Output directory \"" + outputFile.absolutePath + "\" contains \"" + path + "\"", outputFile.exists())
|
||||
}
|
||||
}
|
||||
|
||||
private fun dirContents(dir: File): String {
|
||||
val files = dir.listFiles() ?: return "<not found>"
|
||||
val builder = StringBuilder()
|
||||
for (file in files) {
|
||||
builder.append(" * ").append(file.name).append("\n")
|
||||
}
|
||||
return builder.toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.build
|
||||
|
||||
import org.jetbrains.jps.builders.JpsBuildTestCase
|
||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||
import org.jetbrains.kotlin.compilerRunner.JpsKotlinCompilerRunner
|
||||
import org.jetbrains.kotlin.config.LanguageVersion
|
||||
import org.jetbrains.kotlin.daemon.common.isDaemonEnabled
|
||||
import org.jetbrains.kotlin.jps.build.fixtures.EnableICFixture
|
||||
import org.jetbrains.kotlin.jps.model.kotlinCommonCompilerArguments
|
||||
import org.jetbrains.kotlin.jps.model.kotlinCompilerArguments
|
||||
import java.io.File
|
||||
import kotlin.reflect.KMutableProperty1
|
||||
|
||||
class KotlinJpsBuildTestIncremental : KotlinJpsBuildTest() {
|
||||
private val enableICFixture = EnableICFixture()
|
||||
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
enableICFixture.setUp()
|
||||
}
|
||||
|
||||
override fun tearDown() {
|
||||
enableICFixture.tearDown()
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
fun testKotlinJavaScriptChangePackage() {
|
||||
initProject(LibraryDependency.JS_STDLIB)
|
||||
buildAllModules().assertSuccessful()
|
||||
|
||||
val class2Kt = File(workDir, "src/Class2.kt")
|
||||
val newClass2KtContent = class2Kt.readText().replace("package2", "package1")
|
||||
JpsBuildTestCase.change(class2Kt.path, newClass2KtContent)
|
||||
buildAllModules().assertSuccessful()
|
||||
checkOutputFilesList(File(workDir, "out/production"))
|
||||
}
|
||||
|
||||
fun testJpsDaemonIC() {
|
||||
fun testImpl() {
|
||||
assertTrue("Daemon was not enabled!", isDaemonEnabled())
|
||||
|
||||
doTest()
|
||||
val module = myProject.modules.get(0)
|
||||
val mainKtClassFile = findFileInOutputDir(module, "MainKt.class")
|
||||
assertTrue("$mainKtClassFile does not exist!", mainKtClassFile.exists())
|
||||
|
||||
val fooKt = File(workDir, "src/Foo.kt")
|
||||
JpsBuildTestCase.change(fooKt.path, null)
|
||||
buildAllModules().assertSuccessful()
|
||||
assertCompiled(KotlinBuilder.KOTLIN_BUILDER_NAME, "src/Foo.kt")
|
||||
|
||||
JpsBuildTestCase.change(fooKt.path, "class Foo(val x: Int = 0)")
|
||||
buildAllModules().assertSuccessful()
|
||||
assertCompiled(KotlinBuilder.KOTLIN_BUILDER_NAME, "src/main.kt", "src/Foo.kt")
|
||||
}
|
||||
|
||||
withDaemon {
|
||||
withSystemProperty(JpsKotlinCompilerRunner.FAIL_ON_FALLBACK_PROPERTY, "true") {
|
||||
testImpl()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun testManyFiles() {
|
||||
doTest()
|
||||
|
||||
val module = myProject.modules.get(0)
|
||||
assertFilesExistInOutput(module, "foo/MainKt.class", "boo/BooKt.class", "foo/Bar.class")
|
||||
|
||||
checkWhen(touch("src/main.kt"), null, packageClasses("kotlinProject", "src/main.kt", "foo.MainKt"))
|
||||
checkWhen(touch("src/boo.kt"), null, packageClasses("kotlinProject", "src/boo.kt", "boo.BooKt"))
|
||||
checkWhen(touch("src/Bar.kt"), arrayOf("src/Bar.kt"), arrayOf(module("kotlinProject"), klass("kotlinProject", "foo.Bar")))
|
||||
|
||||
checkWhen(del("src/main.kt"),
|
||||
pathsToCompile = null,
|
||||
pathsToDelete = packageClasses("kotlinProject", "src/main.kt", "foo.MainKt"))
|
||||
assertFilesExistInOutput(module, "boo/BooKt.class", "foo/Bar.class")
|
||||
assertFilesNotExistInOutput(module, "foo/MainKt.class")
|
||||
|
||||
checkWhen(touch("src/boo.kt"), null, packageClasses("kotlinProject", "src/boo.kt", "boo.BooKt"))
|
||||
checkWhen(touch("src/Bar.kt"), null, arrayOf(module("kotlinProject"), klass("kotlinProject", "foo.Bar")))
|
||||
}
|
||||
|
||||
fun testManyFilesForPackage() {
|
||||
doTest()
|
||||
|
||||
val module = myProject.modules.get(0)
|
||||
assertFilesExistInOutput(module, "foo/MainKt.class", "boo/BooKt.class", "foo/Bar.class")
|
||||
|
||||
checkWhen(touch("src/main.kt"), null, packageClasses("kotlinProject", "src/main.kt", "foo.MainKt"))
|
||||
checkWhen(touch("src/boo.kt"), null, packageClasses("kotlinProject", "src/boo.kt", "boo.BooKt"))
|
||||
checkWhen(touch("src/Bar.kt"),
|
||||
arrayOf("src/Bar.kt"),
|
||||
arrayOf(klass("kotlinProject", "foo.Bar"),
|
||||
packagePartClass("kotlinProject", "src/Bar.kt", "foo.MainKt"),
|
||||
module("kotlinProject")))
|
||||
|
||||
checkWhen(del("src/main.kt"),
|
||||
pathsToCompile = null,
|
||||
pathsToDelete = packageClasses("kotlinProject", "src/main.kt", "foo.MainKt"))
|
||||
assertFilesExistInOutput(module, "boo/BooKt.class", "foo/Bar.class")
|
||||
|
||||
checkWhen(touch("src/boo.kt"), null, packageClasses("kotlinProject", "src/boo.kt", "boo.BooKt"))
|
||||
checkWhen(touch("src/Bar.kt"), null,
|
||||
arrayOf(klass("kotlinProject", "foo.Bar"),
|
||||
packagePartClass("kotlinProject", "src/Bar.kt", "foo.MainKt"),
|
||||
module("kotlinProject")))
|
||||
}
|
||||
|
||||
@WorkingDir("LanguageOrApiVersionChanged")
|
||||
fun testLanguageVersionChanged() {
|
||||
languageOrApiVersionChanged(CommonCompilerArguments::languageVersion)
|
||||
}
|
||||
|
||||
@WorkingDir("LanguageOrApiVersionChanged")
|
||||
fun testApiVersionChanged() {
|
||||
languageOrApiVersionChanged(CommonCompilerArguments::apiVersion)
|
||||
}
|
||||
|
||||
private fun languageOrApiVersionChanged(versionProperty: KMutableProperty1<CommonCompilerArguments, String?>) {
|
||||
initProject(LibraryDependency.JVM_MOCK_RUNTIME)
|
||||
|
||||
assertEquals(1, myProject.modules.size)
|
||||
val module = myProject.modules.first()
|
||||
val args = module.kotlinCompilerArguments
|
||||
|
||||
fun setVersion(newVersion: String) {
|
||||
versionProperty.set(args, newVersion)
|
||||
myProject.kotlinCommonCompilerArguments = args
|
||||
}
|
||||
|
||||
assertNull(args.apiVersion)
|
||||
buildAllModules().assertSuccessful()
|
||||
|
||||
setVersion(LanguageVersion.LATEST_STABLE.versionString)
|
||||
buildAllModules().assertSuccessful()
|
||||
assertCompiled(KotlinBuilder.KOTLIN_BUILDER_NAME)
|
||||
|
||||
setVersion(LanguageVersion.KOTLIN_1_3.versionString)
|
||||
buildAllModules().assertSuccessful()
|
||||
assertCompiled(KotlinBuilder.KOTLIN_BUILDER_NAME, "src/Bar.kt", "src/Foo.kt")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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.jps.build
|
||||
|
||||
import org.jetbrains.jps.model.JpsProject
|
||||
import org.jetbrains.jps.model.java.JpsJavaLibraryType
|
||||
import org.jetbrains.jps.model.library.JpsLibrary
|
||||
import org.jetbrains.jps.model.library.JpsOrderRootType
|
||||
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
|
||||
import org.jetbrains.kotlin.utils.PathUtil
|
||||
import java.io.File
|
||||
|
||||
enum class KotlinJpsLibrary(val id: String, vararg val roots: File) {
|
||||
MockRuntime(
|
||||
"kotlin-mock-runtime",
|
||||
ForTestCompileRuntime.minimalRuntimeJarForTests()
|
||||
),
|
||||
|
||||
JvmStdLib(
|
||||
"kotlin-stdlib",
|
||||
PathUtil.kotlinPathsForDistDirectory.stdlibPath,
|
||||
File(PathUtil.kotlinPathsForDistDirectory.libPath, "annotations-13.0.jar")
|
||||
),
|
||||
JvmTest(
|
||||
"kotlin-test",
|
||||
PathUtil.kotlinPathsForDistDirectory.kotlinTestPath
|
||||
),
|
||||
|
||||
JsStdLib(
|
||||
"KotlinJavaScript",
|
||||
PathUtil.kotlinPathsForDistDirectory.jsStdLibJarPath
|
||||
),
|
||||
JsTest(
|
||||
"KotlinJavaScriptTest",
|
||||
PathUtil.kotlinPathsForDistDirectory.jsKotlinTestJarPath
|
||||
);
|
||||
|
||||
fun create(project: JpsProject): JpsLibrary {
|
||||
val library = project.addLibrary(id, JpsJavaLibraryType.INSTANCE)
|
||||
|
||||
for (fileRoot in roots) {
|
||||
library.addRoot(fileRoot, JpsOrderRootType.COMPILED)
|
||||
}
|
||||
|
||||
return library
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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.jps.build
|
||||
|
||||
import com.intellij.util.concurrency.FixedFuture
|
||||
import org.jetbrains.jps.builders.java.dependencyView.Callbacks
|
||||
import org.jetbrains.kotlin.incremental.isJavaFile
|
||||
import java.io.File
|
||||
import java.util.concurrent.Future
|
||||
|
||||
/**
|
||||
* Mocks Intellij Java constant search.
|
||||
* When JPS is run from Intellij, it sends find usages request to IDE (it only searches for references inside Java files).
|
||||
*
|
||||
* We rely on heuristics instead of precise usages search.
|
||||
* A Java file is considered affected if:
|
||||
* 1. It contains changed field name as a content substring.
|
||||
* 2. Its simple file name is not equal to a field's owner class simple name (to avoid recompiling field's declaration again)
|
||||
*/
|
||||
class MockJavaConstantSearch(private val workDir: File) :
|
||||
Callbacks.ConstantAffectionResolver {
|
||||
override fun request(
|
||||
ownerClassName: String,
|
||||
fieldName: String,
|
||||
accessFlags: Int,
|
||||
fieldRemoved: Boolean,
|
||||
accessChanged: Boolean
|
||||
): Future<Callbacks.ConstantAffection> {
|
||||
fun File.isAffected(): Boolean {
|
||||
if (!isJavaFile()) return false
|
||||
|
||||
if (nameWithoutExtension == ownerClassName.substringAfterLast(".")) return false
|
||||
|
||||
val code = readText()
|
||||
return code.contains(fieldName)
|
||||
}
|
||||
|
||||
|
||||
val affectedJavaFiles = workDir.walk().filter(File::isAffected).toList()
|
||||
return FixedFuture(
|
||||
Callbacks.ConstantAffection(
|
||||
affectedJavaFiles
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
+456
@@ -0,0 +1,456 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.jps.build;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class MultiplatformJpsTestWithGeneratedContentGenerated extends AbstractMultiplatformJpsTestWithGeneratedContent {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInMultiplatformMultiModule() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ignoreAndWarnAboutNative")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class IgnoreAndWarnAboutNative extends AbstractMultiplatformJpsTestWithGeneratedContent {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInIgnoreAndWarnAboutNative() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ignoreAndWarnAboutNative"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("editingCKotlin")
|
||||
public void testEditingCKotlin() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ignoreAndWarnAboutNative/editingCKotlin/");
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ignoreAndWarnAboutNative/editingCKotlin")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class EditingCKotlin extends AbstractMultiplatformJpsTestWithGeneratedContent {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInEditingCKotlin() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ignoreAndWarnAboutNative/editingCKotlin"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simple")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Simple extends AbstractMultiplatformJpsTestWithGeneratedContent {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInSimple() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simple"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("editingCKotlin")
|
||||
public void testEditingCKotlin() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simple/editingCKotlin/");
|
||||
}
|
||||
|
||||
@TestMetadata("editingPJsKotlin")
|
||||
public void testEditingPJsKotlin() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simple/editingPJsKotlin/");
|
||||
}
|
||||
|
||||
@TestMetadata("editingPJvmJava")
|
||||
public void testEditingPJvmJava() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simple/editingPJvmJava/");
|
||||
}
|
||||
|
||||
@TestMetadata("editingPJvmKotlin")
|
||||
public void testEditingPJvmKotlin() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simple/editingPJvmKotlin/");
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simple/editingCKotlin")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class EditingCKotlin extends AbstractMultiplatformJpsTestWithGeneratedContent {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInEditingCKotlin() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simple/editingCKotlin"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simple/editingPJsKotlin")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class EditingPJsKotlin extends AbstractMultiplatformJpsTestWithGeneratedContent {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInEditingPJsKotlin() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simple/editingPJsKotlin"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simple/editingPJvmJava")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class EditingPJvmJava extends AbstractMultiplatformJpsTestWithGeneratedContent {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInEditingPJvmJava() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simple/editingPJvmJava"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simple/editingPJvmKotlin")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class EditingPJvmKotlin extends AbstractMultiplatformJpsTestWithGeneratedContent {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInEditingPJvmKotlin() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simple/editingPJvmKotlin"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simpleJsJvmProjectWithTests")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class SimpleJsJvmProjectWithTests extends AbstractMultiplatformJpsTestWithGeneratedContent {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInSimpleJsJvmProjectWithTests() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simpleJsJvmProjectWithTests"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("editingCMainExpectActual")
|
||||
public void testEditingCMainExpectActual() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simpleJsJvmProjectWithTests/editingCMainExpectActual/");
|
||||
}
|
||||
|
||||
@TestMetadata("editingCTestsExpectActual")
|
||||
public void testEditingCTestsExpectActual() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simpleJsJvmProjectWithTests/editingCTestsExpectActual/");
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simpleJsJvmProjectWithTests/editingCMainExpectActual")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class EditingCMainExpectActual extends AbstractMultiplatformJpsTestWithGeneratedContent {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInEditingCMainExpectActual() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simpleJsJvmProjectWithTests/editingCMainExpectActual"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simpleJsJvmProjectWithTests/editingCTestsExpectActual")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class EditingCTestsExpectActual extends AbstractMultiplatformJpsTestWithGeneratedContent {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInEditingCTestsExpectActual() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simpleJsJvmProjectWithTests/editingCTestsExpectActual"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simpleNewMpp")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class SimpleNewMpp extends AbstractMultiplatformJpsTestWithGeneratedContent {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInSimpleNewMpp() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simpleNewMpp"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("editingCKotlin")
|
||||
public void testEditingCKotlin() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simpleNewMpp/editingCKotlin/");
|
||||
}
|
||||
|
||||
@TestMetadata("editingPJsKotlin")
|
||||
public void testEditingPJsKotlin() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simpleNewMpp/editingPJsKotlin/");
|
||||
}
|
||||
|
||||
@TestMetadata("editingPJvmJava")
|
||||
public void testEditingPJvmJava() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simpleNewMpp/editingPJvmJava/");
|
||||
}
|
||||
|
||||
@TestMetadata("editingPJvmKotlin")
|
||||
public void testEditingPJvmKotlin() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simpleNewMpp/editingPJvmKotlin/");
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simpleNewMpp/editingCKotlin")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class EditingCKotlin extends AbstractMultiplatformJpsTestWithGeneratedContent {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInEditingCKotlin() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simpleNewMpp/editingCKotlin"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simpleNewMpp/editingPJsKotlin")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class EditingPJsKotlin extends AbstractMultiplatformJpsTestWithGeneratedContent {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInEditingPJsKotlin() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simpleNewMpp/editingPJsKotlin"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simpleNewMpp/editingPJvmJava")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class EditingPJvmJava extends AbstractMultiplatformJpsTestWithGeneratedContent {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInEditingPJvmJava() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simpleNewMpp/editingPJvmJava"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simpleNewMpp/editingPJvmKotlin")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class EditingPJvmKotlin extends AbstractMultiplatformJpsTestWithGeneratedContent {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInEditingPJvmKotlin() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/simpleNewMpp/editingPJvmKotlin"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ultimate")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Ultimate extends AbstractMultiplatformJpsTestWithGeneratedContent {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInUltimate() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ultimate"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("editingACommonExpectActual")
|
||||
public void testEditingACommonExpectActual() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ultimate/editingACommonExpectActual/");
|
||||
}
|
||||
|
||||
@TestMetadata("editingAJsClientKotlin")
|
||||
public void testEditingAJsClientKotlin() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ultimate/editingAJsClientKotlin/");
|
||||
}
|
||||
|
||||
@TestMetadata("editingAJvmClientJava")
|
||||
public void testEditingAJvmClientJava() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ultimate/editingAJvmClientJava/");
|
||||
}
|
||||
|
||||
@TestMetadata("editingAJvmClientKotlin")
|
||||
public void testEditingAJvmClientKotlin() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ultimate/editingAJvmClientKotlin/");
|
||||
}
|
||||
|
||||
@TestMetadata("editingBCommonExpectActual")
|
||||
public void testEditingBCommonExpectActual() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ultimate/editingBCommonExpectActual/");
|
||||
}
|
||||
|
||||
@TestMetadata("editingRJsKotlin")
|
||||
public void testEditingRJsKotlin() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ultimate/editingRJsKotlin/");
|
||||
}
|
||||
|
||||
@TestMetadata("editingRJvmKotlin")
|
||||
public void testEditingRJvmKotlin() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ultimate/editingRJvmKotlin/");
|
||||
}
|
||||
|
||||
@TestMetadata("editingRaJsKotlin")
|
||||
public void testEditingRaJsKotlin() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ultimate/editingRaJsKotlin/");
|
||||
}
|
||||
|
||||
@TestMetadata("editingRaJvmKotlin")
|
||||
public void testEditingRaJvmKotlin() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ultimate/editingRaJvmKotlin/");
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ultimate/editingACommonExpectActual")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class EditingACommonExpectActual extends AbstractMultiplatformJpsTestWithGeneratedContent {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInEditingACommonExpectActual() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ultimate/editingACommonExpectActual"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ultimate/editingAJsClientKotlin")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class EditingAJsClientKotlin extends AbstractMultiplatformJpsTestWithGeneratedContent {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInEditingAJsClientKotlin() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ultimate/editingAJsClientKotlin"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ultimate/editingAJvmClientJava")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class EditingAJvmClientJava extends AbstractMultiplatformJpsTestWithGeneratedContent {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInEditingAJvmClientJava() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ultimate/editingAJvmClientJava"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ultimate/editingAJvmClientKotlin")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class EditingAJvmClientKotlin extends AbstractMultiplatformJpsTestWithGeneratedContent {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInEditingAJvmClientKotlin() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ultimate/editingAJvmClientKotlin"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ultimate/editingBCommonExpectActual")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class EditingBCommonExpectActual extends AbstractMultiplatformJpsTestWithGeneratedContent {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInEditingBCommonExpectActual() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ultimate/editingBCommonExpectActual"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ultimate/editingRJsKotlin")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class EditingRJsKotlin extends AbstractMultiplatformJpsTestWithGeneratedContent {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInEditingRJsKotlin() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ultimate/editingRJsKotlin"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ultimate/editingRJvmKotlin")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class EditingRJvmKotlin extends AbstractMultiplatformJpsTestWithGeneratedContent {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInEditingRJvmKotlin() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ultimate/editingRJvmKotlin"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ultimate/editingRaJsKotlin")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class EditingRaJsKotlin extends AbstractMultiplatformJpsTestWithGeneratedContent {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInEditingRaJsKotlin() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ultimate/editingRaJsKotlin"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ultimate/editingRaJvmKotlin")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class EditingRaJvmKotlin extends AbstractMultiplatformJpsTestWithGeneratedContent {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInEditingRaJvmKotlin() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/incremental/multiModule/multiplatform/withGeneratedContent/ultimate/editingRaJvmKotlin"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* 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 org.jetbrains.kotlin.jps.build
|
||||
|
||||
import org.jetbrains.jps.builders.*
|
||||
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor
|
||||
import org.jetbrains.jps.cmdline.ProjectDescriptor
|
||||
import org.jetbrains.jps.incremental.ModuleBuildTarget
|
||||
import org.jetbrains.kotlin.cli.jvm.config.JavaSourceRoot
|
||||
import org.jetbrains.kotlin.incremental.KOTLIN_CACHE_DIRECTORY_NAME
|
||||
import org.jetbrains.kotlin.incremental.testingUtils.assertEqualDirectories
|
||||
import org.jetbrains.kotlin.jps.build.fixtures.EnableICFixture
|
||||
import org.jetbrains.kotlin.jps.incremental.KotlinDataContainerTarget
|
||||
import java.io.File
|
||||
import kotlin.io.path.ExperimentalPathApi
|
||||
import kotlin.io.path.createTempDirectory
|
||||
import kotlin.reflect.KFunction1
|
||||
|
||||
class RelocatableJpsCachesTest : BaseKotlinJpsBuildTestCase() {
|
||||
private val enableICFixture = EnableICFixture()
|
||||
private lateinit var workingDir: File
|
||||
|
||||
@OptIn(ExperimentalPathApi::class)
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
enableICFixture.setUp()
|
||||
workingDir = createTempDirectory("RelocatableJpsCachesTest-" + getTestName(false)).toFile()
|
||||
}
|
||||
|
||||
override fun tearDown() {
|
||||
workingDir.deleteRecursively()
|
||||
enableICFixture.tearDown()
|
||||
super.tearDown()
|
||||
}
|
||||
|
||||
fun testRelocatableCaches() {
|
||||
buildTwiceAndCompare(RelocatableCacheTestCase::testRelocatableCaches)
|
||||
}
|
||||
|
||||
private fun buildTwiceAndCompare(testMethod: KFunction1<RelocatableCacheTestCase, Unit>) {
|
||||
val test1WorkingDir = workingDir.resolve("test1")
|
||||
val test1KotlinCachesDir = workingDir.resolve("test1KotlinCaches")
|
||||
val test2WorkingDir = workingDir.resolve("test2")
|
||||
val test2KotlinCachesDir = workingDir.resolve("test2KotlinCaches")
|
||||
|
||||
runTestAndCopyKotlinCaches(test1WorkingDir, test1KotlinCachesDir, testMethod)
|
||||
runTestAndCopyKotlinCaches(test2WorkingDir, test2KotlinCachesDir, testMethod)
|
||||
|
||||
assertEqualDirectories(test1KotlinCachesDir, test2KotlinCachesDir, forgiveExtraFiles = false)
|
||||
}
|
||||
|
||||
private fun runTestAndCopyKotlinCaches(
|
||||
projectWorkingDir: File,
|
||||
dirToCopyKotlinCaches: File,
|
||||
testMethod: KFunction1<RelocatableCacheTestCase, Unit>
|
||||
) {
|
||||
val testCase = object : RelocatableCacheTestCase(
|
||||
projectWorkingDir = projectWorkingDir,
|
||||
dirToCopyKotlinCaches = dirToCopyKotlinCaches
|
||||
) {
|
||||
override fun getName(): String = testMethod.name
|
||||
}
|
||||
testCase.exposedPrivateApi.setUp()
|
||||
|
||||
try {
|
||||
testMethod.call(testCase)
|
||||
} finally {
|
||||
testCase.exposedPrivateApi.tearDown()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// the class should not be executed directly (hence it's abstract)
|
||||
abstract class RelocatableCacheTestCase(
|
||||
private val projectWorkingDir: File,
|
||||
private val dirToCopyKotlinCaches: File
|
||||
) : KotlinJpsBuildTestBase() {
|
||||
val exposedPrivateApi = ExposedPrivateApi()
|
||||
|
||||
fun testRelocatableCaches() {
|
||||
initProject(LibraryDependency.JVM_FULL_RUNTIME)
|
||||
buildAllModules().assertSuccessful()
|
||||
|
||||
assertFilesExistInOutput(
|
||||
myProject.modules.single(),
|
||||
"MainKt.class", "Foo.class", "FooChild.class", "utils/Utils.class"
|
||||
)
|
||||
}
|
||||
|
||||
override fun copyTestDataToTmpDir(testDataDir: File): File {
|
||||
testDataDir.copyRecursively(projectWorkingDir)
|
||||
return projectWorkingDir
|
||||
}
|
||||
|
||||
override fun doBuild(descriptor: ProjectDescriptor, scopeBuilder: CompileScopeTestBuilder?): BuildResult =
|
||||
super.doBuild(descriptor, scopeBuilder).also {
|
||||
copyKotlinCaches(descriptor)
|
||||
}
|
||||
|
||||
private fun copyKotlinCaches(descriptor: ProjectDescriptor) {
|
||||
val kotlinDataPaths = HashSet<File>()
|
||||
val dataPaths = descriptor.dataManager.dataPaths
|
||||
kotlinDataPaths.add(dataPaths.getTargetDataRoot(KotlinDataContainerTarget))
|
||||
|
||||
for (target in descriptor.buildTargetIndex.allTargets) {
|
||||
if (!target.isKotlinTarget(descriptor)) continue
|
||||
|
||||
val targetDataRoot = descriptor.dataManager.dataPaths.getTargetDataRoot(target)
|
||||
val kotlinDataRoot = targetDataRoot.resolve(KOTLIN_CACHE_DIRECTORY_NAME)
|
||||
assert(kotlinDataRoot.isDirectory) { "Kotlin data root '$kotlinDataRoot' is not a directory" }
|
||||
kotlinDataPaths.add(kotlinDataRoot)
|
||||
}
|
||||
|
||||
dirToCopyKotlinCaches.deleteRecursively()
|
||||
val originalStorageRoot = descriptor.dataManager.dataPaths.dataStorageRoot
|
||||
for (kotlinCacheRoot in kotlinDataPaths) {
|
||||
val relativePath = kotlinCacheRoot.relativeTo(originalStorageRoot).path
|
||||
val targetDir = dirToCopyKotlinCaches.resolve(relativePath)
|
||||
targetDir.parentFile.mkdirs()
|
||||
kotlinCacheRoot.copyRecursively(targetDir)
|
||||
}
|
||||
}
|
||||
|
||||
private fun BuildTarget<*>.isKotlinTarget(descriptor: ProjectDescriptor): Boolean {
|
||||
fun JavaSourceRootDescriptor.containsKotlinSources() = root.walk().any { it.isKotlinSourceFile }
|
||||
|
||||
if (this !is ModuleBuildTarget) return false
|
||||
|
||||
val rootDescriptors = computeRootDescriptors(
|
||||
descriptor.model,
|
||||
descriptor.moduleExcludeIndex,
|
||||
descriptor.ignoredFileIndex,
|
||||
descriptor.dataManager.dataPaths
|
||||
)
|
||||
|
||||
return rootDescriptors.any { it is JavaSourceRootDescriptor && it.containsKotlinSources() }
|
||||
}
|
||||
|
||||
// the famous Public Morozov pattern
|
||||
inner class ExposedPrivateApi {
|
||||
fun setUp() {
|
||||
this@RelocatableCacheTestCase.setUp()
|
||||
}
|
||||
|
||||
fun tearDown() {
|
||||
this@RelocatableCacheTestCase.tearDown()
|
||||
}
|
||||
}
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.build
|
||||
|
||||
import com.intellij.util.PathUtil
|
||||
import org.jetbrains.jps.model.java.JpsJavaExtensionService
|
||||
import org.jetbrains.kotlin.cli.common.CompilerSystemProperties
|
||||
import org.jetbrains.kotlin.compilerRunner.JpsKotlinCompilerRunner
|
||||
import org.jetbrains.kotlin.daemon.common.OSKind
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import java.io.File
|
||||
|
||||
class SimpleKotlinJpsBuildTest : AbstractKotlinJpsBuildTestCase() {
|
||||
override fun setUp() {
|
||||
super.setUp()
|
||||
workDir = KotlinTestUtils.tmpDirForTest(this)
|
||||
}
|
||||
|
||||
fun testLoadingKotlinFromDifferentModules() {
|
||||
val aFile = createFile("m1/K.kt",
|
||||
"""
|
||||
package m1;
|
||||
|
||||
interface K {
|
||||
}
|
||||
""")
|
||||
createFile("m1/J.java",
|
||||
"""
|
||||
package m1;
|
||||
|
||||
public interface J {
|
||||
K bar();
|
||||
}
|
||||
""")
|
||||
val a = addModule("m1", PathUtil.getParentPath(aFile))
|
||||
|
||||
val bFile = createFile("m2/m2.kt",
|
||||
"""
|
||||
import m1.J;
|
||||
import m1.K;
|
||||
|
||||
interface M2: J {
|
||||
override fun bar(): K
|
||||
}
|
||||
""")
|
||||
val b = addModule("b", PathUtil.getParentPath(bFile))
|
||||
JpsJavaExtensionService.getInstance().getOrCreateDependencyExtension(
|
||||
b.dependenciesList.addModuleDependency(a)
|
||||
).isExported = false
|
||||
|
||||
addKotlinStdlibDependency()
|
||||
rebuildAllModules()
|
||||
}
|
||||
|
||||
// TODO: add JS tests
|
||||
fun testDaemon() {
|
||||
withDaemon {
|
||||
withSystemProperty(CompilerSystemProperties.COMPILE_DAEMON_VERBOSE_REPORT_PROPERTY.property, "true") {
|
||||
withSystemProperty(JpsKotlinCompilerRunner.FAIL_ON_FALLBACK_PROPERTY, "true") {
|
||||
testLoadingKotlinFromDifferentModules()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// copied from CompilerDaemonTest.kt
|
||||
// TODO: find shared place for this function
|
||||
// java.util.Logger used in the daemon silently forgets to log into a file specified in the config on Windows,
|
||||
// if file path is given in windows form (using backslash as a separator); the reason is unknown
|
||||
// this function makes a path with forward slashed, that works on windows too
|
||||
internal val File.loggerCompatiblePath: String
|
||||
get() =
|
||||
if (OSKind.current == OSKind.Windows) absolutePath.replace('\\', '/')
|
||||
else absolutePath
|
||||
+329
@@ -0,0 +1,329 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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.jps.build.dependeciestxt
|
||||
|
||||
import org.jetbrains.jps.model.java.JpsJavaDependencyScope
|
||||
import org.jetbrains.jps.model.module.JpsModule
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2MetadataCompilerArguments
|
||||
import org.jetbrains.kotlin.config.CompilerSettings
|
||||
import org.jetbrains.kotlin.config.KotlinFacetSettings
|
||||
import org.jetbrains.kotlin.config.KotlinModuleKind.COMPILATION_AND_SOURCE_SET_HOLDER
|
||||
import org.jetbrains.kotlin.config.KotlinModuleKind.SOURCE_SET_HOLDER
|
||||
import org.jetbrains.kotlin.jps.build.dependeciestxt.ModulesTxt.Dependency.Kind.*
|
||||
import org.jetbrains.kotlin.platform.CommonPlatforms
|
||||
import org.jetbrains.kotlin.platform.impl.FakeK2NativeCompilerArguments
|
||||
import org.jetbrains.kotlin.platform.isCommon
|
||||
import org.jetbrains.kotlin.platform.js.JsPlatforms
|
||||
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
|
||||
import org.jetbrains.kotlin.platform.jvm.isJvm
|
||||
import org.jetbrains.kotlin.platform.konan.NativePlatforms
|
||||
import java.io.File
|
||||
import kotlin.reflect.KMutableProperty1
|
||||
import kotlin.reflect.full.findAnnotation
|
||||
import kotlin.reflect.full.memberProperties
|
||||
|
||||
/**
|
||||
* Modules description file.
|
||||
* See [README.md] for more details.
|
||||
*/
|
||||
data class ModulesTxt(
|
||||
val muted: Boolean,
|
||||
val file: File,
|
||||
val fileName: String,
|
||||
val modules: List<Module>,
|
||||
val dependencies: List<Dependency>
|
||||
) {
|
||||
override fun toString() = fileName
|
||||
|
||||
data class Module(val name: String) {
|
||||
var index: Int = -1
|
||||
|
||||
val indexedName
|
||||
get() = "${index.toString().padStart(2, '0')}_$name"
|
||||
|
||||
/**
|
||||
* Facet should not be created for old tests
|
||||
*/
|
||||
var kotlinFacetSettings: KotlinFacetSettings? = null
|
||||
|
||||
val dependencies = mutableListOf<Dependency>()
|
||||
val usages = mutableListOf<Dependency>()
|
||||
|
||||
val isCommonModule
|
||||
get() =
|
||||
kotlinFacetSettings?.targetPlatform.isCommon() ||
|
||||
kotlinFacetSettings?.kind == SOURCE_SET_HOLDER
|
||||
|
||||
val isJvmModule
|
||||
get() = kotlinFacetSettings?.targetPlatform.isJvm()
|
||||
|
||||
val expectedBy
|
||||
get() = dependencies.filter {
|
||||
it.kind == EXPECTED_BY ||
|
||||
it.kind == INCLUDE
|
||||
}
|
||||
|
||||
@Flag
|
||||
var edit: Boolean = false
|
||||
|
||||
@Flag
|
||||
var editJvm: Boolean = false
|
||||
|
||||
@Flag
|
||||
var editExpectActual: Boolean = false
|
||||
|
||||
lateinit var jpsModule: JpsModule
|
||||
|
||||
companion object {
|
||||
val flags: Map<String, KMutableProperty1<Module, Boolean>> = Module::class.memberProperties
|
||||
.filter { it.findAnnotation<Flag>() != null }
|
||||
.filterIsInstance<KMutableProperty1<Module, Boolean>>()
|
||||
.associateBy { it.name }
|
||||
}
|
||||
}
|
||||
|
||||
annotation class Flag
|
||||
|
||||
data class Dependency(
|
||||
val from: Module,
|
||||
val to: Module,
|
||||
val scope: JpsJavaDependencyScope,
|
||||
val kind: Kind,
|
||||
val exported: Boolean
|
||||
) {
|
||||
val effectivelyExported
|
||||
get() = kind == EXPECTED_BY || exported
|
||||
|
||||
init {
|
||||
from.dependencies.add(this)
|
||||
to.usages.add(this)
|
||||
}
|
||||
|
||||
enum class Kind {
|
||||
DEPENDENCY,
|
||||
EXPECTED_BY,
|
||||
INCLUDE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ModulesTxtBuilder {
|
||||
var muted = false
|
||||
|
||||
val modules = mutableMapOf<String, ModuleRef>()
|
||||
private val dependencies = mutableListOf<DependencyBuilder>()
|
||||
|
||||
/**
|
||||
* Reference to module which can be defined later
|
||||
*/
|
||||
class ModuleRef(name: String) {
|
||||
var defined: Boolean = false
|
||||
var actual: ModulesTxt.Module = ModulesTxt.Module(name)
|
||||
|
||||
override fun toString() = actual.name
|
||||
|
||||
fun build(index: Int): ModulesTxt.Module {
|
||||
val result = actual
|
||||
result.index = index
|
||||
val kotlinFacetSettings = result.kotlinFacetSettings
|
||||
if (kotlinFacetSettings != null) {
|
||||
kotlinFacetSettings.implementedModuleNames =
|
||||
result.dependencies.asSequence()
|
||||
.filter { it.kind == EXPECTED_BY }
|
||||
.map { it.to.name }
|
||||
.toList()
|
||||
|
||||
kotlinFacetSettings.sourceSetNames =
|
||||
result.dependencies.asSequence()
|
||||
.filter { it.kind == INCLUDE }
|
||||
.map { it.to.name }
|
||||
.toList()
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Temporary object for resolving references to modules.
|
||||
*/
|
||||
data class DependencyBuilder(
|
||||
val from: ModuleRef,
|
||||
val to: ModuleRef,
|
||||
val scope: JpsJavaDependencyScope,
|
||||
val kind: ModulesTxt.Dependency.Kind,
|
||||
val exported: Boolean
|
||||
) {
|
||||
fun build(): ModulesTxt.Dependency {
|
||||
when (kind) {
|
||||
DEPENDENCY -> Unit
|
||||
EXPECTED_BY -> check(to.actual.isCommonModule) {
|
||||
"$this: ${to.actual} is not common module"
|
||||
}
|
||||
INCLUDE -> check(to.actual.kotlinFacetSettings?.kind == SOURCE_SET_HOLDER) {
|
||||
"$this: ${to.actual} is not source set holder"
|
||||
}
|
||||
}
|
||||
return ModulesTxt.Dependency(from.actual, to.actual, scope, kind, exported)
|
||||
}
|
||||
}
|
||||
|
||||
fun readFile(file: File, fileTitle: String = file.toString()): ModulesTxt {
|
||||
try {
|
||||
file.forEachLine { line ->
|
||||
parseDeclaration(line)
|
||||
}
|
||||
|
||||
// dependencies need to be build first: module.build() requires it
|
||||
val dependencies = dependencies.map { it.build() }
|
||||
val modules = modules.values.mapIndexed { index, moduleRef -> moduleRef.build(index) }
|
||||
|
||||
return ModulesTxt(muted, file, fileTitle, modules, dependencies)
|
||||
} catch (t: Throwable) {
|
||||
throw Error("Error while reading $file: ${t.message}", t)
|
||||
}
|
||||
}
|
||||
|
||||
private fun parseDeclaration(line: String) = doParseDeclaration(removeComments(line))
|
||||
|
||||
private fun removeComments(line: String) = line.split("//", limit = 2)[0].trim()
|
||||
|
||||
private fun doParseDeclaration(line: String) {
|
||||
when {
|
||||
line.isEmpty() -> Unit // skip empty lines
|
||||
line == "MUTED" -> {
|
||||
muted = true
|
||||
}
|
||||
line.contains("->") -> {
|
||||
val (from, rest) = line.split("->", limit = 2)
|
||||
if (rest.isBlank()) {
|
||||
// `name -> ` - module
|
||||
newModule(ValueWithFlags(from))
|
||||
} else {
|
||||
val (to, flags) = parseValueWithFlags(rest.trim())
|
||||
newDependency(from.trim(), to.trim(), flags) // `from -> to [flag1, flag2, ...]` - dependency
|
||||
}
|
||||
}
|
||||
else -> newModule(parseValueWithFlags(line)) // `name [flag1, flag2, ...]` - module
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* `value [flag1, flag2, ...]`
|
||||
*/
|
||||
private fun parseValueWithFlags(str: String): ValueWithFlags {
|
||||
val parts = str.split("[", limit = 2)
|
||||
return if (parts.size > 1) {
|
||||
val (value, flags) = parts
|
||||
ValueWithFlags(
|
||||
value = value.trim(),
|
||||
flags = flags.trim()
|
||||
.removeSuffix("]")
|
||||
.split(",")
|
||||
.map { it.trim() }
|
||||
.filter { it.isNotEmpty() }
|
||||
.toSet()
|
||||
)
|
||||
} else ValueWithFlags(str)
|
||||
}
|
||||
|
||||
data class ValueWithFlags(val value: String, val flags: Set<String> = setOf())
|
||||
|
||||
private fun moduleRef(name: String) =
|
||||
modules.getOrPut(name) { ModuleRef(name) }
|
||||
|
||||
private fun newModule(def: ValueWithFlags): ModulesTxt.Module {
|
||||
val name = def.value.trim()
|
||||
|
||||
val module = ModulesTxt.Module(name)
|
||||
val settings = KotlinFacetSettings()
|
||||
module.kotlinFacetSettings = settings
|
||||
|
||||
settings.useProjectSettings = false
|
||||
settings.compilerSettings = CompilerSettings().also {
|
||||
it.additionalArguments = "-version -Xmulti-platform"
|
||||
}
|
||||
|
||||
val moduleRef = moduleRef(name)
|
||||
check(!moduleRef.defined) { "Module `$name` already defined" }
|
||||
moduleRef.defined = true
|
||||
moduleRef.actual = module
|
||||
|
||||
def.flags.forEach { flag ->
|
||||
when (flag) {
|
||||
"sourceSetHolder" -> settings.kind = SOURCE_SET_HOLDER
|
||||
"compilationAndSourceSetHolder" -> settings.kind = COMPILATION_AND_SOURCE_SET_HOLDER
|
||||
"common" -> settings.compilerArguments =
|
||||
K2MetadataCompilerArguments().also { settings.targetPlatform = CommonPlatforms.defaultCommonPlatform }
|
||||
"jvm" -> settings.compilerArguments =
|
||||
K2JVMCompilerArguments().also { settings.targetPlatform = JvmPlatforms.defaultJvmPlatform }
|
||||
"js" -> settings.compilerArguments =
|
||||
K2JSCompilerArguments().also { settings.targetPlatform = JsPlatforms.defaultJsPlatform }
|
||||
"native" -> settings.compilerArguments =
|
||||
FakeK2NativeCompilerArguments().also { settings.targetPlatform = NativePlatforms.unspecifiedNativePlatform }
|
||||
else -> {
|
||||
val flagProperty = ModulesTxt.Module.flags[flag]
|
||||
if (flagProperty != null) flagProperty.set(module, true)
|
||||
else error("Unknown module flag `$flag`")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return module
|
||||
}
|
||||
|
||||
private fun newDependency(from: String, to: String, flags: Set<String>): DependencyBuilder? {
|
||||
if (to.isEmpty()) {
|
||||
// `x -> ` should just create undefined module `x`
|
||||
moduleRef(from)
|
||||
|
||||
check(flags.isEmpty()) {
|
||||
"`name -> [flag1, flag2, ...]` - not allowed due to the ambiguity of belonging to modules/dependencies. " +
|
||||
"Please use `x [attrs...]` syntax for module attributes."
|
||||
}
|
||||
|
||||
return null
|
||||
} else {
|
||||
var exported = false
|
||||
var scope: JpsJavaDependencyScope? = null
|
||||
var kind: ModulesTxt.Dependency.Kind = DEPENDENCY
|
||||
|
||||
fun setScope(newScope: JpsJavaDependencyScope) {
|
||||
check(scope == null) { "`$this: $from -> $to` dependency is already flagged as $scope" }
|
||||
scope = newScope
|
||||
}
|
||||
|
||||
fun setKind(newKind: ModulesTxt.Dependency.Kind) {
|
||||
check(kind == DEPENDENCY) { "`$this: $from -> $to` dependency is already flagged as $kind" }
|
||||
kind = newKind
|
||||
}
|
||||
|
||||
flags.forEach { flag ->
|
||||
when (flag) {
|
||||
"exported" -> exported = true
|
||||
"compile" -> setScope(JpsJavaDependencyScope.COMPILE)
|
||||
"test" -> setScope(JpsJavaDependencyScope.TEST)
|
||||
"runtime" -> setScope(JpsJavaDependencyScope.RUNTIME)
|
||||
"provided" -> setScope(JpsJavaDependencyScope.PROVIDED)
|
||||
"expectedBy" -> setKind(EXPECTED_BY)
|
||||
"include" -> setKind(INCLUDE)
|
||||
else -> error("Unknown dependency flag `$flag`")
|
||||
}
|
||||
}
|
||||
|
||||
return DependencyBuilder(
|
||||
from = moduleRef(from),
|
||||
to = moduleRef(to),
|
||||
scope = scope ?: JpsJavaDependencyScope.COMPILE,
|
||||
kind = kind,
|
||||
exported = exported
|
||||
).also {
|
||||
dependencies.add(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+441
@@ -0,0 +1,441 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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.jps.build.dependeciestxt
|
||||
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Utility for generating common/platform module stub contents based on it's dependencies.
|
||||
*/
|
||||
fun actualizeMppJpsIncTestCaseDirs(rootDir: String, dir: String) {
|
||||
val rootDirFile = File("$rootDir/$dir")
|
||||
check(rootDirFile.isDirectory) { "`$rootDirFile` is not a directory" }
|
||||
|
||||
rootDirFile.listFiles { it: File -> it.isDirectory }.forEach { dirFile ->
|
||||
val dependenciesTxtFile = File(dirFile, "dependencies.txt")
|
||||
if (dependenciesTxtFile.exists()) {
|
||||
val fileTitle = "$dir/${dirFile.name}/dependencies.txt"
|
||||
val dependenciesTxt = ModulesTxtBuilder().readFile(dependenciesTxtFile, fileTitle)
|
||||
|
||||
MppJpsIncTestsGenerator(dependenciesTxt) { File(dirFile, it.name) }
|
||||
.actualizeTestCasesDirs(dirFile)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
class MppJpsIncTestsGenerator(val txt: ModulesTxt, val testCaseDirProvider: (TestCase) -> File) {
|
||||
val ModulesTxt.Module.capitalName get() = name.capitalize()
|
||||
|
||||
val testCases: List<TestCase>
|
||||
|
||||
init {
|
||||
val testCases = mutableListOf<TestCase>()
|
||||
|
||||
txt.modules.forEach {
|
||||
if (it.edit)
|
||||
testCases.add(EditingTestCase(it, changeJavaClass = false))
|
||||
|
||||
if (it.editJvm && it.isJvmModule)
|
||||
testCases.add(EditingTestCase(it, changeJavaClass = true))
|
||||
|
||||
if (it.editExpectActual && it.isCommonModule)
|
||||
testCases.add(EditingExpectActualTestCase(it))
|
||||
}
|
||||
|
||||
this.testCases = testCases
|
||||
}
|
||||
|
||||
fun actualizeTestCasesDirs(rootDir: File) {
|
||||
val requiredDirs = mutableSetOf<File>()
|
||||
testCases.forEach {
|
||||
val dir = it.dir
|
||||
check(requiredDirs.add(dir)) { "TestCase dir clash $dir" }
|
||||
|
||||
if (!dir.exists()) {
|
||||
File(dir, "build.log").setFileContent("")
|
||||
}
|
||||
}
|
||||
|
||||
rootDir.listFiles().forEach {
|
||||
if (it.isDirectory && it !in requiredDirs) {
|
||||
it.deleteRecursively()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set required content for [this] [File].
|
||||
*/
|
||||
fun File.setFileContent(content: String) {
|
||||
check(!exists()) {
|
||||
"File `$this` already exists," +
|
||||
"\n\n============= contents ============\n" +
|
||||
readText() +
|
||||
"\n===================================\n" +
|
||||
"\n============ new content ==========\n" +
|
||||
content +
|
||||
"\n===================================\n"
|
||||
}
|
||||
|
||||
parentFile.mkdirs()
|
||||
writeText(content)
|
||||
}
|
||||
|
||||
data class ModuleContentSettings(
|
||||
val module: ModulesTxt.Module,
|
||||
val serviceNameSuffix: String = "",
|
||||
val generateActualDeclarationsFor: List<ModulesTxt.Module> = module.expectedBy.map { it.to },
|
||||
val generatePlatformDependent: Boolean = true,
|
||||
var generateKtFile: Boolean = true,
|
||||
var generateJavaFile: Boolean = true
|
||||
)
|
||||
|
||||
inner class EditingTestCase(val module: ModulesTxt.Module, val changeJavaClass: Boolean) : TestCase() {
|
||||
override val name: String =
|
||||
if (changeJavaClass) "editing${module.capitalName}Java"
|
||||
else "editing${module.capitalName}Kotlin"
|
||||
|
||||
override val dir: File = testCaseDirProvider(this)
|
||||
|
||||
override fun generate() {
|
||||
generateBaseContent()
|
||||
|
||||
// create new file with service implementation
|
||||
// don't create expect/actual functions (generatePlatformDependent = false)
|
||||
module.contentsSettings = ModuleContentSettings(
|
||||
module,
|
||||
serviceNameSuffix = "New",
|
||||
generatePlatformDependent = false,
|
||||
generateKtFile = !changeJavaClass,
|
||||
generateJavaFile = changeJavaClass
|
||||
)
|
||||
|
||||
when {
|
||||
module.isCommonModule -> {
|
||||
step("create new service") {
|
||||
generateCommonFile(
|
||||
module,
|
||||
fileNameSuffix = ".new.$step"
|
||||
)
|
||||
}
|
||||
|
||||
step("edit new service") {
|
||||
generateCommonFile(
|
||||
module,
|
||||
fileNameSuffix = ".touch.$step"
|
||||
)
|
||||
}
|
||||
|
||||
step("delete new service") {
|
||||
serviceKtFile(
|
||||
module,
|
||||
fileNameSuffix = ".delete.$step"
|
||||
).setFileContent("")
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
step("create new service") {
|
||||
// generateKtFile event if changeJavaClass requested (for test calling java from kotlin)
|
||||
val prevModuleContentsSettings = module.contentsSettings
|
||||
module.contentsSettings = module.contentsSettings.copy(generateKtFile = true)
|
||||
|
||||
|
||||
generatePlatformFile(
|
||||
module,
|
||||
fileNameSuffix = ".new.$step"
|
||||
)
|
||||
|
||||
module.contentsSettings = prevModuleContentsSettings
|
||||
}
|
||||
|
||||
step("edit new service") {
|
||||
generatePlatformFile(
|
||||
module,
|
||||
fileNameSuffix = ".touch.$step"
|
||||
)
|
||||
}
|
||||
|
||||
step("delete new service") {
|
||||
if (changeJavaClass) serviceJavaFile(module, fileNameSuffix = ".delete.$step").setFileContent("")
|
||||
|
||||
// kotlin file also created for testing java class
|
||||
serviceKtFile(module, fileNameSuffix = ".delete.$step").setFileContent("")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
generateStepsTxt()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inner class EditingExpectActualTestCase(val commonModule: ModulesTxt.Module) : TestCase() {
|
||||
override val name: String = "editing${commonModule.capitalName}ExpectActual"
|
||||
override val dir: File = testCaseDirProvider(this)
|
||||
|
||||
override fun generate() {
|
||||
generateBaseContent()
|
||||
check(commonModule.isCommonModule)
|
||||
val implModules = commonModule.usages
|
||||
.asSequence()
|
||||
.filter {
|
||||
it.kind == ModulesTxt.Dependency.Kind.EXPECTED_BY ||
|
||||
it.kind == ModulesTxt.Dependency.Kind.INCLUDE
|
||||
}
|
||||
.map { it.from }
|
||||
|
||||
commonModule.contentsSettings = ModuleContentSettings(commonModule, serviceNameSuffix = "New")
|
||||
implModules.forEach { implModule ->
|
||||
implModule.contentsSettings = ModuleContentSettings(
|
||||
implModule,
|
||||
serviceNameSuffix = "New",
|
||||
generateActualDeclarationsFor = listOf(commonModule)
|
||||
)
|
||||
}
|
||||
|
||||
step("create new service in ${commonModule.name}") {
|
||||
generateCommonFile(commonModule, fileNameSuffix = ".new.$step")
|
||||
}
|
||||
|
||||
implModules.forEach { implModule ->
|
||||
step("create new service in ${implModule.name}") {
|
||||
generatePlatformFile(implModule, fileNameSuffix = ".new.$step")
|
||||
}
|
||||
}
|
||||
|
||||
step("change new service in ${commonModule.name}") {
|
||||
generateCommonFile(commonModule, fileNameSuffix = ".touch.$step")
|
||||
}
|
||||
|
||||
implModules.forEach { implModule ->
|
||||
if (implModule.isJvmModule) {
|
||||
implModule.contentsSettings.generateKtFile = false
|
||||
implModule.contentsSettings.generateJavaFile = true
|
||||
step("change new service in ${implModule.name}: java") {
|
||||
generatePlatformFile(implModule, fileNameSuffix = ".touch.$step")
|
||||
}
|
||||
|
||||
implModule.contentsSettings.generateKtFile = true
|
||||
implModule.contentsSettings.generateJavaFile = false
|
||||
step("change new service in ${implModule.name}: kotlin") {
|
||||
generatePlatformFile(implModule, fileNameSuffix = ".touch.$step")
|
||||
}
|
||||
} else {
|
||||
step("change new service in ${implModule.name}") {
|
||||
generatePlatformFile(implModule, fileNameSuffix = ".touch.$step")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
implModules.forEach { implModule ->
|
||||
step("delete new service in ${implModule.name}") {
|
||||
serviceKtFile(implModule, fileNameSuffix = ".delete.$step").setFileContent("")
|
||||
}
|
||||
}
|
||||
|
||||
step("delete new service in ${commonModule.name}") {
|
||||
serviceKtFile(commonModule, fileNameSuffix = ".delete.$step").setFileContent("")
|
||||
}
|
||||
|
||||
generateStepsTxt()
|
||||
}
|
||||
}
|
||||
|
||||
abstract inner class TestCase() {
|
||||
abstract val name: String
|
||||
|
||||
abstract fun generate()
|
||||
|
||||
abstract val dir: File
|
||||
|
||||
private val modules = mutableMapOf<ModulesTxt.Module, ModuleContentSettings>()
|
||||
|
||||
var step = 1
|
||||
val steps = mutableListOf<String>()
|
||||
|
||||
protected inline fun step(name: String, body: () -> Unit) {
|
||||
body()
|
||||
steps.add(name)
|
||||
step++
|
||||
}
|
||||
|
||||
var ModulesTxt.Module.contentsSettings: ModuleContentSettings
|
||||
get() = modules.getOrPut(this) { ModuleContentSettings(this) }
|
||||
set(value) {
|
||||
modules[this] = value
|
||||
}
|
||||
|
||||
protected fun generateStepsTxt() {
|
||||
File(dir, "_steps.txt").setFileContent(steps.joinToString("\n"))
|
||||
}
|
||||
|
||||
fun generateBaseContent() {
|
||||
dir.mkdir()
|
||||
|
||||
txt.modules.forEach {
|
||||
generateModuleContents(it)
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateModuleContents(module: ModulesTxt.Module) {
|
||||
when {
|
||||
module.isCommonModule -> {
|
||||
// common module
|
||||
generateCommonFile(module)
|
||||
}
|
||||
module.expectedBy.isEmpty() -> {
|
||||
// regular module
|
||||
generatePlatformFile(module)
|
||||
}
|
||||
else -> {
|
||||
// common module platform implementation
|
||||
generatePlatformFile(module)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val ModulesTxt.Module.serviceName
|
||||
get() = "$capitalName${contentsSettings.serviceNameSuffix}"
|
||||
|
||||
private val ModulesTxt.Module.javaClassName
|
||||
get() = "${serviceName}JavaClass"
|
||||
|
||||
protected fun serviceKtFile(module: ModulesTxt.Module, fileNameSuffix: String = ""): File {
|
||||
val suffix =
|
||||
if (module.isCommonModule) "${module.serviceName}Header"
|
||||
else "${module.name.capitalize()}${module.contentsSettings.serviceNameSuffix}Impl"
|
||||
|
||||
return File(dir, "${module.indexedName}_service$suffix.kt$fileNameSuffix")
|
||||
}
|
||||
|
||||
fun serviceJavaFile(module: ModulesTxt.Module, fileNameSuffix: String = ""): File {
|
||||
return File(dir, "${module.indexedName}_${module.javaClassName}.java$fileNameSuffix")
|
||||
}
|
||||
|
||||
private val ModulesTxt.Module.platformDependentFunName: String
|
||||
get() {
|
||||
check(isCommonModule)
|
||||
return "${name}_platformDependent$serviceName"
|
||||
}
|
||||
|
||||
private val ModulesTxt.Module.platformIndependentFunName: String
|
||||
get() {
|
||||
check(isCommonModule)
|
||||
return "${name}_platformIndependent$serviceName"
|
||||
}
|
||||
|
||||
private val ModulesTxt.Module.platformOnlyFunName: String
|
||||
get() {
|
||||
// platformOnly fun names already unique, so no module name prefix required
|
||||
return "${name}_platformOnly${contentsSettings.serviceNameSuffix}"
|
||||
}
|
||||
|
||||
protected fun generateCommonFile(
|
||||
module: ModulesTxt.Module,
|
||||
fileNameSuffix: String = ""
|
||||
) {
|
||||
val settings = module.contentsSettings
|
||||
|
||||
serviceKtFile(module, fileNameSuffix).setFileContent(buildString {
|
||||
if (settings.generatePlatformDependent)
|
||||
appendLine("expect fun ${module.platformDependentFunName}(): String")
|
||||
|
||||
appendLine("fun ${module.platformIndependentFunName}() = \"common$fileNameSuffix\"")
|
||||
|
||||
appendTestFun(module, settings)
|
||||
})
|
||||
}
|
||||
|
||||
protected fun generatePlatformFile(
|
||||
module: ModulesTxt.Module,
|
||||
fileNameSuffix: String = ""
|
||||
) {
|
||||
val isJvm = module.isJvmModule
|
||||
val settings = module.contentsSettings
|
||||
|
||||
val javaClassName = module.javaClassName
|
||||
|
||||
if (settings.generateKtFile) {
|
||||
serviceKtFile(module, fileNameSuffix).setFileContent(buildString {
|
||||
if (settings.generatePlatformDependent) {
|
||||
for (expectedBy in settings.generateActualDeclarationsFor) {
|
||||
appendLine(
|
||||
"actual fun ${expectedBy.platformDependentFunName}(): String" +
|
||||
" = \"${module.name}$fileNameSuffix\""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
appendLine(
|
||||
"fun ${module.platformOnlyFunName}()" +
|
||||
" = \"${module.name}$fileNameSuffix\""
|
||||
)
|
||||
|
||||
appendTestFun(module, settings)
|
||||
})
|
||||
}
|
||||
|
||||
if (isJvm && settings.generateJavaFile) {
|
||||
serviceJavaFile(module, fileNameSuffix).setFileContent(
|
||||
"""
|
||||
|public class $javaClassName {
|
||||
| public String doStuff() {
|
||||
| return "${module.name}$fileNameSuffix";
|
||||
| }
|
||||
|}
|
||||
""".trimMargin()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// call all functions declared in this module and all of its dependencies recursively
|
||||
private fun StringBuilder.appendTestFun(
|
||||
module: ModulesTxt.Module,
|
||||
settings: ModuleContentSettings
|
||||
) {
|
||||
appendLine()
|
||||
appendLine("fun Test${module.serviceName}() {")
|
||||
|
||||
val thisAndDependencies = mutableSetOf(module)
|
||||
module.collectDependenciesRecursivelyTo(thisAndDependencies)
|
||||
thisAndDependencies.forEach { thisOrDependent ->
|
||||
if (thisOrDependent.isCommonModule) {
|
||||
appendLine(" ${thisOrDependent.platformIndependentFunName}()")
|
||||
|
||||
if (settings.generatePlatformDependent) {
|
||||
appendLine(" ${thisOrDependent.platformDependentFunName}()")
|
||||
}
|
||||
} else {
|
||||
// platform module
|
||||
appendLine(" ${thisOrDependent.platformOnlyFunName}()")
|
||||
|
||||
if (thisOrDependent.isJvmModule && thisOrDependent.contentsSettings.generateJavaFile) {
|
||||
appendLine(" ${thisOrDependent.javaClassName}().doStuff()")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
appendLine("}")
|
||||
}
|
||||
|
||||
private fun ModulesTxt.Module.collectDependenciesRecursivelyTo(
|
||||
collection: MutableCollection<ModulesTxt.Module>,
|
||||
exportedOnly: Boolean = false
|
||||
) {
|
||||
dependencies.forEach {
|
||||
if (!exportedOnly || it.effectivelyExported) {
|
||||
val dependentModule = it.to
|
||||
collection.add(dependentModule)
|
||||
dependentModule.collectDependenciesRecursivelyTo(collection, exportedOnly = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun toString() = name
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
Useful micro-language for concise description of project structure.
|
||||
Mostly like the [DOT language](https://www.graphviz.org/doc/info/attrs.html).
|
||||
|
||||
## Example
|
||||
|
||||
```
|
||||
c [common]
|
||||
p1 [jvm]
|
||||
p2 [jvm]
|
||||
|
||||
p1 -> c [expectedBy]
|
||||
p2 -> c [expectedBy]
|
||||
```
|
||||
|
||||
## Format
|
||||
|
||||
File contains declarations of modules and dependencies:
|
||||
- Module: `module_name [flag1, key1=value1, ...]`
|
||||
- Dependency: `source_module_name -> target_module_name [flag1, key1=value1, ...]`
|
||||
|
||||
Referring to undefined module is allowed (`jvm` module will be created at this case).
|
||||
This modules can be defined after reference. Several declarations for same module is not allowed.
|
||||
|
||||
Supported module flags:
|
||||
- `common` (old MPP)
|
||||
- `sourceSetHolder`, `compilationAndSourceSetHolder` (new MPP)
|
||||
- `jvm` (default)
|
||||
- `js`
|
||||
- `edit`, `editJvm`, `editExcpetActual` - see jps-plugin/testData/incremental/multiplatform/multiModule/README.md
|
||||
|
||||
Supported dependency flags:
|
||||
- `compile` (default)
|
||||
- `test`
|
||||
- `runtime`
|
||||
- `provided`
|
||||
- `expectedBy` (old MPP)
|
||||
- `included` (new MPP)
|
||||
- `exproted`
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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 org.jetbrains.kotlin.jps.build.fixtures
|
||||
|
||||
import org.jetbrains.kotlin.config.IncrementalCompilation
|
||||
|
||||
class EnableICFixture(
|
||||
private val enableJvmIC: Boolean = true,
|
||||
private val enableJsIC: Boolean = true
|
||||
) {
|
||||
private var isICEnabledBackup: Boolean = false
|
||||
private var isICEnabledForJsBackup: Boolean = false
|
||||
|
||||
fun setUp() {
|
||||
isICEnabledBackup = IncrementalCompilation.isEnabledForJvm()
|
||||
IncrementalCompilation.setIsEnabledForJvm(enableJvmIC)
|
||||
|
||||
isICEnabledForJsBackup = IncrementalCompilation.isEnabledForJs()
|
||||
IncrementalCompilation.setIsEnabledForJs(enableJsIC)
|
||||
}
|
||||
|
||||
fun tearDown() {
|
||||
IncrementalCompilation.setIsEnabledForJvm(isICEnabledBackup)
|
||||
IncrementalCompilation.setIsEnabledForJs(isICEnabledForJsBackup)
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.build
|
||||
|
||||
import org.jetbrains.kotlin.incremental.testingUtils.Modification
|
||||
|
||||
class IncrementalRenameModuleTest : AbstractIncrementalJpsTest() {
|
||||
fun testRenameModule() {
|
||||
doTest("jps-plugin/testData/incremental/custom/renameModule/")
|
||||
}
|
||||
|
||||
override fun performAdditionalModifications(modifications: List<Modification>) {
|
||||
projectDescriptor.project.modules.forEach { it.name += "Renamed" }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.build
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import org.jetbrains.kotlin.cli.common.CompilerSystemProperties
|
||||
import org.jetbrains.kotlin.compilerRunner.JpsKotlinCompilerRunner
|
||||
|
||||
inline fun withSystemProperty(property: String, newValue: String?, fn: ()->Unit) {
|
||||
val backup = System.getProperty(property)
|
||||
setOrClearSysProperty(property, newValue)
|
||||
|
||||
try {
|
||||
fn()
|
||||
}
|
||||
finally {
|
||||
setOrClearSysProperty(property, backup)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Suppress("NOTHING_TO_INLINE")
|
||||
inline fun setOrClearSysProperty(property: String, newValue: String?) {
|
||||
if (newValue != null) {
|
||||
System.setProperty(property, newValue)
|
||||
}
|
||||
else {
|
||||
System.clearProperty(property)
|
||||
}
|
||||
}
|
||||
|
||||
fun withDaemon(fn: () -> Unit) {
|
||||
val daemonHome = FileUtil.createTempDirectory("daemon-home", "testJpsDaemonIC")
|
||||
|
||||
withSystemProperty(CompilerSystemProperties.COMPILE_DAEMON_CUSTOM_RUN_FILES_PATH_FOR_TESTS.property, daemonHome.absolutePath) {
|
||||
withSystemProperty(CompilerSystemProperties.COMPILE_DAEMON_ENABLED_PROPERTY.property, "true") {
|
||||
try {
|
||||
fn()
|
||||
} finally {
|
||||
JpsKotlinCompilerRunner.shutdownDaemon()
|
||||
|
||||
// Try to force directory deletion to prevent test failure later in tearDown().
|
||||
// Working Daemon can prevent folder deletion on Windows, because Daemon shutdown
|
||||
// is asynchronous.
|
||||
var attempts = 0
|
||||
daemonHome.deleteRecursively()
|
||||
while (daemonHome.exists() && attempts < 100) {
|
||||
daemonHome.deleteRecursively()
|
||||
attempts++
|
||||
Thread.sleep(50)
|
||||
}
|
||||
|
||||
if (daemonHome.exists()) {
|
||||
error("Couldn't delete Daemon home directory")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.incremental
|
||||
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JsArgumentConstants
|
||||
import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl
|
||||
import org.jetbrains.kotlin.config.Services
|
||||
import org.jetbrains.kotlin.incremental.ProtoData
|
||||
import org.jetbrains.kotlin.incremental.getProtoData
|
||||
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer
|
||||
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumerImpl
|
||||
import org.jetbrains.kotlin.incremental.utils.TestMessageCollector
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.junit.Assert
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractJsProtoComparisonTest : AbstractProtoComparisonTest<ProtoData>() {
|
||||
override fun expectedOutputFile(testDir: File): File =
|
||||
File(testDir, "result-js.out")
|
||||
.takeIf { it.exists() }
|
||||
?: super.expectedOutputFile(testDir)
|
||||
|
||||
override fun compileAndGetClasses(sourceDir: File, outputDir: File): Map<ClassId, ProtoData> {
|
||||
val incrementalResults = IncrementalResultsConsumerImpl()
|
||||
val services = Services.Builder().run {
|
||||
register(IncrementalResultsConsumer::class.java, incrementalResults)
|
||||
build()
|
||||
}
|
||||
|
||||
val ktFiles = sourceDir.walkMatching { it.name.endsWith(".kt") }.map { it.canonicalPath }.toList()
|
||||
val messageCollector = TestMessageCollector()
|
||||
val outputItemsCollector = OutputItemsCollectorImpl()
|
||||
val args = K2JSCompilerArguments().apply {
|
||||
outputFile = File(outputDir, "out.js").canonicalPath
|
||||
metaInfo = true
|
||||
main = K2JsArgumentConstants.NO_CALL
|
||||
freeArgs = ktFiles
|
||||
}
|
||||
|
||||
val env = createTestingCompilerEnvironment(messageCollector, outputItemsCollector, services)
|
||||
runJSCompiler(args, env).let { exitCode ->
|
||||
val expectedOutput = "OK"
|
||||
val actualOutput = (listOf(exitCode?.name) + messageCollector.errors).joinToString("\n")
|
||||
Assert.assertEquals(expectedOutput, actualOutput)
|
||||
}
|
||||
|
||||
val classes = hashMapOf<ClassId, ProtoData>()
|
||||
|
||||
for ((sourceFile, translationResult) in incrementalResults.packageParts) {
|
||||
classes.putAll(getProtoData(sourceFile, translationResult.metadata))
|
||||
}
|
||||
|
||||
return classes
|
||||
}
|
||||
|
||||
override fun ProtoData.toProtoData(): ProtoData? = this
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.incremental
|
||||
|
||||
import org.jetbrains.kotlin.incremental.LocalFileKotlinClass
|
||||
import org.jetbrains.kotlin.incremental.ProtoData
|
||||
import org.jetbrains.kotlin.incremental.storage.ProtoMapValue
|
||||
import org.jetbrains.kotlin.incremental.toProtoData
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.BitEncoding
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.test.MockLibraryUtil
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractJvmProtoComparisonTest : AbstractProtoComparisonTest<LocalFileKotlinClass>() {
|
||||
override fun compileAndGetClasses(sourceDir: File, outputDir: File): Map<ClassId, LocalFileKotlinClass> {
|
||||
MockLibraryUtil.compileKotlin(sourceDir.path, outputDir, extraOptions = listOf("-Xdisable-default-scripting-plugin"))
|
||||
|
||||
val classFiles = outputDir.walkMatching { it.name.endsWith(".class") }
|
||||
val localClassFiles = classFiles.map { LocalFileKotlinClass.create(it)!! }
|
||||
return localClassFiles.associateBy { it.classId }
|
||||
}
|
||||
|
||||
override fun LocalFileKotlinClass.toProtoData(): ProtoData? {
|
||||
assert(classHeader.metadataVersion.isCompatible()) { "Incompatible class ($classHeader): $location" }
|
||||
|
||||
val bytes by lazy { BitEncoding.decodeBytes(classHeader.data!!) }
|
||||
val strings by lazy { classHeader.strings!! }
|
||||
val packageFqName = classId.packageFqName
|
||||
|
||||
return when (classHeader.kind) {
|
||||
KotlinClassHeader.Kind.CLASS -> {
|
||||
ProtoMapValue(false, bytes, strings).toProtoData(packageFqName)
|
||||
}
|
||||
KotlinClassHeader.Kind.FILE_FACADE,
|
||||
KotlinClassHeader.Kind.MULTIFILE_CLASS_PART -> {
|
||||
ProtoMapValue(true, bytes, strings).toProtoData(packageFqName)
|
||||
}
|
||||
else -> {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.incremental
|
||||
|
||||
import org.jetbrains.kotlin.TestWithWorkingDir
|
||||
import org.jetbrains.kotlin.incremental.*
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractProtoComparisonTest<PROTO_DATA> : TestWithWorkingDir() {
|
||||
protected abstract fun compileAndGetClasses(sourceDir: File, outputDir: File): Map<ClassId, PROTO_DATA>
|
||||
protected abstract fun PROTO_DATA.toProtoData(): ProtoData?
|
||||
|
||||
protected open fun expectedOutputFile(testDir: File): File =
|
||||
File(testDir, "result.out")
|
||||
|
||||
fun doTest(testDataPath: String) {
|
||||
val testDir = File(testDataPath)
|
||||
|
||||
val oldClassMap = classesForPrefixedSources(testDir, workingDir, "old")
|
||||
val newClassMap = classesForPrefixedSources(testDir, workingDir, "new")
|
||||
|
||||
val sb = StringBuilder()
|
||||
val p = Printer(sb)
|
||||
|
||||
(oldClassMap.keys - newClassMap.keys).sortedBy { it.toString() }.forEach { classId ->
|
||||
p.println("REMOVED $classId")
|
||||
}
|
||||
|
||||
(newClassMap.keys - oldClassMap.keys).sortedBy { it.toString() }.forEach { classId ->
|
||||
p.println("ADDED $classId")
|
||||
}
|
||||
|
||||
(oldClassMap.keys.intersect(newClassMap.keys)).sortedBy { it.toString() }.forEach { classId ->
|
||||
val oldData = oldClassMap[classId]!!.toProtoData()
|
||||
val newData = newClassMap[classId]!!.toProtoData()
|
||||
|
||||
if (oldData == null || newData == null) {
|
||||
p.println("SKIPPED $classId")
|
||||
return@forEach
|
||||
}
|
||||
|
||||
val rawProtoDifference = when {
|
||||
oldData is ClassProtoData && newData is ClassProtoData -> {
|
||||
ProtoCompareGenerated(
|
||||
oldNameResolver = oldData.nameResolver,
|
||||
newNameResolver = newData.nameResolver,
|
||||
oldTypeTable = oldData.proto.typeTableOrNull,
|
||||
newTypeTable = newData.proto.typeTableOrNull
|
||||
).difference(oldData.proto, newData.proto)
|
||||
}
|
||||
oldData is PackagePartProtoData && newData is PackagePartProtoData -> {
|
||||
ProtoCompareGenerated(
|
||||
oldNameResolver = oldData.nameResolver,
|
||||
newNameResolver = newData.nameResolver,
|
||||
oldTypeTable = oldData.proto.typeTableOrNull,
|
||||
newTypeTable = newData.proto.typeTableOrNull
|
||||
).difference(oldData.proto, newData.proto)
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
rawProtoDifference?.let {
|
||||
if (it.isNotEmpty()) {
|
||||
p.println("PROTO DIFFERENCE in $classId: ${it.sortedBy { it.name }.joinToString()}")
|
||||
}
|
||||
}
|
||||
|
||||
val changesInfo = ChangesCollector().apply { collectProtoChanges(oldData, newData) }.changes()
|
||||
if (changesInfo.isEmpty()) {
|
||||
return@forEach
|
||||
}
|
||||
|
||||
val changes = changesInfo.map {
|
||||
when (it) {
|
||||
is ChangeInfo.SignatureChanged -> "CLASS_SIGNATURE"
|
||||
is ChangeInfo.MembersChanged -> "MEMBERS\n ${it.names.sorted()}"
|
||||
is ChangeInfo.ParentsChanged -> "PARENTS\n ${it.parentsChanged.map { it.asString()}.sorted()}"
|
||||
|
||||
}
|
||||
}.sorted()
|
||||
|
||||
p.println("CHANGES in $classId: ${changes.joinToString()}")
|
||||
}
|
||||
|
||||
KotlinTestUtils.assertEqualsToFile(expectedOutputFile(testDir), sb.toString())
|
||||
}
|
||||
|
||||
private fun classesForPrefixedSources(testDir: File, workingDir: File, prefix: String): Map<ClassId, PROTO_DATA> {
|
||||
val srcDir = workingDir.createSubDirectory("$prefix/src")
|
||||
val outDir = workingDir.createSubDirectory("$prefix/out")
|
||||
copySourceFiles(testDir, srcDir, prefix)
|
||||
return compileAndGetClasses(srcDir, outDir)
|
||||
}
|
||||
|
||||
private fun copySourceFiles(sourceDir: File, targetDir: File, prefix: String) {
|
||||
for (srcFile in sourceDir.walkMatching { it.name.startsWith(prefix) }) {
|
||||
val targetFile = File(targetDir, srcFile.name.replaceFirst(prefix, "main"))
|
||||
srcFile.copyTo(targetFile)
|
||||
}
|
||||
}
|
||||
|
||||
protected fun File.createSubDirectory(relativePath: String): File =
|
||||
File(this, relativePath).apply { mkdirs() }
|
||||
|
||||
protected fun File.walkMatching(predicate: (File)->Boolean): Sequence<File> =
|
||||
walk().filter { predicate(it) }
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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 org.jetbrains.kotlin.jps.incremental
|
||||
|
||||
import org.jetbrains.kotlin.load.kotlin.JvmBytecodeBinaryVersion
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
class CacheVersionTest {
|
||||
@Test
|
||||
fun testConstruct() {
|
||||
assertEquals(
|
||||
3011001,
|
||||
CacheVersion(
|
||||
3,
|
||||
JvmBytecodeBinaryVersion(1, 0, 3),
|
||||
JvmMetadataVersion(1, 1, 13)
|
||||
).intValue
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDeconstruct() {
|
||||
assertEquals(
|
||||
"CacheVersion(caches: 3, bytecode: 1.0, metadata: 1.1)",
|
||||
CacheVersion(3011001).toString()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testConstructDeconstruct() {
|
||||
val version = CacheVersion(
|
||||
1,
|
||||
JvmBytecodeBinaryVersion(2, 3),
|
||||
JvmMetadataVersion(4, 5)
|
||||
)
|
||||
|
||||
assertEquals(1024305, version.intValue)
|
||||
assertEquals("CacheVersion(caches: 1, bytecode: 2.3, metadata: 4.5)", version.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testMaxValues() {
|
||||
assertEquals(
|
||||
"CacheVersion(caches: 2146, bytecode: 9.9, metadata: 9.99)",
|
||||
CacheVersion(
|
||||
2146,
|
||||
JvmBytecodeBinaryVersion(9, 9),
|
||||
JvmMetadataVersion(9, 99)
|
||||
).toString()
|
||||
)
|
||||
}
|
||||
}
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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.jps.incremental
|
||||
|
||||
import org.jetbrains.kotlin.jps.incremental.CacheStatus
|
||||
import org.jetbrains.kotlin.jps.incremental.loadDiff
|
||||
import org.junit.Test
|
||||
import java.io.File
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class CompositeLookupsCacheAttributesManagerTest {
|
||||
val manager = CompositeLookupsCacheAttributesManager(File("not-used"), setOf())
|
||||
|
||||
@Test
|
||||
fun testNothingToJava() {
|
||||
assertEquals(
|
||||
CacheStatus.INVALID,
|
||||
manager.loadDiff(
|
||||
actual = null,
|
||||
expected = CompositeLookupsCacheAttributes(1, setOf("jvm"))
|
||||
).status
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testNothingToJavaAndJs() {
|
||||
assertEquals(
|
||||
CacheStatus.INVALID,
|
||||
manager.loadDiff(
|
||||
actual = null,
|
||||
expected = CompositeLookupsCacheAttributes(1, setOf("jvm", "js"))
|
||||
).status
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testJsToJava() {
|
||||
assertEquals(
|
||||
CacheStatus.INVALID,
|
||||
manager.loadDiff(
|
||||
actual = CompositeLookupsCacheAttributes(1, setOf("jvm")),
|
||||
expected = CompositeLookupsCacheAttributes(1, setOf("js"))
|
||||
).status
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testJsAndJavaToJava() {
|
||||
assertEquals(
|
||||
CacheStatus.VALID,
|
||||
manager.loadDiff(
|
||||
actual = CompositeLookupsCacheAttributes(1, setOf("jvm", "js")),
|
||||
expected = CompositeLookupsCacheAttributes(1, setOf("jvm"))
|
||||
).status
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testJsAndJavaToJavaWithOtherVersion() {
|
||||
assertEquals(
|
||||
CacheStatus.INVALID,
|
||||
manager.loadDiff(
|
||||
actual = CompositeLookupsCacheAttributes(1, setOf("jvm", "js")),
|
||||
expected = CompositeLookupsCacheAttributes(2, setOf("jvm"))
|
||||
).status
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testJavaToJsAndJava() {
|
||||
assertEquals(
|
||||
CacheStatus.INVALID,
|
||||
manager.loadDiff(
|
||||
actual = CompositeLookupsCacheAttributes(1, setOf("jvm")),
|
||||
expected = CompositeLookupsCacheAttributes(1, setOf("jvm", "js"))
|
||||
).status
|
||||
)
|
||||
}
|
||||
}
|
||||
+711
@@ -0,0 +1,711 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.jps.incremental;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class JsProtoComparisonTestGenerated extends AbstractJsProtoComparisonTest {
|
||||
@TestMetadata("jps-plugin/testData/comparison/classSignatureChange")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassSignatureChange extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassSignatureChange() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classSignatureChange"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("classAnnotationListChanged")
|
||||
public void testClassAnnotationListChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classSignatureChange/classAnnotationListChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("classFlagsAndMembersChanged")
|
||||
public void testClassFlagsAndMembersChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classSignatureChange/classFlagsAndMembersChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("classFlagsChanged")
|
||||
public void testClassFlagsChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classSignatureChange/classFlagsChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("classTypeParameterListChanged")
|
||||
public void testClassTypeParameterListChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classSignatureChange/classTypeParameterListChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("classWithSuperTypeListChanged")
|
||||
public void testClassWithSuperTypeListChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classSignatureChange/classWithSuperTypeListChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("nestedClassSignatureChanged")
|
||||
public void testNestedClassSignatureChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classSignatureChange/nestedClassSignatureChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("sealedClassImplAdded")
|
||||
public void testSealedClassImplAdded() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classSignatureChange/sealedClassImplAdded/");
|
||||
}
|
||||
|
||||
@TestMetadata("sealedClassImplRemoved")
|
||||
public void testSealedClassImplRemoved() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classSignatureChange/sealedClassImplRemoved/");
|
||||
}
|
||||
|
||||
@TestMetadata("sealedClassNestedImplAdded")
|
||||
public void testSealedClassNestedImplAdded() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classSignatureChange/sealedClassNestedImplAdded/");
|
||||
}
|
||||
|
||||
@TestMetadata("sealedClassNestedImplAddedDeep")
|
||||
public void testSealedClassNestedImplAddedDeep() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classSignatureChange/sealedClassNestedImplAddedDeep/");
|
||||
}
|
||||
|
||||
@TestMetadata("sealedClassNestedImplRemoved")
|
||||
public void testSealedClassNestedImplRemoved() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classSignatureChange/sealedClassNestedImplRemoved/");
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classSignatureChange/classAnnotationListChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassAnnotationListChanged extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassAnnotationListChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classSignatureChange/classAnnotationListChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classSignatureChange/classFlagsAndMembersChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassFlagsAndMembersChanged extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassFlagsAndMembersChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classSignatureChange/classFlagsAndMembersChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classSignatureChange/classFlagsChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassFlagsChanged extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassFlagsChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classSignatureChange/classFlagsChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classSignatureChange/classTypeParameterListChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassTypeParameterListChanged extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassTypeParameterListChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classSignatureChange/classTypeParameterListChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classSignatureChange/classWithSuperTypeListChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassWithSuperTypeListChanged extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassWithSuperTypeListChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classSignatureChange/classWithSuperTypeListChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classSignatureChange/nestedClassSignatureChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class NestedClassSignatureChanged extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInNestedClassSignatureChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classSignatureChange/nestedClassSignatureChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classSignatureChange/sealedClassImplAdded")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class SealedClassImplAdded extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInSealedClassImplAdded() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classSignatureChange/sealedClassImplAdded"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classSignatureChange/sealedClassImplRemoved")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class SealedClassImplRemoved extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInSealedClassImplRemoved() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classSignatureChange/sealedClassImplRemoved"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classSignatureChange/sealedClassNestedImplAdded")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class SealedClassNestedImplAdded extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInSealedClassNestedImplAdded() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classSignatureChange/sealedClassNestedImplAdded"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classSignatureChange/sealedClassNestedImplAddedDeep")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class SealedClassNestedImplAddedDeep extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInSealedClassNestedImplAddedDeep() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classSignatureChange/sealedClassNestedImplAddedDeep"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classSignatureChange/sealedClassNestedImplRemoved")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class SealedClassNestedImplRemoved extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInSealedClassNestedImplRemoved() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classSignatureChange/sealedClassNestedImplRemoved"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classPrivateOnlyChange")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassPrivateOnlyChange extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassPrivateOnlyChange() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classPrivateOnlyChange"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("classWithPrivateFunChanged")
|
||||
public void testClassWithPrivateFunChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivateFunChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("classWithPrivatePrimaryConstructorChanged")
|
||||
public void testClassWithPrivatePrimaryConstructorChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivatePrimaryConstructorChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("classWithPrivateSecondaryConstructorChanged")
|
||||
public void testClassWithPrivateSecondaryConstructorChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivateSecondaryConstructorChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("classWithPrivateValChanged")
|
||||
public void testClassWithPrivateValChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivateValChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("classWithPrivateVarChanged")
|
||||
public void testClassWithPrivateVarChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivateVarChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivateFunChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassWithPrivateFunChanged extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassWithPrivateFunChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivateFunChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivatePrimaryConstructorChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassWithPrivatePrimaryConstructorChanged extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassWithPrivatePrimaryConstructorChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivatePrimaryConstructorChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivateSecondaryConstructorChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassWithPrivateSecondaryConstructorChanged extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassWithPrivateSecondaryConstructorChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivateSecondaryConstructorChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivateValChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassWithPrivateValChanged extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassWithPrivateValChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivateValChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivateVarChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassWithPrivateVarChanged extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassWithPrivateVarChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivateVarChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassMembersOnlyChanged extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassMembersOnlyChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classMembersOnlyChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("classWithCompanionObjectChanged")
|
||||
public void testClassWithCompanionObjectChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classMembersOnlyChanged/classWithCompanionObjectChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("classWithConstructorChanged")
|
||||
public void testClassWithConstructorChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classMembersOnlyChanged/classWithConstructorChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("classWithFunAndValChanged")
|
||||
public void testClassWithFunAndValChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classMembersOnlyChanged/classWithFunAndValChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("classWithNestedClassesChanged")
|
||||
public void testClassWithNestedClassesChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classMembersOnlyChanged/classWithNestedClassesChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("classWitnEnumChanged")
|
||||
public void testClassWitnEnumChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classMembersOnlyChanged/classWitnEnumChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("defaultValues")
|
||||
public void testDefaultValues() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classMembersOnlyChanged/defaultValues/");
|
||||
}
|
||||
|
||||
@TestMetadata("membersAnnotationListChanged")
|
||||
public void testMembersAnnotationListChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classMembersOnlyChanged/membersAnnotationListChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("membersFlagsChanged")
|
||||
public void testMembersFlagsChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classMembersOnlyChanged/membersFlagsChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("nestedClassMembersChanged")
|
||||
public void testNestedClassMembersChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classMembersOnlyChanged/nestedClassMembersChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("sealedClassImplAdded")
|
||||
public void testSealedClassImplAdded() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classMembersOnlyChanged/sealedClassImplAdded/");
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/classWithCompanionObjectChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassWithCompanionObjectChanged extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassWithCompanionObjectChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classMembersOnlyChanged/classWithCompanionObjectChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/classWithConstructorChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassWithConstructorChanged extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassWithConstructorChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classMembersOnlyChanged/classWithConstructorChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/classWithFunAndValChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassWithFunAndValChanged extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassWithFunAndValChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classMembersOnlyChanged/classWithFunAndValChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/classWithNestedClassesChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassWithNestedClassesChanged extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassWithNestedClassesChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classMembersOnlyChanged/classWithNestedClassesChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/classWitnEnumChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassWitnEnumChanged extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassWitnEnumChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classMembersOnlyChanged/classWitnEnumChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/defaultValues")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class DefaultValues extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInDefaultValues() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classMembersOnlyChanged/defaultValues"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/membersAnnotationListChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class MembersAnnotationListChanged extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInMembersAnnotationListChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classMembersOnlyChanged/membersAnnotationListChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/membersFlagsChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class MembersFlagsChanged extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInMembersFlagsChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classMembersOnlyChanged/membersFlagsChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/nestedClassMembersChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class NestedClassMembersChanged extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInNestedClassMembersChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classMembersOnlyChanged/nestedClassMembersChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/sealedClassImplAdded")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class SealedClassImplAdded extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInSealedClassImplAdded() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classMembersOnlyChanged/sealedClassImplAdded"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/packageMembers")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class PackageMembers extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInPackageMembers() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/packageMembers"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("defaultValues")
|
||||
public void testDefaultValues() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/packageMembers/defaultValues/");
|
||||
}
|
||||
|
||||
@TestMetadata("membersAnnotationListChanged")
|
||||
public void testMembersAnnotationListChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/packageMembers/membersAnnotationListChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("membersFlagsChanged")
|
||||
public void testMembersFlagsChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/packageMembers/membersFlagsChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("packageFacadePrivateOnlyChanges")
|
||||
public void testPackageFacadePrivateOnlyChanges() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/packageMembers/packageFacadePrivateOnlyChanges/");
|
||||
}
|
||||
|
||||
@TestMetadata("packageFacadePublicChanges")
|
||||
public void testPackageFacadePublicChanges() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/packageMembers/packageFacadePublicChanges/");
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/packageMembers/defaultValues")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class DefaultValues extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInDefaultValues() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/packageMembers/defaultValues"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/packageMembers/membersAnnotationListChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class MembersAnnotationListChanged extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInMembersAnnotationListChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/packageMembers/membersAnnotationListChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/packageMembers/membersFlagsChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class MembersFlagsChanged extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInMembersFlagsChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/packageMembers/membersFlagsChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/packageMembers/packageFacadePrivateOnlyChanges")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class PackageFacadePrivateOnlyChanges extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInPackageFacadePrivateOnlyChanges() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/packageMembers/packageFacadePrivateOnlyChanges"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/packageMembers/packageFacadePublicChanges")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class PackageFacadePublicChanges extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInPackageFacadePublicChanges() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/packageMembers/packageFacadePublicChanges"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/unchanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Unchanged extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInUnchanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/unchanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("unchangedClass")
|
||||
public void testUnchangedClass() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/unchanged/unchangedClass/");
|
||||
}
|
||||
|
||||
@TestMetadata("unchangedPackageFacade")
|
||||
public void testUnchangedPackageFacade() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/unchanged/unchangedPackageFacade/");
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/unchanged/unchangedClass")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class UnchangedClass extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInUnchangedClass() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/unchanged/unchangedClass"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/unchanged/unchangedPackageFacade")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class UnchangedPackageFacade extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInUnchangedPackageFacade() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/unchanged/unchangedPackageFacade"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/jsOnly")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class JsOnly extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInJsOnly() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/jsOnly"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("externals")
|
||||
public void testExternals() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/jsOnly/externals/");
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/jsOnly/externals")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Externals extends AbstractJsProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInExternals() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/jsOnly/externals"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+765
@@ -0,0 +1,765 @@
|
||||
/*
|
||||
* Copyright 2010-2021 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.jps.incremental;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class JvmProtoComparisonTestGenerated extends AbstractJvmProtoComparisonTest {
|
||||
@TestMetadata("jps-plugin/testData/comparison/classSignatureChange")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassSignatureChange extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassSignatureChange() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classSignatureChange"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("classAnnotationListChanged")
|
||||
public void testClassAnnotationListChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classSignatureChange/classAnnotationListChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("classFlagsAndMembersChanged")
|
||||
public void testClassFlagsAndMembersChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classSignatureChange/classFlagsAndMembersChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("classFlagsChanged")
|
||||
public void testClassFlagsChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classSignatureChange/classFlagsChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("classTypeParameterListChanged")
|
||||
public void testClassTypeParameterListChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classSignatureChange/classTypeParameterListChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("classWithSuperTypeListChanged")
|
||||
public void testClassWithSuperTypeListChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classSignatureChange/classWithSuperTypeListChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("nestedClassSignatureChanged")
|
||||
public void testNestedClassSignatureChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classSignatureChange/nestedClassSignatureChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("sealedClassImplAdded")
|
||||
public void testSealedClassImplAdded() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classSignatureChange/sealedClassImplAdded/");
|
||||
}
|
||||
|
||||
@TestMetadata("sealedClassImplRemoved")
|
||||
public void testSealedClassImplRemoved() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classSignatureChange/sealedClassImplRemoved/");
|
||||
}
|
||||
|
||||
@TestMetadata("sealedClassNestedImplAdded")
|
||||
public void testSealedClassNestedImplAdded() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classSignatureChange/sealedClassNestedImplAdded/");
|
||||
}
|
||||
|
||||
@TestMetadata("sealedClassNestedImplAddedDeep")
|
||||
public void testSealedClassNestedImplAddedDeep() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classSignatureChange/sealedClassNestedImplAddedDeep/");
|
||||
}
|
||||
|
||||
@TestMetadata("sealedClassNestedImplRemoved")
|
||||
public void testSealedClassNestedImplRemoved() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classSignatureChange/sealedClassNestedImplRemoved/");
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classSignatureChange/classAnnotationListChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassAnnotationListChanged extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassAnnotationListChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classSignatureChange/classAnnotationListChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classSignatureChange/classFlagsAndMembersChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassFlagsAndMembersChanged extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassFlagsAndMembersChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classSignatureChange/classFlagsAndMembersChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classSignatureChange/classFlagsChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassFlagsChanged extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassFlagsChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classSignatureChange/classFlagsChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classSignatureChange/classTypeParameterListChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassTypeParameterListChanged extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassTypeParameterListChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classSignatureChange/classTypeParameterListChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classSignatureChange/classWithSuperTypeListChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassWithSuperTypeListChanged extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassWithSuperTypeListChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classSignatureChange/classWithSuperTypeListChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classSignatureChange/nestedClassSignatureChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class NestedClassSignatureChanged extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInNestedClassSignatureChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classSignatureChange/nestedClassSignatureChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classSignatureChange/sealedClassImplAdded")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class SealedClassImplAdded extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInSealedClassImplAdded() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classSignatureChange/sealedClassImplAdded"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classSignatureChange/sealedClassImplRemoved")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class SealedClassImplRemoved extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInSealedClassImplRemoved() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classSignatureChange/sealedClassImplRemoved"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classSignatureChange/sealedClassNestedImplAdded")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class SealedClassNestedImplAdded extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInSealedClassNestedImplAdded() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classSignatureChange/sealedClassNestedImplAdded"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classSignatureChange/sealedClassNestedImplAddedDeep")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class SealedClassNestedImplAddedDeep extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInSealedClassNestedImplAddedDeep() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classSignatureChange/sealedClassNestedImplAddedDeep"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classSignatureChange/sealedClassNestedImplRemoved")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class SealedClassNestedImplRemoved extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInSealedClassNestedImplRemoved() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classSignatureChange/sealedClassNestedImplRemoved"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classPrivateOnlyChange")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassPrivateOnlyChange extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassPrivateOnlyChange() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classPrivateOnlyChange"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("classWithPrivateFunChanged")
|
||||
public void testClassWithPrivateFunChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivateFunChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("classWithPrivatePrimaryConstructorChanged")
|
||||
public void testClassWithPrivatePrimaryConstructorChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivatePrimaryConstructorChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("classWithPrivateSecondaryConstructorChanged")
|
||||
public void testClassWithPrivateSecondaryConstructorChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivateSecondaryConstructorChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("classWithPrivateValChanged")
|
||||
public void testClassWithPrivateValChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivateValChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("classWithPrivateVarChanged")
|
||||
public void testClassWithPrivateVarChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivateVarChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivateFunChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassWithPrivateFunChanged extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassWithPrivateFunChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivateFunChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivatePrimaryConstructorChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassWithPrivatePrimaryConstructorChanged extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassWithPrivatePrimaryConstructorChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivatePrimaryConstructorChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivateSecondaryConstructorChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassWithPrivateSecondaryConstructorChanged extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassWithPrivateSecondaryConstructorChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivateSecondaryConstructorChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivateValChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassWithPrivateValChanged extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassWithPrivateValChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivateValChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivateVarChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassWithPrivateVarChanged extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassWithPrivateVarChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classPrivateOnlyChange/classWithPrivateVarChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassMembersOnlyChanged extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassMembersOnlyChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classMembersOnlyChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("classWithCompanionObjectChanged")
|
||||
public void testClassWithCompanionObjectChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classMembersOnlyChanged/classWithCompanionObjectChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("classWithConstructorChanged")
|
||||
public void testClassWithConstructorChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classMembersOnlyChanged/classWithConstructorChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("classWithFunAndValChanged")
|
||||
public void testClassWithFunAndValChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classMembersOnlyChanged/classWithFunAndValChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("classWithNestedClassesChanged")
|
||||
public void testClassWithNestedClassesChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classMembersOnlyChanged/classWithNestedClassesChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("classWitnEnumChanged")
|
||||
public void testClassWitnEnumChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classMembersOnlyChanged/classWitnEnumChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("defaultValues")
|
||||
public void testDefaultValues() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classMembersOnlyChanged/defaultValues/");
|
||||
}
|
||||
|
||||
@TestMetadata("membersAnnotationListChanged")
|
||||
public void testMembersAnnotationListChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classMembersOnlyChanged/membersAnnotationListChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("membersFlagsChanged")
|
||||
public void testMembersFlagsChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classMembersOnlyChanged/membersFlagsChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("nestedClassMembersChanged")
|
||||
public void testNestedClassMembersChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classMembersOnlyChanged/nestedClassMembersChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("sealedClassImplAdded")
|
||||
public void testSealedClassImplAdded() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/classMembersOnlyChanged/sealedClassImplAdded/");
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/classWithCompanionObjectChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassWithCompanionObjectChanged extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassWithCompanionObjectChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classMembersOnlyChanged/classWithCompanionObjectChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/classWithConstructorChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassWithConstructorChanged extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassWithConstructorChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classMembersOnlyChanged/classWithConstructorChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/classWithFunAndValChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassWithFunAndValChanged extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassWithFunAndValChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classMembersOnlyChanged/classWithFunAndValChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/classWithNestedClassesChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassWithNestedClassesChanged extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassWithNestedClassesChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classMembersOnlyChanged/classWithNestedClassesChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/classWitnEnumChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassWitnEnumChanged extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassWitnEnumChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classMembersOnlyChanged/classWitnEnumChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/defaultValues")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class DefaultValues extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInDefaultValues() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classMembersOnlyChanged/defaultValues"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/membersAnnotationListChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class MembersAnnotationListChanged extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInMembersAnnotationListChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classMembersOnlyChanged/membersAnnotationListChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/membersFlagsChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class MembersFlagsChanged extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInMembersFlagsChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classMembersOnlyChanged/membersFlagsChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/nestedClassMembersChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class NestedClassMembersChanged extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInNestedClassMembersChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classMembersOnlyChanged/nestedClassMembersChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/classMembersOnlyChanged/sealedClassImplAdded")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class SealedClassImplAdded extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInSealedClassImplAdded() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/classMembersOnlyChanged/sealedClassImplAdded"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/packageMembers")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class PackageMembers extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInPackageMembers() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/packageMembers"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("defaultValues")
|
||||
public void testDefaultValues() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/packageMembers/defaultValues/");
|
||||
}
|
||||
|
||||
@TestMetadata("membersAnnotationListChanged")
|
||||
public void testMembersAnnotationListChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/packageMembers/membersAnnotationListChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("membersFlagsChanged")
|
||||
public void testMembersFlagsChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/packageMembers/membersFlagsChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("packageFacadePrivateOnlyChanges")
|
||||
public void testPackageFacadePrivateOnlyChanges() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/packageMembers/packageFacadePrivateOnlyChanges/");
|
||||
}
|
||||
|
||||
@TestMetadata("packageFacadePublicChanges")
|
||||
public void testPackageFacadePublicChanges() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/packageMembers/packageFacadePublicChanges/");
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/packageMembers/defaultValues")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class DefaultValues extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInDefaultValues() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/packageMembers/defaultValues"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/packageMembers/membersAnnotationListChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class MembersAnnotationListChanged extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInMembersAnnotationListChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/packageMembers/membersAnnotationListChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/packageMembers/membersFlagsChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class MembersFlagsChanged extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInMembersFlagsChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/packageMembers/membersFlagsChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/packageMembers/packageFacadePrivateOnlyChanges")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class PackageFacadePrivateOnlyChanges extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInPackageFacadePrivateOnlyChanges() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/packageMembers/packageFacadePrivateOnlyChanges"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/packageMembers/packageFacadePublicChanges")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class PackageFacadePublicChanges extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInPackageFacadePublicChanges() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/packageMembers/packageFacadePublicChanges"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/unchanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class Unchanged extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInUnchanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/unchanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("unchangedClass")
|
||||
public void testUnchangedClass() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/unchanged/unchangedClass/");
|
||||
}
|
||||
|
||||
@TestMetadata("unchangedPackageFacade")
|
||||
public void testUnchangedPackageFacade() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/unchanged/unchangedPackageFacade/");
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/unchanged/unchangedClass")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class UnchangedClass extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInUnchangedClass() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/unchanged/unchangedClass"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/unchanged/unchangedPackageFacade")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class UnchangedPackageFacade extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInUnchangedPackageFacade() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/unchanged/unchangedPackageFacade"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/jvmOnly")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class JvmOnly extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInJvmOnly() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/jvmOnly"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("classToFileFacade")
|
||||
public void testClassToFileFacade() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/jvmOnly/classToFileFacade/");
|
||||
}
|
||||
|
||||
@TestMetadata("membersFlagsChanged")
|
||||
public void testMembersFlagsChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/jvmOnly/membersFlagsChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("packageFacadeMultifileClassChanged")
|
||||
public void testPackageFacadeMultifileClassChanged() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/jvmOnly/packageFacadeMultifileClassChanged/");
|
||||
}
|
||||
|
||||
@TestMetadata("packageFacadeToClass")
|
||||
public void testPackageFacadeToClass() throws Exception {
|
||||
runTest("jps-plugin/testData/comparison/jvmOnly/packageFacadeToClass/");
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/jvmOnly/classToFileFacade")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class ClassToFileFacade extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInClassToFileFacade() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/jvmOnly/classToFileFacade"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/jvmOnly/membersFlagsChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class MembersFlagsChanged extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInMembersFlagsChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/jvmOnly/membersFlagsChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/jvmOnly/packageFacadeMultifileClassChanged")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class PackageFacadeMultifileClassChanged extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInPackageFacadeMultifileClassChanged() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/jvmOnly/packageFacadeMultifileClassChanged"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/comparison/jvmOnly/packageFacadeToClass")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class PackageFacadeToClass extends AbstractJvmProtoComparisonTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInPackageFacadeToClass() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("jps-plugin/testData/comparison/jvmOnly/packageFacadeToClass"), Pattern.compile("^([^\\.]+)$"), null, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.incremental
|
||||
|
||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.cli.js.K2JSCompiler
|
||||
import org.jetbrains.kotlin.compilerRunner.*
|
||||
import org.jetbrains.kotlin.config.Services
|
||||
import org.jetbrains.kotlin.jps.build.KotlinBuilder
|
||||
import org.jetbrains.kotlin.utils.PathUtil
|
||||
import java.io.*
|
||||
|
||||
fun createTestingCompilerEnvironment(
|
||||
messageCollector: MessageCollector,
|
||||
outputItemsCollector: OutputItemsCollectorImpl,
|
||||
services: Services
|
||||
): JpsCompilerEnvironment {
|
||||
val paths = PathUtil.kotlinPathsForDistDirectory
|
||||
|
||||
val wrappedMessageCollector = MessageCollectorToOutputItemsCollectorAdapter(messageCollector, outputItemsCollector)
|
||||
return JpsCompilerEnvironment(
|
||||
paths,
|
||||
services,
|
||||
KotlinBuilder.classesToLoadByParent,
|
||||
wrappedMessageCollector,
|
||||
outputItemsCollector,
|
||||
MockProgressReporter
|
||||
)
|
||||
}
|
||||
|
||||
fun runJSCompiler(args: K2JSCompilerArguments, env: JpsCompilerEnvironment): ExitCode? {
|
||||
val argsArray = ArgumentUtils.convertArgumentsToStringList(args).toTypedArray()
|
||||
|
||||
val stream = ByteArrayOutputStream()
|
||||
val out = PrintStream(stream)
|
||||
val exitCode = CompilerRunnerUtil.invokeExecMethod(K2JSCompiler::class.java.name, argsArray, env, out)
|
||||
val reader = BufferedReader(StringReader(stream.toString()))
|
||||
CompilerOutputParser.parseCompilerMessagesFromReader(env.messageCollector, reader, env.outputItemsCollector)
|
||||
return exitCode as? ExitCode
|
||||
}
|
||||
|
||||
private object MockProgressReporter : ProgressReporter {
|
||||
override fun progress(message: String) {
|
||||
}
|
||||
|
||||
override fun compilationStarted() {
|
||||
}
|
||||
|
||||
override fun clearProgress() {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jvm.compiler
|
||||
|
||||
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType
|
||||
import org.jetbrains.kotlin.build.JvmSourceRoot
|
||||
import org.jetbrains.kotlin.modules.KotlinModuleXmlBuilder
|
||||
import org.jetbrains.kotlin.test.MockLibraryUtil
|
||||
import org.jetbrains.kotlin.test.TestCaseWithTmpdir
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil
|
||||
import org.jetbrains.kotlin.utils.PathUtil
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* This test checks that Java classes from sources have higher priority in Kotlin resolution process than classes from binaries.
|
||||
* To test this, we compile a Kotlin+Java module (in two modes: CLI and module-based) where a runtime Java class was replaced
|
||||
* with a "newer" version in sources, and check that this class resolves to the one from sources by calling a method absent in the runtime
|
||||
*/
|
||||
class ClasspathOrderTest : TestCaseWithTmpdir() {
|
||||
companion object {
|
||||
private val sourceDir = File(KtTestUtil.getTestDataPathBase() + "/classpathOrder").absoluteFile
|
||||
}
|
||||
|
||||
fun testClasspathOrderForCLI() {
|
||||
MockLibraryUtil.compileKotlin(sourceDir.path, tmpdir)
|
||||
}
|
||||
|
||||
fun testClasspathOrderForModuleScriptBuild() {
|
||||
val xmlContent = KotlinModuleXmlBuilder().addModule(
|
||||
"name",
|
||||
File(tmpdir, "output").absolutePath,
|
||||
listOf(sourceDir),
|
||||
listOf(JvmSourceRoot(sourceDir)),
|
||||
listOf(PathUtil.kotlinPathsForDistDirectory.stdlibPath),
|
||||
emptyList(),
|
||||
null,
|
||||
JavaModuleBuildTargetType.PRODUCTION.typeId,
|
||||
JavaModuleBuildTargetType.PRODUCTION.isTests,
|
||||
setOf(),
|
||||
emptyList()
|
||||
).asText().toString()
|
||||
|
||||
val xml = File(tmpdir, "module.xml")
|
||||
xml.writeText(xmlContent)
|
||||
|
||||
MockLibraryUtil.compileKotlinModule(xml.absolutePath)
|
||||
}
|
||||
}
|
||||
+111
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.modules;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType;
|
||||
import org.jetbrains.kotlin.build.JvmSourceRoot;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
|
||||
public class KotlinModuleXmlGeneratorTest extends TestCase {
|
||||
public void testBasic() throws Exception {
|
||||
String actual = new KotlinModuleXmlBuilder().addModule(
|
||||
"name",
|
||||
"output",
|
||||
Arrays.asList(new File("s1"), new File("s2")),
|
||||
Collections.singletonList(new JvmSourceRoot(new File("java"), null)),
|
||||
Arrays.asList(new File("cp1"), new File("cp2")),
|
||||
Collections.emptyList(),
|
||||
null,
|
||||
JavaModuleBuildTargetType.PRODUCTION.getTypeId(),
|
||||
JavaModuleBuildTargetType.PRODUCTION.isTests(),
|
||||
Collections.emptySet(),
|
||||
Collections.emptyList()
|
||||
).asText().toString();
|
||||
KotlinTestUtils.assertEqualsToFile(new File("idea/testData/modules.xml/basic.xml"), actual);
|
||||
}
|
||||
|
||||
public void testFiltered() throws Exception {
|
||||
String actual = new KotlinModuleXmlBuilder().addModule(
|
||||
"name",
|
||||
"output",
|
||||
Arrays.asList(new File("s1"), new File("s2")),
|
||||
Collections.emptyList(),
|
||||
Arrays.asList(new File("cp1"), new File("cp2")),
|
||||
Collections.emptyList(),
|
||||
null,
|
||||
JavaModuleBuildTargetType.PRODUCTION.getTypeId(),
|
||||
JavaModuleBuildTargetType.PRODUCTION.isTests(),
|
||||
Collections.singleton(new File("cp1")),
|
||||
Collections.emptyList()
|
||||
).asText().toString();
|
||||
KotlinTestUtils.assertEqualsToFile(new File("idea/testData/modules.xml/filtered.xml"), actual);
|
||||
}
|
||||
|
||||
public void testMultiple() throws Exception {
|
||||
KotlinModuleXmlBuilder builder = new KotlinModuleXmlBuilder();
|
||||
builder.addModule(
|
||||
"name",
|
||||
"output",
|
||||
Arrays.asList(new File("s1"), new File("s2")),
|
||||
Collections.emptyList(),
|
||||
Arrays.asList(new File("cp1"), new File("cp2")),
|
||||
Collections.emptyList(),
|
||||
null,
|
||||
JavaModuleBuildTargetType.PRODUCTION.getTypeId(),
|
||||
JavaModuleBuildTargetType.PRODUCTION.isTests(),
|
||||
Collections.singleton(new File("cp1")),
|
||||
Collections.emptyList()
|
||||
);
|
||||
builder.addModule(
|
||||
"name2",
|
||||
"output2",
|
||||
Arrays.asList(new File("s12"), new File("s22")),
|
||||
Collections.emptyList(),
|
||||
Arrays.asList(new File("cp12"), new File("cp22")),
|
||||
Collections.emptyList(),
|
||||
null,
|
||||
JavaModuleBuildTargetType.TEST.getTypeId(),
|
||||
JavaModuleBuildTargetType.TEST.isTests(),
|
||||
Collections.singleton(new File("cp12")),
|
||||
Collections.emptyList()
|
||||
);
|
||||
String actual = builder.asText().toString();
|
||||
KotlinTestUtils.assertEqualsToFile(new File("idea/testData/modules.xml/multiple.xml"), actual);
|
||||
}
|
||||
|
||||
public void testModularJdkRoot() throws Exception {
|
||||
String actual = new KotlinModuleXmlBuilder().addModule(
|
||||
"name",
|
||||
"output",
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList(),
|
||||
Collections.emptyList(),
|
||||
new File("/path/to/modular/jdk"),
|
||||
JavaModuleBuildTargetType.PRODUCTION.getTypeId(),
|
||||
JavaModuleBuildTargetType.PRODUCTION.isTests(),
|
||||
Collections.emptySet(),
|
||||
Collections.emptyList()
|
||||
).asText().toString();
|
||||
KotlinTestUtils.assertEqualsToFile(new File("idea/testData/modules.xml/modularJdkRoot.xml"), actual);
|
||||
}
|
||||
}
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.build.kannotator;
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.builders.BuildResult;
|
||||
import org.jetbrains.jps.model.module.JpsModule;
|
||||
import org.jetbrains.jps.model.module.JpsModuleSourceRoot;
|
||||
import org.jetbrains.kotlin.incremental.testingUtils.ClassFilesComparisonKt;
|
||||
import org.jetbrains.kotlin.jps.build.AbstractKotlinJpsBuildTestCase;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class KannotatorJpsTest extends AbstractKotlinJpsBuildTestCase {
|
||||
private static final String JDK_NAME = "1.6";
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
File sourceFilesRoot = new File(TEST_DATA_PATH + File.separator + "kannotator");
|
||||
workDir = copyTestDataToTmpDir(sourceFilesRoot);
|
||||
}
|
||||
|
||||
public void testMakeKannotator() throws IOException {
|
||||
initProject();
|
||||
rebuildAllModules();
|
||||
FileUtil.copyDir(getOutDir(), getOutDirAfterRebuild());
|
||||
for (JpsModule module : myProject.getModules()) {
|
||||
for (JpsModuleSourceRoot sourceRoot : module.getSourceRoots()) {
|
||||
processFile(sourceRoot.getFile());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private File getOutDir() {
|
||||
return new File(workDir, "out");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private File getOutDirAfterRebuild() {
|
||||
return new File(workDir, "out-after-rebuild");
|
||||
}
|
||||
|
||||
private void processFile(File root) {
|
||||
if (root.isDirectory()) {
|
||||
File[] files = root.listFiles();
|
||||
if (files == null) return;
|
||||
for (File file : files) {
|
||||
processFile(file);
|
||||
}
|
||||
}
|
||||
else if (root.getName().endsWith(".kt")) {
|
||||
System.out.println("Test started. File: " + root.getName());
|
||||
String path = root.getAbsolutePath();
|
||||
System.out.println("Change file: " + path);
|
||||
change(path);
|
||||
buildAllModules().assertSuccessful();
|
||||
System.out.println("Make successful");
|
||||
|
||||
System.out.println("Checking output directories after make and rebuild");
|
||||
|
||||
ClassFilesComparisonKt
|
||||
.assertEqualDirectories(new File(getOutDirAfterRebuild(), "production"), new File(getOutDir(), "production"), false);
|
||||
ClassFilesComparisonKt.assertEqualDirectories(new File(getOutDirAfterRebuild(), "test"), new File(getOutDir(), "test"), false);
|
||||
|
||||
System.out.println("Test successfully finished. File: " + root.getName());
|
||||
System.out.println("-----");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void rebuildAllModules() {
|
||||
System.out.println("'Rebuild all' started");
|
||||
super.rebuildAllModules();
|
||||
System.out.println("'Rebuild all' finished");
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected BuildResult buildAllModules() {
|
||||
System.out.println("'Make all' started");
|
||||
BuildResult result = super.buildAllModules();
|
||||
System.out.println("'Make all' finished");
|
||||
return result;
|
||||
}
|
||||
|
||||
private void initProject() {
|
||||
addJdk(JDK_NAME);
|
||||
loadProject(workDir.getAbsolutePath());
|
||||
addKotlinStdlibDependency();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tearDown() throws Exception {
|
||||
FileUtil.delete(workDir);
|
||||
super.tearDown();
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
org.jetbrains.kotlin.jps.build.KotlinSourceRootProvider
|
||||
org.jetbrains.kotlin.jps.build.KotlinResourcesRootProvider
|
||||
+1
@@ -0,0 +1 @@
|
||||
org.jetbrains.kotlin.jps.build.KotlinJavaBuilderExtension
|
||||
+1
@@ -0,0 +1 @@
|
||||
org.jetbrains.jps.builders.java.dependencyView.NullabilityAnnotationsTracker
|
||||
+1
@@ -0,0 +1 @@
|
||||
org.jetbrains.kotlin.jps.build.KotlinBuilderService
|
||||
+1
@@ -0,0 +1 @@
|
||||
org.jetbrains.kotlin.jps.model.KotlinModelSerializerService
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jps.builders.java.dependencyView
|
||||
|
||||
import gnu.trove.TIntHashSet
|
||||
import org.jetbrains.jps.builders.java.dependencyView.TypeRepr.ClassType
|
||||
import org.jetbrains.kotlin.fileClasses.internalNameWithoutInnerClasses
|
||||
import org.jetbrains.kotlin.load.java.JAVAX_NONNULL_ANNOTATION
|
||||
import org.jetbrains.kotlin.load.java.NOT_NULL_ANNOTATIONS
|
||||
import org.jetbrains.kotlin.load.java.NULLABLE_ANNOTATIONS
|
||||
import java.util.*
|
||||
|
||||
internal class NullabilityAnnotationsTracker : AnnotationsChangeTracker() {
|
||||
private val annotations =
|
||||
(NULLABLE_ANNOTATIONS + JAVAX_NONNULL_ANNOTATION + NOT_NULL_ANNOTATIONS).mapTo(HashSet()) { it.internalNameWithoutInnerClasses }
|
||||
.toTypedArray()
|
||||
|
||||
override fun methodAnnotationsChanged(
|
||||
context: DependencyContext,
|
||||
method: MethodRepr,
|
||||
annotationsDiff: Difference.Specifier<ClassType, Difference>,
|
||||
paramAnnotationsDiff: Difference.Specifier<ParamAnnotation, Difference>
|
||||
): Set<Recompile> {
|
||||
val changedAnnotations = annotationsDiff.addedOrRemoved() +
|
||||
paramAnnotationsDiff.addedOrRemoved().map { it.type }
|
||||
|
||||
return handleNullAnnotationsChanges(context, method, changedAnnotations)
|
||||
}
|
||||
|
||||
|
||||
override fun fieldAnnotationsChanged(
|
||||
context: NamingContext,
|
||||
field: FieldRepr,
|
||||
annotationsDiff: Difference.Specifier<ClassType, Difference>
|
||||
): Set<Recompile> {
|
||||
return handleNullAnnotationsChanges(context, field, annotationsDiff.addedOrRemoved())
|
||||
}
|
||||
|
||||
private fun handleNullAnnotationsChanges(
|
||||
context: NamingContext,
|
||||
protoMember: ProtoMember,
|
||||
annotations: Sequence<TypeRepr.ClassType>
|
||||
): Set<Recompile> {
|
||||
val nullabilityAnnotations = TIntHashSet(this.annotations.toIntArray { context.get(it) })
|
||||
val changedNullAnnotation = annotations.firstOrNull { nullabilityAnnotations.contains(it.className) }
|
||||
|
||||
val result = EnumSet.noneOf(Recompile::class.java)
|
||||
if (changedNullAnnotation != null) {
|
||||
result.add(Recompile.USAGES)
|
||||
|
||||
if (protoMember is MethodRepr && !protoMember.isFinal) {
|
||||
// methods can be overridden, whereas fields cannot be
|
||||
result.add(Recompile.SUBCLASSES)
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun <T> Difference.Specifier<T, Difference>.addedOrRemoved(): Sequence<T> =
|
||||
added().asSequence() + removed().asSequence()
|
||||
|
||||
private inline fun <T> Array<T>.toIntArray(fn: (T) -> Int): IntArray =
|
||||
IntArray(size) { i -> fn(get(i)) }
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.compilerRunner
|
||||
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.preloading.ClassPreloadingUtils
|
||||
import org.jetbrains.kotlin.preloading.Preloader
|
||||
import org.jetbrains.kotlin.utils.KotlinPaths
|
||||
import org.jetbrains.kotlin.utils.KotlinPathsFromBaseDirectory
|
||||
import java.io.File
|
||||
import java.io.PrintStream
|
||||
import java.lang.ref.SoftReference
|
||||
|
||||
object CompilerRunnerUtil {
|
||||
private var ourClassLoaderRef = SoftReference<ClassLoader>(null)
|
||||
|
||||
internal val jdkToolsJar: File?
|
||||
get() {
|
||||
val javaHomePath = System.getProperty("java.home")
|
||||
if (javaHomePath == null || javaHomePath.isEmpty()) {
|
||||
return null
|
||||
}
|
||||
val javaHome = File(javaHomePath)
|
||||
var toolsJar = File(javaHome, "lib/tools.jar")
|
||||
if (toolsJar.exists()) {
|
||||
return toolsJar.canonicalFile
|
||||
}
|
||||
|
||||
// We might be inside jre.
|
||||
if (javaHome.name == "jre") {
|
||||
toolsJar = File(javaHome.parent, "lib/tools.jar")
|
||||
if (toolsJar.exists()) {
|
||||
return toolsJar.canonicalFile
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun getOrCreateClassLoader(
|
||||
environment: JpsCompilerEnvironment,
|
||||
paths: List<File>
|
||||
): ClassLoader {
|
||||
var classLoader = ourClassLoaderRef.get()
|
||||
if (classLoader == null) {
|
||||
classLoader = ClassPreloadingUtils.preloadClasses(
|
||||
paths,
|
||||
Preloader.DEFAULT_CLASS_NUMBER_ESTIMATE,
|
||||
CompilerRunnerUtil::class.java.classLoader,
|
||||
environment.classesToLoadByParent
|
||||
)
|
||||
ourClassLoaderRef = SoftReference(classLoader)
|
||||
}
|
||||
return classLoader!!
|
||||
}
|
||||
|
||||
fun getLibPath(paths: KotlinPaths, messageCollector: MessageCollector): File? {
|
||||
val libs = paths.libPath
|
||||
if (libs.exists() && !libs.isFile) return libs
|
||||
|
||||
messageCollector.report(
|
||||
ERROR,
|
||||
"Broken compiler at '" + libs.absolutePath + "'. Make sure plugin is properly installed", null
|
||||
)
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
fun invokeExecMethod(
|
||||
compilerClassName: String,
|
||||
arguments: Array<String>,
|
||||
environment: JpsCompilerEnvironment,
|
||||
out: PrintStream
|
||||
): Any? = withCompilerClassloader(environment) { classLoader ->
|
||||
val compiler = Class.forName(compilerClassName, true, classLoader)
|
||||
val exec = compiler.getMethod(
|
||||
"execAndOutputXml",
|
||||
PrintStream::class.java,
|
||||
Class.forName("org.jetbrains.kotlin.config.Services", true, classLoader),
|
||||
Array<String>::class.java
|
||||
)
|
||||
exec.invoke(compiler.newInstance(), out, environment.services, arguments)
|
||||
}
|
||||
|
||||
fun invokeClassesFqNames(
|
||||
environment: JpsCompilerEnvironment,
|
||||
files: Set<File>
|
||||
): Set<String> = withCompilerClassloader(environment) { classLoader ->
|
||||
val klass = Class.forName("org.jetbrains.kotlin.incremental.parsing.ParseFileUtilsKt", true, classLoader)
|
||||
val method = klass.getMethod("classesFqNames", Set::class.java)
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
method.invoke(klass, files) as? Set<String>
|
||||
} ?: emptySet()
|
||||
|
||||
private fun <T> withCompilerClassloader(
|
||||
environment: JpsCompilerEnvironment,
|
||||
fn: (ClassLoader) -> T
|
||||
): T? {
|
||||
val libPath = getLibPath(environment.kotlinPaths, environment.messageCollector) ?: return null
|
||||
val kotlinPaths = KotlinPathsFromBaseDirectory(libPath)
|
||||
val paths = kotlinPaths.classPath(KotlinPaths.ClassPaths.CompilerWithScripting).toMutableList()
|
||||
jdkToolsJar?.let { paths.add(it) }
|
||||
|
||||
val classLoader = getOrCreateClassLoader(environment, paths)
|
||||
return fn(classLoader)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.compilerRunner
|
||||
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.config.Services
|
||||
import org.jetbrains.kotlin.preloading.ClassCondition
|
||||
import org.jetbrains.kotlin.utils.KotlinPaths
|
||||
|
||||
class JpsCompilerEnvironment(
|
||||
val kotlinPaths: KotlinPaths,
|
||||
services: Services,
|
||||
val classesToLoadByParent: ClassCondition,
|
||||
messageCollector: MessageCollector,
|
||||
outputItemsCollector: OutputItemsCollectorImpl,
|
||||
val progressReporter: ProgressReporter
|
||||
) : CompilerEnvironment(services, messageCollector, outputItemsCollector) {
|
||||
override val outputItemsCollector: OutputItemsCollectorImpl
|
||||
get() = super.outputItemsCollector as OutputItemsCollectorImpl
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.compilerRunner
|
||||
|
||||
import org.jetbrains.kotlin.daemon.client.CompilerCallbackServicesFacadeServer
|
||||
import org.jetbrains.kotlin.daemon.client.reportFromDaemon
|
||||
import org.jetbrains.kotlin.daemon.common.JpsCompilerServicesFacade
|
||||
import org.jetbrains.kotlin.daemon.common.SOCKET_ANY_FREE_PORT
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider
|
||||
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer
|
||||
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
|
||||
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
|
||||
import java.io.Serializable
|
||||
|
||||
internal class JpsCompilerServicesFacadeImpl(
|
||||
private val env: JpsCompilerEnvironment,
|
||||
port: Int = SOCKET_ANY_FREE_PORT
|
||||
) : CompilerCallbackServicesFacadeServer(
|
||||
env.services[IncrementalCompilationComponents::class.java],
|
||||
env.services[LookupTracker::class.java],
|
||||
env.services[CompilationCanceledStatus::class.java],
|
||||
env.services[ExpectActualTracker::class.java],
|
||||
env.services[IncrementalResultsConsumer::class.java],
|
||||
env.services[IncrementalDataProvider::class.java],
|
||||
port
|
||||
), JpsCompilerServicesFacade {
|
||||
|
||||
override fun report(category: Int, severity: Int, message: String?, attachment: Serializable?) {
|
||||
env.messageCollector.reportFromDaemon(
|
||||
{ outFile, srcFiles -> env.outputItemsCollector.add(srcFiles, outFile) },
|
||||
category, severity, message, attachment
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,375 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.compilerRunner
|
||||
|
||||
import com.intellij.util.xmlb.XmlSerializerUtil
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.jps.api.GlobalOptions
|
||||
import org.jetbrains.kotlin.cli.common.CompilerSystemProperties
|
||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||
import org.jetbrains.kotlin.cli.common.arguments.*
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollectorUtil
|
||||
import org.jetbrains.kotlin.config.CompilerSettings
|
||||
import org.jetbrains.kotlin.config.IncrementalCompilation
|
||||
import org.jetbrains.kotlin.config.additionalArgumentsAsList
|
||||
import org.jetbrains.kotlin.daemon.client.CompileServiceSession
|
||||
import org.jetbrains.kotlin.daemon.client.KotlinCompilerClient
|
||||
import org.jetbrains.kotlin.daemon.common.*
|
||||
import org.jetbrains.kotlin.jps.build.KotlinBuilder
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.File
|
||||
import java.io.PrintStream
|
||||
|
||||
class JpsKotlinCompilerRunner {
|
||||
private val log: KotlinLogger = JpsKotlinLogger(KotlinBuilder.LOG)
|
||||
|
||||
private var compilerSettings: CompilerSettings? = null
|
||||
|
||||
private inline fun withCompilerSettings(settings: CompilerSettings, fn: () -> Unit) {
|
||||
val old = compilerSettings
|
||||
try {
|
||||
compilerSettings = settings
|
||||
fn()
|
||||
} finally {
|
||||
compilerSettings = old
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
@Volatile
|
||||
private var _jpsCompileServiceSession: CompileServiceSession? = null
|
||||
|
||||
@TestOnly
|
||||
fun shutdownDaemon() {
|
||||
_jpsCompileServiceSession?.let {
|
||||
try {
|
||||
it.compileService.shutdown()
|
||||
} catch (_: Throwable) {
|
||||
}
|
||||
}
|
||||
_jpsCompileServiceSession = null
|
||||
}
|
||||
|
||||
fun releaseCompileServiceSession() {
|
||||
_jpsCompileServiceSession?.let {
|
||||
try {
|
||||
it.compileService.releaseCompileSession(it.sessionId)
|
||||
} catch (_: Throwable) {
|
||||
}
|
||||
}
|
||||
_jpsCompileServiceSession = null
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun getOrCreateDaemonConnection(newConnection: () -> CompileServiceSession?): CompileServiceSession? {
|
||||
// TODO: consider adding state "ping" to the daemon interface
|
||||
if (_jpsCompileServiceSession == null || _jpsCompileServiceSession!!.compileService.getDaemonOptions() !is CompileService.CallResult.Good<DaemonOptions>) {
|
||||
releaseCompileServiceSession()
|
||||
_jpsCompileServiceSession = newConnection()
|
||||
}
|
||||
|
||||
return _jpsCompileServiceSession
|
||||
}
|
||||
|
||||
const val FAIL_ON_FALLBACK_PROPERTY = "test.kotlin.jps.compiler.runner.fail.on.fallback"
|
||||
}
|
||||
|
||||
fun classesFqNamesByFiles(
|
||||
environment: JpsCompilerEnvironment,
|
||||
files: Set<File>
|
||||
): Set<String> = withDaemonOrFallback(
|
||||
withDaemon = {
|
||||
doWithDaemon(environment) { sessionId, daemon ->
|
||||
daemon.classesFqNamesByFiles(
|
||||
sessionId,
|
||||
files.toSet() // convert to standard HashSet to avoid serialization issues
|
||||
)
|
||||
}
|
||||
},
|
||||
fallback = {
|
||||
CompilerRunnerUtil.invokeClassesFqNames(environment, files)
|
||||
}
|
||||
)
|
||||
|
||||
fun runK2MetadataCompiler(
|
||||
commonArguments: CommonCompilerArguments,
|
||||
k2MetadataArguments: K2MetadataCompilerArguments,
|
||||
compilerSettings: CompilerSettings,
|
||||
environment: JpsCompilerEnvironment,
|
||||
destination: String,
|
||||
classpath: Collection<String>,
|
||||
sourceFiles: Collection<File>
|
||||
) {
|
||||
val arguments = mergeBeans(commonArguments, XmlSerializerUtil.createCopy(k2MetadataArguments))
|
||||
|
||||
val classpathSet = arguments.classpath?.split(File.pathSeparator)?.toMutableSet() ?: mutableSetOf()
|
||||
classpathSet.addAll(classpath)
|
||||
arguments.classpath = classpath.joinToString(File.pathSeparator)
|
||||
arguments.freeArgs = sourceFiles.map { it.absolutePath }
|
||||
arguments.destination = arguments.destination ?: destination
|
||||
|
||||
withCompilerSettings(compilerSettings) {
|
||||
runCompiler(KotlinCompilerClass.METADATA, arguments, environment)
|
||||
}
|
||||
}
|
||||
|
||||
fun runK2JvmCompiler(
|
||||
commonArguments: CommonCompilerArguments,
|
||||
k2jvmArguments: K2JVMCompilerArguments,
|
||||
compilerSettings: CompilerSettings,
|
||||
environment: JpsCompilerEnvironment,
|
||||
moduleFile: File
|
||||
) {
|
||||
val arguments = mergeBeans(commonArguments, XmlSerializerUtil.createCopy(k2jvmArguments))
|
||||
setupK2JvmArguments(moduleFile, arguments)
|
||||
withCompilerSettings(compilerSettings) {
|
||||
runCompiler(KotlinCompilerClass.JVM, arguments, environment)
|
||||
}
|
||||
}
|
||||
|
||||
fun runK2JsCompiler(
|
||||
commonArguments: CommonCompilerArguments,
|
||||
k2jsArguments: K2JSCompilerArguments,
|
||||
compilerSettings: CompilerSettings,
|
||||
environment: JpsCompilerEnvironment,
|
||||
allSourceFiles: Collection<File>,
|
||||
commonSources: Collection<File>,
|
||||
sourceMapRoots: Collection<File>,
|
||||
libraries: List<String>,
|
||||
friendModules: List<String>,
|
||||
outputFile: File
|
||||
) {
|
||||
log.debug("K2JS: common arguments: " + ArgumentUtils.convertArgumentsToStringList(commonArguments))
|
||||
log.debug("K2JS: JS arguments: " + ArgumentUtils.convertArgumentsToStringList(k2jsArguments))
|
||||
|
||||
val arguments = mergeBeans(commonArguments, XmlSerializerUtil.createCopy(k2jsArguments))
|
||||
log.debug("K2JS: merged arguments: " + ArgumentUtils.convertArgumentsToStringList(arguments))
|
||||
|
||||
setupK2JsArguments(outputFile, allSourceFiles, commonSources, libraries, friendModules, arguments)
|
||||
if (arguments.sourceMap) {
|
||||
arguments.sourceMapBaseDirs = sourceMapRoots.joinToString(File.pathSeparator) { it.path }
|
||||
}
|
||||
|
||||
log.debug("K2JS: arguments after setup" + ArgumentUtils.convertArgumentsToStringList(arguments))
|
||||
|
||||
withCompilerSettings(compilerSettings) {
|
||||
runCompiler(KotlinCompilerClass.JS, arguments, environment)
|
||||
}
|
||||
}
|
||||
|
||||
private fun compileWithDaemonOrFallback(
|
||||
compilerClassName: String,
|
||||
compilerArgs: CommonCompilerArguments,
|
||||
environment: JpsCompilerEnvironment
|
||||
) {
|
||||
log.debug("Using kotlin-home = " + environment.kotlinPaths.homePath)
|
||||
|
||||
withDaemonOrFallback(
|
||||
withDaemon = { compileWithDaemon(compilerClassName, compilerArgs, environment) },
|
||||
fallback = { fallbackCompileStrategy(compilerArgs, compilerClassName, environment) }
|
||||
)
|
||||
}
|
||||
|
||||
private fun runCompiler(compilerClassName: String, compilerArgs: CommonCompilerArguments, environment: JpsCompilerEnvironment) {
|
||||
try {
|
||||
compileWithDaemonOrFallback(compilerClassName, compilerArgs, environment)
|
||||
} catch (e: Throwable) {
|
||||
MessageCollectorUtil.reportException(environment.messageCollector, e)
|
||||
reportInternalCompilerError(environment.messageCollector)
|
||||
}
|
||||
}
|
||||
|
||||
private fun compileWithDaemon(
|
||||
compilerClassName: String,
|
||||
compilerArgs: CommonCompilerArguments,
|
||||
environment: JpsCompilerEnvironment
|
||||
): Int? {
|
||||
val targetPlatform = when (compilerClassName) {
|
||||
KotlinCompilerClass.JVM -> CompileService.TargetPlatform.JVM
|
||||
KotlinCompilerClass.JS -> CompileService.TargetPlatform.JS
|
||||
KotlinCompilerClass.METADATA -> CompileService.TargetPlatform.METADATA
|
||||
else -> throw IllegalArgumentException("Unknown compiler type $compilerClassName")
|
||||
}
|
||||
val compilerMode = CompilerMode.JPS_COMPILER
|
||||
val verbose = compilerArgs.verbose
|
||||
val options = CompilationOptions(
|
||||
compilerMode,
|
||||
targetPlatform,
|
||||
reportCategories(verbose),
|
||||
reportSeverity(verbose),
|
||||
requestedCompilationResults = emptyArray()
|
||||
)
|
||||
return doWithDaemon(environment) { sessionId, daemon ->
|
||||
environment.withProgressReporter { progress ->
|
||||
progress.compilationStarted()
|
||||
daemon.compile(
|
||||
sessionId,
|
||||
withAdditionalCompilerArgs(compilerArgs),
|
||||
options,
|
||||
JpsCompilerServicesFacadeImpl(environment),
|
||||
null
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun <T> withDaemonOrFallback(withDaemon: () -> T?, fallback: () -> T): T =
|
||||
if (isDaemonEnabled()) {
|
||||
withDaemon() ?: fallback()
|
||||
} else {
|
||||
fallback()
|
||||
}
|
||||
|
||||
private fun <T> doWithDaemon(
|
||||
environment: JpsCompilerEnvironment,
|
||||
fn: (sessionId: Int, daemon: CompileService) -> CompileService.CallResult<T>
|
||||
): T? {
|
||||
log.debug("Try to connect to daemon")
|
||||
val connection = getDaemonConnection(environment)
|
||||
if (connection == null) {
|
||||
log.info("Could not connect to daemon")
|
||||
return null
|
||||
}
|
||||
|
||||
val (daemon, sessionId) = connection
|
||||
val res = fn(sessionId, daemon)
|
||||
// TODO: consider implementing connection retry, instead of fallback here
|
||||
return res.takeUnless { it is CompileService.CallResult.Dying }?.get()
|
||||
}
|
||||
|
||||
private fun withAdditionalCompilerArgs(compilerArgs: CommonCompilerArguments): Array<String> {
|
||||
val allArgs = ArgumentUtils.convertArgumentsToStringList(compilerArgs) +
|
||||
(compilerSettings?.additionalArgumentsAsList ?: emptyList())
|
||||
return allArgs.toTypedArray()
|
||||
}
|
||||
|
||||
private fun reportCategories(verbose: Boolean): Array<Int> {
|
||||
val categories =
|
||||
if (!verbose) {
|
||||
arrayOf(ReportCategory.COMPILER_MESSAGE, ReportCategory.EXCEPTION)
|
||||
} else {
|
||||
ReportCategory.values()
|
||||
}
|
||||
|
||||
return categories.map { it.code }.toTypedArray()
|
||||
}
|
||||
|
||||
|
||||
private fun reportSeverity(verbose: Boolean): Int =
|
||||
if (!verbose) {
|
||||
ReportSeverity.INFO.code
|
||||
} else {
|
||||
ReportSeverity.DEBUG.code
|
||||
}
|
||||
|
||||
private fun fallbackCompileStrategy(
|
||||
compilerArgs: CommonCompilerArguments,
|
||||
compilerClassName: String,
|
||||
environment: JpsCompilerEnvironment
|
||||
) {
|
||||
if ("true" == System.getProperty("kotlin.jps.tests") && "true" == System.getProperty(FAIL_ON_FALLBACK_PROPERTY)) {
|
||||
error("Cannot compile with Daemon, see logs bellow. Fallback strategy is disabled in tests")
|
||||
}
|
||||
|
||||
// otherwise fallback to in-process
|
||||
log.info("Compile in-process")
|
||||
|
||||
val stream = ByteArrayOutputStream()
|
||||
val out = PrintStream(stream)
|
||||
|
||||
// the property should be set at least for parallel builds to avoid parallel building problems (racing between destroying and using environment)
|
||||
// unfortunately it cannot be currently set by default globally, because it breaks many tests
|
||||
// since there is no reliable way so far to detect running under tests, switching it on only for parallel builds
|
||||
if (System.getProperty(GlobalOptions.COMPILE_PARALLEL_OPTION, "false").toBoolean())
|
||||
CompilerSystemProperties.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY.value = "true"
|
||||
|
||||
val rc = environment.withProgressReporter { progress ->
|
||||
progress.compilationStarted()
|
||||
CompilerRunnerUtil.invokeExecMethod(compilerClassName, withAdditionalCompilerArgs(compilerArgs), environment, out)
|
||||
}
|
||||
|
||||
// exec() returns an ExitCode object, class of which is loaded with a different class loader,
|
||||
// so we take it's contents through reflection
|
||||
val exitCode = ExitCode.valueOf(getReturnCodeFromObject(rc))
|
||||
processCompilerOutput(environment.messageCollector, environment.outputItemsCollector, stream, exitCode)
|
||||
}
|
||||
|
||||
private fun setupK2JvmArguments(moduleFile: File, settings: K2JVMCompilerArguments) {
|
||||
with(settings) {
|
||||
buildFile = moduleFile.absolutePath
|
||||
destination = null
|
||||
noStdlib = true
|
||||
noReflect = true
|
||||
noJdk = true
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupK2JsArguments(
|
||||
_outputFile: File,
|
||||
allSourceFiles: Collection<File>,
|
||||
_commonSources: Collection<File>,
|
||||
_libraries: List<String>,
|
||||
_friendModules: List<String>,
|
||||
settings: K2JSCompilerArguments
|
||||
) {
|
||||
with(settings) {
|
||||
noStdlib = true
|
||||
freeArgs = allSourceFiles.map { it.path }.toMutableList()
|
||||
commonSources = _commonSources.map { it.path }.toTypedArray()
|
||||
outputFile = _outputFile.path
|
||||
metaInfo = true
|
||||
libraries = _libraries.joinToString(File.pathSeparator)
|
||||
friendModules = _friendModules.joinToString(File.pathSeparator)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getReturnCodeFromObject(rc: Any?): String = when {
|
||||
rc == null -> ExitCode.INTERNAL_ERROR.toString()
|
||||
ExitCode::class.java.name == rc::class.java.name -> rc.toString()
|
||||
else -> throw IllegalStateException("Unexpected return: " + rc)
|
||||
}
|
||||
|
||||
private fun getDaemonConnection(environment: JpsCompilerEnvironment): CompileServiceSession? =
|
||||
getOrCreateDaemonConnection {
|
||||
environment.progressReporter.progress("connecting to daemon")
|
||||
val libPath = CompilerRunnerUtil.getLibPath(environment.kotlinPaths, environment.messageCollector)
|
||||
val compilerPath = File(libPath, "kotlin-compiler.jar")
|
||||
val daemonJarPath = File(libPath, "kotlin-daemon.jar")
|
||||
val toolsJarPath = CompilerRunnerUtil.jdkToolsJar
|
||||
val compilerId = CompilerId.makeCompilerId(listOfNotNull(compilerPath, toolsJarPath, daemonJarPath))
|
||||
val daemonOptions = configureDaemonOptions()
|
||||
val additionalJvmParams = mutableListOf<String>()
|
||||
|
||||
IncrementalCompilation.toJvmArgs(additionalJvmParams)
|
||||
|
||||
val clientFlagFile = KotlinCompilerClient.getOrCreateClientFlagFile(daemonOptions)
|
||||
val sessionFlagFile = makeAutodeletingFlagFile("compiler-jps-session-", File(daemonOptions.runFilesPathOrDefault))
|
||||
|
||||
environment.withProgressReporter { progress ->
|
||||
progress.progress("connecting to daemon")
|
||||
KotlinCompilerRunnerUtils.newDaemonConnection(
|
||||
compilerId,
|
||||
clientFlagFile,
|
||||
sessionFlagFile,
|
||||
environment.messageCollector,
|
||||
log.isDebugEnabled,
|
||||
daemonOptions,
|
||||
additionalJvmParams.toTypedArray()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.compilerRunner
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
|
||||
internal class JpsKotlinLogger(private val log: Logger) : KotlinLogger {
|
||||
override fun error(msg: String) {
|
||||
log.error(msg)
|
||||
}
|
||||
|
||||
override fun warn(msg: String) {
|
||||
log.warn(msg)
|
||||
}
|
||||
|
||||
override fun info(msg: String) {
|
||||
log.info(msg)
|
||||
}
|
||||
|
||||
override fun debug(msg: String) {
|
||||
log.debug(msg)
|
||||
}
|
||||
|
||||
override val isDebugEnabled: Boolean
|
||||
get() = log.isDebugEnabled
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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.compilerRunner
|
||||
|
||||
import org.jetbrains.jps.ModuleChunk
|
||||
import org.jetbrains.jps.incremental.CompileContext
|
||||
import org.jetbrains.jps.incremental.messages.ProgressMessage
|
||||
|
||||
interface ProgressReporter {
|
||||
fun progress(message: String)
|
||||
fun compilationStarted()
|
||||
fun clearProgress()
|
||||
}
|
||||
|
||||
class ProgressReporterImpl(private val context: CompileContext, private val chunk: ModuleChunk) : ProgressReporter {
|
||||
override fun progress(message: String) {
|
||||
context.processMessage(ProgressMessage("Kotlin: $message"))
|
||||
}
|
||||
|
||||
override fun compilationStarted() {
|
||||
progress("compiling [${chunk.presentableShortName}]")
|
||||
}
|
||||
|
||||
override fun clearProgress() {
|
||||
context.processMessage(ProgressMessage(""))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inline fun <T> JpsCompilerEnvironment.withProgressReporter(fn: (ProgressReporter) -> T): T =
|
||||
try {
|
||||
fn(progressReporter)
|
||||
} finally {
|
||||
progressReporter.clearProgress()
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.build
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import org.jetbrains.jps.ModuleChunk
|
||||
import org.jetbrains.jps.builders.BuildRootDescriptor
|
||||
import org.jetbrains.jps.builders.BuildTarget
|
||||
import org.jetbrains.jps.builders.FileProcessor
|
||||
import org.jetbrains.jps.builders.impl.DirtyFilesHolderBase
|
||||
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor
|
||||
import org.jetbrains.jps.builders.java.dependencyView.Mappings
|
||||
import org.jetbrains.jps.incremental.BuildOperations
|
||||
import org.jetbrains.jps.incremental.CompileContext
|
||||
import org.jetbrains.jps.incremental.FSOperations
|
||||
import org.jetbrains.jps.incremental.ModuleBuildTarget
|
||||
import org.jetbrains.jps.incremental.fs.CompilationRound
|
||||
import java.io.File
|
||||
import java.util.HashMap
|
||||
import kotlin.collections.*
|
||||
|
||||
/**
|
||||
* Entry point for safely marking files as dirty.
|
||||
*/
|
||||
class FSOperationsHelper(
|
||||
private val compileContext: CompileContext,
|
||||
private val chunk: ModuleChunk,
|
||||
private val dirtyFilesHolder: KotlinDirtySourceFilesHolder,
|
||||
private val log: Logger
|
||||
) {
|
||||
private val moduleBasedFilter = ModulesBasedFileFilter(compileContext, chunk)
|
||||
|
||||
internal var hasMarkedDirty = false
|
||||
private set
|
||||
|
||||
private val buildLogger = compileContext.testingContext?.buildLogger
|
||||
|
||||
fun markChunk(recursively: Boolean, kotlinOnly: Boolean, excludeFiles: Set<File> = setOf()) {
|
||||
fun shouldMark(file: File): Boolean {
|
||||
if (kotlinOnly && !file.isKotlinSourceFile) return false
|
||||
|
||||
if (file in excludeFiles) return false
|
||||
|
||||
hasMarkedDirty = true
|
||||
return true
|
||||
}
|
||||
|
||||
if (recursively) {
|
||||
FSOperations.markDirtyRecursively(compileContext, CompilationRound.NEXT, chunk, ::shouldMark)
|
||||
} else {
|
||||
FSOperations.markDirty(compileContext, CompilationRound.NEXT, chunk, ::shouldMark)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun markFilesForCurrentRound(files: Iterable<File>) {
|
||||
files.forEach {
|
||||
val root = compileContext.projectDescriptor.buildRootIndex.findJavaRootDescriptor(compileContext, it)
|
||||
if (root != null) dirtyFilesHolder.byTarget[root.target]?._markDirty(it, root)
|
||||
}
|
||||
|
||||
markFilesImpl(files, currentRound = true) { it.exists() && moduleBasedFilter.accept(it) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks given [files] as dirty for current round and given [target] of [chunk].
|
||||
*/
|
||||
fun markFilesForCurrentRound(target: ModuleBuildTarget, files: Collection<File>) {
|
||||
require(target in chunk.targets)
|
||||
|
||||
val targetDirtyFiles = dirtyFilesHolder.byTarget.getValue(target)
|
||||
val dirtyFileToRoot = HashMap<File, JavaSourceRootDescriptor>()
|
||||
files.forEach { file ->
|
||||
val root = compileContext.projectDescriptor.buildRootIndex
|
||||
.findAllParentDescriptors<BuildRootDescriptor>(file, compileContext)
|
||||
.single { sourceRoot -> sourceRoot.target == target }
|
||||
|
||||
targetDirtyFiles._markDirty(file, root as JavaSourceRootDescriptor)
|
||||
dirtyFileToRoot[file] = root
|
||||
}
|
||||
|
||||
markFilesImpl(files, currentRound = true) { it.exists() }
|
||||
cleanOutputsForNewDirtyFilesInCurrentRound(target, dirtyFileToRoot)
|
||||
}
|
||||
|
||||
private fun cleanOutputsForNewDirtyFilesInCurrentRound(target: ModuleBuildTarget, dirtyFiles: Map<File, JavaSourceRootDescriptor>) {
|
||||
val dirtyFilesHolder = object : DirtyFilesHolderBase<JavaSourceRootDescriptor, ModuleBuildTarget>(compileContext) {
|
||||
override fun processDirtyFiles(processor: FileProcessor<JavaSourceRootDescriptor, ModuleBuildTarget>) {
|
||||
dirtyFiles.forEach { (file, root) -> processor.apply(target, file, root) }
|
||||
}
|
||||
|
||||
override fun hasDirtyFiles(): Boolean = dirtyFiles.isNotEmpty()
|
||||
}
|
||||
BuildOperations.cleanOutputsCorrespondingToChangedFiles(compileContext, dirtyFilesHolder)
|
||||
}
|
||||
|
||||
fun markFiles(files: Iterable<File>) {
|
||||
markFilesImpl(files, currentRound = false) { it.exists() }
|
||||
}
|
||||
|
||||
fun markInChunkOrDependents(files: Iterable<File>, excludeFiles: Set<File>) {
|
||||
markFilesImpl(files, currentRound = false) {
|
||||
it !in excludeFiles && it.exists() && moduleBasedFilter.accept(it)
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun markFilesImpl(
|
||||
files: Iterable<File>,
|
||||
currentRound: Boolean,
|
||||
shouldMark: (File) -> Boolean
|
||||
) {
|
||||
val filesToMark = files.filterTo(HashSet(), shouldMark)
|
||||
if (filesToMark.isEmpty()) return
|
||||
|
||||
val compilationRound = if (currentRound) {
|
||||
buildLogger?.markedAsDirtyBeforeRound(filesToMark)
|
||||
CompilationRound.CURRENT
|
||||
} else {
|
||||
buildLogger?.markedAsDirtyAfterRound(filesToMark)
|
||||
hasMarkedDirty = true
|
||||
CompilationRound.NEXT
|
||||
}
|
||||
|
||||
for (fileToMark in filesToMark) {
|
||||
FSOperations.markDirty(compileContext, compilationRound, fileToMark)
|
||||
}
|
||||
log.debug("Mark dirty: $filesToMark ($compilationRound)")
|
||||
}
|
||||
|
||||
// Based on `JavaBuilderUtil#ModulesBasedFileFilter` from Intellij
|
||||
private class ModulesBasedFileFilter(
|
||||
private val context: CompileContext,
|
||||
chunk: ModuleChunk
|
||||
) : Mappings.DependentFilesFilter {
|
||||
private val chunkTargets = chunk.targets
|
||||
private val buildRootIndex = context.projectDescriptor.buildRootIndex
|
||||
private val buildTargetIndex = context.projectDescriptor.buildTargetIndex
|
||||
private val cache = HashMap<BuildTarget<*>, Set<BuildTarget<*>>>()
|
||||
|
||||
override fun accept(file: File): Boolean {
|
||||
val rd = buildRootIndex.findJavaRootDescriptor(context, file) ?: return true
|
||||
val target = rd.target
|
||||
if (target in chunkTargets) return true
|
||||
|
||||
val targetOfFileWithDependencies = cache.getOrPut(target) { buildTargetIndex.getDependenciesRecursively(target, context) }
|
||||
return ContainerUtil.intersects(targetOfFileWithDependencies, chunkTargets)
|
||||
}
|
||||
|
||||
override fun belongsToCurrentTargetChunk(file: File): Boolean {
|
||||
val rd = buildRootIndex.findJavaRootDescriptor(context, file)
|
||||
return rd != null && chunkTargets.contains(rd.target)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* 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 org.jetbrains.kotlin.jps.build
|
||||
|
||||
import org.jetbrains.jps.model.JpsProject
|
||||
import org.jetbrains.jps.model.serialization.JpsModelSerializationDataService
|
||||
import org.jetbrains.kotlin.incremental.storage.RelativeFileToPathConverter
|
||||
|
||||
internal class JpsFileToPathConverter(
|
||||
jpsProject: JpsProject
|
||||
) : RelativeFileToPathConverter(JpsModelSerializationDataService.getBaseDirectory(jpsProject))
|
||||
@@ -0,0 +1,772 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.build
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import org.jetbrains.jps.ModuleChunk
|
||||
import org.jetbrains.jps.builders.DirtyFilesHolder
|
||||
import org.jetbrains.jps.builders.FileProcessor
|
||||
import org.jetbrains.jps.builders.impl.DirtyFilesHolderBase
|
||||
import org.jetbrains.jps.builders.java.JavaBuilderUtil
|
||||
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor
|
||||
import org.jetbrains.jps.builders.storage.BuildDataCorruptedException
|
||||
import org.jetbrains.jps.incremental.*
|
||||
import org.jetbrains.jps.incremental.ModuleLevelBuilder.ExitCode.*
|
||||
import org.jetbrains.jps.incremental.java.JavaBuilder
|
||||
import org.jetbrains.jps.model.JpsProject
|
||||
import org.jetbrains.kotlin.build.GeneratedFile
|
||||
import org.jetbrains.kotlin.build.GeneratedJvmClass
|
||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.*
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollectorUtil
|
||||
import org.jetbrains.kotlin.compilerRunner.*
|
||||
import org.jetbrains.kotlin.config.IncrementalCompilation
|
||||
import org.jetbrains.kotlin.config.KotlinModuleKind
|
||||
import org.jetbrains.kotlin.config.Services
|
||||
import org.jetbrains.kotlin.daemon.common.isDaemonEnabled
|
||||
import org.jetbrains.kotlin.incremental.*
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.build.report.ICReporterBase
|
||||
import org.jetbrains.kotlin.jps.incremental.JpsIncrementalCache
|
||||
import org.jetbrains.kotlin.jps.incremental.JpsLookupStorageManager
|
||||
import org.jetbrains.kotlin.jps.model.kotlinKind
|
||||
import org.jetbrains.kotlin.jps.targets.KotlinJvmModuleBuildTarget
|
||||
import org.jetbrains.kotlin.jps.targets.KotlinModuleBuildTarget
|
||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.preloading.ClassCondition
|
||||
import org.jetbrains.kotlin.utils.KotlinPaths
|
||||
import org.jetbrains.kotlin.utils.KotlinPathsFromHomeDir
|
||||
import org.jetbrains.kotlin.utils.PathUtil
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
import kotlin.collections.HashSet
|
||||
import kotlin.system.measureTimeMillis
|
||||
|
||||
class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
|
||||
companion object {
|
||||
const val KOTLIN_BUILDER_NAME: String = "Kotlin Builder"
|
||||
|
||||
val LOG = Logger.getInstance("#org.jetbrains.kotlin.jps.build.KotlinBuilder")
|
||||
const val SKIP_CACHE_VERSION_CHECK_PROPERTY = "kotlin.jps.skip.cache.version.check"
|
||||
const val JPS_KOTLIN_HOME_PROPERTY = "jps.kotlin.home"
|
||||
|
||||
val classesToLoadByParent: ClassCondition
|
||||
get() = ClassCondition { className ->
|
||||
className.startsWith("org.jetbrains.kotlin.load.kotlin.incremental.components.")
|
||||
|| className.startsWith("org.jetbrains.kotlin.incremental.components.")
|
||||
|| className.startsWith("org.jetbrains.kotlin.incremental.js")
|
||||
|| className == "org.jetbrains.kotlin.config.Services"
|
||||
|| className.startsWith("org.apache.log4j.") // For logging from compiler
|
||||
|| className == "org.jetbrains.kotlin.progress.CompilationCanceledStatus"
|
||||
|| className == "org.jetbrains.kotlin.progress.CompilationCanceledException"
|
||||
|| className == "org.jetbrains.kotlin.modules.TargetId"
|
||||
|| className == "org.jetbrains.kotlin.cli.common.ExitCode"
|
||||
}
|
||||
}
|
||||
|
||||
private val statisticsLogger = TeamcityStatisticsLogger()
|
||||
|
||||
override fun getPresentableName() = KOTLIN_BUILDER_NAME
|
||||
|
||||
override fun getCompilableFileExtensions() = arrayListOf("kt", "kts")
|
||||
|
||||
override fun buildStarted(context: CompileContext) {
|
||||
logSettings(context)
|
||||
}
|
||||
|
||||
private fun logSettings(context: CompileContext) {
|
||||
LOG.debug("==========================================")
|
||||
LOG.info("is Kotlin incremental compilation enabled for JVM: ${IncrementalCompilation.isEnabledForJvm()}")
|
||||
LOG.info("is Kotlin incremental compilation enabled for JS: ${IncrementalCompilation.isEnabledForJs()}")
|
||||
LOG.info("is Kotlin compiler daemon enabled: ${isDaemonEnabled()}")
|
||||
|
||||
val historyLabel = context.getBuilderParameter("history label")
|
||||
if (historyLabel != null) {
|
||||
LOG.info("Label in local history: $historyLabel")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure Kotlin Context initialized.
|
||||
* Kotlin Context should be initialized only when required (before first kotlin chunk build).
|
||||
*/
|
||||
private fun ensureKotlinContextInitialized(context: CompileContext): KotlinCompileContext {
|
||||
val kotlinCompileContext = context.getUserData(kotlinCompileContextKey)
|
||||
if (kotlinCompileContext != null) return kotlinCompileContext
|
||||
|
||||
// don't synchronize on context, since it is chunk local only
|
||||
synchronized(kotlinCompileContextKey) {
|
||||
val actualKotlinCompileContext = context.getUserData(kotlinCompileContextKey)
|
||||
if (actualKotlinCompileContext != null) return actualKotlinCompileContext
|
||||
|
||||
try {
|
||||
return initializeKotlinContext(context)
|
||||
} catch (t: Throwable) {
|
||||
jpsReportInternalBuilderError(context, Error("Cannot initialize Kotlin context: ${t.message}", t))
|
||||
throw t
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun initializeKotlinContext(context: CompileContext): KotlinCompileContext {
|
||||
val kotlinContext: KotlinCompileContext
|
||||
|
||||
val time = measureTimeMillis {
|
||||
kotlinContext = KotlinCompileContext(context)
|
||||
|
||||
context.putUserData(kotlinCompileContextKey, kotlinContext)
|
||||
context.testingContext?.kotlinCompileContext = kotlinContext
|
||||
|
||||
if (kotlinContext.shouldCheckCacheVersions && kotlinContext.hasKotlin()) {
|
||||
kotlinContext.checkCacheVersions()
|
||||
}
|
||||
|
||||
kotlinContext.cleanupCaches()
|
||||
kotlinContext.reportUnsupportedTargets()
|
||||
}
|
||||
|
||||
LOG.info("Total Kotlin global compile context initialization time: $time ms")
|
||||
|
||||
return kotlinContext
|
||||
}
|
||||
|
||||
override fun buildFinished(context: CompileContext) {
|
||||
ensureKotlinContextDisposed(context)
|
||||
}
|
||||
|
||||
private fun ensureKotlinContextDisposed(context: CompileContext) {
|
||||
if (context.getUserData(kotlinCompileContextKey) != null) {
|
||||
// don't synchronize on context, since it chunk local only
|
||||
synchronized(kotlinCompileContextKey) {
|
||||
val kotlinCompileContext = context.getUserData(kotlinCompileContextKey)
|
||||
if (kotlinCompileContext != null) {
|
||||
kotlinCompileContext.dispose()
|
||||
context.putUserData(kotlinCompileContextKey, null)
|
||||
|
||||
statisticsLogger.reportTotal()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun chunkBuildStarted(context: CompileContext, chunk: ModuleChunk) {
|
||||
super.chunkBuildStarted(context, chunk)
|
||||
|
||||
if (chunk.isDummy(context)) return
|
||||
|
||||
val kotlinContext = ensureKotlinContextInitialized(context)
|
||||
|
||||
val buildLogger = context.testingContext?.buildLogger
|
||||
buildLogger?.chunkBuildStarted(context, chunk)
|
||||
|
||||
if (JavaBuilderUtil.isForcedRecompilationAllJavaModules(context)) return
|
||||
|
||||
val targets = chunk.targets
|
||||
if (targets.none { kotlinContext.hasKotlinMarker[it] == true }) return
|
||||
|
||||
val kotlinChunk = kotlinContext.getChunk(chunk) ?: return
|
||||
kotlinContext.checkChunkCacheVersion(kotlinChunk)
|
||||
|
||||
if (!kotlinContext.rebuildingAllKotlin && kotlinChunk.isEnabled) {
|
||||
markAdditionalFilesForInitialRound(kotlinChunk, chunk, kotlinContext)
|
||||
}
|
||||
|
||||
buildLogger?.afterChunkBuildStarted(context, chunk)
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate usages of removed classes.
|
||||
* See KT-13677 for more details.
|
||||
*
|
||||
* todo(1.2.80): move to KotlinChunk
|
||||
* todo(1.2.80): got rid of jpsGlobalContext usages (replace with KotlinCompileContext)
|
||||
*/
|
||||
private fun markAdditionalFilesForInitialRound(
|
||||
kotlinChunk: KotlinChunk,
|
||||
chunk: ModuleChunk,
|
||||
kotlinContext: KotlinCompileContext
|
||||
) {
|
||||
val context = kotlinContext.jpsContext
|
||||
val dirtyFilesHolder = KotlinDirtySourceFilesHolder(
|
||||
chunk,
|
||||
context,
|
||||
object : DirtyFilesHolderBase<JavaSourceRootDescriptor, ModuleBuildTarget>(context) {
|
||||
override fun processDirtyFiles(processor: FileProcessor<JavaSourceRootDescriptor, ModuleBuildTarget>) {
|
||||
FSOperations.processFilesToRecompile(context, chunk, processor)
|
||||
}
|
||||
}
|
||||
)
|
||||
val fsOperations = FSOperationsHelper(context, chunk, dirtyFilesHolder, LOG)
|
||||
|
||||
val representativeTarget = kotlinContext.targetsBinding[chunk.representativeTarget()] ?: return
|
||||
|
||||
// dependent caches are not required, since we are not going to update caches
|
||||
val incrementalCaches = kotlinChunk.loadCaches(loadDependent = false)
|
||||
|
||||
val messageCollector = MessageCollectorAdapter(context, representativeTarget)
|
||||
val environment = createCompileEnvironment(
|
||||
kotlinContext.jpsContext,
|
||||
representativeTarget,
|
||||
incrementalCaches,
|
||||
LookupTracker.DO_NOTHING,
|
||||
ExpectActualTracker.DoNothing,
|
||||
chunk,
|
||||
messageCollector
|
||||
) ?: return
|
||||
|
||||
val removedClasses = HashSet<String>()
|
||||
for (target in kotlinChunk.targets) {
|
||||
val cache = incrementalCaches[target] ?: continue
|
||||
val dirtyFiles = dirtyFilesHolder.getDirtyFiles(target.jpsModuleBuildTarget).keys
|
||||
val removedFiles = dirtyFilesHolder.getRemovedFiles(target.jpsModuleBuildTarget)
|
||||
|
||||
val existingClasses = JpsKotlinCompilerRunner().classesFqNamesByFiles(environment, dirtyFiles)
|
||||
val previousClasses = cache.classesFqNamesBySources(dirtyFiles + removedFiles)
|
||||
for (jvmClassName in previousClasses) {
|
||||
val fqName = jvmClassName.asString()
|
||||
if (fqName !in existingClasses) {
|
||||
removedClasses.add(fqName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val changesCollector = ChangesCollector()
|
||||
removedClasses.forEach { changesCollector.collectSignature(FqName(it), areSubclassesAffected = true) }
|
||||
val affectedByRemovedClasses = changesCollector.getDirtyFiles(incrementalCaches.values, kotlinContext.lookupStorageManager)
|
||||
|
||||
fsOperations.markFilesForCurrentRound(affectedByRemovedClasses.dirtyFiles + affectedByRemovedClasses.forceRecompileTogether)
|
||||
}
|
||||
|
||||
override fun chunkBuildFinished(context: CompileContext, chunk: ModuleChunk) {
|
||||
super.chunkBuildFinished(context, chunk)
|
||||
|
||||
if (chunk.isDummy(context)) return
|
||||
|
||||
// Temporary workaround for KT-33808
|
||||
val kotlinContext = ensureKotlinContextInitialized(context)
|
||||
for (target in chunk.targets) {
|
||||
if (kotlinContext.hasKotlinMarker[target] != true) continue
|
||||
|
||||
val outputRoots = target.getOutputRoots(context)
|
||||
if (outputRoots.size > 1) {
|
||||
outputRoots.forEach { it.mkdirs() }
|
||||
}
|
||||
}
|
||||
|
||||
LOG.debug("------------------------------------------")
|
||||
}
|
||||
|
||||
override fun build(
|
||||
context: CompileContext,
|
||||
chunk: ModuleChunk,
|
||||
dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>,
|
||||
outputConsumer: ModuleLevelBuilder.OutputConsumer
|
||||
): ModuleLevelBuilder.ExitCode {
|
||||
if (chunk.isDummy(context))
|
||||
return NOTHING_DONE
|
||||
|
||||
val kotlinTarget = context.kotlinBuildTargets[chunk.representativeTarget()] ?: return OK
|
||||
val messageCollector = MessageCollectorAdapter(context, kotlinTarget)
|
||||
|
||||
// New mpp project model: modules which is imported from sources sets of the compilations shouldn't be compiled for now.
|
||||
// It should be compiled only as one of source root of target compilation, which is added in [KotlinSourceRootProvider].
|
||||
if (chunk.modules.any { it.kotlinKind == KotlinModuleKind.SOURCE_SET_HOLDER }) {
|
||||
if (chunk.modules.size > 1) {
|
||||
messageCollector.report(
|
||||
CompilerMessageSeverity.ERROR,
|
||||
"Cyclically dependent modules are not supported in multiplatform projects"
|
||||
)
|
||||
return ABORT
|
||||
}
|
||||
|
||||
return NOTHING_DONE
|
||||
}
|
||||
|
||||
val kotlinDirtyFilesHolder = KotlinDirtySourceFilesHolder(chunk, context, dirtyFilesHolder)
|
||||
val fsOperations = FSOperationsHelper(context, chunk, kotlinDirtyFilesHolder, LOG)
|
||||
|
||||
try {
|
||||
val proposedExitCode =
|
||||
doBuild(chunk, kotlinTarget, context, kotlinDirtyFilesHolder, messageCollector, outputConsumer, fsOperations)
|
||||
|
||||
val actualExitCode = if (proposedExitCode == OK && fsOperations.hasMarkedDirty) ADDITIONAL_PASS_REQUIRED else proposedExitCode
|
||||
|
||||
LOG.debug("Build result: $actualExitCode")
|
||||
|
||||
context.testingContext?.buildLogger?.buildFinished(actualExitCode)
|
||||
|
||||
return actualExitCode
|
||||
} catch (e: StopBuildException) {
|
||||
LOG.info("Caught exception: $e")
|
||||
throw e
|
||||
} catch (e: BuildDataCorruptedException) {
|
||||
LOG.info("Caught exception: $e")
|
||||
throw e
|
||||
} catch (e: Throwable) {
|
||||
LOG.info("Caught exception: $e")
|
||||
MessageCollectorUtil.reportException(messageCollector, e)
|
||||
return ABORT
|
||||
}
|
||||
}
|
||||
|
||||
private fun doBuild(
|
||||
chunk: ModuleChunk,
|
||||
representativeTarget: KotlinModuleBuildTarget<*>,
|
||||
context: CompileContext,
|
||||
kotlinDirtyFilesHolder: KotlinDirtySourceFilesHolder,
|
||||
messageCollector: MessageCollectorAdapter,
|
||||
outputConsumer: OutputConsumer,
|
||||
fsOperations: FSOperationsHelper
|
||||
): ModuleLevelBuilder.ExitCode {
|
||||
// Workaround for Android Studio
|
||||
if (representativeTarget is KotlinJvmModuleBuildTarget && !JavaBuilder.IS_ENABLED[context, true]) {
|
||||
messageCollector.report(INFO, "Kotlin JPS plugin is disabled")
|
||||
return NOTHING_DONE
|
||||
}
|
||||
|
||||
val kotlinContext = context.kotlin
|
||||
val kotlinChunk = chunk.toKotlinChunk(context)!!
|
||||
|
||||
if (!kotlinChunk.haveSameCompiler) {
|
||||
messageCollector.report(
|
||||
ERROR,
|
||||
"Cyclically dependent modules ${kotlinChunk.presentableModulesToCompilersList} should have same compiler."
|
||||
)
|
||||
return ABORT
|
||||
}
|
||||
|
||||
if (!kotlinChunk.isEnabled) {
|
||||
return NOTHING_DONE
|
||||
}
|
||||
|
||||
val projectDescriptor = context.projectDescriptor
|
||||
val dataManager = projectDescriptor.dataManager
|
||||
val targets = chunk.targets
|
||||
|
||||
val isChunkRebuilding = JavaBuilderUtil.isForcedRecompilationAllJavaModules(context)
|
||||
|| targets.any { kotlinContext.rebuildAfterCacheVersionChanged[it] == true }
|
||||
|
||||
if (!kotlinDirtyFilesHolder.hasDirtyOrRemovedFiles) {
|
||||
if (isChunkRebuilding) {
|
||||
targets.forEach {
|
||||
kotlinContext.hasKotlinMarker[it] = false
|
||||
}
|
||||
}
|
||||
|
||||
targets.forEach { kotlinContext.rebuildAfterCacheVersionChanged.clean(it) }
|
||||
return NOTHING_DONE
|
||||
}
|
||||
|
||||
// Request CHUNK_REBUILD when IC is off and there are dirty Kotlin files
|
||||
// Otherwise unexpected compile error might happen, when there are Groovy files,
|
||||
// but they are not dirty, so Groovy builder does not generate source stubs,
|
||||
// and Kotlin builder is filtering out output directory from classpath
|
||||
// (because it may contain outdated Java classes).
|
||||
if (!isChunkRebuilding && !representativeTarget.isIncrementalCompilationEnabled) {
|
||||
targets.forEach { kotlinContext.rebuildAfterCacheVersionChanged[it] = true }
|
||||
return CHUNK_REBUILD_REQUIRED
|
||||
}
|
||||
|
||||
val targetsWithoutOutputDir = targets.filter { it.outputDir == null }
|
||||
if (targetsWithoutOutputDir.isNotEmpty()) {
|
||||
messageCollector.report(ERROR, "Output directory not specified for " + targetsWithoutOutputDir.joinToString())
|
||||
return ABORT
|
||||
}
|
||||
|
||||
val project = projectDescriptor.project
|
||||
val lookupTracker = getLookupTracker(project, representativeTarget)
|
||||
val exceptActualTracer = ExpectActualTrackerImpl()
|
||||
val incrementalCaches = kotlinChunk.loadCaches()
|
||||
val environment = createCompileEnvironment(
|
||||
context,
|
||||
representativeTarget,
|
||||
incrementalCaches,
|
||||
lookupTracker,
|
||||
exceptActualTracer,
|
||||
chunk,
|
||||
messageCollector
|
||||
) ?: return ABORT
|
||||
|
||||
context.testingContext?.buildLogger?.compilingFiles(
|
||||
kotlinDirtyFilesHolder.allDirtyFiles,
|
||||
kotlinDirtyFilesHolder.allRemovedFilesFiles
|
||||
)
|
||||
|
||||
if (LOG.isDebugEnabled) {
|
||||
LOG.debug("Compiling files: ${kotlinDirtyFilesHolder.allDirtyFiles}")
|
||||
}
|
||||
|
||||
val start = System.nanoTime()
|
||||
val outputItemCollector = doCompileModuleChunk(
|
||||
kotlinChunk,
|
||||
representativeTarget,
|
||||
kotlinChunk.compilerArguments,
|
||||
context,
|
||||
kotlinDirtyFilesHolder,
|
||||
fsOperations,
|
||||
environment,
|
||||
incrementalCaches
|
||||
)
|
||||
|
||||
statisticsLogger.registerStatistic(chunk, System.nanoTime() - start)
|
||||
|
||||
if (outputItemCollector == null) {
|
||||
return NOTHING_DONE
|
||||
}
|
||||
|
||||
val compilationErrors = Utils.ERRORS_DETECTED_KEY[context, false]
|
||||
if (compilationErrors) {
|
||||
LOG.info("Compiled with errors")
|
||||
return ABORT
|
||||
} else {
|
||||
LOG.info("Compiled successfully")
|
||||
}
|
||||
|
||||
val generatedFiles = getGeneratedFiles(context, chunk, environment.outputItemsCollector)
|
||||
|
||||
markDirtyComplementaryMultifileClasses(generatedFiles, kotlinContext, incrementalCaches, fsOperations)
|
||||
|
||||
val kotlinTargets = kotlinContext.targetsBinding
|
||||
for ((target, outputItems) in generatedFiles) {
|
||||
val kotlinTarget = kotlinTargets[target] ?: error("Could not find Kotlin target for JPS target $target")
|
||||
kotlinTarget.registerOutputItems(outputConsumer, outputItems)
|
||||
}
|
||||
kotlinChunk.saveVersions()
|
||||
|
||||
if (targets.any { kotlinContext.hasKotlinMarker[it] == null }) {
|
||||
fsOperations.markChunk(recursively = false, kotlinOnly = true, excludeFiles = kotlinDirtyFilesHolder.allDirtyFiles)
|
||||
}
|
||||
|
||||
for (target in targets) {
|
||||
kotlinContext.hasKotlinMarker[target] = true
|
||||
kotlinContext.rebuildAfterCacheVersionChanged.clean(target)
|
||||
}
|
||||
|
||||
kotlinChunk.targets.forEach {
|
||||
it.doAfterBuild()
|
||||
}
|
||||
|
||||
representativeTarget.updateChunkMappings(
|
||||
context,
|
||||
chunk,
|
||||
kotlinDirtyFilesHolder,
|
||||
generatedFiles,
|
||||
incrementalCaches
|
||||
)
|
||||
|
||||
if (!representativeTarget.isIncrementalCompilationEnabled) {
|
||||
return OK
|
||||
}
|
||||
|
||||
context.checkCanceled()
|
||||
|
||||
environment.withProgressReporter { progress ->
|
||||
progress.progress("performing incremental compilation analysis")
|
||||
|
||||
val changesCollector = ChangesCollector()
|
||||
|
||||
for ((target, files) in generatedFiles) {
|
||||
val kotlinModuleBuilderTarget = kotlinContext.targetsBinding[target]!!
|
||||
kotlinModuleBuilderTarget.updateCaches(
|
||||
kotlinDirtyFilesHolder,
|
||||
incrementalCaches[kotlinModuleBuilderTarget]!!,
|
||||
files,
|
||||
changesCollector,
|
||||
environment
|
||||
)
|
||||
}
|
||||
|
||||
updateLookupStorage(lookupTracker, kotlinContext.lookupStorageManager, kotlinDirtyFilesHolder)
|
||||
|
||||
if (!isChunkRebuilding) {
|
||||
changesCollector.processChangesUsingLookups(
|
||||
kotlinDirtyFilesHolder.allDirtyFiles,
|
||||
kotlinContext.lookupStorageManager,
|
||||
fsOperations,
|
||||
incrementalCaches.values
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return OK
|
||||
}
|
||||
|
||||
// todo(1.2.80): got rid of ModuleChunk (replace with KotlinChunk)
|
||||
// todo(1.2.80): introduce KotlinRoundCompileContext, move dirtyFilesHolder, fsOperations, environment to it
|
||||
private fun doCompileModuleChunk(
|
||||
kotlinChunk: KotlinChunk,
|
||||
representativeTarget: KotlinModuleBuildTarget<*>,
|
||||
commonArguments: CommonCompilerArguments,
|
||||
context: CompileContext,
|
||||
dirtyFilesHolder: KotlinDirtySourceFilesHolder,
|
||||
fsOperations: FSOperationsHelper,
|
||||
environment: JpsCompilerEnvironment,
|
||||
incrementalCaches: Map<KotlinModuleBuildTarget<*>, JpsIncrementalCache>
|
||||
): OutputItemsCollector? {
|
||||
loadPlugins(representativeTarget, commonArguments, context)
|
||||
|
||||
kotlinChunk.targets.forEach {
|
||||
it.nextRound(context)
|
||||
}
|
||||
|
||||
if (representativeTarget.isIncrementalCompilationEnabled) {
|
||||
for (target in kotlinChunk.targets) {
|
||||
val cache = incrementalCaches[target]
|
||||
val jpsTarget = target.jpsModuleBuildTarget
|
||||
|
||||
val targetDirtyFiles = dirtyFilesHolder.byTarget[jpsTarget]
|
||||
if (cache != null && targetDirtyFiles != null) {
|
||||
val dirtyFiles = targetDirtyFiles.dirty.keys + targetDirtyFiles.removed
|
||||
val complementaryFiles = cache.getComplementaryFilesRecursive(dirtyFiles)
|
||||
|
||||
// Get all parts of @JvmMultifileClass file for simultaneous rebuild
|
||||
var dirtyMultifileClassFiles: Collection<File> = emptyList()
|
||||
if (cache is IncrementalJvmCache) {
|
||||
dirtyMultifileClassFiles = cache.classesBySources(dirtyFiles)
|
||||
.filter { cache.isMultifileFacade(it) }
|
||||
.flatMap { cache.getAllPartsOfMultifileFacade(it).orEmpty() }
|
||||
.flatMap { cache.sourcesByInternalName(it) }
|
||||
.distinct()
|
||||
.filter { !dirtyFiles.contains(it) }
|
||||
}
|
||||
fsOperations.markFilesForCurrentRound(jpsTarget, complementaryFiles + dirtyMultifileClassFiles)
|
||||
|
||||
cache.markDirty(targetDirtyFiles.dirty.keys + targetDirtyFiles.removed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val isDoneSomething = representativeTarget.compileModuleChunk(commonArguments, dirtyFilesHolder, environment)
|
||||
|
||||
return if (isDoneSomething) environment.outputItemsCollector else null
|
||||
}
|
||||
|
||||
private fun loadPlugins(
|
||||
representativeTarget: KotlinModuleBuildTarget<*>,
|
||||
commonArguments: CommonCompilerArguments,
|
||||
context: CompileContext
|
||||
) {
|
||||
fun concatenate(strings: Array<String>?, cp: List<String>) = arrayOf(*strings.orEmpty(), *cp.toTypedArray())
|
||||
|
||||
for (argumentProvider in ServiceLoader.load(KotlinJpsCompilerArgumentsProvider::class.java)) {
|
||||
val jpsModuleBuildTarget = representativeTarget.jpsModuleBuildTarget
|
||||
// appending to pluginOptions
|
||||
commonArguments.pluginOptions = concatenate(
|
||||
commonArguments.pluginOptions,
|
||||
argumentProvider.getExtraArguments(jpsModuleBuildTarget, context)
|
||||
)
|
||||
// appending to classpath
|
||||
commonArguments.pluginClasspaths = concatenate(
|
||||
commonArguments.pluginClasspaths,
|
||||
argumentProvider.getClasspath(jpsModuleBuildTarget, context)
|
||||
)
|
||||
|
||||
LOG.debug("Plugin loaded: ${argumentProvider::class.java.simpleName}")
|
||||
}
|
||||
}
|
||||
|
||||
private fun createCompileEnvironment(
|
||||
context: CompileContext,
|
||||
kotlinModuleBuilderTarget: KotlinModuleBuildTarget<*>,
|
||||
incrementalCaches: Map<KotlinModuleBuildTarget<*>, JpsIncrementalCache>,
|
||||
lookupTracker: LookupTracker,
|
||||
exceptActualTracer: ExpectActualTracker,
|
||||
chunk: ModuleChunk,
|
||||
messageCollector: MessageCollectorAdapter
|
||||
): JpsCompilerEnvironment? {
|
||||
val compilerServices = with(Services.Builder()) {
|
||||
kotlinModuleBuilderTarget.makeServices(this, incrementalCaches, lookupTracker, exceptActualTracer)
|
||||
build()
|
||||
}
|
||||
|
||||
val paths = computeKotlinPathsForJpsPlugin()
|
||||
if (paths == null || !paths.homePath.exists()) {
|
||||
messageCollector.report(
|
||||
ERROR, "Cannot find kotlinc home. Make sure the plugin is properly installed, " +
|
||||
"or specify $JPS_KOTLIN_HOME_PROPERTY system property"
|
||||
)
|
||||
return null
|
||||
}
|
||||
|
||||
return JpsCompilerEnvironment(
|
||||
paths,
|
||||
compilerServices,
|
||||
classesToLoadByParent,
|
||||
messageCollector,
|
||||
OutputItemsCollectorImpl(),
|
||||
ProgressReporterImpl(context, chunk)
|
||||
)
|
||||
}
|
||||
|
||||
// When JPS is run on TeamCity, it can not rely on Kotlin plugin layout,
|
||||
// so the path to Kotlin is specified in a system property
|
||||
private fun computeKotlinPathsForJpsPlugin(): KotlinPaths? {
|
||||
if (System.getProperty("kotlin.jps.tests").equals("true", ignoreCase = true)) {
|
||||
return PathUtil.kotlinPathsForDistDirectory
|
||||
}
|
||||
|
||||
val jpsKotlinHome = System.getProperty(JPS_KOTLIN_HOME_PROPERTY)
|
||||
if (jpsKotlinHome != null) {
|
||||
return KotlinPathsFromHomeDir(File(jpsKotlinHome))
|
||||
}
|
||||
|
||||
val jar = PathUtil.pathUtilJar.takeIf(File::exists)
|
||||
if (jar?.name == "kotlin-jps-plugin.jar") {
|
||||
val pluginHome = jar.parentFile.parentFile.parentFile
|
||||
return KotlinPathsFromHomeDir(File(pluginHome, PathUtil.HOME_FOLDER_NAME))
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun getGeneratedFiles(
|
||||
context: CompileContext,
|
||||
chunk: ModuleChunk,
|
||||
outputItemCollector: OutputItemsCollectorImpl
|
||||
): Map<ModuleBuildTarget, List<GeneratedFile>> {
|
||||
// If there's only one target, this map is empty: get() always returns null, and the representativeTarget will be used below
|
||||
val sourceToTarget = HashMap<File, ModuleBuildTarget>()
|
||||
if (chunk.targets.size > 1) {
|
||||
for (target in chunk.targets) {
|
||||
context.kotlinBuildTargets[target]?.sourceFiles?.forEach {
|
||||
sourceToTarget[it] = target
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val representativeTarget = chunk.representativeTarget()
|
||||
fun SimpleOutputItem.target() =
|
||||
sourceFiles.firstOrNull()?.let { sourceToTarget[it] }
|
||||
?: chunk.targets.singleOrNull { target ->
|
||||
target.outputDir?.let { outputDir ->
|
||||
outputFile.startsWith(outputDir)
|
||||
} ?: false
|
||||
}
|
||||
?: representativeTarget
|
||||
|
||||
return outputItemCollector.outputs
|
||||
.sortedBy { it.outputFile }
|
||||
.groupBy(SimpleOutputItem::target, SimpleOutputItem::toGeneratedFile)
|
||||
}
|
||||
|
||||
private fun updateLookupStorage(
|
||||
lookupTracker: LookupTracker,
|
||||
lookupStorageManager: JpsLookupStorageManager,
|
||||
dirtyFilesHolder: KotlinDirtySourceFilesHolder
|
||||
) {
|
||||
if (lookupTracker !is LookupTrackerImpl)
|
||||
throw AssertionError("Lookup tracker is expected to be LookupTrackerImpl, got ${lookupTracker::class.java}")
|
||||
|
||||
lookupStorageManager.withLookupStorage { lookupStorage ->
|
||||
lookupStorage.removeLookupsFrom(dirtyFilesHolder.allDirtyFiles.asSequence() + dirtyFilesHolder.allRemovedFilesFiles.asSequence())
|
||||
lookupStorage.addAll(lookupTracker.lookups, lookupTracker.pathInterner.values)
|
||||
}
|
||||
}
|
||||
|
||||
private fun markDirtyComplementaryMultifileClasses(
|
||||
generatedFiles: Map<ModuleBuildTarget, List<GeneratedFile>>,
|
||||
kotlinContext: KotlinCompileContext,
|
||||
incrementalCaches: Map<KotlinModuleBuildTarget<*>, JpsIncrementalCache>,
|
||||
fsOperations: FSOperationsHelper
|
||||
) {
|
||||
for ((target, files) in generatedFiles) {
|
||||
val kotlinModuleBuilderTarget = kotlinContext.targetsBinding[target] ?: continue
|
||||
val cache = incrementalCaches[kotlinModuleBuilderTarget] as? IncrementalJvmCache ?: continue
|
||||
val generated = files.filterIsInstance<GeneratedJvmClass>()
|
||||
val multifileClasses = generated.filter { it.outputClass.classHeader.kind == KotlinClassHeader.Kind.MULTIFILE_CLASS }
|
||||
val expectedAllParts = multifileClasses.flatMap { cache.getAllPartsOfMultifileFacade(it.outputClass.className).orEmpty() }
|
||||
if (multifileClasses.isEmpty()) continue
|
||||
val actualParts = generated.filter { it.outputClass.classHeader.kind == KotlinClassHeader.Kind.MULTIFILE_CLASS_PART }
|
||||
.map { it.outputClass.className.toString() }
|
||||
if (!actualParts.containsAll(expectedAllParts)) {
|
||||
fsOperations.markFiles(expectedAllParts.flatMap { cache.sourcesByInternalName(it) }
|
||||
+ multifileClasses.flatMap { it.sourceFiles })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class JpsICReporter : ICReporterBase() {
|
||||
override fun reportCompileIteration(incremental: Boolean, sourceFiles: Collection<File>, exitCode: ExitCode) {
|
||||
}
|
||||
|
||||
override fun report(message: () -> String) {
|
||||
if (KotlinBuilder.LOG.isDebugEnabled) {
|
||||
KotlinBuilder.LOG.debug(message())
|
||||
}
|
||||
}
|
||||
|
||||
override fun reportVerbose(message: () -> String) {
|
||||
report(message)
|
||||
}
|
||||
}
|
||||
|
||||
private fun ChangesCollector.processChangesUsingLookups(
|
||||
compiledFiles: Set<File>,
|
||||
lookupStorageManager: JpsLookupStorageManager,
|
||||
fsOperations: FSOperationsHelper,
|
||||
caches: Iterable<JpsIncrementalCache>
|
||||
) {
|
||||
val allCaches = caches.flatMap { it.thisWithDependentCaches }
|
||||
val reporter = JpsICReporter()
|
||||
|
||||
reporter.reportVerbose { "Start processing changes" }
|
||||
|
||||
val dirtyFiles = getDirtyFiles(allCaches, lookupStorageManager)
|
||||
// if list of inheritors of sealed class has changed it should be recompiled with all the inheritors
|
||||
// Here we have a small optimization. Do not recompile the bunch if ALL these files were recompiled during the previous round.
|
||||
val excludeFiles = if (compiledFiles.containsAll(dirtyFiles.forceRecompileTogether))
|
||||
compiledFiles
|
||||
else
|
||||
compiledFiles.minus(dirtyFiles.forceRecompileTogether)
|
||||
fsOperations.markInChunkOrDependents(
|
||||
(dirtyFiles.dirtyFiles + dirtyFiles.forceRecompileTogether).asIterable(),
|
||||
excludeFiles = excludeFiles
|
||||
)
|
||||
|
||||
reporter.reportVerbose { "End of processing changes" }
|
||||
}
|
||||
|
||||
data class FilesToRecompile(val dirtyFiles: Set<File>, val forceRecompileTogether: Set<File>)
|
||||
|
||||
private fun ChangesCollector.getDirtyFiles(
|
||||
caches: Iterable<IncrementalCacheCommon>,
|
||||
lookupStorageManager: JpsLookupStorageManager
|
||||
): FilesToRecompile {
|
||||
val reporter = JpsICReporter()
|
||||
val (dirtyLookupSymbols, dirtyClassFqNames, forceRecompile) = getDirtyData(caches, reporter)
|
||||
val dirtyFilesFromLookups = lookupStorageManager.withLookupStorage {
|
||||
mapLookupSymbolsToFiles(it, dirtyLookupSymbols, reporter)
|
||||
}
|
||||
return FilesToRecompile(
|
||||
dirtyFilesFromLookups + mapClassesFqNamesToFiles(caches, dirtyClassFqNames, reporter),
|
||||
mapClassesFqNamesToFiles(caches, forceRecompile, reporter)
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
private fun getLookupTracker(project: JpsProject, representativeTarget: KotlinModuleBuildTarget<*>): LookupTracker {
|
||||
val testLookupTracker = project.testingContext?.lookupTracker ?: LookupTracker.DO_NOTHING
|
||||
|
||||
if (representativeTarget.isIncrementalCompilationEnabled) return LookupTrackerImpl(testLookupTracker)
|
||||
|
||||
return testLookupTracker
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.build;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jps.incremental.BuilderService;
|
||||
import org.jetbrains.jps.incremental.ModuleLevelBuilder;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class KotlinBuilderService extends BuilderService {
|
||||
@NotNull
|
||||
@Override
|
||||
public List<? extends ModuleLevelBuilder> createModuleLevelBuilders() {
|
||||
return Collections.singletonList(new KotlinBuilder());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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.jps.build
|
||||
|
||||
import org.jetbrains.jps.incremental.ModuleBuildTarget
|
||||
import org.jetbrains.kotlin.config.ApiVersion
|
||||
import org.jetbrains.kotlin.config.LanguageVersion
|
||||
import org.jetbrains.kotlin.config.VersionView
|
||||
import org.jetbrains.kotlin.jps.incremental.CacheStatus
|
||||
import org.jetbrains.kotlin.jps.incremental.JpsIncrementalCache
|
||||
import org.jetbrains.kotlin.jps.incremental.getKotlinCache
|
||||
import org.jetbrains.kotlin.jps.model.kotlinCompilerArguments
|
||||
import org.jetbrains.kotlin.jps.targets.KotlinModuleBuildTarget
|
||||
import org.jetbrains.kotlin.utils.keysToMapExceptNulls
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Chunk of cyclically dependent [KotlinModuleBuildTarget]s
|
||||
*/
|
||||
class KotlinChunk internal constructor(val context: KotlinCompileContext, val targets: List<KotlinModuleBuildTarget<*>>) {
|
||||
val containsTests = targets.any { it.isTests }
|
||||
|
||||
lateinit var dependencies: List<KotlinModuleBuildTarget.Dependency>
|
||||
// Should be initialized only in KotlinChunk.calculateChunkDependencies
|
||||
internal set
|
||||
|
||||
lateinit var dependent: List<KotlinModuleBuildTarget.Dependency>
|
||||
// Should be initialized only in KotlinChunk.calculateChunkDependencies
|
||||
internal set
|
||||
|
||||
// used only during dependency calculation
|
||||
internal var _dependent: MutableSet<KotlinModuleBuildTarget.Dependency>? = mutableSetOf()
|
||||
|
||||
val representativeTarget
|
||||
get() = targets.first()
|
||||
|
||||
val presentableModulesToCompilersList: String
|
||||
get() = targets.joinToString { "${it.module.name} (${it.globalLookupCacheId})" }
|
||||
|
||||
val haveSameCompiler = targets.all { it.javaClass == representativeTarget.javaClass }
|
||||
|
||||
private val defaultLanguageVersion = VersionView.RELEASED_VERSION
|
||||
|
||||
val compilerArguments = representativeTarget.jpsModuleBuildTarget.module.kotlinCompilerArguments.also {
|
||||
it.reportOutputFiles = true
|
||||
|
||||
// Always report the version to help diagnosing user issues if they submit the compiler output
|
||||
it.version = true
|
||||
|
||||
if (it.languageVersion == null) it.languageVersion = defaultLanguageVersion.versionString
|
||||
}
|
||||
|
||||
val langVersion =
|
||||
compilerArguments.languageVersion?.let { LanguageVersion.fromVersionString(it) }
|
||||
?: defaultLanguageVersion // use default language version when version string is invalid (todo: report warning?)
|
||||
|
||||
val apiVersion =
|
||||
compilerArguments.apiVersion?.let { ApiVersion.parse(it) }
|
||||
?: ApiVersion.createByLanguageVersion(langVersion) // todo: report version parse error?
|
||||
|
||||
val isEnabled: Boolean = representativeTarget.isEnabled(compilerArguments)
|
||||
|
||||
fun shouldRebuild(): Boolean {
|
||||
val buildMetaInfo = representativeTarget.buildMetaInfoFactory.create(compilerArguments)
|
||||
|
||||
targets.forEach { target ->
|
||||
if (target.isVersionChanged(this, buildMetaInfo)) {
|
||||
KotlinBuilder.LOG.info("$target version changed, rebuilding $this")
|
||||
return true
|
||||
}
|
||||
|
||||
if (target.initialLocalCacheAttributesDiff.status == CacheStatus.INVALID) {
|
||||
context.testingLogger?.invalidOrUnusedCache(this, null, target.initialLocalCacheAttributesDiff)
|
||||
KotlinBuilder.LOG.info("$target cache is invalid ${target.initialLocalCacheAttributesDiff}, rebuilding $this")
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
fun buildMetaInfoFile(target: ModuleBuildTarget): File =
|
||||
File(
|
||||
context.dataPaths.getTargetDataRoot(target),
|
||||
representativeTarget.buildMetaInfoFileName
|
||||
)
|
||||
|
||||
fun saveVersions() {
|
||||
context.ensureLookupsCacheAttributesSaved()
|
||||
|
||||
targets.forEach {
|
||||
it.initialLocalCacheAttributesDiff.manager.writeVersion()
|
||||
}
|
||||
|
||||
val serializedMetaInfo = representativeTarget.buildMetaInfoFactory.serializeToString(compilerArguments)
|
||||
|
||||
targets.forEach {
|
||||
buildMetaInfoFile(it.jpsModuleBuildTarget).writeText(serializedMetaInfo)
|
||||
}
|
||||
}
|
||||
|
||||
fun collectDependentChunksRecursivelyExportedOnly(result: MutableSet<KotlinChunk> = mutableSetOf()) {
|
||||
dependent.forEach {
|
||||
if (result.add(it.src.chunk)) {
|
||||
if (it.exported) {
|
||||
it.src.chunk.collectDependentChunksRecursivelyExportedOnly(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun loadCaches(loadDependent: Boolean = true): Map<KotlinModuleBuildTarget<*>, JpsIncrementalCache> {
|
||||
val dataManager = context.dataManager
|
||||
|
||||
val cacheByChunkTarget = targets.keysToMapExceptNulls {
|
||||
dataManager.getKotlinCache(it)
|
||||
}
|
||||
|
||||
if (loadDependent) {
|
||||
addDependentCaches(cacheByChunkTarget.values)
|
||||
}
|
||||
|
||||
return cacheByChunkTarget
|
||||
}
|
||||
|
||||
private fun addDependentCaches(targetsCaches: Collection<JpsIncrementalCache>) {
|
||||
val dependentChunks = mutableSetOf<KotlinChunk>()
|
||||
|
||||
collectDependentChunksRecursivelyExportedOnly(dependentChunks)
|
||||
|
||||
val dataManager = context.dataManager
|
||||
dependentChunks.forEach { decedentChunk ->
|
||||
decedentChunk.targets.forEach {
|
||||
val dependentCache = dataManager.getKotlinCache(it)
|
||||
if (dependentCache != null) {
|
||||
|
||||
for (chunkCache in targetsCaches) {
|
||||
chunkCache.addJpsDependentCache(dependentCache)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The same as [org.jetbrains.jps.ModuleChunk.getPresentableShortName]
|
||||
*/
|
||||
val presentableShortName: String
|
||||
get() = buildString {
|
||||
if (containsTests) append("tests of ")
|
||||
append(targets.first().module.name)
|
||||
if (targets.size > 1) {
|
||||
val andXMore = " and ${targets.size - 1} more"
|
||||
val other = ", " + targets.asSequence().drop(1).joinToString()
|
||||
append(if (other.length < andXMore.length) other else andXMore)
|
||||
}
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "KotlinChunk<${representativeTarget.javaClass.simpleName}>" +
|
||||
"(${targets.joinToString { it.jpsModuleBuildTarget.presentableName }})"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,314 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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.jps.build
|
||||
|
||||
import org.jetbrains.jps.ModuleChunk
|
||||
import org.jetbrains.jps.incremental.CompileContext
|
||||
import org.jetbrains.jps.incremental.FSOperations
|
||||
import org.jetbrains.jps.incremental.GlobalContextKey
|
||||
import org.jetbrains.jps.incremental.fs.CompilationRound
|
||||
import org.jetbrains.jps.incremental.messages.BuildMessage
|
||||
import org.jetbrains.jps.incremental.messages.CompilerMessage
|
||||
import org.jetbrains.kotlin.config.CompilerRunnerConstants
|
||||
import org.jetbrains.kotlin.config.CompilerRunnerConstants.*
|
||||
import org.jetbrains.kotlin.incremental.LookupSymbol
|
||||
import org.jetbrains.kotlin.incremental.storage.FileToPathConverter
|
||||
import org.jetbrains.kotlin.jps.incremental.*
|
||||
import org.jetbrains.kotlin.jps.targets.KotlinTargetsIndex
|
||||
import org.jetbrains.kotlin.jps.targets.KotlinTargetsIndexBuilder
|
||||
import org.jetbrains.kotlin.jps.targets.KotlinUnsupportedModuleBuildTarget
|
||||
import java.io.File
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
/**
|
||||
* KotlinCompileContext is shared between all threads (i.e. it is [GlobalContextKey]).
|
||||
*
|
||||
* It is initialized lazily, and only before building of first chunk with kotlin code,
|
||||
* and will be disposed on build finish.
|
||||
*/
|
||||
internal val CompileContext.kotlin: KotlinCompileContext
|
||||
get() {
|
||||
val userData = getUserData(kotlinCompileContextKey)
|
||||
if (userData != null) return userData
|
||||
|
||||
// here is error (KotlinCompilation available only at build phase)
|
||||
// let's also check for concurrent initialization
|
||||
val errorMessage = "KotlinCompileContext available only at build phase " +
|
||||
"(between first KotlinBuilder.chunkBuildStarted and KotlinBuilder.buildFinished)"
|
||||
|
||||
synchronized(kotlinCompileContextKey) {
|
||||
val newUsedData = getUserData(kotlinCompileContextKey)
|
||||
if (newUsedData != null) {
|
||||
error("Concurrent CompileContext.kotlin getter call and KotlinCompileContext initialization detected: $errorMessage")
|
||||
}
|
||||
}
|
||||
|
||||
error(errorMessage)
|
||||
}
|
||||
|
||||
internal val kotlinCompileContextKey = GlobalContextKey<KotlinCompileContext>("kotlin")
|
||||
|
||||
class KotlinCompileContext(val jpsContext: CompileContext) {
|
||||
val dataManager = jpsContext.projectDescriptor.dataManager
|
||||
val dataPaths = dataManager.dataPaths
|
||||
val testingLogger: TestingBuildLogger?
|
||||
get() = jpsContext.testingContext?.buildLogger
|
||||
|
||||
val targetsIndex: KotlinTargetsIndex = KotlinTargetsIndexBuilder(this).build()
|
||||
|
||||
val targetsBinding
|
||||
get() = targetsIndex.byJpsTarget
|
||||
|
||||
val lookupsCacheAttributesManager: CompositeLookupsCacheAttributesManager = makeLookupsCacheAttributesManager()
|
||||
|
||||
val shouldCheckCacheVersions = System.getProperty(KotlinBuilder.SKIP_CACHE_VERSION_CHECK_PROPERTY) == null
|
||||
|
||||
val hasKotlinMarker = HasKotlinMarker(dataManager)
|
||||
|
||||
val isInstrumentationEnabled: Boolean by lazy {
|
||||
val value = System.getProperty("kotlin.jps.instrument.bytecode")?.toBoolean() ?: false
|
||||
if (value) {
|
||||
val message = "Experimental bytecode instrumentation for Kotlin classes is enabled"
|
||||
jpsContext.processMessage(CompilerMessage(KOTLIN_COMPILER_NAME, BuildMessage.Kind.INFO, message))
|
||||
}
|
||||
value
|
||||
}
|
||||
|
||||
val fileToPathConverter: FileToPathConverter =
|
||||
JpsFileToPathConverter(jpsContext.projectDescriptor.project)
|
||||
|
||||
val lookupStorageManager = JpsLookupStorageManager(dataManager, fileToPathConverter)
|
||||
|
||||
/**
|
||||
* Flag to prevent rebuilding twice.
|
||||
*
|
||||
* TODO: looks like it is not required since cache version checking are refactored
|
||||
*/
|
||||
val rebuildAfterCacheVersionChanged = RebuildAfterCacheVersionChangeMarker(dataManager)
|
||||
|
||||
var rebuildingAllKotlin = false
|
||||
|
||||
/**
|
||||
* Note, [loadLookupsCacheStateDiff] should be initialized last as it requires initialized
|
||||
* [targetsIndex], [hasKotlinMarker] and [rebuildAfterCacheVersionChanged] (see [markChunkForRebuildBeforeBuild])
|
||||
*/
|
||||
private val initialLookupsCacheStateDiff: CacheAttributesDiff<*> = loadLookupsCacheStateDiff()
|
||||
|
||||
private fun makeLookupsCacheAttributesManager(): CompositeLookupsCacheAttributesManager {
|
||||
val expectedLookupsCacheComponents = mutableSetOf<String>()
|
||||
|
||||
targetsIndex.chunks.forEach { chunk ->
|
||||
chunk.targets.forEach { target ->
|
||||
if (target.isIncrementalCompilationEnabled) {
|
||||
expectedLookupsCacheComponents.add(target.globalLookupCacheId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val lookupsCacheRootPath = dataPaths.getTargetDataRoot(KotlinDataContainerTarget)
|
||||
return CompositeLookupsCacheAttributesManager(lookupsCacheRootPath, expectedLookupsCacheComponents)
|
||||
}
|
||||
|
||||
private fun loadLookupsCacheStateDiff(): CacheAttributesDiff<CompositeLookupsCacheAttributes> {
|
||||
val diff = lookupsCacheAttributesManager.loadDiff()
|
||||
|
||||
if (diff.status == CacheStatus.VALID) {
|
||||
// try to perform a lookup
|
||||
// request rebuild if storage is corrupted
|
||||
try {
|
||||
lookupStorageManager.withLookupStorage {
|
||||
it.get(LookupSymbol("<#NAME#>", "<#SCOPE#>"))
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
// replace to jpsReportInternalBuilderError when IDEA-201297 will be implemented
|
||||
jpsContext.processMessage(
|
||||
CompilerMessage(
|
||||
"Kotlin", BuildMessage.Kind.WARNING,
|
||||
"Incremental caches are corrupted. All Kotlin code will be rebuilt."
|
||||
)
|
||||
)
|
||||
KotlinBuilder.LOG.info(Error("Lookup storage is corrupted, probe failed: ${e.message}", e))
|
||||
|
||||
markAllKotlinForRebuild("Lookup storage is corrupted")
|
||||
return diff.copy(actual = null)
|
||||
}
|
||||
}
|
||||
|
||||
return diff
|
||||
}
|
||||
|
||||
fun hasKotlin() = targetsIndex.chunks.any { chunk ->
|
||||
chunk.targets.any { target ->
|
||||
hasKotlinMarker[target] == true
|
||||
}
|
||||
}
|
||||
|
||||
fun checkCacheVersions() {
|
||||
when (initialLookupsCacheStateDiff.status) {
|
||||
CacheStatus.INVALID -> {
|
||||
// global cache needs to be rebuilt
|
||||
|
||||
testingLogger?.invalidOrUnusedCache(null, null, initialLookupsCacheStateDiff)
|
||||
|
||||
if (initialLookupsCacheStateDiff.actual != null) {
|
||||
markAllKotlinForRebuild("Kotlin incremental cache settings or format was changed")
|
||||
clearLookupCache()
|
||||
} else {
|
||||
markAllKotlinForRebuild("Kotlin incremental cache is missed or corrupted")
|
||||
}
|
||||
}
|
||||
CacheStatus.VALID -> Unit
|
||||
CacheStatus.SHOULD_BE_CLEARED -> {
|
||||
jpsContext.testingContext?.buildLogger?.invalidOrUnusedCache(null, null, initialLookupsCacheStateDiff)
|
||||
KotlinBuilder.LOG.info("Removing global cache as it is not required anymore: $initialLookupsCacheStateDiff")
|
||||
|
||||
clearAllCaches()
|
||||
}
|
||||
CacheStatus.CLEARED -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
private val lookupAttributesSaved = AtomicBoolean(false)
|
||||
|
||||
/**
|
||||
* Called on every successful compilation
|
||||
*/
|
||||
fun ensureLookupsCacheAttributesSaved() {
|
||||
if (lookupAttributesSaved.compareAndSet(false, true)) {
|
||||
initialLookupsCacheStateDiff.manager.writeVersion()
|
||||
}
|
||||
}
|
||||
|
||||
fun checkChunkCacheVersion(chunk: KotlinChunk) {
|
||||
if (shouldCheckCacheVersions && !rebuildingAllKotlin) {
|
||||
if (chunk.shouldRebuild()) markChunkForRebuildBeforeBuild(chunk)
|
||||
}
|
||||
}
|
||||
|
||||
private fun logMarkDirtyForTestingBeforeRound(file: File, shouldProcess: Boolean): Boolean {
|
||||
if (shouldProcess) {
|
||||
testingLogger?.markedAsDirtyBeforeRound(listOf(file))
|
||||
}
|
||||
return shouldProcess
|
||||
}
|
||||
|
||||
private fun markAllKotlinForRebuild(reason: String) {
|
||||
if (rebuildingAllKotlin) return
|
||||
rebuildingAllKotlin = true
|
||||
|
||||
KotlinBuilder.LOG.info("Rebuilding all Kotlin: $reason")
|
||||
|
||||
targetsIndex.chunks.forEach {
|
||||
markChunkForRebuildBeforeBuild(it)
|
||||
}
|
||||
|
||||
lookupStorageManager.cleanLookupStorage(KotlinBuilder.LOG)
|
||||
}
|
||||
|
||||
private fun markChunkForRebuildBeforeBuild(chunk: KotlinChunk) {
|
||||
chunk.targets.forEach {
|
||||
FSOperations.markDirty(jpsContext, CompilationRound.NEXT, it.jpsModuleBuildTarget) { file ->
|
||||
logMarkDirtyForTestingBeforeRound(file, file.isKotlinSourceFile)
|
||||
}
|
||||
|
||||
dataManager.getKotlinCache(it)?.clean()
|
||||
hasKotlinMarker.clean(it)
|
||||
rebuildAfterCacheVersionChanged[it] = true
|
||||
}
|
||||
}
|
||||
|
||||
private fun clearAllCaches() {
|
||||
clearLookupCache()
|
||||
|
||||
KotlinBuilder.LOG.info("Clearing caches for all targets")
|
||||
targetsIndex.chunks.forEach { chunk ->
|
||||
chunk.targets.forEach {
|
||||
dataManager.getKotlinCache(it)?.clean()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun clearLookupCache() {
|
||||
KotlinBuilder.LOG.info("Clearing lookup cache")
|
||||
lookupStorageManager.cleanLookupStorage(KotlinBuilder.LOG)
|
||||
initialLookupsCacheStateDiff.manager.writeVersion()
|
||||
}
|
||||
|
||||
fun cleanupCaches() {
|
||||
// todo: remove lookups for targets with disabled IC (or split global lookups cache into several caches for each compiler)
|
||||
|
||||
targetsIndex.chunks.forEach { chunk ->
|
||||
chunk.targets.forEach { target ->
|
||||
if (target.initialLocalCacheAttributesDiff.status == CacheStatus.SHOULD_BE_CLEARED) {
|
||||
KotlinBuilder.LOG.info(
|
||||
"$target caches is cleared as not required anymore: ${target.initialLocalCacheAttributesDiff}"
|
||||
)
|
||||
testingLogger?.invalidOrUnusedCache(null, target, target.initialLocalCacheAttributesDiff)
|
||||
target.initialLocalCacheAttributesDiff.manager.writeVersion(null)
|
||||
dataManager.getKotlinCache(target)?.clean()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun dispose() {
|
||||
|
||||
}
|
||||
|
||||
fun getChunk(rawChunk: ModuleChunk): KotlinChunk? {
|
||||
val rawRepresentativeTarget = rawChunk.representativeTarget()
|
||||
if (rawRepresentativeTarget !in targetsBinding) return null
|
||||
|
||||
return targetsIndex.chunksByJpsRepresentativeTarget[rawRepresentativeTarget]
|
||||
?: error("Kotlin binding for chunk $this is not loaded at build start")
|
||||
}
|
||||
|
||||
fun reportUnsupportedTargets() {
|
||||
// group all KotlinUnsupportedModuleBuildTarget by kind
|
||||
// only representativeTarget will be added
|
||||
val byKind = mutableMapOf<String?, MutableList<KotlinUnsupportedModuleBuildTarget>>()
|
||||
|
||||
targetsIndex.chunks.forEach {
|
||||
val target = it.representativeTarget
|
||||
if (target is KotlinUnsupportedModuleBuildTarget) {
|
||||
if (target.sourceFiles.isNotEmpty()) {
|
||||
byKind.getOrPut(target.kind) { mutableListOf() }.add(target)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
byKind.forEach { (kind, targets) ->
|
||||
targets.sortBy { it.module.name }
|
||||
val chunkNames = targets.map { it.chunk.presentableShortName }
|
||||
val presentableChunksListString = chunkNames.joinToReadableString()
|
||||
|
||||
val msg =
|
||||
if (kind == null) {
|
||||
"$presentableChunksListString is not yet supported in IDEA internal build system. " +
|
||||
"Please use Gradle to build them (enable 'Delegate IDE build/run actions to Gradle' in Settings)."
|
||||
} else {
|
||||
"$kind is not yet supported in IDEA internal build system. " +
|
||||
"Please use Gradle to build $presentableChunksListString (enable 'Delegate IDE build/run actions to Gradle' in Settings)."
|
||||
}
|
||||
|
||||
testingLogger?.addCustomMessage(msg)
|
||||
jpsContext.processMessage(
|
||||
CompilerMessage(
|
||||
KOTLIN_COMPILER_NAME,
|
||||
BuildMessage.Kind.WARNING,
|
||||
msg
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun List<String>.joinToReadableString(): String = when {
|
||||
size > 5 -> take(5).joinToString() + " and ${size - 5} more"
|
||||
size > 1 -> dropLast(1).joinToString() + " and ${last()}"
|
||||
size == 1 -> single()
|
||||
else -> ""
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.build
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtilRt
|
||||
import org.jetbrains.jps.ModuleChunk
|
||||
import org.jetbrains.jps.builders.DirtyFilesHolder
|
||||
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor
|
||||
import org.jetbrains.jps.incremental.CompileContext
|
||||
import org.jetbrains.jps.incremental.ModuleBuildTarget
|
||||
import org.jetbrains.kotlin.jps.targets.KotlinModuleBuildTarget
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Holding kotlin dirty files list for particular build round.
|
||||
* Dirty and removed files set are initialized from [delegate].
|
||||
*
|
||||
* Additional dirty files should be added only through [FSOperationsHelper.markFilesForCurrentRound]
|
||||
*/
|
||||
class KotlinDirtySourceFilesHolder(
|
||||
val chunk: ModuleChunk,
|
||||
val context: CompileContext,
|
||||
delegate: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>
|
||||
) {
|
||||
val byTarget: Map<ModuleBuildTarget, TargetFiles>
|
||||
|
||||
inner class TargetFiles(val target: ModuleBuildTarget, val removed: Collection<File>) {
|
||||
private val _dirty: MutableMap<File, KotlinModuleBuildTarget.Source> = mutableMapOf()
|
||||
|
||||
val dirty: Map<File, KotlinModuleBuildTarget.Source>
|
||||
get() = _dirty
|
||||
|
||||
/**
|
||||
* Should be called only from [FSOperationsHelper.markFilesForCurrentRound]
|
||||
* and during KotlinDirtySourceFilesHolder initialization.
|
||||
*/
|
||||
internal fun _markDirty(file: File, root: JavaSourceRootDescriptor) {
|
||||
val isCrossCompiled = root is KotlinIncludedModuleSourceRoot
|
||||
val old = _dirty.put(file.canonicalFile, KotlinModuleBuildTarget.Source(file, isCrossCompiled))
|
||||
|
||||
check(old == null || old.isCrossCompiled == isCrossCompiled) {
|
||||
"`${file.canonicalFile}` already marked as dirty: " +
|
||||
"old is cross compiled: ${old!!.isCrossCompiled}, " +
|
||||
"new is cross compiled: $isCrossCompiled"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val hasRemovedFiles: Boolean
|
||||
get() = byTarget.any { it.value.removed.isNotEmpty() }
|
||||
|
||||
val hasDirtyFiles: Boolean
|
||||
get() = byTarget.any { it.value.dirty.isNotEmpty() }
|
||||
|
||||
val hasDirtyOrRemovedFiles: Boolean
|
||||
get() = hasRemovedFiles || hasDirtyFiles
|
||||
|
||||
init {
|
||||
val byTarget = mutableMapOf<ModuleBuildTarget, TargetFiles>()
|
||||
|
||||
chunk.targets.forEach { target ->
|
||||
val removedFiles = delegate.getRemovedFiles(target)
|
||||
.map { File(it) }
|
||||
.filter { it.isKotlinSourceFile }
|
||||
|
||||
byTarget[target] = TargetFiles(target, removedFiles)
|
||||
}
|
||||
|
||||
delegate.processDirtyFiles { target, file, root ->
|
||||
val targetInfo = byTarget[target]
|
||||
?: error("processDirtyFiles should callback only on chunk `$chunk` targets (`$target` is not)")
|
||||
|
||||
if (file.isKotlinSourceFile) {
|
||||
targetInfo._markDirty(file, root)
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
this.byTarget = byTarget
|
||||
}
|
||||
|
||||
fun getDirtyFiles(target: ModuleBuildTarget): Map<File, KotlinModuleBuildTarget.Source> =
|
||||
byTarget[target]?.dirty ?: mapOf()
|
||||
|
||||
fun getRemovedFiles(target: ModuleBuildTarget): Collection<File> =
|
||||
byTarget[target]?.removed ?: listOf()
|
||||
|
||||
val allDirtyFiles: Set<File>
|
||||
get() = byTarget.flatMapTo(mutableSetOf()) { it.value.dirty.keys }
|
||||
|
||||
val allRemovedFilesFiles: Set<File>
|
||||
get() = byTarget.flatMapTo(mutableSetOf()) { it.value.removed }
|
||||
}
|
||||
|
||||
val File.isKotlinSourceFile: Boolean
|
||||
get() = FileUtilRt.extensionEquals(name, "kt") || FileUtilRt.extensionEquals(name, "kts")
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2000-2018 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.jps.build
|
||||
|
||||
import org.jetbrains.jps.api.BasicFuture
|
||||
import org.jetbrains.jps.builders.java.JavaBuilderExtension
|
||||
import org.jetbrains.jps.builders.java.dependencyView.Callbacks
|
||||
import org.jetbrains.jps.incremental.CompileContext
|
||||
import org.jetbrains.kotlin.incremental.LookupSymbol
|
||||
import java.io.File
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.concurrent.Future
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class KotlinJavaBuilderExtension : JavaBuilderExtension() {
|
||||
override fun getConstantSearch(context: CompileContext): Callbacks.ConstantAffectionResolver {
|
||||
return KotlinLookupConstantSearch(context)
|
||||
}
|
||||
}
|
||||
|
||||
private class KotlinLookupConstantSearch(context: CompileContext) : Callbacks.ConstantAffectionResolver {
|
||||
private val pool = Executors.newSingleThreadExecutor()
|
||||
private val kotlinContext by lazy { context.kotlin }
|
||||
|
||||
override fun request(
|
||||
ownerClassName: String,
|
||||
fieldName: String,
|
||||
accessFlags: Int,
|
||||
fieldRemoved: Boolean,
|
||||
accessChanged: Boolean
|
||||
): Future<Callbacks.ConstantAffection> {
|
||||
val future = object : BasicFuture<Callbacks.ConstantAffection>() {
|
||||
@Volatile
|
||||
private var result: Callbacks.ConstantAffection = Callbacks.ConstantAffection.EMPTY
|
||||
|
||||
fun result(files: Collection<File>) {
|
||||
result = Callbacks.ConstantAffection(files)
|
||||
setDone()
|
||||
}
|
||||
|
||||
override fun get(): Callbacks.ConstantAffection {
|
||||
super.get()
|
||||
return result
|
||||
}
|
||||
|
||||
override fun get(timeout: Long, unit: TimeUnit): Callbacks.ConstantAffection {
|
||||
super.get(timeout, unit)
|
||||
return result
|
||||
}
|
||||
}
|
||||
pool.submit {
|
||||
if (!future.isCancelled) {
|
||||
kotlinContext.lookupStorageManager.withLookupStorage { storage ->
|
||||
val paths = storage.get(LookupSymbol(name = fieldName, scope = ownerClassName))
|
||||
future.result(paths.map { File(it) })
|
||||
}
|
||||
}
|
||||
}
|
||||
return future
|
||||
}
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.build
|
||||
|
||||
import org.jetbrains.jps.incremental.CompileContext
|
||||
import org.jetbrains.jps.incremental.ModuleBuildTarget
|
||||
|
||||
interface KotlinJpsCompilerArgumentsProvider {
|
||||
fun getExtraArguments(moduleBuildTarget: ModuleBuildTarget, context: CompileContext): List<String>
|
||||
fun getClasspath(moduleBuildTarget: ModuleBuildTarget, context: CompileContext): List<String>
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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.jps.build
|
||||
|
||||
import org.jetbrains.jps.builders.AdditionalRootsProviderService
|
||||
import org.jetbrains.jps.builders.BuildTarget
|
||||
import org.jetbrains.jps.builders.java.ResourceRootDescriptor
|
||||
import org.jetbrains.jps.builders.java.ResourcesTargetType
|
||||
import org.jetbrains.jps.builders.storage.BuildDataPaths
|
||||
import org.jetbrains.jps.incremental.ResourcesTarget
|
||||
import org.jetbrains.jps.model.java.JavaResourceRootProperties
|
||||
import org.jetbrains.kotlin.config.ResourceKotlinRootType
|
||||
import org.jetbrains.kotlin.config.TestResourceKotlinRootType
|
||||
|
||||
class KotlinResourcesRootProvider : AdditionalRootsProviderService<ResourceRootDescriptor>(ResourcesTargetType.ALL_TYPES) {
|
||||
override fun getAdditionalRoots(
|
||||
target: BuildTarget<ResourceRootDescriptor>,
|
||||
dataPaths: BuildDataPaths?
|
||||
): List<ResourceRootDescriptor> {
|
||||
val moduleBuildTarget = target as? ResourcesTarget ?: return listOf()
|
||||
val module = moduleBuildTarget.module
|
||||
|
||||
val result = mutableListOf<ResourceRootDescriptor>()
|
||||
|
||||
// Add source roots with type KotlinResourceRootType.
|
||||
// See the note in KotlinSourceRootProvider
|
||||
val kotlinResourceRootType = if (target.isTests) TestResourceKotlinRootType else ResourceKotlinRootType
|
||||
module.getSourceRoots(kotlinResourceRootType).forEach {
|
||||
result.add(
|
||||
ResourceRootDescriptor(
|
||||
it.file,
|
||||
target,
|
||||
it.properties.packagePrefix,
|
||||
setOf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copied from implementation of org.jetbrains.jps.incremental.ResourcesTarget.computeRootDescriptors
|
||||
*/
|
||||
private val JavaResourceRootProperties.packagePrefix: String
|
||||
get() = relativeOutputPath.replace('/', '.')
|
||||
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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.jps.build
|
||||
|
||||
import org.jetbrains.jps.builders.AdditionalRootsProviderService
|
||||
import org.jetbrains.jps.builders.BuildTarget
|
||||
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType
|
||||
import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor
|
||||
import org.jetbrains.jps.builders.storage.BuildDataPaths
|
||||
import org.jetbrains.jps.incremental.ModuleBuildTarget
|
||||
import org.jetbrains.jps.model.java.JavaResourceRootType
|
||||
import org.jetbrains.jps.model.java.JavaSourceRootProperties
|
||||
import org.jetbrains.jps.model.java.JavaSourceRootType
|
||||
import org.jetbrains.jps.model.module.JpsModule
|
||||
import org.jetbrains.jps.model.module.JpsModuleSourceRootType
|
||||
import org.jetbrains.kotlin.config.*
|
||||
import org.jetbrains.kotlin.jps.model.expectedByModules
|
||||
import org.jetbrains.kotlin.jps.model.isTestModule
|
||||
import org.jetbrains.kotlin.jps.model.sourceSetModules
|
||||
import java.io.File
|
||||
|
||||
class KotlinSourceRootProvider : AdditionalRootsProviderService<JavaSourceRootDescriptor>(JavaModuleBuildTargetType.ALL_TYPES) {
|
||||
override fun getAdditionalRoots(
|
||||
target: BuildTarget<JavaSourceRootDescriptor>,
|
||||
dataPaths: BuildDataPaths?
|
||||
): List<JavaSourceRootDescriptor> {
|
||||
val moduleBuildTarget = target as? ModuleBuildTarget ?: return listOf()
|
||||
val module = moduleBuildTarget.module
|
||||
|
||||
val result = mutableListOf<JavaSourceRootDescriptor>()
|
||||
|
||||
// Add source roots with type KotlinSourceRootType.
|
||||
//
|
||||
// Note: `KotlinSourceRootType` cannot be supported directly, since `SourceRootDescriptors` are computed by
|
||||
// `ModuleBuildTarget.computeAllTargets`. `ModuleBuildTarget` is required for incremental compilation.
|
||||
// We cannot define our own `ModuleBuildTarget` since it is final and `ModuleBuildTarget` supports only `JavaSourceRootDescriptor`.
|
||||
// So the only one way to support `KotlinSourceRootType` is to add a fake `JavaSourceRootDescriptor` for each source root with that type.
|
||||
val kotlinSourceRootType = if (target.isTests) TestSourceKotlinRootType else SourceKotlinRootType
|
||||
module.getSourceRoots(kotlinSourceRootType).forEach {
|
||||
result.add(
|
||||
JavaSourceRootDescriptor(
|
||||
it.file,
|
||||
target,
|
||||
false,
|
||||
false,
|
||||
it.properties.packagePrefix,
|
||||
setOf()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
// new multiplatform model support:
|
||||
if (target.isTests == module.isTestModule) {
|
||||
module.sourceSetModules.forEach { sourceSetModule ->
|
||||
addModuleSourceRoots(result, sourceSetModule, target)
|
||||
}
|
||||
}
|
||||
|
||||
// legacy multiplatform model support:
|
||||
module.expectedByModules.forEach { commonModule ->
|
||||
addModuleSourceRoots(result, commonModule, target)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun addModuleSourceRoots(
|
||||
result: MutableList<JavaSourceRootDescriptor>,
|
||||
module: JpsModule,
|
||||
target: ModuleBuildTarget
|
||||
) {
|
||||
for (commonSourceRoot in module.sourceRoots) {
|
||||
val isCommonTestsRootType = commonSourceRoot.rootType.isTestsRootType
|
||||
if (isCommonTestsRootType != null && target.isTests == isCommonTestsRootType) {
|
||||
val javaSourceRootProperties = commonSourceRoot.properties as? JavaSourceRootProperties
|
||||
|
||||
result.add(
|
||||
KotlinIncludedModuleSourceRoot(
|
||||
commonSourceRoot.file,
|
||||
target,
|
||||
javaSourceRootProperties?.isForGeneratedSources ?: false,
|
||||
false,
|
||||
javaSourceRootProperties?.packagePrefix ?: "",
|
||||
setOf()
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val JpsModuleSourceRootType<*>.isTestsRootType
|
||||
get() = when (this) {
|
||||
is KotlinSourceRootType -> this == TestSourceKotlinRootType
|
||||
is KotlinResourceRootType -> this == TestResourceKotlinRootType
|
||||
// for compatibility:
|
||||
is JavaSourceRootType -> this == JavaSourceRootType.TEST_SOURCE
|
||||
is JavaResourceRootType -> this == JavaResourceRootType.TEST_RESOURCE
|
||||
else -> null
|
||||
}
|
||||
|
||||
class KotlinIncludedModuleSourceRoot(
|
||||
root: File,
|
||||
target: ModuleBuildTarget,
|
||||
isGenerated: Boolean,
|
||||
isTemp: Boolean,
|
||||
packagePrefix: String,
|
||||
excludes: Set<File>
|
||||
) : JavaSourceRootDescriptor(root, target, isGenerated, isTemp, packagePrefix, excludes)
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.build
|
||||
|
||||
import org.jetbrains.jps.builders.storage.BuildDataPaths
|
||||
import org.jetbrains.jps.incremental.ModuleBuildTarget
|
||||
import org.jetbrains.jps.incremental.storage.BuildDataManager
|
||||
import org.jetbrains.kotlin.incremental.KOTLIN_CACHE_DIRECTORY_NAME
|
||||
import org.jetbrains.kotlin.jps.targets.KotlinModuleBuildTarget
|
||||
import java.io.File
|
||||
|
||||
private val HAS_KOTLIN_MARKER_FILE_NAME = "has-kotlin-marker.txt"
|
||||
private val REBUILD_AFTER_CACHE_VERSION_CHANGE_MARKER = "rebuild-after-cache-version-change-marker.txt"
|
||||
|
||||
abstract class MarkerFile(private val fileName: String, private val paths: BuildDataPaths) {
|
||||
operator fun get(target: KotlinModuleBuildTarget<*>): Boolean? =
|
||||
get(target.jpsModuleBuildTarget)
|
||||
|
||||
operator fun get(target: ModuleBuildTarget): Boolean? {
|
||||
val file = target.markerFile
|
||||
|
||||
if (!file.exists()) return null
|
||||
|
||||
return file.readText().toBoolean()
|
||||
}
|
||||
|
||||
operator fun set(target: KotlinModuleBuildTarget<*>, value: Boolean) =
|
||||
set(target.jpsModuleBuildTarget, value)
|
||||
|
||||
operator fun set(target: ModuleBuildTarget, value: Boolean) {
|
||||
val file = target.markerFile
|
||||
|
||||
if (!file.exists()) {
|
||||
file.parentFile.mkdirs()
|
||||
file.createNewFile()
|
||||
}
|
||||
|
||||
file.writeText(value.toString())
|
||||
}
|
||||
|
||||
fun clean(target: KotlinModuleBuildTarget<*>) =
|
||||
clean(target.jpsModuleBuildTarget)
|
||||
|
||||
fun clean(target: ModuleBuildTarget) {
|
||||
target.markerFile.delete()
|
||||
}
|
||||
|
||||
private val ModuleBuildTarget.markerFile: File
|
||||
get() {
|
||||
val directory = File(paths.getTargetDataRoot(this), KOTLIN_CACHE_DIRECTORY_NAME)
|
||||
return File(directory, fileName)
|
||||
}
|
||||
}
|
||||
|
||||
class HasKotlinMarker(dataManager: BuildDataManager) : MarkerFile(HAS_KOTLIN_MARKER_FILE_NAME, dataManager.dataPaths)
|
||||
class RebuildAfterCacheVersionChangeMarker(dataManager: BuildDataManager) :
|
||||
MarkerFile(REBUILD_AFTER_CACHE_VERSION_CHANGE_MARKER, dataManager.dataPaths)
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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.jps.build
|
||||
|
||||
import org.jetbrains.jps.incremental.CompileContext
|
||||
import org.jetbrains.jps.incremental.messages.BuildMessage
|
||||
import org.jetbrains.jps.incremental.messages.CompilerMessage
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSourceLocation
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.config.CompilerRunnerConstants
|
||||
import org.jetbrains.kotlin.jps.targets.KotlinModuleBuildTarget
|
||||
import java.io.File
|
||||
|
||||
class MessageCollectorAdapter(
|
||||
private val context: CompileContext,
|
||||
private val kotlinTarget: KotlinModuleBuildTarget<*>?
|
||||
) : MessageCollector {
|
||||
private var hasErrors = false
|
||||
|
||||
override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageSourceLocation?) {
|
||||
hasErrors = hasErrors || severity.isError
|
||||
|
||||
var prefix = ""
|
||||
if (severity == CompilerMessageSeverity.EXCEPTION) {
|
||||
prefix = CompilerRunnerConstants.INTERNAL_ERROR_PREFIX
|
||||
}
|
||||
|
||||
val kind = kind(severity)
|
||||
if (kind != null) {
|
||||
// Report target when cross-compiling common files
|
||||
if (location != null && kotlinTarget != null && kotlinTarget.isFromIncludedSourceRoot(File(location.path))) {
|
||||
val moduleName = kotlinTarget.module.name
|
||||
prefix += "[$moduleName] "
|
||||
}
|
||||
|
||||
context.processMessage(
|
||||
CompilerMessage(
|
||||
CompilerRunnerConstants.KOTLIN_COMPILER_NAME,
|
||||
kind,
|
||||
prefix + message,
|
||||
location?.path,
|
||||
-1, -1, -1,
|
||||
location?.line?.toLong() ?: -1,
|
||||
location?.column?.toLong() ?: -1
|
||||
)
|
||||
)
|
||||
} else {
|
||||
val path = if (location != null) "${location.path}:${location.line}:${location.column}: " else ""
|
||||
KotlinBuilder.LOG.debug(path + message)
|
||||
}
|
||||
}
|
||||
|
||||
override fun clear() {
|
||||
hasErrors = false
|
||||
}
|
||||
|
||||
override fun hasErrors(): Boolean = hasErrors
|
||||
|
||||
private fun kind(severity: CompilerMessageSeverity): BuildMessage.Kind? {
|
||||
return when (severity) {
|
||||
CompilerMessageSeverity.INFO -> BuildMessage.Kind.INFO
|
||||
CompilerMessageSeverity.ERROR, CompilerMessageSeverity.EXCEPTION -> BuildMessage.Kind.ERROR
|
||||
CompilerMessageSeverity.WARNING, CompilerMessageSeverity.STRONG_WARNING -> BuildMessage.Kind.WARNING
|
||||
CompilerMessageSeverity.LOGGING -> null
|
||||
else -> throw IllegalArgumentException("Unsupported severity: $severity")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.build
|
||||
|
||||
import org.jetbrains.jps.ModuleChunk
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.concurrent.atomic.AtomicLong
|
||||
|
||||
class TeamcityStatisticsLogger {
|
||||
private val isOnTeamcity = System.getenv("TEAMCITY_VERSION") != null
|
||||
|
||||
private val totalTime = AtomicLong()
|
||||
|
||||
//NOTE: mostly copied from TeamCityBuildInfoPrinter
|
||||
private fun escapedChar(c: Char): Char {
|
||||
return when (c) {
|
||||
'\n' -> 'n'
|
||||
'\r' -> 'r'
|
||||
'\u0085' -> 'x' // next-line character
|
||||
'\u2028' -> 'l' // line-separator character
|
||||
'\u2029' -> 'p' // paragraph-separator character
|
||||
'|' -> '|'
|
||||
'\'' -> '\''
|
||||
'[' -> '['
|
||||
']' -> ']'
|
||||
else -> 0.toChar()
|
||||
}
|
||||
}
|
||||
|
||||
private fun escape(text: String): String {
|
||||
val escaped = StringBuilder()
|
||||
for (c in text.toCharArray()) {
|
||||
val escChar = escapedChar(c)
|
||||
if (escChar == 0.toChar()) {
|
||||
escaped.append(c)
|
||||
} else {
|
||||
escaped.append('|').append(escChar)
|
||||
}
|
||||
}
|
||||
|
||||
return escaped.toString()
|
||||
}
|
||||
|
||||
fun registerStatistic(moduleChunk: ModuleChunk, timeToCompileNs: Long) {
|
||||
if (!isOnTeamcity) return
|
||||
|
||||
totalTime.addAndGet(timeToCompileNs)
|
||||
printPerChunkStatistics(moduleChunk, timeToCompileNs)
|
||||
}
|
||||
|
||||
private fun printPerChunkStatistics(moduleChunk: ModuleChunk, timeToCompileNs: Long) {
|
||||
printStatisticMessage(
|
||||
"${KotlinBuilder.KOTLIN_BUILDER_NAME} for ${moduleChunk.presentableShortName} compilation time, ms",
|
||||
timeToCompileNs.nanosToMillis().toString()
|
||||
)
|
||||
}
|
||||
|
||||
fun reportTotal() {
|
||||
if (!isOnTeamcity) return
|
||||
|
||||
printStatisticMessage(
|
||||
"${KotlinBuilder.KOTLIN_BUILDER_NAME} total compilation time, ms",
|
||||
totalTime.get().nanosToMillis().toString()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
private fun printStatisticMessage(key: String, value: String) {
|
||||
println("##teamcity[buildStatisticValue key='${escape(key)}' value='${escape(value)}']")
|
||||
}
|
||||
|
||||
private fun Long.nanosToMillis() = TimeUnit.NANOSECONDS.toMillis(this)
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.build
|
||||
|
||||
import org.jetbrains.jps.incremental.CompileContext
|
||||
import org.jetbrains.jps.incremental.ModuleLevelBuilder
|
||||
import org.jetbrains.kotlin.jps.incremental.CacheAttributesDiff
|
||||
import org.jetbrains.kotlin.jps.targets.KotlinModuleBuildTarget
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
* Used for assertions in tests.
|
||||
*/
|
||||
interface TestingBuildLogger {
|
||||
fun invalidOrUnusedCache(chunk: KotlinChunk?, target: KotlinModuleBuildTarget<*>?, attributesDiff: CacheAttributesDiff<*>) = Unit
|
||||
fun chunkBuildStarted(context: CompileContext, chunk: org.jetbrains.jps.ModuleChunk) = Unit
|
||||
fun afterChunkBuildStarted(context: CompileContext, chunk: org.jetbrains.jps.ModuleChunk) = Unit
|
||||
fun compilingFiles(files: Collection<File>, allRemovedFilesFiles: Collection<File>) = Unit
|
||||
fun addCustomMessage(message: String) = Unit
|
||||
fun buildFinished(exitCode: ModuleLevelBuilder.ExitCode) = Unit
|
||||
fun markedAsDirtyBeforeRound(files: Iterable<File>) = Unit
|
||||
fun markedAsDirtyAfterRound(files: Iterable<File>) = Unit
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.jps.build
|
||||
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.jps.incremental.CompileContext
|
||||
import org.jetbrains.jps.model.JpsElementFactory
|
||||
import org.jetbrains.jps.model.JpsProject
|
||||
import org.jetbrains.jps.model.JpsSimpleElement
|
||||
import org.jetbrains.jps.model.ex.JpsElementChildRoleBase
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
|
||||
private val TESTING_CONTEXT = JpsElementChildRoleBase.create<JpsSimpleElement<out TestingContext>>("Testing kcontext")
|
||||
|
||||
@TestOnly
|
||||
fun JpsProject.setTestingContext(context: TestingContext) {
|
||||
val dataContainer = JpsElementFactory.getInstance().createSimpleElement(context)
|
||||
container.setChild(TESTING_CONTEXT, dataContainer)
|
||||
}
|
||||
|
||||
val JpsProject.testingContext: TestingContext?
|
||||
get() = container.getChild(TESTING_CONTEXT)?.data
|
||||
|
||||
val CompileContext.testingContext: TestingContext?
|
||||
get() = projectDescriptor?.project?.testingContext
|
||||
|
||||
class TestingContext(
|
||||
val lookupTracker: LookupTracker,
|
||||
val buildLogger: TestingBuildLogger?
|
||||
) {
|
||||
var kotlinCompileContext: KotlinCompileContext? = null
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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.jps.build
|
||||
|
||||
import org.jetbrains.jps.incremental.CompileContext
|
||||
import org.jetbrains.jps.incremental.messages.CompilerMessage
|
||||
|
||||
fun jpsReportInternalBuilderError(context: CompileContext, error: Throwable) {
|
||||
val builderError = CompilerMessage.createInternalBuilderError("Kotlin", error)
|
||||
context.processMessage(builderError)
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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.jps.build
|
||||
|
||||
import org.jetbrains.jps.incremental.CompileContext
|
||||
import org.jetbrains.jps.incremental.messages.CompilerMessage
|
||||
|
||||
fun jpsReportInternalBuilderError(context: CompileContext, error: Throwable) {
|
||||
KotlinBuilder.LOG.info(error)
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright 2010-2018 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.jps.build
|
||||
|
||||
import org.jetbrains.jps.incremental.CompileContext
|
||||
import org.jetbrains.jps.incremental.messages.CompilerMessage
|
||||
|
||||
fun jpsReportInternalBuilderError(context: CompileContext, error: Throwable) {
|
||||
KotlinBuilder.LOG.info(error)
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user