diff --git a/libraries/tools/kotlin-maven-plugin-test/pom.xml b/libraries/tools/kotlin-maven-plugin-test/pom.xml
index 58979e707ac..8adc99308c0 100644
--- a/libraries/tools/kotlin-maven-plugin-test/pom.xml
+++ b/libraries/tools/kotlin-maven-plugin-test/pom.xml
@@ -12,8 +12,45 @@
kotlin-maven-plugin-test
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+ org.jetbrains.kotlin
+ kotlin-maven-plugin
+ ${project.version}
+ test
+
+
+
+ ${project.basedir}/src/test/java
+
+
+
+ ${project.basedir}/src/test/resources
+ true
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+
+ test-compile
+ test-compile
+ testCompile
+
+
+
+
maven-deploy-plugin
@@ -35,6 +72,33 @@
+
+ maven-failsafe-plugin
+ 2.6
+
+
+
+ integration-test
+ verify
+
+
+ ${env.JAVA_HOME}/bin/java
+ once
+
+
+ maven.home
+ ${maven.home}
+
+
+ kotlin.version
+ ${project.version}
+
+
+
+
+
+
+
maven-invoker-plugin
1.9
diff --git a/libraries/tools/kotlin-maven-plugin-test/src/test/java/org.jetbrains.kotlin.maven/Action.java b/libraries/tools/kotlin-maven-plugin-test/src/test/java/org.jetbrains.kotlin.maven/Action.java
new file mode 100644
index 00000000000..0473386da97
--- /dev/null
+++ b/libraries/tools/kotlin-maven-plugin-test/src/test/java/org.jetbrains.kotlin.maven/Action.java
@@ -0,0 +1,5 @@
+package org.jetbrains.kotlin.maven;
+
+interface Action {
+ void run(T param) throws Exception;
+}
diff --git a/libraries/tools/kotlin-maven-plugin-test/src/test/java/org.jetbrains.kotlin.maven/IncrementalCompilationIT.java b/libraries/tools/kotlin-maven-plugin-test/src/test/java/org.jetbrains.kotlin.maven/IncrementalCompilationIT.java
new file mode 100644
index 00000000000..00b5c629dbf
--- /dev/null
+++ b/libraries/tools/kotlin-maven-plugin-test/src/test/java/org.jetbrains.kotlin.maven/IncrementalCompilationIT.java
@@ -0,0 +1,61 @@
+package org.jetbrains.kotlin.maven;
+
+import org.junit.Test;
+
+import java.io.File;
+
+public class IncrementalCompilationIT {
+ @Test
+ public void testSimpleCompile() throws Exception {
+ MavenProject project = new MavenProject("kotlinSimple");
+ project.exec("package")
+ .succeeded()
+ .compiledKotlin("src/A.kt", "src/useA.kt", "src/Dummy.kt");
+ }
+
+ @Test
+ public void testNoChanges() throws Exception {
+ MavenProject project = new MavenProject("kotlinSimple");
+ project.exec("package");
+
+ project.exec("package")
+ .succeeded()
+ .compiledKotlin();
+ }
+
+ @Test
+ public void testCompileError() throws Exception {
+ MavenProject project = new MavenProject("kotlinSimple");
+ project.exec("package");
+
+ File aKt = project.file("src/A.kt");
+ String original = "class A";
+ String replacement = "private class A";
+ MavenTestUtils.replaceFirstInFile(aKt, original, replacement);
+
+ project.exec("package")
+ .failed()
+ .contains("Cannot access 'A': it is private in file");
+
+ MavenTestUtils.replaceFirstInFile(aKt, replacement, original);
+ project.exec("package")
+ .succeeded()
+ .compiledKotlin("src/A.kt", "src/useA.kt");
+
+ }
+
+ @Test
+ public void testFunctionVisibilityChanged() throws Exception {
+ MavenProject project = new MavenProject("kotlinSimple");
+ project.exec("package");
+
+ File aKt = project.file("src/A.kt");
+ MavenTestUtils.replaceFirstInFile(aKt, "fun foo", "internal fun foo");
+
+ project.exec("package")
+ .succeeded()
+ .compiledKotlin("src/A.kt", "src/useA.kt");
+
+ // todo rebuild and compare output
+ }
+}
diff --git a/libraries/tools/kotlin-maven-plugin-test/src/test/java/org.jetbrains.kotlin.maven/MavenExecutionResult.java b/libraries/tools/kotlin-maven-plugin-test/src/test/java/org.jetbrains.kotlin.maven/MavenExecutionResult.java
new file mode 100644
index 00000000000..5975a5c912e
--- /dev/null
+++ b/libraries/tools/kotlin-maven-plugin-test/src/test/java/org.jetbrains.kotlin.maven/MavenExecutionResult.java
@@ -0,0 +1,113 @@
+package org.jetbrains.kotlin.maven;
+
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import org.jetbrains.annotations.NotNull;
+import org.junit.Assert;
+
+import java.io.File;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+class MavenExecutionResult {
+ @NotNull
+ private final String stdout;
+
+ @NotNull
+ private final File workingDir;
+
+ private int exitCode;
+
+ MavenExecutionResult(
+ @NotNull String output,
+ @NotNull File workingDir,
+ int exitCode
+ ) {
+ this.stdout = output;
+ this.workingDir = workingDir;
+ this.exitCode = exitCode;
+ }
+
+ MavenExecutionResult check(@NotNull Action fn) throws Exception {
+ try {
+ fn.run(this);
+ }
+ catch (Throwable t) {
+ System.out.println(stdout);
+ throw new RuntimeException(t);
+ }
+ return this;
+ }
+
+ MavenExecutionResult succeeded() throws Exception {
+ return check(new Action() {
+ @Override
+ public void run(MavenExecutionResult execResult) {
+ Assert.assertEquals("Maven process was expected to succeeded", 0, exitCode);
+ }
+ });
+ }
+
+ MavenExecutionResult failed() throws Exception {
+ return check(new Action() {
+ @Override
+ public void run(MavenExecutionResult execResult) {
+ Assert.assertNotEquals("Maven process was expected to fail", 0, exitCode);
+ }
+ });
+ }
+
+ MavenExecutionResult contains(@NotNull final String str) throws Exception {
+ return check(new Action() {
+ @Override
+ public void run(MavenExecutionResult execResult) {
+ if (!stdout.contains(str)) {
+ throw new AssertionError("Maven output should contain '" + str + "'");
+ }
+ }
+ });
+ }
+
+ MavenExecutionResult notContains(@NotNull final String str) throws Exception {
+ return check(new Action() {
+ @Override
+ public void run(MavenExecutionResult execResult) {
+ if (stdout.contains(str)) {
+ throw new AssertionError("Maven output should not contain '" + str + "'");
+ }
+ }
+ });
+ }
+
+ MavenExecutionResult compiledKotlin(@NotNull final String... expectedPaths) throws Exception {
+ return check(new Action() {
+ @Override
+ public void run(MavenExecutionResult execResult) {
+ Pattern kotlinCompileIteration = Pattern.compile("(?m)Kotlin compile iteration: (.*)$");
+ Matcher m = kotlinCompileIteration.matcher(stdout);
+
+ Set normalizedActualPaths = new HashSet();
+ while (m.find()) {
+ String[] compiledFiles = m.group(1).split(",");
+ for (String path : compiledFiles) {
+ File file = new File(path.trim());
+ String relativePath = FileUtil.getRelativePath(workingDir, file);
+ normalizedActualPaths.add(FileUtil.normalize(relativePath));
+ }
+ }
+ String[] actualPaths = normalizedActualPaths.toArray(new String[normalizedActualPaths.size()]);
+ Arrays.sort(actualPaths);
+
+ for (int i = 0; i < expectedPaths.length; i++) {
+ expectedPaths[i] = FileUtil.normalize(expectedPaths[i]);
+ }
+ Arrays.sort(expectedPaths);
+
+ String expected = StringUtil.join(expectedPaths, "\n");
+ String actual = StringUtil.join(actualPaths, "\n");
+ Assert.assertEquals("Compiled files differ", expected, actual);
+ }
+ });
+ }
+}
diff --git a/libraries/tools/kotlin-maven-plugin-test/src/test/java/org.jetbrains.kotlin.maven/MavenProject.java b/libraries/tools/kotlin-maven-plugin-test/src/test/java/org.jetbrains.kotlin.maven/MavenProject.java
new file mode 100644
index 00000000000..90dd81d5770
--- /dev/null
+++ b/libraries/tools/kotlin-maven-plugin-test/src/test/java/org.jetbrains.kotlin.maven/MavenProject.java
@@ -0,0 +1,77 @@
+package org.jetbrains.kotlin.maven;
+
+import com.intellij.openapi.util.io.FileUtil;
+import kotlin.io.TextStreamsKt;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.*;
+import java.util.*;
+
+import static org.jetbrains.kotlin.maven.MavenTestUtils.getNotNullSystemProperty;
+
+class MavenProject {
+ @NotNull
+ private final File workingDir;
+
+ MavenProject(@NotNull String name) throws IOException {
+ File originalProjectDir = new File("src/test/resources/" + name);
+ workingDir = FileUtil.createTempDirectory("maven-test-" + name, null);
+ File[] filesToCopy = originalProjectDir.listFiles();
+
+ for (File from : filesToCopy) {
+ File to = new File(workingDir, from.getName());
+ FileUtil.copyFileOrDir(from, to);
+ }
+ }
+
+ @NotNull
+ File file(@NotNull String path) {
+ return new File(workingDir, path);
+ }
+
+ MavenExecutionResult exec(String... targets) throws Exception {
+ List cmd = buildCmd(targets);
+ ProcessBuilder processBuilder = new ProcessBuilder(cmd);
+ setUpEnvVars(processBuilder.environment());
+
+ processBuilder.directory(workingDir);
+ processBuilder.redirectErrorStream(true);
+ Process process = processBuilder.start();
+
+ BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
+ String stdout = TextStreamsKt.readText(reader);
+ int exitCode = process.waitFor();
+
+ return new MavenExecutionResult(stdout, workingDir, exitCode);
+ }
+
+ private void setUpEnvVars(Map env) throws IOException {
+ String mavenHome = getNotNullSystemProperty("maven.home");
+ env.put("M2_HOME", mavenHome);
+ String mavenPath = mavenHome + File.separator + "bin";
+ env.put("PATH", env.get("PATH") + File.pathSeparator + mavenPath);
+ }
+
+ private List buildCmd(String... args) {
+ List cmd = new ArrayList();
+
+ String osName = getNotNullSystemProperty("os.name");
+ if (osName.contains("Windows")) {
+ cmd.addAll(Arrays.asList("cmd", "/C"));
+ }
+ else {
+ cmd.add("/bin/bash");
+ }
+
+ cmd.add("mvn");
+ cmd.add("-Dkotlin.compiler.incremental.log.level=info");
+
+ String kotlinVersion = getNotNullSystemProperty("kotlin.version");
+ cmd.add("-Dkotlin.version=" + kotlinVersion);
+
+ cmd.addAll(Arrays.asList(args));
+
+ return cmd;
+ }
+}
+
diff --git a/libraries/tools/kotlin-maven-plugin-test/src/test/java/org.jetbrains.kotlin.maven/MavenTestUtils.java b/libraries/tools/kotlin-maven-plugin-test/src/test/java/org.jetbrains.kotlin.maven/MavenTestUtils.java
new file mode 100644
index 00000000000..8f0442624ca
--- /dev/null
+++ b/libraries/tools/kotlin-maven-plugin-test/src/test/java/org.jetbrains.kotlin.maven/MavenTestUtils.java
@@ -0,0 +1,33 @@
+package org.jetbrains.kotlin.maven;
+
+import kotlin.io.FilesKt;
+import kotlin.text.Charsets;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.*;
+
+class MavenTestUtils {
+ @NotNull
+ static String readText(@NotNull File file) throws IOException {
+ return FilesKt.readText(file, Charsets.UTF_8);
+ }
+
+ static void writeText(@NotNull File file, @NotNull String text) throws IOException {
+ FilesKt.writeText(file, text, Charsets.UTF_8);
+ }
+
+ static void replaceFirstInFile(@NotNull File file, @NotNull String regex, @NotNull String replacement) throws IOException {
+ String text = readText(file);
+ String processedText = text.replaceFirst(regex, replacement);
+ writeText(file, processedText);
+ }
+
+ @NotNull
+ static String getNotNullSystemProperty(@NotNull String propertyName) {
+ String value = System.getProperty(propertyName);
+ if (value == null) {
+ throw new IllegalStateException("A system property '" + propertyName + "' is not set");
+ }
+ return value;
+ }
+}
diff --git a/libraries/tools/kotlin-maven-plugin-test/src/test/resources/kotlinSimple/pom.xml b/libraries/tools/kotlin-maven-plugin-test/src/test/resources/kotlinSimple/pom.xml
new file mode 100644
index 00000000000..9dbae229971
--- /dev/null
+++ b/libraries/tools/kotlin-maven-plugin-test/src/test/resources/kotlinSimple/pom.xml
@@ -0,0 +1,69 @@
+
+
+ 4.0.0
+
+ org.jetbrains.kotlin
+ test-kotlin-incremental
+ 1.0-SNAPSHOT
+
+
+ true
+
+
+
+
+ org.jetbrains.kotlin
+ kotlin-stdlib
+ ${kotlin.version}
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 2.3.2
+
+ 1.6
+ 1.6
+
+
+
+ org.apache.maven.plugins
+ maven-source-plugin
+ 2.1.2
+
+
+
+
+ ${project.basedir}/src
+
+
+ kotlin-maven-plugin
+ org.jetbrains.kotlin
+ ${kotlin.version}
+
+
+ compile
+ process-sources
+
+ compile
+
+
+
+ test-compile
+ process-test-sources
+
+ test-compile
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/libraries/tools/kotlin-maven-plugin-test/src/test/resources/kotlinSimple/src/A.kt b/libraries/tools/kotlin-maven-plugin-test/src/test/resources/kotlinSimple/src/A.kt
new file mode 100644
index 00000000000..0cb3e2f1d8a
--- /dev/null
+++ b/libraries/tools/kotlin-maven-plugin-test/src/test/resources/kotlinSimple/src/A.kt
@@ -0,0 +1,3 @@
+class A {
+ fun foo(s: String) = s + s
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-maven-plugin-test/src/test/resources/kotlinSimple/src/Dummy.kt b/libraries/tools/kotlin-maven-plugin-test/src/test/resources/kotlinSimple/src/Dummy.kt
new file mode 100644
index 00000000000..be783c00c18
--- /dev/null
+++ b/libraries/tools/kotlin-maven-plugin-test/src/test/resources/kotlinSimple/src/Dummy.kt
@@ -0,0 +1 @@
+class Dummy
\ No newline at end of file
diff --git a/libraries/tools/kotlin-maven-plugin-test/src/test/resources/kotlinSimple/src/useA.kt b/libraries/tools/kotlin-maven-plugin-test/src/test/resources/kotlinSimple/src/useA.kt
new file mode 100644
index 00000000000..f89d301d503
--- /dev/null
+++ b/libraries/tools/kotlin-maven-plugin-test/src/test/resources/kotlinSimple/src/useA.kt
@@ -0,0 +1,3 @@
+fun useA() {
+ A().foo("Hello, world")
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/K2JVMCompileMojo.java b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/K2JVMCompileMojo.java
index 7d9cdde02c9..62371714220 100644
--- a/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/K2JVMCompileMojo.java
+++ b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/K2JVMCompileMojo.java
@@ -20,13 +20,17 @@ import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.*;
import org.apache.maven.project.MavenProject;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.kotlin.cli.common.CLICompiler;
+import org.jetbrains.kotlin.cli.common.ExitCode;
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments;
+import org.jetbrains.kotlin.cli.common.messages.MessageCollector;
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler;
+import org.jetbrains.kotlin.incremental.IncrementalJvmCompilerRunnerKt;
+import org.jetbrains.kotlin.maven.incremental.MavenICReporter;
import org.jetbrains.kotlin.maven.kapt.AnnotationProcessingManager;
import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.*;
import static com.intellij.openapi.util.text.StringUtil.join;
import static org.jetbrains.kotlin.maven.Util.filterClassPath;
@@ -65,6 +69,26 @@ public class K2JVMCompileMojo extends KotlinCompileMojoBase scriptTemplates;
+ @Parameter(property = "kotlin.compiler.incremental", defaultValue = "false", required = false, readonly = false)
+ private boolean myIncremental;
+
+ @Parameter(property = "kotlin.compiler.incremental.cache.root", defaultValue = "${project.build.directory}/kotlin-ic", required = false, readonly = false)
+ public String incrementalCachesRoot;
+
+ @NotNull
+ private File getCachesDir() {
+ return new File(incrementalCachesRoot, getSourceSetName());
+ }
+
+ protected boolean isIncremental() {
+ return myIncremental;
+ }
+
+ private boolean isIncrementalSystemProperty() {
+ String value = System.getProperty("kotlin.incremental");
+ return value != null && value.equals("true");
+ }
+
@Override
protected List getRelatedSourceRoots(MavenProject project) {
return project.getCompileSourceRoots();
@@ -141,4 +165,50 @@ public class K2JVMCompileMojo extends KotlinCompileMojoBase compiler,
+ MessageCollector messageCollector,
+ K2JVMCompilerArguments arguments,
+ List sourceRoots
+ ) throws MojoExecutionException {
+ if (isIncremental()) {
+ return runIncrementalCompiler(messageCollector, arguments, sourceRoots);
+ }
+
+ return super.execCompiler(compiler, messageCollector, arguments, sourceRoots);
+ }
+
+ @NotNull
+ private ExitCode runIncrementalCompiler(
+ MessageCollector messageCollector,
+ K2JVMCompilerArguments arguments,
+ List sourceRoots
+ ) throws MojoExecutionException {
+ getLog().warn("Using experimental Kotlin incremental compilation");
+ File cachesDir = getCachesDir();
+ //noinspection ResultOfMethodCallIgnored
+ cachesDir.mkdirs();
+
+ MavenICReporter icReporter = MavenICReporter.get(getLog());
+
+ try {
+ IncrementalJvmCompilerRunnerKt.makeIncrementally(cachesDir, sourceRoots, arguments, messageCollector, icReporter);
+
+ int compiledKtFilesCount = icReporter.getCompiledKotlinFiles().size();
+ getLog().info("Compiled " + icReporter.getCompiledKotlinFiles().size() + " Kotlin files using incremental compiler");
+ }
+ catch (Throwable t) {
+ t.printStackTrace();
+ return ExitCode.INTERNAL_ERROR;
+ }
+
+ if (messageCollector.hasErrors()) {
+ return ExitCode.COMPILATION_ERROR;
+ }
+ else {
+ return ExitCode.OK;
+ }
+ }
}
diff --git a/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/KotlinCompileMojoBase.java b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/KotlinCompileMojoBase.java
index 31b2b41de1f..9092b2543d4 100644
--- a/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/KotlinCompileMojoBase.java
+++ b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/KotlinCompileMojoBase.java
@@ -38,6 +38,7 @@ import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.cli.common.CLICompiler;
import org.jetbrains.kotlin.cli.common.ExitCode;
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments;
+import org.jetbrains.kotlin.cli.common.messages.MessageCollector;
import org.jetbrains.kotlin.config.KotlinCompilerVersion;
import org.jetbrains.kotlin.config.Services;
@@ -192,18 +193,33 @@ public abstract class KotlinCompileMojoBase e
A arguments = createCompilerArguments();
CLICompiler compiler = createCompiler();
+ List sourceRoots = getSourceRoots();
+
configureCompilerArguments(arguments, compiler);
printCompilerArgumentsIfDebugEnabled(arguments, compiler);
MavenPluginLogMessageCollector messageCollector = new MavenPluginLogMessageCollector(getLog());
- ExitCode exitCode = compiler.exec(messageCollector, Services.EMPTY, arguments);
+ ExitCode exitCode = execCompiler(compiler, messageCollector, arguments, sourceRoots);
if (exitCode != ExitCode.OK) {
messageCollector.throwKotlinCompilerException();
}
}
+ @NotNull
+ protected ExitCode execCompiler(
+ CLICompiler compiler,
+ MessageCollector messageCollector,
+ A arguments,
+ List sourceRoots
+ ) throws MojoExecutionException {
+ for (File sourceRoot : sourceRoots) {
+ arguments.freeArgs.add(sourceRoot.getPath());
+ }
+ return compiler.exec(messageCollector, Services.EMPTY, arguments);
+ }
+
private boolean hasKotlinFilesInSources() throws MojoExecutionException {
List sources = getSourceDirs();
if (sources == null || sources.isEmpty()) return false;
@@ -400,32 +416,34 @@ public abstract class KotlinCompileMojoBase e
return pluginOptions;
}
+ @NotNull
+ private List getSourceRoots() throws MojoExecutionException {
+ List sourceRoots = new ArrayList();
+ for (File sourceDir : getSourceDirs()) {
+ if (sourceDir.exists()) {
+ sourceRoots.add(sourceDir);
+ }
+ else {
+ getLog().warn("Source root doesn't exist: " + sourceDir);
+ }
+ }
+ if (sourceRoots.isEmpty()) {
+ throw new MojoExecutionException("No source roots to compile");
+ }
+ getLog().info("Compiling Kotlin sources from " + sourceRoots);
+ return sourceRoots;
+ }
+
private void configureCompilerArguments(@NotNull A arguments, @NotNull CLICompiler compiler) throws MojoExecutionException {
if (getLog().isDebugEnabled()) {
arguments.verbose = true;
}
- List sources = new ArrayList();
- for (File source : getSourceDirs()) {
- if (source.exists()) {
- sources.add(source.getPath());
- }
- else {
- getLog().warn("Source root doesn't exist: " + source);
- }
- }
-
- if (sources.isEmpty()) {
- throw new MojoExecutionException("No source roots to compile");
- }
-
arguments.suppressWarnings = nowarn;
arguments.languageVersion = languageVersion;
arguments.apiVersion = apiVersion;
arguments.multiPlatform = multiPlatform;
- getLog().info("Compiling Kotlin sources from " + sources);
-
configureSpecificCompilerArguments(arguments);
try {
@@ -435,8 +453,6 @@ public abstract class KotlinCompileMojoBase e
throw new MojoExecutionException(e.getMessage());
}
- arguments.freeArgs.addAll(sources);
-
if (arguments.noInline) {
getLog().info("Method inlining is turned off");
}
diff --git a/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/incremental/MavenICReporter.java b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/incremental/MavenICReporter.java
new file mode 100644
index 00000000000..994203f8c16
--- /dev/null
+++ b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/incremental/MavenICReporter.java
@@ -0,0 +1,124 @@
+package org.jetbrains.kotlin.maven.incremental;
+
+import kotlin.jvm.functions.Function0;
+import org.apache.maven.plugin.logging.Log;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.kotlin.cli.common.ExitCode;
+import org.jetbrains.kotlin.incremental.ICReporter;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+public class MavenICReporter implements ICReporter {
+ private static final String IC_LOG_LEVEL_PROPERTY_NAME = "kotlin.compiler.incremental.log.level";
+ private static final String IC_LOG_LEVEL_NONE = "none";
+ private static final String IC_LOG_LEVEL_INFO = "info";
+ private static final String IC_LOG_LEVEL_DEBUG = "debug";
+
+ public static MavenICReporter get(@NotNull final Log log) {
+ String logLevel = System.getProperty(IC_LOG_LEVEL_PROPERTY_NAME);
+ if (logLevel == null) {
+ if (log.isDebugEnabled()) {
+ logLevel = IC_LOG_LEVEL_DEBUG;
+ }
+ else {
+ logLevel = IC_LOG_LEVEL_NONE;
+ }
+ }
+
+ if (logLevel.equalsIgnoreCase(IC_LOG_LEVEL_INFO)) {
+ return MavenICReporter.info(log);
+ }
+ else if (logLevel.equalsIgnoreCase(IC_LOG_LEVEL_DEBUG)) {
+ return MavenICReporter.debug(log);
+ }
+ else {
+ if (!logLevel.equalsIgnoreCase(IC_LOG_LEVEL_NONE)) {
+ log.warn("Unknown incremental compilation log level '" + logLevel + "'," +
+ "possible values: " + IC_LOG_LEVEL_NONE + ", " + IC_LOG_LEVEL_INFO + ", " + IC_LOG_LEVEL_DEBUG);
+ }
+
+ return MavenICReporter.noLog();
+ }
+ }
+
+ private static MavenICReporter info(@NotNull final Log log) {
+ return new MavenICReporter() {
+ @Override
+ protected boolean isLogEnabled() {
+ return log.isInfoEnabled();
+ }
+
+ @Override
+ protected void log(String str) {
+ log.info(str);
+ }
+ };
+ }
+
+ private static MavenICReporter debug(@NotNull final Log log) {
+ return new MavenICReporter() {
+ @Override
+ protected boolean isLogEnabled() {
+ return log.isDebugEnabled();
+ }
+
+ @Override
+ protected void log(String str) {
+ log.debug(str);
+ }
+ };
+ }
+
+ private static MavenICReporter noLog() {
+ return new MavenICReporter();
+ }
+
+ @NotNull
+ private final Set compiledKotlinFiles = new HashSet();
+
+ protected boolean isLogEnabled() {
+ return false;
+ }
+
+ protected void log(String str) {
+ }
+
+ private MavenICReporter() {
+ }
+
+ @Override
+ public void report(Function0 getMessage) {
+ if (isLogEnabled()) {
+ log(getMessage.invoke());
+ }
+ }
+
+ @Override
+ public void reportCompileIteration(Collection extends File> sourceFiles, ExitCode exitCode) {
+ compiledKotlinFiles.addAll(sourceFiles);
+ if (isLogEnabled()) {
+ log("Kotlin compile iteration: " + pathsAsString(sourceFiles));
+ log("Exit code: " + exitCode.toString());
+ }
+ }
+
+ @NotNull
+ @Override
+ public String pathsAsString(Iterable extends File> files) {
+ return ICReporter.DefaultImpls.pathsAsString(this, files);
+ }
+
+ @NotNull
+ @Override
+ public String pathsAsString(File... files) {
+ return ICReporter.DefaultImpls.pathsAsString(this, files);
+ }
+
+ @NotNull
+ public Set getCompiledKotlinFiles() {
+ return compiledKotlinFiles;
+ }
+}
diff --git a/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/kapt/KaptJVMCompilerMojo.java b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/kapt/KaptJVMCompilerMojo.java
index cc477ac1e4d..13b7fa4a6b0 100644
--- a/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/kapt/KaptJVMCompilerMojo.java
+++ b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/kapt/KaptJVMCompilerMojo.java
@@ -180,4 +180,9 @@ public class KaptJVMCompilerMojo extends K2JVMCompileMojo {
return result;
}
+
+ @Override
+ protected boolean isIncremental() {
+ return false;
+ }
}
\ No newline at end of file