Skip to content

Commit 51a8f6e

Browse files
Implement server side IC
1 parent f411bb0 commit 51a8f6e

File tree

14 files changed

+375
-51
lines changed

14 files changed

+375
-51
lines changed

compiler/compiler-runner/src/org/jetbrains/kotlin/compilerRunner/KotlinCompilerRunner.kt

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ abstract class KotlinCompilerRunner<in Env : CompilerEnvironment> {
9393
protected fun processCompilerOutput(
9494
environment: Env,
9595
stream: ByteArrayOutputStream,
96-
exitCode: ExitCode
96+
exitCode: ExitCode?
9797
) {
9898
val reader = BufferedReader(StringReader(stream.toString()))
9999
CompilerOutputParser.parseCompilerMessagesFromReader(environment.messageCollector, reader, environment.outputItemsCollector)
@@ -194,12 +194,12 @@ abstract class KotlinCompilerRunner<in Env : CompilerEnvironment> {
194194
return null
195195
}
196196

197-
protected fun exitCodeFromProcessExitCode(res: Int): ExitCode =
198-
if (res == 0) {
199-
ExitCode.OK
200-
}
201-
else {
202-
ExitCode.COMPILATION_ERROR
203-
}
197+
protected fun exitCodeFromProcessExitCode(code: Int): ExitCode {
198+
val exitCode = ExitCode.values().find { it.code == code }
199+
if (exitCode != null) return exitCode
200+
201+
log.debug("Could not find exit code by value: $code")
202+
return if (code == 0) ExitCode.OK else ExitCode.COMPILATION_ERROR
203+
}
204204
}
205205

compiler/daemon/daemon-common/src/org/jetbrains/kotlin/daemon/common/CompileService.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,16 @@ interface CompileService : Remote {
125125
operationsTracer: RemoteOperationsTracer?
126126
): CallResult<Int>
127127

128+
@Throws(RemoteException::class)
129+
fun serverSideJvmIC(
130+
sessionId: Int,
131+
args: Array<out String>,
132+
servicesFacade: IncrementalCompilationServicesFacade,
133+
compilerOutputStream: RemoteOutputStream,
134+
serviceOutputStream: RemoteOutputStream,
135+
operationsTracer: RemoteOperationsTracer?
136+
): CallResult<Int>
137+
128138
@Throws(RemoteException::class)
129139
fun leaseReplSession(
130140
aliveFlagPath: String?,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright 2010-2016 JetBrains s.r.o.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.jetbrains.kotlin.daemon.common
18+
19+
import java.io.File
20+
import java.rmi.Remote
21+
import java.rmi.RemoteException
22+
23+
interface IncrementalCompilationServicesFacade : Remote {
24+
@Throws(RemoteException::class)
25+
fun areFileChangesKnown(): Boolean
26+
27+
@Throws(RemoteException::class)
28+
fun modifiedFiles(): List<File>?
29+
30+
@Throws(RemoteException::class)
31+
fun deletedFiles(): List<File>?
32+
33+
@Throws(RemoteException::class)
34+
fun workingDir(): File
35+
36+
// ICReporter
37+
38+
@Throws(RemoteException::class)
39+
fun shouldReportIC(): Boolean
40+
41+
@Throws(RemoteException::class)
42+
fun reportIC(message: String)
43+
44+
@Throws(RemoteException::class)
45+
fun reportCompileIteration(files: Iterable<File>, exitCode: Int)
46+
47+
// AnnotationFileUpdater
48+
@Throws(RemoteException::class)
49+
fun hasAnnotationsFileUpdater(): Boolean
50+
51+
@Throws(RemoteException::class)
52+
fun updateAnnotations(outdatedClassesJvmNames: Iterable<String>)
53+
54+
@Throws(RemoteException::class)
55+
fun revert()
56+
}

compiler/daemon/daemon.iml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,8 @@
1212
<orderEntry type="module" module-name="util" />
1313
<orderEntry type="library" name="intellij-core" level="project" />
1414
<orderEntry type="module" module-name="frontend" />
15+
<orderEntry type="module" module-name="incremental-compilation-impl" />
16+
<orderEntry type="module" module-name="build-common" />
17+
<orderEntry type="module" module-name="descriptor.loader.java" />
1518
</component>
1619
</module>

compiler/daemon/src/org/jetbrains/kotlin/daemon/CompileServiceImpl.kt

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,31 @@ import com.intellij.openapi.Disposable
2020
import com.intellij.openapi.util.Disposer
2121
import com.intellij.openapi.vfs.impl.ZipHandler
2222
import com.intellij.openapi.vfs.impl.jar.CoreJarFileSystem
23+
import org.jetbrains.kotlin.annotation.AnnotationFileUpdater
2324
import org.jetbrains.kotlin.cli.common.CLICompiler
2425
import org.jetbrains.kotlin.cli.common.ExitCode
2526
import org.jetbrains.kotlin.cli.common.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY
27+
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
28+
import org.jetbrains.kotlin.cli.common.messages.*
29+
import org.jetbrains.kotlin.cli.common.modules.ModuleXmlParser
2630
import org.jetbrains.kotlin.cli.common.repl.ReplCheckResult
2731
import org.jetbrains.kotlin.cli.common.repl.ReplCodeLine
2832
import org.jetbrains.kotlin.cli.common.repl.ReplCompileResult
2933
import org.jetbrains.kotlin.cli.common.repl.ReplEvalResult
34+
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
3035
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
36+
import org.jetbrains.kotlin.config.IncrementalCompilation
3137
import org.jetbrains.kotlin.config.Services
3238
import org.jetbrains.kotlin.daemon.common.*
39+
import org.jetbrains.kotlin.incremental.*
3340
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
41+
import org.jetbrains.kotlin.modules.Module
42+
import org.jetbrains.kotlin.name.FqName
3443
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
44+
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
3545
import org.jetbrains.kotlin.utils.addToStdlib.check
3646
import java.io.BufferedOutputStream
47+
import java.io.ByteArrayOutputStream
3748
import java.io.File
3849
import java.io.PrintStream
3950
import java.rmi.NoSuchObjectException
@@ -306,6 +317,58 @@ class CompileServiceImpl(
306317
}
307318
}
308319

320+
override fun serverSideJvmIC(
321+
sessionId: Int,
322+
args: Array<out String>,
323+
servicesFacade: IncrementalCompilationServicesFacade,
324+
compilerOutputStream: RemoteOutputStream,
325+
serviceOutputStream: RemoteOutputStream,
326+
operationsTracer: RemoteOperationsTracer?
327+
): CompileService.CallResult<Int> {
328+
return doCompile(sessionId, args, compilerOutputStream, serviceOutputStream, operationsTracer) { printStream, eventManager, profiler ->
329+
val reporter = RemoteICReporter(servicesFacade)
330+
val annotationFileUpdater = if (servicesFacade.hasAnnotationsFileUpdater()) RemoteAnnotationsFileUpdater(servicesFacade) else null
331+
332+
// these flags do not have any effect on the compiler (only on caches, incremental compilation logic, jps plugin)
333+
// so it's OK to just set them true
334+
IncrementalCompilation.setIsEnabled(true)
335+
IncrementalCompilation.setIsExperimental(true)
336+
337+
val k2jvmArgs = K2JVMCompilerArguments()
338+
(compiler[CompileService.TargetPlatform.JVM] as K2JVMCompiler).parseArguments(args, k2jvmArgs)
339+
340+
val moduleFile = k2jvmArgs.module?.let(::File)
341+
assert(moduleFile?.exists() ?: false) { "Module does not exist ${k2jvmArgs.module}" }
342+
val renderer = MessageRenderer.XML
343+
val messageCollector = PrintingMessageCollector(printStream, renderer, k2jvmArgs.verbose)
344+
val filteringMessageCollector = FilteringMessageCollector(messageCollector) { it == CompilerMessageSeverity.ERROR }
345+
346+
val parsedModule = ModuleXmlParser.parseModuleScript(k2jvmArgs.module, filteringMessageCollector)
347+
val javaSourceRoots = parsedModule.modules.flatMapTo(HashSet()) { it.getJavaSourceRoots().map { File(it.path) } }
348+
val allKotlinFiles = parsedModule.modules.flatMap { it.getSourceFiles().map(::File) }
349+
k2jvmArgs.friendPaths = parsedModule.modules.flatMap(Module::getFriendPaths).toTypedArray()
350+
351+
val changedFiles = if (servicesFacade.areFileChangesKnown()) {
352+
ChangedFiles.Known(servicesFacade.modifiedFiles()!!, servicesFacade.deletedFiles()!!)
353+
}
354+
else {
355+
ChangedFiles.Unknown()
356+
}
357+
358+
val workingDir = servicesFacade.workingDir()
359+
val versions = commonCacheVersions(workingDir) + standaloneCacheVersion(workingDir, forceEnable = true)
360+
361+
try {
362+
printStream.print(renderer.renderPreamble())
363+
IncrementalJvmCompilerRunner(workingDir, javaSourceRoots, versions, reporter, annotationFileUpdater)
364+
.compile(allKotlinFiles, k2jvmArgs, messageCollector, { changedFiles })
365+
}
366+
finally {
367+
printStream.print(renderer.renderConclusion())
368+
}
369+
}
370+
}
371+
309372
override fun leaseReplSession(
310373
aliveFlagPath: String?,
311374
targetPlatform: CompileService.TargetPlatform,
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright 2010-2016 JetBrains s.r.o.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.jetbrains.kotlin.daemon
18+
19+
import org.jetbrains.kotlin.annotation.AnnotationFileUpdater
20+
import org.jetbrains.kotlin.cli.common.ExitCode
21+
import org.jetbrains.kotlin.daemon.common.IncrementalCompilationServicesFacade
22+
import org.jetbrains.kotlin.incremental.ICReporter
23+
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
24+
import java.io.File
25+
26+
internal class RemoteAnnotationsFileUpdater(private val servicesFacade: IncrementalCompilationServicesFacade) : AnnotationFileUpdater {
27+
override fun updateAnnotations(outdatedClasses: Iterable<JvmClassName>) {
28+
servicesFacade.updateAnnotations(outdatedClasses.map { it.internalName })
29+
}
30+
31+
override fun revert() {
32+
servicesFacade.revert()
33+
}
34+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright 2010-2016 JetBrains s.r.o.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.jetbrains.kotlin.daemon
18+
19+
import org.jetbrains.kotlin.cli.common.ExitCode
20+
import org.jetbrains.kotlin.daemon.common.IncrementalCompilationServicesFacade
21+
import org.jetbrains.kotlin.incremental.ICReporter
22+
import java.io.File
23+
24+
internal class RemoteICReporter(private val servicesFacade: IncrementalCompilationServicesFacade) : ICReporter() {
25+
override fun report(message: () -> String) {
26+
if (servicesFacade.shouldReportIC()) {
27+
servicesFacade.reportIC(message())
28+
}
29+
}
30+
31+
override fun reportCompileIteration(sourceFiles: Iterable<File>, exitCode: ExitCode) {
32+
if (servicesFacade.shouldReportIC()) {
33+
servicesFacade.reportCompileIteration(sourceFiles, exitCode.code)
34+
}
35+
}
36+
}

compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,7 @@ fun makeIncrementally(
4949
messageCollector: MessageCollector = MessageCollector.NONE,
5050
reporter: ICReporter = EmptyICReporter
5151
) {
52-
val versions = listOf(normalCacheVersion(cachesDir),
53-
experimentalCacheVersion(cachesDir),
54-
dataContainerCacheVersion(cachesDir),
55-
standaloneCacheVersion(cachesDir))
52+
val versions = commonCacheVersions(cachesDir) + standaloneCacheVersion(cachesDir)
5653

5754
val kotlinExtensions = listOf("kt", "kts")
5855
val allExtensions = kotlinExtensions + listOf("java")
@@ -313,9 +310,6 @@ class IncrementalJvmCompilerRunner(
313310
caches.incrementalCache.removeClassfilesBySources(dirtySources)
314311

315312
val (sourcesToCompile, removedKotlinSources) = dirtySources.partition(File::exists)
316-
if (sourcesToCompile.isNotEmpty()) {
317-
reporter.report { "compile iteration: ${reporter.pathsAsString(sourcesToCompile)}" }
318-
}
319313

320314
// todo: more optimal to save only last iteration, but it will require adding standalone-ic specific logs
321315
// (because jps rebuilds all files from last build if it failed and gradle rebuilds everything)
Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,15 @@ import java.io.File
2222
internal const val STANDALONE_CACHE_VERSION = 0
2323
internal const val STANDALONE_VERSION_FILE_NAME = "standalone-ic-format-version.txt"
2424

25-
internal fun standaloneCacheVersion(dataRoot: File): CacheVersion =
25+
fun standaloneCacheVersion(dataRoot: File, forceEnable: Boolean = false): CacheVersion =
2626
CacheVersion(ownVersion = STANDALONE_CACHE_VERSION,
2727
versionFile = File(dataRoot, STANDALONE_VERSION_FILE_NAME),
2828
whenVersionChanged = CacheVersion.Action.REBUILD_ALL_KOTLIN,
2929
whenTurnedOn = CacheVersion.Action.REBUILD_ALL_KOTLIN,
3030
whenTurnedOff = CacheVersion.Action.REBUILD_ALL_KOTLIN,
31-
isEnabled = { IncrementalCompilation.isExperimental() })
31+
isEnabled = { IncrementalCompilation.isExperimental() || forceEnable })
32+
33+
fun commonCacheVersions(cachesDir: File): List<CacheVersion> =
34+
listOf(normalCacheVersion(cachesDir),
35+
experimentalCacheVersion(cachesDir),
36+
dataContainerCacheVersion(cachesDir))
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package org.jetbrains.kotlin.compilerRunner
22

3+
import org.jetbrains.kotlin.annotation.AnnotationFileUpdater
34
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
45
import org.jetbrains.kotlin.config.Services
6+
import org.jetbrains.kotlin.incremental.ChangedFiles
7+
import org.jetbrains.kotlin.incremental.GradleICReporter
58
import java.io.File
69
import java.net.URL
710

8-
internal class GradleCompilerEnvironment(
11+
internal open class GradleCompilerEnvironment(
912
val compilerJar: File,
1013
messageCollector: MessageCollector,
1114
outputItemsCollector: OutputItemsCollector
@@ -15,4 +18,14 @@ internal class GradleCompilerEnvironment(
1518

1619
val compilerClasspathURLs: List<URL>
1720
get() = compilerClasspath.map { it.toURI().toURL() }
18-
}
21+
}
22+
23+
internal class GradleIncrementalCompilerEnvironment(
24+
compilerJar: File,
25+
val changedFiles: ChangedFiles,
26+
val reporter: GradleICReporter,
27+
val workingDir: File,
28+
messageCollector: MessageCollector,
29+
outputItemsCollector: OutputItemsCollector,
30+
val kaptAnnotationsFileUpdater: AnnotationFileUpdater?
31+
) : GradleCompilerEnvironment(compilerJar, messageCollector, outputItemsCollector)

0 commit comments

Comments
 (0)