diff --git a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/KaptContext.kt b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/KaptContext.kt index bf4c945a647..a36c63353d5 100644 --- a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/KaptContext.kt +++ b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/KaptContext.kt @@ -55,14 +55,6 @@ class KaptContext( KaptTreeMaker.preRegister(context, this) KaptJavaCompiler.preRegister(context) - fileManager = context.get(JavaFileManager::class.java) as JavacFileManager - compiler = JavaCompiler.instance(context) as KaptJavaCompiler - compiler.keepComments = true - - ClassReader.instance(context).saveParameterNames = true - - javaLog = compiler.log as KaptJavaLog - options = Options.instance(context) for ((key, value) in processorOptions) { val option = if (value.isEmpty()) "-A$key" else "-A$key=$value" @@ -80,6 +72,14 @@ class KaptContext( if (logger.isVerbose) { logger.info("Javac options: " + options.keySet().keysToMap { key -> options[key] ?: "" }) } + + fileManager = context.get(JavaFileManager::class.java) as JavacFileManager + compiler = JavaCompiler.instance(context) as KaptJavaCompiler + compiler.keepComments = true + + ClassReader.instance(context).saveParameterNames = true + + javaLog = compiler.log as KaptJavaLog } override fun close() { diff --git a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/javac/KaptJavaLog.kt b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/javac/KaptJavaLog.kt index 41f1df602da..757ceeacb6f 100644 --- a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/javac/KaptJavaLog.kt +++ b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/javac/KaptJavaLog.kt @@ -31,6 +31,7 @@ import org.jetbrains.kotlin.kapt3.util.MessageCollectorBackedWriter import org.jetbrains.kotlin.kapt3.util.isJava9OrLater import java.io.File import java.io.PrintWriter +import javax.tools.Diagnostic import javax.tools.JavaFileObject import com.sun.tools.javac.util.List as JavacList @@ -106,17 +107,32 @@ class KaptJavaLog( val locationDiagnostic = diagnosticFactory.note(null as DiagnosticSource?, null, "proc.messager", locationMessage) val wrappedDiagnostic = JCDiagnostic.MultilineDiagnostic(diagnostic, JavacList.of(locationDiagnostic)) - super.report(wrappedDiagnostic) - _reportedDiagnostics += wrappedDiagnostic - - // Avoid reporting the diagnostic twice - return + reportDiagnostic(wrappedDiagnostic) + return // Avoid reporting the diagnostic twice } } - _reportedDiagnostics += diagnostic + reportDiagnostic(diagnostic) + } - super.report(diagnostic) + private fun reportDiagnostic(diagnostic: JCDiagnostic) { + if (diagnostic.kind == Diagnostic.Kind.ERROR) { + val oldErrors = nerrors + super.report(diagnostic) + if (nerrors > oldErrors) { + _reportedDiagnostics += diagnostic + } + } + else if (diagnostic.kind == Diagnostic.Kind.WARNING) { + val oldWarnings = nwarnings + super.report(diagnostic) + if (nwarnings > oldWarnings) { + _reportedDiagnostics += diagnostic + } + } + else { + super.report(diagnostic) + } } override fun writeDiagnostic(diagnostic: JCDiagnostic) { diff --git a/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/AbstractKotlinKapt3Test.kt b/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/AbstractKotlinKapt3Test.kt index ee2f87eb43a..d667f2a9c42 100644 --- a/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/AbstractKotlinKapt3Test.kt +++ b/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/AbstractKotlinKapt3Test.kt @@ -84,8 +84,16 @@ abstract class AbstractKotlinKapt3Test : CodegenTestCase() { val generationState = GenerationUtils.compileFiles(myFiles.psiFiles, myEnvironment, classBuilderFactory) val logger = KaptLogger(isVerbose = true, messageCollector = messageCollector) + + val javacOptions = wholeFile.getOptionValues("JAVAC_OPTION") + .map { opt -> + val (key, value) = opt.split('=').map { it.trim() }.also { assert(it.size == 2) } + key to value + }.toMap() + val kaptContext = KaptContext(logger, generationState.project, generationState.bindingContext, classBuilderFactory.compiledClasses, - classBuilderFactory.origins, generationState, processorOptions = emptyMap()) + classBuilderFactory.origins, generationState, + processorOptions = emptyMap(), javacOptions = javacOptions) val javaFiles = files .filter { it.name.toLowerCase().endsWith(".java") } @@ -136,6 +144,14 @@ abstract class AbstractKotlinKapt3Test : CodegenTestCase() { } } + protected fun File.isOptionSet(name: String) = this.useLines { lines -> lines.any { it.trim() == "// $name" } } + + protected fun File.getRawOptionValues(name: String) = this.useLines { lines -> + lines.filter { it.startsWith("// $name") }.toList() + } + + protected fun File.getOptionValues(name: String) = getRawOptionValues(name).map { it.drop("// ".length + name.length).trim() } + protected abstract fun check( kaptContext: KaptContext, javaFiles: List, @@ -210,16 +226,10 @@ open class AbstractClassFileToSourceStubConverterTest : AbstractKotlinKapt3Test( } override fun check(kaptContext: KaptContext, javaFiles: List, txtFile: File, wholeFile: File) { - fun isOptionSet(name: String) = wholeFile.useLines { lines -> lines.any { it.trim() == "// $name" } } - - fun getOptionValues(name: String) = wholeFile.useLines { lines -> - lines.filter { it.startsWith("// $name") }.toList() - } - - val generateNonExistentClass = isOptionSet("NON_EXISTENT_CLASS") - val correctErrorTypes = isOptionSet("CORRECT_ERROR_TYPES") - val validate = !isOptionSet("NO_VALIDATION") - val expectedErrors = getOptionValues(EXPECTED_ERROR).sorted() + val generateNonExistentClass = wholeFile.isOptionSet("NON_EXISTENT_CLASS") + val correctErrorTypes = wholeFile.isOptionSet("CORRECT_ERROR_TYPES") + val validate = !wholeFile.isOptionSet("NO_VALIDATION") + val expectedErrors = wholeFile.getRawOptionValues(EXPECTED_ERROR).sorted() val convertedFiles = convert(kaptContext, javaFiles, generateNonExistentClass, correctErrorTypes) diff --git a/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/ClassFileToSourceStubConverterTestGenerated.java b/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/ClassFileToSourceStubConverterTestGenerated.java index ff00af6cb97..dafd5274abb 100644 --- a/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/ClassFileToSourceStubConverterTestGenerated.java +++ b/plugins/kapt3/kapt3-compiler/test/org/jetbrains/kotlin/kapt3/test/ClassFileToSourceStubConverterTestGenerated.java @@ -240,6 +240,12 @@ public class ClassFileToSourceStubConverterTestGenerated extends AbstractClassFi doTest(fileName); } + @TestMetadata("maxErrorCount.kt") + public void testMaxErrorCount() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("plugins/kapt3/kapt3-compiler/testData/converter/maxErrorCount.kt"); + doTest(fileName); + } + @TestMetadata("methodParameterNames.kt") public void testMethodParameterNames() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("plugins/kapt3/kapt3-compiler/testData/converter/methodParameterNames.kt"); diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/maxErrorCount.kt b/plugins/kapt3/kapt3-compiler/testData/converter/maxErrorCount.kt new file mode 100644 index 00000000000..3a350101b88 --- /dev/null +++ b/plugins/kapt3/kapt3-compiler/testData/converter/maxErrorCount.kt @@ -0,0 +1,13 @@ +// CORRECT_ERROR_TYPES +// EXPECTED_ERROR(10;5) cannot find symbol (Kotlin location: /maxErrorCount.kt: (9, 5)) +// JAVAC_OPTION -Xmaxerrs=1 + +@file:Suppress("UNRESOLVED_REFERENCE") +import kotlin.reflect.KClass + +class Test { + fun a(a: ABC, b: BCD) {} +} + +// There are two errors (unresolved identifier ABC, BCD) actually. +// But we specified the max error count, so the error output is limited. \ No newline at end of file diff --git a/plugins/kapt3/kapt3-compiler/testData/converter/maxErrorCount.txt b/plugins/kapt3/kapt3-compiler/testData/converter/maxErrorCount.txt new file mode 100644 index 00000000000..7efa3b60adc --- /dev/null +++ b/plugins/kapt3/kapt3-compiler/testData/converter/maxErrorCount.txt @@ -0,0 +1,35 @@ +import kotlin.reflect.KClass; + +@kotlin.Metadata() +@kapt.internal.KaptMetadata() +public final class Test { + + @kapt.internal.KaptSignature(value = "a(Lerror/NonExistentClass;Lerror/NonExistentClass;)V") + public final void a(@org.jetbrains.annotations.NotNull() + ABC a, @org.jetbrains.annotations.NotNull() + BCD b) { + } + + @kapt.internal.KaptSignature(value = "()V") + public Test() { + super(); + } +} + +//////////////////// + +package kapt.internal; + +public @interface KaptMetadata { + + public java.lang.String value(); +} + +//////////////////// + +package kapt.internal; + +public @interface KaptSignature { + + public java.lang.String value(); +}