Delete Kotlin IntelliJ IDEA plugin sources

Kotlin plugin sources were migrated to intellij-community:
https://github.com/JetBrains/intellij-community/tree/master/plugins/kotlin

Preserve `jps-plugin/testData/incremental`
because it's used in `compiler/incremental-compilation-impl/test`

Preserve `idea/testData/multiModuleHighlighting/multiplatform`
because it's used in `MppHighlightingTestDataWithGradleIT`
This commit is contained in:
Nikita Bobko
2021-07-19 18:33:33 +02:00
parent b8d74698f1
commit 39fa2b0baf
49333 changed files with 0 additions and 1160202 deletions
-68
View File
@@ -1,68 +0,0 @@
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"))
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 {}
@@ -1,31 +0,0 @@
/*
* 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)
}
@@ -1,52 +0,0 @@
/*
* 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)
}
@@ -1,684 +0,0 @@
/*
* 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.JpsBuildTestCase
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()
JpsBuildTestCase::class.java.getDeclaredField("myProject")[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?.lowercase() == makeOverallResult.mappingsDump?.lowercase()) {
// 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]"
@@ -1,681 +0,0 @@
/*
* 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]"
@@ -1,40 +0,0 @@
/*
* 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)
)
}
}
}
@@ -1,19 +0,0 @@
/*
* 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
}
}
}
@@ -1,151 +0,0 @@
/*
* 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
}
}
@@ -1,116 +0,0 @@
/*
* 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
}
}
}
@@ -1,368 +0,0 @@
/*
* 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))
}
}
@@ -1,37 +0,0 @@
/*
* 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}_"
}
@@ -1,53 +0,0 @@
/*
* 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()
}
}
}
@@ -1,229 +0,0 @@
/*
* 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);
}
}
}
@@ -1,229 +0,0 @@
/*
* 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);
}
}
}
@@ -1,43 +0,0 @@
/*
* 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/")
}
}
@@ -1,463 +0,0 @@
/*
* 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);
}
}
}
File diff suppressed because it is too large Load Diff
@@ -1,263 +0,0 @@
/*
* 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);
}
}
}
}
@@ -1,48 +0,0 @@
/*
* 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)
}
}
@@ -1,59 +0,0 @@
/*
* 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()
)
}
}
@@ -1,61 +0,0 @@
/*
* 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/");
}
}
@@ -1,61 +0,0 @@
/*
* 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/");
}
}
@@ -1,76 +0,0 @@
/*
* 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
@@ -1,133 +0,0 @@
/*
* 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 org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
import org.jetbrains.kotlin.config.KotlinFacetSettings
import org.jetbrains.kotlin.jps.model.JpsKotlinFacetModuleExtension
import org.jetbrains.kotlin.platform.js.JsPlatforms
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_WITHOUT_FACET,
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_WITHOUT_FACET -> addKotlinJavaScriptStdlibDependency()
LibraryDependency.JS_STDLIB -> {
addKotlinJavaScriptStdlibDependency()
setupKotlinJSFacet()
}
}
}
protected fun setupKotlinJSFacet() {
myProject.modules.forEach {
val facet = KotlinFacetSettings()
facet.compilerArguments = K2JSCompilerArguments()
facet.targetPlatform = JsPlatforms.defaultJsPlatform
it.container.setChild(
JpsKotlinFacetModuleExtension.KIND,
JpsKotlinFacetModuleExtension(facet)
)
}
}
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()
}
}
}
@@ -1,159 +0,0 @@
/*
* 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")
}
}
@@ -1,50 +0,0 @@
/*
* 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
}
}
@@ -1,49 +0,0 @@
/*
* 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
)
)
}
}
@@ -1,456 +0,0 @@
/*
* 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);
}
}
}
}
@@ -1,152 +0,0 @@
/*
* 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()
}
}
}
@@ -1,89 +0,0 @@
/*
* 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
@@ -1,329 +0,0 @@
/*
* 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)
}
}
}
}
@@ -1,441 +0,0 @@
/*
* 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.replaceFirstChar(Char::uppercaseChar)
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.replaceFirstChar(Char::uppercaseChar)}${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
}
}
@@ -1,38 +0,0 @@
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`
@@ -1,29 +0,0 @@
/*
* 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)
}
}
@@ -1,29 +0,0 @@
/*
* 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" }
}
}
@@ -1,73 +0,0 @@
/*
* 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")
}
}
}
}
}
@@ -1,72 +0,0 @@
/*
* 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
}
@@ -1,58 +0,0 @@
/*
* 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
}
}
}
}
@@ -1,123 +0,0 @@
/*
* 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) }
}
@@ -1,57 +0,0 @@
/*
* 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()
)
}
}
@@ -1,82 +0,0 @@
/*
* 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
)
}
}
@@ -1,711 +0,0 @@
/*
* 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);
}
}
}
}
@@ -1,765 +0,0 @@
/*
* 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);
}
}
}
}
@@ -1,67 +0,0 @@
/*
* 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() {
}
}
@@ -1,62 +0,0 @@
/*
* 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)
}
}
@@ -1,111 +0,0 @@
/*
* 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);
}
}
@@ -1,115 +0,0 @@
/*
* 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();
}
}
@@ -1,2 +0,0 @@
org.jetbrains.kotlin.jps.build.KotlinSourceRootProvider
org.jetbrains.kotlin.jps.build.KotlinResourcesRootProvider
@@ -1 +0,0 @@
org.jetbrains.kotlin.jps.build.KotlinJavaBuilderExtension
@@ -1 +0,0 @@
org.jetbrains.jps.builders.java.dependencyView.NullabilityAnnotationsTracker
@@ -1 +0,0 @@
org.jetbrains.kotlin.jps.build.KotlinBuilderService
@@ -1 +0,0 @@
org.jetbrains.kotlin.jps.model.KotlinModelSerializerService
@@ -1,79 +0,0 @@
/*
* 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)) }
}
@@ -1,123 +0,0 @@
/*
* 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)
}
}
@@ -1,34 +0,0 @@
/*
* 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
}
@@ -1,50 +0,0 @@
/*
* 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
)
}
}
@@ -1,375 +0,0 @@
/*
* 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()
)
}
}
}
@@ -1,40 +0,0 @@
/*
* 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
}
@@ -1,38 +0,0 @@
/*
* 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()
}
@@ -1,168 +0,0 @@
/*
* 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)
}
}
}
@@ -1,14 +0,0 @@
/*
* 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))
@@ -1,812 +0,0 @@
/*
* 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.BuildOperations.deleteRecursively
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.ERROR
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.INFO
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(
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
)
cleanJsOutputs(context, kotlinChunk, incrementalCaches, kotlinDirtyFilesHolder)
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
}
private fun cleanJsOutputs(
context: CompileContext,
kotlinChunk: KotlinChunk,
incrementalCaches: Map<KotlinModuleBuildTarget<*>, JpsIncrementalCache>,
kotlinDirtyFilesHolder: KotlinDirtySourceFilesHolder
) {
for (target in kotlinChunk.targets) {
val cache = incrementalCaches[target] ?: continue
if (cache is IncrementalJsCache) {
val filesToDelete = mutableListOf<File>()
val dirtyFiles = kotlinDirtyFilesHolder.getDirtyFiles(target.jpsModuleBuildTarget).keys
val removedFiles = kotlinDirtyFilesHolder.getRemovedFiles(target.jpsModuleBuildTarget)
for (file: File in dirtyFiles + removedFiles) {
filesToDelete.addAll(cache.getOutputsBySource(file).filter { it !in filesToDelete })
}
if (filesToDelete.isNotEmpty()) {
val deletedForThisSource = mutableSetOf<String>()
val parentDirs = mutableSetOf<File>()
for (kjsmFile in filesToDelete) {
deleteRecursively(kjsmFile.path, deletedForThisSource, parentDirs)
}
FSOperations.pruneEmptyDirs(context, parentDirs)
val logger = context.loggingManager.projectBuilderLogger
if (logger.isEnabled && deletedForThisSource.isNotEmpty()) {
logger.logDeletedFiles(deletedForThisSource)
}
}
}
}
}
// 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
}
@@ -1,32 +0,0 @@
/*
* 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());
}
}
@@ -1,166 +0,0 @@
/*
* 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 }})"
}
}
@@ -1,314 +0,0 @@
/*
* 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 -> ""
}
@@ -1,111 +0,0 @@
/*
* 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")
@@ -1,64 +0,0 @@
/*
* 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
}
}
@@ -1,25 +0,0 @@
/*
* 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>
}
@@ -1,50 +0,0 @@
/*
* 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('/', '.')
@@ -1,112 +0,0 @@
/*
* 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)
@@ -1,71 +0,0 @@
/*
* 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)
@@ -1,72 +0,0 @@
/*
* 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")
}
}
}
@@ -1,87 +0,0 @@
/*
* 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)
}
@@ -1,37 +0,0 @@
/*
* 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
}
@@ -1,46 +0,0 @@
/*
* 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
}
@@ -1,14 +0,0 @@
/*
* 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)
}
@@ -1,13 +0,0 @@
/*
* 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)
}
@@ -1,13 +0,0 @@
/*
* 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)
}
@@ -1,13 +0,0 @@
/*
* 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)
}
@@ -1,13 +0,0 @@
/*
* 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)
}
@@ -1,47 +0,0 @@
/*
* 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.ModuleChunk
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType
import org.jetbrains.jps.incremental.CompileContext
import org.jetbrains.jps.incremental.ModuleBuildTarget
import org.jetbrains.jps.model.module.JpsModule
fun ModuleChunk.isDummy(context: CompileContext): Boolean {
val targetIndex = context.projectDescriptor.buildTargetIndex
return targets.all { targetIndex.isDummy(it) }
}
@Deprecated("Use `kotlin.targetBinding` instead", ReplaceWith("kotlin.targetsBinding"))
val CompileContext.kotlinBuildTargets
get() = kotlin.targetsBinding
fun ModuleChunk.toKotlinChunk(context: CompileContext): KotlinChunk? =
context.kotlin.getChunk(this)
fun ModuleBuildTarget(module: JpsModule, isTests: Boolean) =
ModuleBuildTarget(
module,
if (isTests) JavaModuleBuildTargetType.TEST else JavaModuleBuildTargetType.PRODUCTION
)
val JpsModule.productionBuildTarget
get() = ModuleBuildTarget(this, false)
val JpsModule.testBuildTarget
get() = ModuleBuildTarget(this, true)
@@ -1,33 +0,0 @@
/*
* 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
/**
* Diff between actual and expected cache attributes.
* [status] are calculated based on this diff (see [CacheStatus]).
* Based on that [status] system may perform required actions (i.e. rebuild something, clearing caches, etc...).
*
* [CacheAttributesDiff] can be used to cache current attribute values and as facade for version operations.
*/
data class CacheAttributesDiff<Attrs: Any>(
val manager: CacheAttributesManager<Attrs>,
val actual: Attrs?,
val expected: Attrs?
) {
val status: CacheStatus
get() =
if (expected != null) {
if (actual != null && manager.isCompatible(actual, expected)) CacheStatus.VALID
else CacheStatus.INVALID
} else {
if (actual != null) CacheStatus.SHOULD_BE_CLEARED
else CacheStatus.CLEARED
}
override fun toString(): String {
return "$status: actual=$actual -> expected=$expected"
}
}
@@ -1,47 +0,0 @@
/*
* 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
/**
* Manages cache attributes values.
*
* Attribute values can be loaded by calling [loadActual].
* Based on loaded actual and fixed [expected] values [CacheAttributesDiff] can be constructed which can calculate [CacheStatus].
* Build system may perform required actions based on that (i.e. rebuild something, clearing caches, etc...).
*
* [CacheAttributesDiff] can be used to cache current attribute values and then can be used as facade for cache version operations.
*/
interface CacheAttributesManager<Attrs : Any> {
/**
* Cache attribute values expected by the current version of build system and compiler.
* `null` means that cache is not required (incremental compilation is disabled).
*/
val expected: Attrs?
/**
* Load actual cache attribute values.
* `null` means that cache is not yet created.
*
* This is internal operation that should be implemented by particular implementation of CacheAttributesManager.
* Consider using `loadDiff().actual` for getting actual values.
*/
fun loadActual(): Attrs?
/**
* Write [values] as cache attributes for next build execution.
*/
fun writeVersion(values: Attrs? = expected)
/**
* Check if cache with [actual] attributes values can be used when [expected] attributes are required.
*/
fun isCompatible(actual: Attrs, expected: Attrs): Boolean = actual == expected
}
fun <Attrs : Any> CacheAttributesManager<Attrs>.loadDiff(
actual: Attrs? = this.loadActual(),
expected: Attrs? = this.expected
) = CacheAttributesDiff(this, actual, expected)
@@ -1,31 +0,0 @@
/*
* 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
/**
* Status that is used by system to perform required actions (i.e. rebuild something, clearing caches, etc...).
*/
enum class CacheStatus {
/**
* Cache is valid and ready to use.
*/
VALID,
/**
* Cache is not exists or have outdated versions and/or other attributes.
*/
INVALID,
/**
* Cache is exists, but not required anymore.
*/
SHOULD_BE_CLEARED,
/**
* Cache is not exists and not required.
*/
CLEARED
}
@@ -1,82 +0,0 @@
/*
* 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.annotations.TestOnly
import org.jetbrains.kotlin.load.kotlin.JvmBytecodeBinaryVersion
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion
import java.io.File
import java.io.IOException
/**
* Manages files with actual version [loadActual] and provides expected version [expected].
* Based on that actual and expected versions [CacheStatus] can be calculated.
* This can be done by constructing [CacheAttributesDiff] and calling [CacheAttributesDiff.status].
* Based on that status system may perform required actions (i.e. rebuild something, clearing caches, etc...).
*/
class CacheVersionManager(
private val versionFile: File,
expectedOwnVersion: Int?
) : CacheAttributesManager<CacheVersion> {
override val expected: CacheVersion? =
if (expectedOwnVersion == null) null
else CacheVersion(expectedOwnVersion, JvmBytecodeBinaryVersion.INSTANCE, JvmMetadataVersion.INSTANCE)
override fun loadActual(): CacheVersion? =
if (!versionFile.exists()) null
else try {
CacheVersion(versionFile.readText().toInt())
} catch (e: NumberFormatException) {
null
} catch (e: IOException) {
null
}
override fun writeVersion(values: CacheVersion?) {
if (values == null) versionFile.delete()
else {
versionFile.parentFile.mkdirs()
versionFile.writeText(values.intValue.toString())
}
}
@get:TestOnly
val versionFileForTesting: File
get() = versionFile
}
fun CacheVersion(own: Int, bytecode: JvmBytecodeBinaryVersion, metadata: JvmMetadataVersion): CacheVersion {
require(own in 0..(Int.MAX_VALUE / 1000000 - 1))
require(bytecode.major in 0..9)
require(bytecode.minor in 0..9)
require(metadata.major in 0..9)
require(metadata.minor in 0..99)
return CacheVersion(
own * 1000000 +
bytecode.major * 10000 + bytecode.minor * 100 +
metadata.major * 1000 + metadata.minor
)
}
data class CacheVersion(val intValue: Int) {
val own: Int
get() = intValue / 1000000
val bytecode: JvmBytecodeBinaryVersion
get() = JvmBytecodeBinaryVersion(
intValue / 10000 % 10,
intValue / 100 % 10
)
val metadata: JvmMetadataVersion
get() = JvmMetadataVersion(
intValue / 1000 % 10,
intValue / 1 % 100
)
override fun toString(): String = "CacheVersion(caches: $own, bytecode: $bytecode, metadata: $metadata)"
}
@@ -1,75 +0,0 @@
/*
* 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.annotations.TestOnly
import java.io.File
import java.io.IOException
/**
* Attributes manager for global lookups cache that may contain lookups for several compilers (jvm, js).
* Works by delegating to [lookupsCacheVersionManager] and managing additional file with list of executed compilers (cache components).
*
* TODO(1.2.80): got rid of shared lookup cache, replace with individual lookup cache for each compiler
*/
class CompositeLookupsCacheAttributesManager(
rootPath: File,
expectedComponents: Set<String>
) : CacheAttributesManager<CompositeLookupsCacheAttributes> {
private val versionManager = lookupsCacheVersionManager(
rootPath,
expectedComponents.isNotEmpty()
)
private val actualComponentsFile = File(rootPath, "components.txt")
override val expected: CompositeLookupsCacheAttributes? =
if (expectedComponents.isEmpty()) null
else CompositeLookupsCacheAttributes(versionManager.expected!!.intValue, expectedComponents)
override fun loadActual(): CompositeLookupsCacheAttributes? {
val version = versionManager.loadActual() ?: return null
if (!actualComponentsFile.exists()) return null
val components = try {
actualComponentsFile.readLines().toSet()
} catch (e: IOException) {
return null
}
return CompositeLookupsCacheAttributes(version.intValue, components)
}
override fun writeVersion(values: CompositeLookupsCacheAttributes?) {
if (values == null) {
versionManager.writeVersion(null)
actualComponentsFile.delete()
} else {
versionManager.writeVersion(CacheVersion(values.version))
actualComponentsFile.parentFile.mkdirs()
actualComponentsFile.writeText(values.components.joinToString("\n"))
}
}
override fun isCompatible(actual: CompositeLookupsCacheAttributes, expected: CompositeLookupsCacheAttributes): Boolean {
// cache can be reused when all required (expected) components are present
// (components that are not required anymore are not not interfere)
return actual.version == expected.version && actual.components.containsAll(expected.components)
}
@get:TestOnly
val versionManagerForTesting
get() = versionManager
}
data class CompositeLookupsCacheAttributes(
val version: Int,
val components: Set<String>
) {
override fun toString() = "($version, $components)"
}
@@ -1,83 +0,0 @@
/*
* 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.incremental
import org.jetbrains.jps.builders.storage.BuildDataPaths
import org.jetbrains.jps.builders.storage.StorageProvider
import org.jetbrains.jps.incremental.ModuleBuildTarget
import org.jetbrains.jps.incremental.storage.BuildDataManager
import org.jetbrains.jps.incremental.storage.StorageOwner
import org.jetbrains.kotlin.incremental.IncrementalCacheCommon
import org.jetbrains.kotlin.incremental.IncrementalJsCache
import org.jetbrains.kotlin.incremental.IncrementalJvmCache
import org.jetbrains.kotlin.incremental.storage.FileToPathConverter
import org.jetbrains.kotlin.jps.build.KotlinBuilder
import org.jetbrains.kotlin.jps.targets.KotlinModuleBuildTarget
import org.jetbrains.kotlin.serialization.js.JsSerializerProtocol
import java.io.File
interface JpsIncrementalCache : IncrementalCacheCommon, StorageOwner {
fun addJpsDependentCache(cache: JpsIncrementalCache)
}
class JpsIncrementalJvmCache(
target: ModuleBuildTarget,
paths: BuildDataPaths,
pathConverter: FileToPathConverter
) : IncrementalJvmCache(paths.getTargetDataRoot(target), target.outputDir, pathConverter), JpsIncrementalCache {
override fun addJpsDependentCache(cache: JpsIncrementalCache) {
if (cache is JpsIncrementalJvmCache) {
addDependentCache(cache)
}
}
override fun debugLog(message: String) {
KotlinBuilder.LOG.debug(message)
}
}
class JpsIncrementalJsCache(
target: ModuleBuildTarget,
paths: BuildDataPaths,
pathConverter: FileToPathConverter
) : IncrementalJsCache(paths.getTargetDataRoot(target), pathConverter, JsSerializerProtocol), JpsIncrementalCache {
override fun addJpsDependentCache(cache: JpsIncrementalCache) {
if (cache is JpsIncrementalJsCache) {
addDependentCache(cache)
}
}
}
private class KotlinIncrementalStorageProvider(
private val target: KotlinModuleBuildTarget<*>,
private val paths: BuildDataPaths
) : StorageProvider<JpsIncrementalCache>() {
init {
check(target.hasCaches)
}
override fun equals(other: Any?) = other is KotlinIncrementalStorageProvider && target == other.target
override fun hashCode() = target.hashCode()
override fun createStorage(targetDataDir: File): JpsIncrementalCache = target.createCacheStorage(paths)
}
fun BuildDataManager.getKotlinCache(target: KotlinModuleBuildTarget<*>?): JpsIncrementalCache? =
if (target == null || !target.hasCaches) null
else getStorage(target.jpsModuleBuildTarget, KotlinIncrementalStorageProvider(target, dataPaths))
@@ -1,71 +0,0 @@
/*
* 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 com.intellij.openapi.diagnostic.Logger
import org.jetbrains.jps.builders.storage.BuildDataCorruptedException
import org.jetbrains.jps.builders.storage.StorageProvider
import org.jetbrains.jps.incremental.storage.BuildDataManager
import org.jetbrains.jps.incremental.storage.StorageOwner
import org.jetbrains.kotlin.incremental.LookupStorage
import org.jetbrains.kotlin.incremental.storage.FileToPathConverter
import java.io.File
import java.io.IOException
private object LookupStorageLock
class JpsLookupStorageManager(
private val buildDataManager: BuildDataManager,
pathConverter: FileToPathConverter
) {
private val storageProvider = JpsLookupStorageProvider(pathConverter)
fun cleanLookupStorage(log: Logger) {
synchronized(LookupStorageLock) {
try {
buildDataManager.cleanTargetStorages(KotlinDataContainerTarget)
} catch (e: IOException) {
if (!buildDataManager.dataPaths.getTargetDataRoot(KotlinDataContainerTarget).deleteRecursively()) {
log.debug("Could not clear lookup storage caches", e)
}
}
}
}
fun <T> withLookupStorage(fn: (LookupStorage) -> T): T {
synchronized(LookupStorageLock) {
try {
val lookupStorage = buildDataManager.getStorage(KotlinDataContainerTarget, storageProvider)
return fn(lookupStorage)
} catch (e: IOException) {
throw BuildDataCorruptedException(e)
}
}
}
private class JpsLookupStorageProvider(
private val pathConverter: FileToPathConverter
) : StorageProvider<JpsLookupStorage>() {
override fun createStorage(targetDataDir: File): JpsLookupStorage =
JpsLookupStorage(targetDataDir, pathConverter)
}
private class JpsLookupStorage(
targetDataDir: File,
pathConverter: FileToPathConverter
) : StorageOwner, LookupStorage(targetDataDir, pathConverter)
}
@@ -1,62 +0,0 @@
/*
* 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.jps.builders.*
import org.jetbrains.jps.builders.storage.BuildDataPaths
import org.jetbrains.jps.incremental.CompileContext
import org.jetbrains.jps.indices.IgnoredFileIndex
import org.jetbrains.jps.indices.ModuleExcludeIndex
import org.jetbrains.jps.model.JpsModel
import java.io.File
private val KOTLIN_DATA_CONTAINER = "kotlin-data-container"
object KotlinDataContainerTargetType : BuildTargetType<KotlinDataContainerTarget>(KOTLIN_DATA_CONTAINER) {
override fun computeAllTargets(model: JpsModel): List<KotlinDataContainerTarget> = listOf(KotlinDataContainerTarget)
override fun createLoader(model: JpsModel): BuildTargetLoader<KotlinDataContainerTarget> =
object : BuildTargetLoader<KotlinDataContainerTarget>() {
override fun createTarget(targetId: String): KotlinDataContainerTarget? = KotlinDataContainerTarget
}
}
// Fake target to store data per project for incremental compilation
object KotlinDataContainerTarget : BuildTarget<BuildRootDescriptor>(KotlinDataContainerTargetType) {
override fun getId(): String? = KOTLIN_DATA_CONTAINER
override fun getPresentableName(): String = KOTLIN_DATA_CONTAINER
override fun computeRootDescriptors(
model: JpsModel?,
index: ModuleExcludeIndex?,
ignoredFileIndex: IgnoredFileIndex?,
dataPaths: BuildDataPaths?
): List<BuildRootDescriptor> = listOf()
override fun getOutputRoots(context: CompileContext): Collection<File> {
val dataManager = context.projectDescriptor.dataManager
val storageRoot = dataManager.dataPaths.dataStorageRoot
return listOf(File(storageRoot, KOTLIN_DATA_CONTAINER))
}
override fun findRootDescriptor(rootId: String?, rootIndex: BuildRootIndex?): BuildRootDescriptor? = null
override fun computeDependencies(
targetRegistry: BuildTargetRegistry?,
outputIndex: TargetOutputIndex?
): Collection<BuildTarget<*>>? = listOf()
}
@@ -1,17 +0,0 @@
/*
* 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 java.io.File
private val NORMAL_VERSION = 14
private val NORMAL_VERSION_FILE_NAME = "format-version.txt"
fun localCacheVersionManager(dataRoot: File, isCachesEnabled: Boolean) =
CacheVersionManager(
File(dataRoot, NORMAL_VERSION_FILE_NAME),
if (isCachesEnabled) NORMAL_VERSION else null
)
@@ -1,17 +0,0 @@
/*
* 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 java.io.File
private val DATA_CONTAINER_VERSION_FILE_NAME = "data-container-format-version.txt"
private val DATA_CONTAINER_VERSION = 5
fun lookupsCacheVersionManager(dataRoot: File, isEnabled: Boolean) =
CacheVersionManager(
File(dataRoot, DATA_CONTAINER_VERSION_FILE_NAME),
if (isEnabled) DATA_CONTAINER_VERSION else null
)
@@ -1,45 +0,0 @@
/*
* 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.incremental.storages
import com.intellij.openapi.util.io.FileUtil
import com.intellij.util.io.IOUtil
import com.intellij.util.io.KeyDescriptor
import gnu.trove.THashSet
import org.jetbrains.jps.incremental.storage.PathStringDescriptor
import org.jetbrains.kotlin.incremental.storage.CollectionExternalizer
import java.io.DataInput
import java.io.DataOutput
object PathFunctionPairKeyDescriptor : KeyDescriptor<PathFunctionPair> {
override fun read(input: DataInput): PathFunctionPair {
val path = IOUtil.readUTF(input)
val function = IOUtil.readUTF(input)
return PathFunctionPair(path, function)
}
override fun save(output: DataOutput, value: PathFunctionPair) {
IOUtil.writeUTF(output, value.path)
IOUtil.writeUTF(output, value.function)
}
override fun getHashCode(value: PathFunctionPair): Int = value.hashCode()
override fun isEqual(val1: PathFunctionPair, val2: PathFunctionPair): Boolean = val1 == val2
}
object PathCollectionExternalizer : CollectionExternalizer<String>(PathStringDescriptor(), { THashSet(FileUtil.PATH_HASHING_STRATEGY) })
@@ -1,42 +0,0 @@
/*
* 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.incremental.storages
import com.intellij.openapi.util.io.FileUtil
class PathFunctionPair(
val path: String,
val function: String
) : Comparable<PathFunctionPair> {
override fun compareTo(other: PathFunctionPair): Int {
val pathComp = FileUtil.comparePaths(path, other.path)
if (pathComp != 0) return pathComp
return function.compareTo(other.function)
}
override fun equals(other: Any?): Boolean =
when (other) {
is PathFunctionPair ->
FileUtil.pathsEqual(path, other.path) && function == other.function
else ->
false
}
override fun hashCode(): Int = 31 * FileUtil.pathHashCode(path) + function.hashCode()
}
@@ -1,117 +0,0 @@
/*
* 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.model
import org.jetbrains.jps.model.ex.JpsElementBase
import org.jetbrains.jps.model.ex.JpsElementChildRoleBase
import org.jetbrains.jps.model.java.JpsJavaExtensionService
import org.jetbrains.jps.model.module.JpsModule
import org.jetbrains.kotlin.cli.common.arguments.*
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.platform.TargetPlatform
val JpsModule.kotlinFacet: JpsKotlinFacetModuleExtension?
get() = container.getChild(JpsKotlinFacetModuleExtension.KIND)
val JpsModule.platform: TargetPlatform?
get() = kotlinFacet?.settings?.targetPlatform
val JpsModule.kotlinKind: KotlinModuleKind
get() = kotlinFacet?.settings?.kind ?: KotlinModuleKind.DEFAULT
val JpsModule.isTestModule: Boolean
get() = kotlinFacet?.settings?.isTestModule ?: false
/**
* Modules which is imported from sources sets of the compilation represented by this module.
* This module is not included.
*/
val JpsModule.sourceSetModules: List<JpsModule>
get() = findDependencies(kotlinFacet?.settings?.sourceSetNames)
/**
* Legacy. List of modules with `expectedBy` dependency.
*/
val JpsModule.expectedByModules: List<JpsModule>
get() = findDependencies(kotlinFacet?.settings?.implementedModuleNames)
private fun JpsModule.findDependencies(moduleNames: List<String>?): List<JpsModule> {
if (moduleNames == null || moduleNames.isEmpty()) return listOf()
val result = mutableSetOf<JpsModule>()
JpsJavaExtensionService.dependencies(this)
.processModules {
if (it.name in moduleNames) {
// Note, production sources should be added for both production and tests targets
result.add(it)
}
}
return result.toList()
}
val JpsModule.productionOutputFilePath: String?
get() {
val facetSettings = kotlinFacet?.settings ?: return null
if (facetSettings.useProjectSettings) return null
return facetSettings.productionOutputPath
}
val JpsModule.testOutputFilePath: String?
get() {
val facetSettings = kotlinFacet?.settings ?: return null
if (facetSettings.useProjectSettings) return null
return facetSettings.testOutputPath
}
val JpsModule.kotlinCompilerSettings: CompilerSettings
get() {
val defaultSettings = copyBean(project.kotlinCompilerSettings)
val facetSettings = kotlinFacet?.settings ?: return defaultSettings
if (facetSettings.useProjectSettings) return defaultSettings
return facetSettings.compilerSettings ?: defaultSettings
}
val JpsModule.kotlinCompilerArguments
get() = getCompilerArguments<CommonCompilerArguments>()
val JpsModule.k2MetadataCompilerArguments
get() = getCompilerArguments<K2MetadataCompilerArguments>()
val JpsModule.k2JsCompilerArguments
get() = getCompilerArguments<K2JSCompilerArguments>()
val JpsModule.k2JvmCompilerArguments
get() = getCompilerArguments<K2JVMCompilerArguments>()
private inline fun <reified T : CommonCompilerArguments> JpsModule.getCompilerArguments(): T {
val projectSettings = project.kotlinCompilerSettingsContainer[T::class.java]
val projectSettingsCopy = copyBean(projectSettings)
val facetSettings = kotlinFacet?.settings ?: return projectSettingsCopy
if (facetSettings.useProjectSettings) return projectSettingsCopy
facetSettings.updateMergedArguments()
return facetSettings.mergedCompilerArguments as? T ?: projectSettingsCopy
}
class JpsKotlinFacetModuleExtension(settings: KotlinFacetSettings) : JpsElementBase<JpsKotlinFacetModuleExtension>() {
var settings = settings
private set
companion object {
val KIND = JpsElementChildRoleBase.create<JpsKotlinFacetModuleExtension>("kotlin facet extension")
// These must be changed in sync with KotlinFacetType.TYPE_ID and KotlinFacetType.NAME
val FACET_TYPE_ID = "kotlin-language"
val FACET_NAME = "Kotlin"
}
override fun createCopy() = JpsKotlinFacetModuleExtension(settings)
override fun applyChanges(modified: JpsKotlinFacetModuleExtension) {
this.settings = modified.settings
}
}
@@ -1,91 +0,0 @@
/*
* 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.model
import org.jetbrains.jps.model.JpsProject
import org.jetbrains.jps.model.ex.JpsElementBase
import org.jetbrains.jps.model.ex.JpsElementChildRoleBase
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
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
var JpsProject.kotlinCompilerSettings
get() = kotlinCompilerSettingsContainer.compilerSettings
internal set(value) {
getOrCreateSettings().compilerSettings = value
}
var JpsProject.kotlinCommonCompilerArguments
get() = kotlinCompilerSettingsContainer.commonCompilerArguments
internal set(value) {
getOrCreateSettings().commonCompilerArguments = value
}
var JpsProject.k2MetadataCompilerArguments
get() = kotlinCompilerSettingsContainer.k2MetadataCompilerArguments
internal set(value) {
getOrCreateSettings().k2MetadataCompilerArguments = value
}
var JpsProject.k2JsCompilerArguments
get() = kotlinCompilerSettingsContainer.k2JsCompilerArguments
internal set(value) {
getOrCreateSettings().k2JsCompilerArguments = value
}
var JpsProject.k2JvmCompilerArguments
get() = kotlinCompilerSettingsContainer.k2JvmCompilerArguments
internal set(value) {
getOrCreateSettings().k2JvmCompilerArguments = value
}
internal val JpsProject.kotlinCompilerSettingsContainer
get() = container.getChild(JpsKotlinCompilerSettings.ROLE) ?: JpsKotlinCompilerSettings()
private fun JpsProject.getOrCreateSettings(): JpsKotlinCompilerSettings {
var settings = container.getChild(JpsKotlinCompilerSettings.ROLE)
if (settings == null) {
settings = JpsKotlinCompilerSettings()
container.setChild(JpsKotlinCompilerSettings.ROLE, settings)
}
return settings
}
class JpsKotlinCompilerSettings : JpsElementBase<JpsKotlinCompilerSettings>() {
internal var commonCompilerArguments: CommonCompilerArguments = CommonCompilerArguments.DummyImpl()
internal var k2MetadataCompilerArguments = K2MetadataCompilerArguments()
internal var k2JvmCompilerArguments = K2JVMCompilerArguments()
internal var k2JsCompilerArguments = K2JSCompilerArguments()
internal var compilerSettings = CompilerSettings()
@Suppress("UNCHECKED_CAST")
internal operator fun <T : CommonCompilerArguments> get(compilerArgumentsClass: Class<T>): T = when (compilerArgumentsClass) {
K2MetadataCompilerArguments::class.java -> k2MetadataCompilerArguments as T
K2JVMCompilerArguments::class.java -> k2JvmCompilerArguments as T
K2JSCompilerArguments::class.java -> k2JsCompilerArguments as T
else -> commonCompilerArguments as T
}
override fun createCopy(): JpsKotlinCompilerSettings {
val copy = JpsKotlinCompilerSettings()
copy.commonCompilerArguments = this.commonCompilerArguments
copy.k2MetadataCompilerArguments = this.k2MetadataCompilerArguments
copy.k2JvmCompilerArguments = this.k2JvmCompilerArguments
copy.k2JsCompilerArguments = this.k2JsCompilerArguments
copy.compilerSettings = this.compilerSettings
return copy
}
override fun applyChanges(modified: JpsKotlinCompilerSettings) {
// do nothing
}
companion object {
internal val ROLE = JpsElementChildRoleBase.create<JpsKotlinCompilerSettings>("Kotlin Compiler Settings")
}
}
@@ -1,107 +0,0 @@
/*
* 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.model
import com.intellij.util.xmlb.XmlSerializer
import org.jdom.Element
import org.jetbrains.jps.model.JpsElement
import org.jetbrains.jps.model.JpsProject
import org.jetbrains.jps.model.module.JpsModule
import org.jetbrains.jps.model.serialization.JpsProjectExtensionSerializer
import org.jetbrains.jps.model.serialization.facet.JpsFacetConfigurationSerializer
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.setApiVersionToLanguageVersionIfNeeded
import org.jetbrains.kotlin.config.*
import java.util.*
class KotlinModelSerializerService : KotlinCommonJpsModelSerializerExtension() {
override fun getProjectExtensionSerializers() = listOf(
KotlinCommonCompilerArgumentsSerializer(),
Kotlin2JvmCompilerArgumentsSerializer(),
Kotlin2JsCompilerArgumentsSerializer(),
KotlinCompilerSettingsSerializer()
)
override fun getFacetConfigurationSerializers() = listOf(JpsKotlinFacetConfigurationSerializer)
}
object JpsKotlinFacetConfigurationSerializer : JpsFacetConfigurationSerializer<JpsKotlinFacetModuleExtension>(
JpsKotlinFacetModuleExtension.KIND,
JpsKotlinFacetModuleExtension.FACET_TYPE_ID,
JpsKotlinFacetModuleExtension.FACET_NAME
) {
override fun loadExtension(
facetConfigurationElement: Element,
name: String,
parent: JpsElement?,
module: JpsModule
): JpsKotlinFacetModuleExtension {
return JpsKotlinFacetModuleExtension(deserializeFacetSettings(facetConfigurationElement))
}
override fun saveExtension(
extension: JpsKotlinFacetModuleExtension?,
facetConfigurationTag: Element,
module: JpsModule
) {
(extension as JpsKotlinFacetModuleExtension).settings.serializeFacetSettings(facetConfigurationTag)
}
}
abstract class BaseJpsCompilerSettingsSerializer<in T : Any>(
componentName: String,
private val settingsFactory: () -> T
) : JpsProjectExtensionSerializer(SettingConstants.KOTLIN_COMPILER_SETTINGS_FILE, componentName) {
protected abstract fun onLoad(project: JpsProject, settings: T)
override fun loadExtension(project: JpsProject, componentTag: Element) {
val settings = settingsFactory().apply {
if (this is CommonCompilerArguments) {
freeArgs = ArrayList()
}
}
XmlSerializer.deserializeInto(settings, componentTag)
onLoad(project, settings)
}
override fun saveExtension(project: JpsProject, componentTag: Element) {
}
}
internal class KotlinCompilerSettingsSerializer : BaseJpsCompilerSettingsSerializer<CompilerSettings>(
SettingConstants.KOTLIN_COMPILER_SETTINGS_SECTION, ::CompilerSettings
) {
override fun onLoad(project: JpsProject, settings: CompilerSettings) {
project.kotlinCompilerSettings = settings
}
}
internal class KotlinCommonCompilerArgumentsSerializer : BaseJpsCompilerSettingsSerializer<CommonCompilerArguments.DummyImpl>(
SettingConstants.KOTLIN_COMMON_COMPILER_ARGUMENTS_SECTION, CommonCompilerArguments::DummyImpl
) {
override fun onLoad(project: JpsProject, settings: CommonCompilerArguments.DummyImpl) {
settings.setApiVersionToLanguageVersionIfNeeded()
project.kotlinCommonCompilerArguments = settings
}
}
internal class Kotlin2JsCompilerArgumentsSerializer : BaseJpsCompilerSettingsSerializer<K2JSCompilerArguments>(
SettingConstants.KOTLIN_TO_JS_COMPILER_ARGUMENTS_SECTION, ::K2JSCompilerArguments
) {
override fun onLoad(project: JpsProject, settings: K2JSCompilerArguments) {
project.k2JsCompilerArguments = settings
}
}
internal class Kotlin2JvmCompilerArgumentsSerializer : BaseJpsCompilerSettingsSerializer<K2JVMCompilerArguments>(
SettingConstants.KOTLIN_TO_JVM_COMPILER_ARGUMENTS_SECTION, ::K2JVMCompilerArguments
) {
override fun onLoad(project: JpsProject, settings: K2JVMCompilerArguments) {
project.k2JvmCompilerArguments = settings
}
}
@@ -1,110 +0,0 @@
/*
* 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.targets
import org.jetbrains.jps.builders.storage.BuildDataPaths
import org.jetbrains.jps.incremental.ModuleBuildTarget
import org.jetbrains.jps.model.library.JpsOrderRootType
import org.jetbrains.jps.model.module.JpsModule
import org.jetbrains.jps.util.JpsPathUtil
import org.jetbrains.kotlin.build.CommonBuildMetaInfo
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.K2MetadataCompilerArguments
import org.jetbrains.kotlin.compilerRunner.JpsCompilerEnvironment
import org.jetbrains.kotlin.compilerRunner.JpsKotlinCompilerRunner
import org.jetbrains.kotlin.jps.build.KotlinCompileContext
import org.jetbrains.kotlin.jps.build.KotlinDirtySourceFilesHolder
import org.jetbrains.kotlin.jps.build.ModuleBuildTarget
import org.jetbrains.kotlin.jps.model.k2MetadataCompilerArguments
import org.jetbrains.kotlin.jps.model.kotlinCompilerSettings
private const val COMMON_BUILD_META_INFO_FILE_NAME = "common-build-meta-info.txt"
class KotlinCommonModuleBuildTarget(kotlinContext: KotlinCompileContext, jpsModuleBuildTarget: ModuleBuildTarget) :
KotlinModuleBuildTarget<CommonBuildMetaInfo>(kotlinContext, jpsModuleBuildTarget) {
override fun isEnabled(chunkCompilerArguments: CommonCompilerArguments): Boolean {
val k2MetadataArguments = module.k2MetadataCompilerArguments
return k2MetadataArguments.enabledInJps || (chunkCompilerArguments as? K2MetadataCompilerArguments)?.enabledInJps == true
}
override val isIncrementalCompilationEnabled: Boolean
get() = false
override val buildMetaInfoFactory
get() = CommonBuildMetaInfo
override val buildMetaInfoFileName
get() = COMMON_BUILD_META_INFO_FILE_NAME
override val globalLookupCacheId: String
get() = "metadata-compiler"
override fun compileModuleChunk(
commonArguments: CommonCompilerArguments,
dirtyFilesHolder: KotlinDirtySourceFilesHolder,
environment: JpsCompilerEnvironment
): Boolean {
require(chunk.representativeTarget == this)
reportAndSkipCircular(environment)
JpsKotlinCompilerRunner().runK2MetadataCompiler(
commonArguments,
module.k2MetadataCompilerArguments,
module.kotlinCompilerSettings,
environment,
destination,
dependenciesOutputDirs + libraryFiles,
sourceFiles // incremental K2MetadataCompiler not supported yet
)
return true
}
private val libraryFiles: List<String>
get() = mutableListOf<String>().also { result ->
for (library in allDependencies.libraries) {
for (root in library.getRoots(JpsOrderRootType.COMPILED)) {
result.add(JpsPathUtil.urlToPath(root.url))
}
}
}
private val dependenciesOutputDirs: List<String>
get() = mutableListOf<String>().also { result ->
allDependencies.processModules { module ->
if (isTests) addDependencyMetaFile(module, result, isTests = true)
// note: production targets should be also added as dependency to test targets
addDependencyMetaFile(module, result, isTests = false)
}
}
val destination: String
get() = module.k2MetadataCompilerArguments.destination ?: outputDir.absolutePath
private fun addDependencyMetaFile(
module: JpsModule,
result: MutableList<String>,
isTests: Boolean
) {
val dependencyBuildTarget = kotlinContext.targetsBinding[ModuleBuildTarget(module, isTests)]
if (dependencyBuildTarget != this@KotlinCommonModuleBuildTarget &&
dependencyBuildTarget is KotlinCommonModuleBuildTarget &&
dependencyBuildTarget.sources.isNotEmpty()
) {
result.add(dependencyBuildTarget.destination)
}
}
override val hasCaches: Boolean
get() = false
override fun createCacheStorage(paths: BuildDataPaths) =
error("incremental K2MetadataCompiler not supported yet, createCacheStorage() should not be called")
}
@@ -1,244 +0,0 @@
/*
* 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.targets
import org.jetbrains.jps.builders.storage.BuildDataPaths
import org.jetbrains.jps.incremental.ModuleBuildTarget
import org.jetbrains.jps.incremental.ModuleLevelBuilder
import org.jetbrains.jps.model.library.JpsOrderRootType
import org.jetbrains.jps.model.module.JpsModule
import org.jetbrains.jps.util.JpsPathUtil
import org.jetbrains.kotlin.build.GeneratedFile
import org.jetbrains.kotlin.build.JsBuildMetaInfo
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.compilerRunner.JpsCompilerEnvironment
import org.jetbrains.kotlin.compilerRunner.JpsKotlinCompilerRunner
import org.jetbrains.kotlin.config.IncrementalCompilation
import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.incremental.ChangesCollector
import org.jetbrains.kotlin.incremental.IncrementalJsCache
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.IncrementalDataProviderFromCache
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer
import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumerImpl
import org.jetbrains.kotlin.jps.build.KotlinCompileContext
import org.jetbrains.kotlin.jps.build.KotlinDirtySourceFilesHolder
import org.jetbrains.kotlin.jps.build.ModuleBuildTarget
import org.jetbrains.kotlin.jps.incremental.JpsIncrementalCache
import org.jetbrains.kotlin.jps.incremental.JpsIncrementalJsCache
import org.jetbrains.kotlin.jps.model.k2JsCompilerArguments
import org.jetbrains.kotlin.jps.model.kotlinCompilerSettings
import org.jetbrains.kotlin.jps.model.productionOutputFilePath
import org.jetbrains.kotlin.jps.model.testOutputFilePath
import org.jetbrains.kotlin.utils.JsLibraryUtils
import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils.JS_EXT
import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils.META_JS_SUFFIX
import java.io.File
import java.net.URI
private const val JS_BUILD_META_INFO_FILE_NAME = "js-build-meta-info.txt"
class KotlinJsModuleBuildTarget(kotlinContext: KotlinCompileContext, jpsModuleBuildTarget: ModuleBuildTarget) :
KotlinModuleBuildTarget<JsBuildMetaInfo>(kotlinContext, jpsModuleBuildTarget) {
override val globalLookupCacheId: String
get() = "js"
override val isIncrementalCompilationEnabled: Boolean
get() = IncrementalCompilation.isEnabledForJs()
override val buildMetaInfoFactory
get() = JsBuildMetaInfo
override val buildMetaInfoFileName: String
get() = JS_BUILD_META_INFO_FILE_NAME
val isFirstBuild: Boolean
get() {
val targetDataRoot = jpsGlobalContext.projectDescriptor.dataManager.dataPaths.getTargetDataRoot(jpsModuleBuildTarget)
return !IncrementalJsCache.hasHeaderFile(targetDataRoot)
}
override fun makeServices(
builder: Services.Builder,
incrementalCaches: Map<KotlinModuleBuildTarget<*>, JpsIncrementalCache>,
lookupTracker: LookupTracker,
exceptActualTracer: ExpectActualTracker
) {
super.makeServices(builder, incrementalCaches, lookupTracker, exceptActualTracer)
with(builder) {
register(IncrementalResultsConsumer::class.java, IncrementalResultsConsumerImpl())
if (isIncrementalCompilationEnabled && !isFirstBuild) {
val cache = incrementalCaches[this@KotlinJsModuleBuildTarget] as IncrementalJsCache
register(
IncrementalDataProvider::class.java,
IncrementalDataProviderFromCache(cache)
)
}
}
}
override fun compileModuleChunk(
commonArguments: CommonCompilerArguments,
dirtyFilesHolder: KotlinDirtySourceFilesHolder,
environment: JpsCompilerEnvironment
): Boolean {
require(chunk.representativeTarget == this)
if (reportAndSkipCircular(environment)) return false
val sources = collectSourcesToCompile(dirtyFilesHolder)
if (!sources.logFiles()) {
return false
}
val libraries = libraryFiles + dependenciesMetaFiles
JpsKotlinCompilerRunner().runK2JsCompiler(
commonArguments,
module.k2JsCompilerArguments,
module.kotlinCompilerSettings,
environment,
sources.allFiles,
sources.crossCompiledFiles,
sourceMapRoots,
libraries,
friendBuildTargetsMetaFiles,
outputFile
)
return true
}
override fun doAfterBuild() {
copyJsLibraryFilesIfNeeded()
}
private fun copyJsLibraryFilesIfNeeded() {
if (module.kotlinCompilerSettings.copyJsLibraryFiles) {
val outputLibraryRuntimeDirectory = File(outputDir, module.kotlinCompilerSettings.outputDirectoryForJsLibraryFiles).absolutePath
JsLibraryUtils.copyJsFilesFromLibraries(
libraryFiles, outputLibraryRuntimeDirectory,
copySourceMap = module.k2JsCompilerArguments.sourceMap
)
}
}
private val sourceMapRoots: List<File>
get() {
// Compiler starts to produce path relative to base dirs in source maps if at least one statement is true:
// 1) base dirs are specified;
// 2) prefix is specified (i.e. non-empty)
// Otherwise compiler produces paths relative to source maps location.
// We don't have UI to configure base dirs, but we have UI to configure prefix.
// If prefix is not specified (empty) in UI, we want to produce paths relative to source maps location
return if (module.k2JsCompilerArguments.sourceMapPrefix.isNullOrBlank()) emptyList()
else module.contentRootsList.urls
.map { URI.create(it) }
.filter { it.scheme == "file" }
.map { File(it.path) }
}
val friendBuildTargetsMetaFiles
get() = friendBuildTargets.mapNotNull {
(it as? KotlinJsModuleBuildTarget)?.outputMetaFile?.absoluteFile?.toString()
}
val outputFile
get() = explicitOutputPath?.let { File(it) } ?: implicitOutputFile
private val explicitOutputPath
get() = if (isTests) module.testOutputFilePath else module.productionOutputFilePath
private val implicitOutputFile: File
get() {
val suffix = if (isTests) "_test" else ""
return File(outputDir, module.name + suffix + JS_EXT)
}
private val outputFileBaseName: String
get() = outputFile.path.substringBeforeLast(".")
val outputMetaFile: File
get() = File(outputFileBaseName + META_JS_SUFFIX)
private val libraryFiles: List<String>
get() = mutableListOf<String>().also { result ->
for (library in allDependencies.libraries) {
for (root in library.getRoots(JpsOrderRootType.COMPILED)) {
result.add(JpsPathUtil.urlToPath(root.url))
}
}
}
private val dependenciesMetaFiles: List<String>
get() = mutableListOf<String>().also { result ->
allDependencies.processModules { module ->
if (isTests) addDependencyMetaFile(module, result, isTests = true)
// note: production targets should be also added as dependency to test targets
addDependencyMetaFile(module, result, isTests = false)
}
}
private fun addDependencyMetaFile(
module: JpsModule,
result: MutableList<String>,
isTests: Boolean
) {
val dependencyBuildTarget = kotlinContext.targetsBinding[ModuleBuildTarget(module, isTests)]
if (dependencyBuildTarget != this@KotlinJsModuleBuildTarget &&
dependencyBuildTarget is KotlinJsModuleBuildTarget &&
dependencyBuildTarget.sources.isNotEmpty()
) {
val metaFile = dependencyBuildTarget.outputMetaFile
if (metaFile.exists()) {
result.add(metaFile.absolutePath)
}
}
}
override fun createCacheStorage(paths: BuildDataPaths) =
JpsIncrementalJsCache(jpsModuleBuildTarget, paths, kotlinContext.fileToPathConverter)
override fun updateCaches(
dirtyFilesHolder: KotlinDirtySourceFilesHolder,
jpsIncrementalCache: JpsIncrementalCache,
files: List<GeneratedFile>,
changesCollector: ChangesCollector,
environment: JpsCompilerEnvironment
) {
super.updateCaches(dirtyFilesHolder, jpsIncrementalCache, files, changesCollector, environment)
val incrementalResults = environment.services[IncrementalResultsConsumer::class.java] as IncrementalResultsConsumerImpl
val jsCache = jpsIncrementalCache as IncrementalJsCache
jsCache.header = incrementalResults.headerMetadata
jsCache.updateSourceToOutputMap(files)
jsCache.compareAndUpdate(incrementalResults, changesCollector)
jsCache.clearCacheForRemovedClasses(changesCollector)
}
override fun registerOutputItems(outputConsumer: ModuleLevelBuilder.OutputConsumer, outputItems: List<GeneratedFile>) {
if (isIncrementalCompilationEnabled) {
for (output in outputItems) {
for (source in output.sourceFiles) {
outputConsumer.registerOutputFile(jpsModuleBuildTarget, File("${source.path.hashCode()}"), listOf(source.path))
}
}
} else {
super.registerOutputItems(outputConsumer, outputItems)
}
}
}

Some files were not shown because too many files have changed in this diff Show More