Kapt: Disable location mapping by default, allow to enable it manually

This commit is contained in:
Yan Zhulanow
2018-01-15 23:29:22 +09:00
parent 5668a7af92
commit 7c7c929b0e
15 changed files with 113 additions and 14 deletions
@@ -28,6 +28,10 @@ class ExampleAnnotationProcessor : AbstractProcessor() {
processAnnotation(roundEnv, annotation, prefix)
}
for (errorElement in roundEnv.getElementsAnnotatedWith(GenError::class.java)) {
processingEnv.messager.printMessage(Diagnostic.Kind.ERROR, "GenError element", errorElement)
}
return true
}
@@ -67,7 +71,9 @@ class ExampleAnnotationProcessor : AbstractProcessor() {
override fun getSupportedSourceVersion() = SourceVersion.RELEASE_6
override fun getSupportedAnnotationTypes() = ANNOTATION_TO_PREFIX.keys.map { it.java.canonicalName }.toSet()
override fun getSupportedAnnotationTypes(): Set<String> {
return ANNOTATION_TO_PREFIX.keys.map { it.java.canonicalName }.toSet() + GenError::class.java.canonicalName
}
override fun getSupportedOptions() = setOf(SUFFIX_OPTION, GENERATE_KOTLIN_CODE_OPTION, GENERATE_ERROR)
}
@@ -15,4 +15,6 @@ annotation class ExampleBinaryAnnotation
@Inherited
@Retention(AnnotationRetention.RUNTIME)
annotation class ExampleRuntimeAnnotation
annotation class ExampleRuntimeAnnotation
annotation class GenError
@@ -301,6 +301,32 @@ open class Kapt3IT : Kapt3BaseIT() {
}
}
@Test
fun testLocationMapping() {
val project = Project("locationMapping", GRADLE_VERSION, directoryPrefix = "kapt2")
project.build("build") {
assertFailed()
assertContains("Test.java:9: error: GenError element")
assertContains("Test.java:17: error: GenError element")
}
project.projectDir.getFileByName("build.gradle").modify {
it.replace("mapDiagnosticLocations = false", "mapDiagnosticLocations = true")
}
project.build("build") {
assertFailed()
assertNotContains("Test.java:9: error: GenError element")
assertNotContains("Test.java:17: error: GenError element")
assertContains("test.kt:3: error: GenError element")
assertContains("test.kt:7: error: GenError element")
}
}
@Test
fun testChangesInLocalAnnotationProcessor() {
val project = Project("localAnnotationProcessor", GRADLE_VERSION, directoryPrefix = "kapt2")
@@ -0,0 +1,29 @@
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
apply plugin: "java"
apply plugin: "kotlin"
apply plugin: "kotlin-kapt"
repositories {
mavenLocal()
mavenCentral()
}
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
compile "org.jetbrains.kotlin:annotation-processor-example:$kotlin_version"
kapt "org.jetbrains.kotlin:annotation-processor-example:$kotlin_version"
testCompile 'junit:junit:4.12'
}
kapt {
mapDiagnosticLocations = false
}
@@ -0,0 +1,8 @@
package example
class Test {
@field:example.GenError
val a: String
fun b(@example.GenError a: Boolean) {}
}
@@ -278,6 +278,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
pluginOptions += SubpluginOption("useLightAnalysis", "${kaptExtension.useLightAnalysis}")
pluginOptions += SubpluginOption("correctErrorTypes", "${kaptExtension.correctErrorTypes}")
pluginOptions += SubpluginOption("mapDiagnosticLocations", "${kaptExtension.mapDiagnosticLocations}")
pluginOptions += FilesSubpluginOption("stubs", listOf(getKaptStubsDir()))
if (project.hasProperty(VERBOSE_OPTION_NAME) && project.property(VERBOSE_OPTION_NAME) == "true") {
@@ -30,6 +30,8 @@ open class KaptExtension {
open var correctErrorTypes: Boolean = false
open var mapDiagnosticLocations: Boolean = false
open var processors: String = ""
/** Explicit opt-in switch for Kapt caching. Should be used when annotation processors used by this project are
@@ -55,6 +55,9 @@ public class KaptJVMCompilerMojo extends K2JVMCompileMojo {
@Parameter
private boolean correctErrorTypes = false;
@Parameter
private boolean mapDiagnosticLocations = false;
@Parameter
private List<String> annotationProcessorArgs;
@@ -94,6 +97,7 @@ public class KaptJVMCompilerMojo extends K2JVMCompileMojo {
options.add(new KaptOption("aptOnly", true));
options.add(new KaptOption("useLightAnalysis", useLightAnalysis));
options.add(new KaptOption("correctErrorTypes", correctErrorTypes));
options.add(new KaptOption("mapDiagnosticLocations", mapDiagnosticLocations));
options.add(new KaptOption("processors", annotationProcessors));
if (arguments.getVerbose()) {
@@ -71,12 +71,13 @@ class ClasspathBasedKapt3Extension(
aptMode: AptMode,
val useLightAnalysis: Boolean,
correctErrorTypes: Boolean,
mapDiagnosticLocations: Boolean,
pluginInitializedTime: Long,
logger: KaptLogger,
compilerConfiguration: CompilerConfiguration
) : AbstractKapt3Extension(compileClasspath, annotationProcessingClasspath, javaSourceRoots, sourcesOutputDir,
classFilesOutputDir, stubsOutputDir, incrementalDataOutputDir, options, javacOptions, annotationProcessors,
aptMode, pluginInitializedTime, logger, correctErrorTypes, compilerConfiguration) {
aptMode, pluginInitializedTime, logger, correctErrorTypes, mapDiagnosticLocations, compilerConfiguration) {
override val analyzePartially: Boolean
get() = useLightAnalysis
@@ -129,6 +130,7 @@ abstract class AbstractKapt3Extension(
val pluginInitializedTime: Long,
val logger: KaptLogger,
val correctErrorTypes: Boolean,
val mapDiagnosticLocations: Boolean,
val compilerConfiguration: CompilerConfiguration
) : PartialAnalysisHandlerExtension() {
val compileClasspath = compileClasspath.distinct()
@@ -204,7 +206,8 @@ abstract class AbstractKapt3Extension(
private fun generateStubs(project: Project, module: ModuleDescriptor, context: BindingContext, files: Collection<KtFile>): KaptContext<*> {
if (!aptMode.generateStubs) {
return KaptContext(logger, project, BindingContext.EMPTY, emptyList(), emptyMap(), null, options, javacOptions)
return KaptContext(logger, project, BindingContext.EMPTY, emptyList(), emptyMap(), null,
mapDiagnosticLocations, options, javacOptions)
}
logger.info { "Kotlin files to compile: " + files.map { it.virtualFile?.name ?: "<in memory ${it.hashCode()}>" } }
@@ -259,7 +262,8 @@ abstract class AbstractKapt3Extension(
logger.info { "Stubs compilation took $classFilesCompilationTime ms" }
logger.info { "Compiled classes: " + compiledClasses.joinToString { it.name } }
return KaptContext(logger, project, bindingContext, compiledClasses, origins, generationState, options, javacOptions)
return KaptContext(logger, project, bindingContext, compiledClasses, origins, generationState,
mapDiagnosticLocations, options, javacOptions)
}
private fun generateKotlinSourceStubs(kaptContext: KaptContext<GenerationState>) {
@@ -88,6 +88,9 @@ object Kapt3ConfigurationKeys {
val CORRECT_ERROR_TYPES: CompilerConfigurationKey<String> =
CompilerConfigurationKey.create<String>("replace error types with ones from the declaration sources")
val MAP_DIAGNOSTIC_LOCATIONS: CompilerConfigurationKey<String> =
CompilerConfigurationKey.create<String>("map diagnostic reported on kapt stubs to original locations in Kotlin sources")
}
class Kapt3CommandLineProcessor : CommandLineProcessor {
@@ -141,6 +144,9 @@ class Kapt3CommandLineProcessor : CommandLineProcessor {
val CORRECT_ERROR_TYPES_OPTION: CliOption =
CliOption("correctErrorTypes", "true | false", "Replace generated or error types with ones from the generated sources", required = false)
val MAP_DIAGNOSTIC_LOCATIONS_OPTION: CliOption =
CliOption("mapDiagnosticLocations", "true | false", "Map diagnostic reported on kapt stubs to original locations in Kotlin sources", required = false)
}
override val pluginId: String = ANNOTATION_PROCESSING_COMPILER_PLUGIN_ID
@@ -149,7 +155,7 @@ class Kapt3CommandLineProcessor : CommandLineProcessor {
listOf(SOURCE_OUTPUT_DIR_OPTION, ANNOTATION_PROCESSOR_CLASSPATH_OPTION, APT_OPTIONS_OPTION, JAVAC_CLI_OPTIONS_OPTION,
CLASS_OUTPUT_DIR_OPTION, VERBOSE_MODE_OPTION, STUBS_OUTPUT_DIR_OPTION, APT_ONLY_OPTION, APT_MODE_OPTION,
USE_LIGHT_ANALYSIS_OPTION, CORRECT_ERROR_TYPES_OPTION, ANNOTATION_PROCESSORS_OPTION, INCREMENTAL_DATA_OUTPUT_DIR_OPTION,
CONFIGURATION)
CONFIGURATION, MAP_DIAGNOSTIC_LOCATIONS_OPTION)
override fun processOption(option: CliOption, value: String, configuration: CompilerConfiguration) {
when (option) {
@@ -166,6 +172,7 @@ class Kapt3CommandLineProcessor : CommandLineProcessor {
APT_MODE_OPTION -> configuration.put(Kapt3ConfigurationKeys.APT_MODE, value)
USE_LIGHT_ANALYSIS_OPTION -> configuration.put(Kapt3ConfigurationKeys.USE_LIGHT_ANALYSIS, value)
CORRECT_ERROR_TYPES_OPTION -> configuration.put(Kapt3ConfigurationKeys.CORRECT_ERROR_TYPES, value)
MAP_DIAGNOSTIC_LOCATIONS_OPTION -> configuration.put(Kapt3ConfigurationKeys.MAP_DIAGNOSTIC_LOCATIONS, value)
CONFIGURATION -> configuration.applyOptionsFrom(decodePluginOptions(value), pluginOptions)
else -> throw CliOptionProcessingException("Unknown option: ${option.name}")
}
@@ -254,12 +261,14 @@ class Kapt3ComponentRegistrar : ComponentRegistrar {
val useLightAnalysis = configuration.get(Kapt3ConfigurationKeys.USE_LIGHT_ANALYSIS) == "true"
val correctErrorTypes = configuration.get(Kapt3ConfigurationKeys.CORRECT_ERROR_TYPES) == "true"
val mapDiagnosticLocations = configuration.get(Kapt3ConfigurationKeys.MAP_DIAGNOSTIC_LOCATIONS) == "true"
if (isVerbose) {
logger.info("Kapt3 is enabled.")
logger.info("Annotation processing mode: $aptMode")
logger.info("Use light analysis: $useLightAnalysis")
logger.info("Correct error types: $correctErrorTypes")
logger.info("Map diagnostic locations: $mapDiagnosticLocations")
logger.info("Source output directory: $sourcesOutputDir")
logger.info("Classes output directory: $classFilesOutputDir")
logger.info("Stubs output directory: $stubsOutputDir")
@@ -274,7 +283,7 @@ class Kapt3ComponentRegistrar : ComponentRegistrar {
val kapt3AnalysisCompletedHandlerExtension = ClasspathBasedKapt3Extension(
compileClasspath, apClasspath, javaSourceRoots, sourcesOutputDir, classFilesOutputDir,
stubsOutputDir, incrementalDataOutputDir, apOptions, javacCliOptions, annotationProcessors,
aptMode, useLightAnalysis, correctErrorTypes, System.currentTimeMillis(), logger, configuration)
aptMode, useLightAnalysis, correctErrorTypes, mapDiagnosticLocations, System.currentTimeMillis(), logger, configuration)
AnalysisHandlerExtension.registerExtension(project, kapt3AnalysisCompletedHandlerExtension)
}
@@ -40,6 +40,7 @@ class KaptContext<out GState : GenerationState?>(
val compiledClasses: List<ClassNode>,
val origins: Map<Any, JvmDeclarationOrigin>,
val generationState: GState,
mapDiagnosticLocations: Boolean,
processorOptions: Map<String, String>,
javacOptions: Map<String, String> = emptyMap()
) : AutoCloseable {
@@ -50,7 +51,7 @@ class KaptContext<out GState : GenerationState?>(
val javaLog: KaptJavaLog
init {
KaptJavaLog.preRegister(this, logger.messageCollector)
KaptJavaLog.preRegister(this, logger.messageCollector, mapDiagnosticLocations)
JavacFileManager.preRegister(context)
KaptTreeMaker.preRegister(context, this)
KaptJavaCompiler.preRegister(context)
@@ -41,7 +41,8 @@ class KaptJavaLog(
errWriter: PrintWriter,
warnWriter: PrintWriter,
noticeWriter: PrintWriter,
val interceptorData: DiagnosticInterceptorData
val interceptorData: DiagnosticInterceptorData,
val mapDiagnosticLocations: Boolean
) : Log(context, errWriter, warnWriter, noticeWriter) {
private val stubLineInfo = KaptStubLineInformation()
private val javacMessages = JavacMessages.instance(context)
@@ -97,7 +98,7 @@ class KaptJavaLog(
}
}
if (sourceFile != null && targetElement.tree != null) {
if (mapDiagnosticLocations && sourceFile != null && targetElement.tree != null) {
val kotlinPosition = stubLineInfo.getPositionInKotlinFile(sourceFile, targetElement.tree)
val kotlinFile = kotlinPosition?.let { getKotlinSourceFile(it) }
if (kotlinPosition != null && kotlinFile != null) {
@@ -229,14 +230,18 @@ class KaptJavaLog(
"compiler.err.annotation.type.not.applicable",
"compiler.err.doesnt.exist")
internal fun preRegister(kaptContext: KaptContext<*>, messageCollector: MessageCollector) {
internal fun preRegister(kaptContext: KaptContext<*>, messageCollector: MessageCollector, mapDiagnosticLocations: Boolean) {
val interceptorData = DiagnosticInterceptorData()
kaptContext.context.put(Log.logKey, Context.Factory<Log> { newContext ->
fun makeWriter(severity: CompilerMessageSeverity) = PrintWriter(MessageCollectorBackedWriter(messageCollector, severity))
val errWriter = makeWriter(ERROR)
val warnWriter = makeWriter(STRONG_WARNING)
val noticeWriter = makeWriter(WARNING)
KaptJavaLog(kaptContext.project, newContext, errWriter, warnWriter, noticeWriter, interceptorData)
KaptJavaLog(
kaptContext.project, newContext, errWriter, warnWriter, noticeWriter,
interceptorData, mapDiagnosticLocations)
})
}
}
@@ -165,7 +165,8 @@ abstract class AbstractKotlinKapt3IntegrationTest : CodegenTestCase() {
) : AbstractKapt3Extension(PathUtil.getJdkClassesRootsFromCurrentJre() + PathUtil.kotlinPathsForIdeaPlugin.stdlibPath,
emptyList(), javaSourceRoots, outputDir, outputDir,
stubsOutputDir, incrementalDataOutputDir, options, emptyMap(), "", STUBS_AND_APT, System.currentTimeMillis(),
KaptLogger(true), correctErrorTypes = true, compilerConfiguration = CompilerConfiguration.EMPTY
KaptLogger(true), correctErrorTypes = true, mapDiagnosticLocations = true,
compilerConfiguration = CompilerConfiguration.EMPTY
) {
internal var savedStubs: String? = null
internal var savedBindings: Map<String, KaptJavaFileObject>? = null
@@ -114,7 +114,7 @@ abstract class AbstractKotlinKapt3Test : CodegenTestCase() {
}.toMap()
val kaptContext = KaptContext(logger, generationState.project, generationState.bindingContext, classBuilderFactory.compiledClasses,
classBuilderFactory.origins, generationState,
classBuilderFactory.origins, generationState, mapDiagnosticLocations = true,
processorOptions = emptyMap(), javacOptions = javacOptions)
val javaFiles = files
@@ -86,6 +86,7 @@ class JavaKaptContextTest {
compiledClasses = emptyList(),
origins = emptyMap(),
generationState = null,
mapDiagnosticLocations = true,
processorOptions = emptyMap()
).doAnnotationProcessing(
listOf(javaSourceFile),