Introduce TestingContext to pass data between tests and KotlinBuilder; introduce BuildLogger to log build events (build finished, files marked as dirty) in KotlinBuilder

This commit is contained in:
Zalim Bashorov
2016-01-25 22:34:10 +03:00
parent 4ec3865830
commit f6e7f8c3c0
286 changed files with 5556 additions and 2354 deletions
@@ -0,0 +1,35 @@
/*
* 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.ModuleLevelBuilder
import java.io.File
interface BuildLogger {
fun buildFinished(exitCode: ModuleLevelBuilder.ExitCode)
fun markedAsDirty(files: Iterable<File>)
companion object {
val DO_NOTHING = object : BuildLogger {
override fun buildFinished(exitCode: ModuleLevelBuilder.ExitCode) {
}
override fun markedAsDirty(files: Iterable<File>) {
}
}
}
}
@@ -32,6 +32,8 @@ class FSOperationsHelper(
fun hasMarkedDirty(): Boolean = markedDirty
private val buildLogger = compileContext.testingContext?.buildLogger ?: BuildLogger.DO_NOTHING
fun markChunk(recursively: Boolean, kotlinOnly: Boolean, excludeFiles: Set<File> = setOf()) {
fun shouldMark(file: File): Boolean {
if (kotlinOnly && !KotlinSourceFileCollector.isKotlinSourceFile(file)) return false
@@ -53,7 +55,9 @@ class FSOperationsHelper(
fun markFiles(files: Iterable<File>, excludeFiles: Set<File> = setOf()) {
val filesToMark = files.toMutableSet()
filesToMark.removeAll(excludeFiles)
log.debug("Mark dirty: $filesToMark")
buildLogger.markedAsDirty(filesToMark)
for (file in filesToMark) {
if (!file.exists()) continue
@@ -34,8 +34,6 @@ import org.jetbrains.jps.incremental.messages.BuildMessage
import org.jetbrains.jps.incremental.messages.CompilerMessage
import org.jetbrains.jps.incremental.storage.BuildDataManager
import org.jetbrains.jps.model.JpsProject
import org.jetbrains.jps.model.JpsSimpleElement
import org.jetbrains.jps.model.ex.JpsElementChildRoleBase
import org.jetbrains.jps.model.java.JpsJavaClasspathKind
import org.jetbrains.jps.model.java.JpsJavaExtensionService
import org.jetbrains.jps.model.module.JpsModule
@@ -78,7 +76,6 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
companion object {
@JvmField val KOTLIN_BUILDER_NAME: String = "Kotlin Builder"
val LOOKUP_TRACKER: JpsElementChildRoleBase<JpsSimpleElement<out LookupTracker>> = JpsElementChildRoleBase.create("lookup tracker")
val LOG = Logger.getInstance("#org.jetbrains.kotlin.jps.build.KotlinBuilder")
}
@@ -123,13 +120,19 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
applyActionsOnCacheVersionChange(actions, cacheVersionsProvider, context, dataManager, targets, fsOperations)
}
override fun chunkBuildFinished(context: CompileContext?, chunk: ModuleChunk?) {
super.chunkBuildFinished(context, chunk)
LOG.debug("------------------------------------------")
}
override fun build(
context: CompileContext,
chunk: ModuleChunk,
dirtyFilesHolder: DirtyFilesHolder<JavaSourceRootDescriptor, ModuleBuildTarget>,
outputConsumer: ModuleLevelBuilder.OutputConsumer
): ModuleLevelBuilder.ExitCode {
LOG.debug("------------------------------------------")
val messageCollector = MessageCollectorAdapter(context)
val fsOperations = FSOperationsHelper(context, chunk, LOG)
@@ -139,6 +142,11 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
val actualExitCode = if (proposedExitCode == OK && fsOperations.hasMarkedDirty()) ADDITIONAL_PASS_REQUIRED else proposedExitCode
LOG.info("Build result: " + actualExitCode)
context.testingContext?.run {
buildLogger.buildFinished(actualExitCode)
}
return actualExitCode
}
catch (e: StopBuildException) {
@@ -847,19 +855,11 @@ private fun withSubtypes(
}
private fun getLookupTracker(project: JpsProject): LookupTracker {
var lookupTracker = LookupTracker.DO_NOTHING
val testLookupTracker = project.testingContext?.lookupTracker ?: LookupTracker.DO_NOTHING
if ("true".equals(System.getProperty("kotlin.jps.tests"), ignoreCase = true)) {
val testTracker = project.container.getChild(KotlinBuilder.LOOKUP_TRACKER)?.data
if (IncrementalCompilation.isExperimental()) return LookupTrackerImpl(testLookupTracker)
if (testTracker != null) {
lookupTracker = testTracker
}
}
if (IncrementalCompilation.isExperimental()) return LookupTrackerImpl(lookupTracker)
return lookupTracker
return testLookupTracker
}
private fun getIncrementalCaches(chunk: ModuleChunk, context: CompileContext): Map<ModuleBuildTarget, JpsIncrementalCacheImpl> {
@@ -0,0 +1,44 @@
/*
* 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 context")
@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: BuildLogger
)