Initial support for kotlin-java interop in incremental compilation.

This commit is contained in:
Evgeny Gerashchenko
2014-09-26 20:49:53 +04:00
parent 3011bdb7d7
commit 70331e3b82
31 changed files with 236 additions and 7 deletions
@@ -649,6 +649,7 @@ fun main(args: Array<String>) {
testClass(javaClass<AbstractIncrementalJpsTest>()) {
model("incremental/circularDependency", extension = null, excludeParentDirs = true)
model("incremental/pureKotlin", extension = null, excludeParentDirs = true)
model("incremental/withJava", extension = null, excludeParentDirs = true)
}
}
@@ -52,6 +52,9 @@ import org.jetbrains.jet.utils.keysToMap
import org.jetbrains.jps.incremental.ModuleLevelBuilder.ExitCode.*
import com.intellij.openapi.diagnostic.Logger
import org.jetbrains.jet.lang.resolve.java.JvmAbi
import org.jetbrains.org.objectweb.asm.ClassReader
import org.jetbrains.jps.builders.java.JavaBuilderUtil
import com.intellij.util.containers.MultiMap
public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
class object {
@@ -136,6 +139,7 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR
val compilerSettings = JpsKotlinCompilerSettings.getCompilerSettings(project)
val allCompiledFiles = getAllCompiledFilesContainer(context)
val filesToCompile: MultiMap<ModuleBuildTarget, File>
if (JpsUtils.isJsKotlinModule(representativeTarget)) {
if (chunk.getModules().size() > 1) {
@@ -152,6 +156,8 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR
val sourceFiles = KotlinSourceFileCollector.getAllKotlinSourceFiles(representativeTarget)
//List<File> sourceFiles = KotlinSourceFileCollector.getDirtySourceFiles(dirtyFilesHolder);
filesToCompile = MultiMap.emptyInstance() // won't be used
if (sourceFiles.isEmpty()) {
return NOTHING_DONE
}
@@ -171,10 +177,7 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR
+ "Kotlin will compile them, but some strange effect may happen", NO_LOCATION)
}
val filesToCompile = KotlinSourceFileCollector.getDirtySourceFiles(dirtyFilesHolder)
for (target in filesToCompile.keySet()) {
filesToCompile.getModifiable(target).removeAll(allCompiledFiles)
}
filesToCompile = KotlinSourceFileCollector.getDirtySourceFiles(dirtyFilesHolder)
allCompiledFiles.addAll(filesToCompile.values())
val processedTargetsWithRemoved = getProcessedTargetsWithRemovedFilesContainer(context)
@@ -243,6 +246,21 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR
outputConsumer.registerOutputFile(target, outputFile, sourceFiles.map { it.getPath() })
}
val delta = context.getProjectDescriptor().dataManager.getMappings()!!.createDelta()
val callback = delta!!.getCallback()!!
for (outputItem in outputItemCollector.getOutputs()) {
val outputFile = outputItem.getOutputFile()
callback.associate(FileUtil.toSystemIndependentName(outputFile.getAbsolutePath()),
outputItem.getSourceFiles().map { FileUtil.toSystemIndependentName(it.getAbsolutePath()) },
ClassReader(outputFile.readBytes())
)
}
val allCompiled = filesToCompile.values()
val compiledInThisRound = if (compilationErrors) listOf<File>() else allCompiled
JavaBuilderUtil.updateMappings(context, delta, dirtyFilesHolder, chunk, allCompiled, compiledInThisRound)
if (compilationErrors) {
return ABORT
}
@@ -254,7 +272,9 @@ public class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR
}
if (recompilationDecision == IncrementalCacheImpl.RecompilationDecision.COMPILE_OTHERS) {
// TODO should mark dependencies as dirty, as well
FSOperations.markDirty(context, chunk, { file -> !allCompiledFiles.contains(file) })
FSOperations.markDirty(context, chunk, { file ->
KotlinSourceFileCollector.isKotlinSourceFile(file) && file !in allCompiledFiles
})
}
return ADDITIONAL_PASS_REQUIRED
}
@@ -131,7 +131,7 @@ public class KotlinSourceFileCollector {
return (Iterable) target.getModule().getSourceRoots(sourceRootType);
}
private static boolean isKotlinSourceFile(File file) {
static boolean isKotlinSourceFile(File file) {
return FileUtilRt.extensionEquals(file.getName(), "kt");
}
@@ -28,7 +28,7 @@ import java.util.regex.Pattern;
/** This class is generated by {@link org.jetbrains.jet.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@InnerTestClasses({IncrementalJpsTestGenerated.CircularDependency.class, IncrementalJpsTestGenerated.PureKotlin.class})
@InnerTestClasses({IncrementalJpsTestGenerated.CircularDependency.class, IncrementalJpsTestGenerated.PureKotlin.class, IncrementalJpsTestGenerated.WithJava.class})
@RunWith(JUnit3RunnerWithInners.class)
public class IncrementalJpsTestGenerated extends AbstractIncrementalJpsTest {
@TestMetadata("jps-plugin/testData/incremental/circularDependency")
@@ -290,6 +290,75 @@ public class IncrementalJpsTestGenerated extends AbstractIncrementalJpsTest {
String fileName = JetTestUtils.navigationMetadata("jps-plugin/testData/incremental/pureKotlin/traitClassObjectConstantChanged/");
doTest(fileName);
}
}
@TestMetadata("jps-plugin/testData/incremental/withJava")
@TestDataPath("$PROJECT_ROOT")
@InnerTestClasses({WithJava.JavaUsedInKotlin.class, WithJava.KotlinUsedInJava.class})
@RunWith(org.jetbrains.jet.JUnit3RunnerWithInners.class)
public static class WithJava extends AbstractIncrementalJpsTest {
public void testAllFilesPresentInWithJava() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/withJava"), Pattern.compile("^([^\\.]+)$"), true);
}
@TestMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin")
@TestDataPath("$PROJECT_ROOT")
@InnerTestClasses({})
@RunWith(org.jetbrains.jet.JUnit3RunnerWithInners.class)
public static class JavaUsedInKotlin extends AbstractIncrementalJpsTest {
public void testAllFilesPresentInJavaUsedInKotlin() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/withJava/javaUsedInKotlin"), Pattern.compile("^([^\\.]+)$"), true);
}
@TestMetadata("changeNotUsedSignature")
public void testChangeNotUsedSignature() throws Exception {
String fileName = JetTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/changeNotUsedSignature/");
doTest(fileName);
}
@TestMetadata("changeSignature")
public void testChangeSignature() throws Exception {
String fileName = JetTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/changeSignature/");
doTest(fileName);
}
@TestMetadata("notChangeSignature")
public void testNotChangeSignature() throws Exception {
String fileName = JetTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/javaUsedInKotlin/notChangeSignature/");
doTest(fileName);
}
}
@TestMetadata("jps-plugin/testData/incremental/withJava/kotlinUsedInJava")
@TestDataPath("$PROJECT_ROOT")
@InnerTestClasses({})
@RunWith(org.jetbrains.jet.JUnit3RunnerWithInners.class)
public static class KotlinUsedInJava extends AbstractIncrementalJpsTest {
public void testAllFilesPresentInKotlinUsedInJava() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/withJava/kotlinUsedInJava"), Pattern.compile("^([^\\.]+)$"), true);
}
@TestMetadata("changeNotUsedSignature")
public void testChangeNotUsedSignature() throws Exception {
String fileName = JetTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/kotlinUsedInJava/changeNotUsedSignature/");
doTest(fileName);
}
@TestMetadata("changeSignature")
public void testChangeSignature() throws Exception {
String fileName = JetTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/kotlinUsedInJava/changeSignature/");
doTest(fileName);
}
@TestMetadata("notChangeSignature")
public void testNotChangeSignature() throws Exception {
String fileName = JetTestUtils.navigationMetadata("jps-plugin/testData/incremental/withJava/kotlinUsedInJava/notChangeSignature/");
doTest(fileName);
}
}
}
}
@@ -6,8 +6,11 @@ Compiling files:
src/const.kt
End of files
Cleaning output files:
out/production/module/test/Klass$object.class
out/production/module/test/Klass.class
out/production/module/test/Usage.class
End of files
Compiling files:
src/const.kt
src/usage.kt
End of files
@@ -9,6 +9,10 @@ COMPILATION FAILED
Kotlin:ERROR:Expecting an expression
Cleaning output files:
out/production/module/_DefaultPackage$fun$*.class
End of files
Compiling files:
src/fun.kt
src/usage.kt
End of files
@@ -7,8 +7,12 @@ Compiling files:
src/const.kt
End of files
Cleaning output files:
out/production/module/test/Trait$$TImpl.class
out/production/module/test/Trait$object.class
out/production/module/test/Trait.class
out/production/module/test/Usage.class
End of files
Compiling files:
src/const.kt
src/usage.kt
End of files
@@ -0,0 +1,4 @@
public class JavaClass {
public static void foo() {
}
}
@@ -0,0 +1,5 @@
public class JavaClass {
public static String foo() {
return ":)";
}
}
@@ -0,0 +1,6 @@
Cleaning output files:
out/production/module/JavaClass.class
End of files
Compiling files:
src/JavaClass.java
End of files
@@ -0,0 +1,2 @@
fun main(args: Array<String>) {
}
@@ -0,0 +1,4 @@
public class JavaClass {
public static void foo() {
}
}
@@ -0,0 +1,5 @@
public class JavaClass {
public static String foo() {
return ":)";
}
}
@@ -0,0 +1,13 @@
Cleaning output files:
out/production/module/JavaClass.class
End of files
Compiling files:
src/JavaClass.java
End of files
Cleaning output files:
out/production/module/_DefaultPackage$usage$*.class
out/production/module/_DefaultPackage.class
End of files
Compiling files:
src/usage.kt
End of files
@@ -0,0 +1,3 @@
fun main(args: Array<String>) {
JavaClass.foo()
}
@@ -0,0 +1,4 @@
public class JavaClass {
public static void foo() {
}
}
@@ -0,0 +1,4 @@
public class JavaClass {
public static void foo() {
}
}
@@ -0,0 +1,6 @@
Cleaning output files:
out/production/module/JavaClass.class
End of files
Compiling files:
src/JavaClass.java
End of files
@@ -0,0 +1,3 @@
fun main(args: Array<String>) {
JavaClass.foo()
}
@@ -0,0 +1,2 @@
public class NotUsage {
}
@@ -0,0 +1,7 @@
Cleaning output files:
out/production/module/test/TestPackage$fun$*.class
out/production/module/test/TestPackage.class
End of files
Compiling files:
src/fun.kt
End of files
@@ -0,0 +1,5 @@
package test
fun foo() {
}
@@ -0,0 +1,5 @@
package test
fun foo(): String {
return "Hello, world!"
}
@@ -0,0 +1,5 @@
public class Usage {
public static void main(String[] args) {
test.TestPackage.foo();
}
}
@@ -0,0 +1,13 @@
Cleaning output files:
out/production/module/test/TestPackage$fun$*.class
out/production/module/test/TestPackage.class
End of files
Compiling files:
src/fun.kt
End of files
Cleaning output files:
out/production/module/Usage.class
End of files
Compiling files:
src/Usage.java
End of files
@@ -0,0 +1,5 @@
package test
fun foo() {
}
@@ -0,0 +1,5 @@
package test
fun foo(): String {
return "Hello, world!"
}
@@ -0,0 +1,5 @@
public class Usage {
public static void main(String[] args) {
test.TestPackage.foo();
}
}
@@ -0,0 +1,7 @@
Cleaning output files:
out/production/module/test/TestPackage$fun$*.class
out/production/module/test/TestPackage.class
End of files
Compiling files:
src/fun.kt
End of files
@@ -0,0 +1,5 @@
package test
fun foo() {
}
@@ -0,0 +1,5 @@
package test
fun foo() {
}