diff --git a/libraries/tools/kotlin-annotation-processing/src/main/kotlin/org/jetbrains/kotlin/annotation/AnnotationProcessorWrapper.kt b/libraries/tools/kotlin-annotation-processing/src/main/kotlin/org/jetbrains/kotlin/annotation/AnnotationProcessorWrapper.kt index 2b6fae96b1c..dec2c68a12c 100644 --- a/libraries/tools/kotlin-annotation-processing/src/main/kotlin/org/jetbrains/kotlin/annotation/AnnotationProcessorWrapper.kt +++ b/libraries/tools/kotlin-annotation-processing/src/main/kotlin/org/jetbrains/kotlin/annotation/AnnotationProcessorWrapper.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.annotation +import java.io.File import java.io.IOException import javax.annotation.processing.* import javax.lang.model.SourceVersion @@ -43,6 +44,10 @@ public abstract class AnnotationProcessorWrapper( private val taskQualifier: String ) : Processor { + private companion object { + val KAPT_ANNOTATION_OPTION = "kapt.annotations" + } + private val processor: Processor by Delegates.lazy { try { val instance = Class.forName(processorFqName).newInstance() as? Processor @@ -76,12 +81,16 @@ public abstract class AnnotationProcessorWrapper( return } - try { - val annotationsTxt = processingEnv.getFiler().getResource(StandardLocation.CLASS_PATH, "", "annotations.$taskQualifier.txt") - kotlinAnnotationsProvider = FileObjectKotlinAnnotationProvider(annotationsTxt) - } catch (e: IOException) { - kotlinAnnotationsProvider = EmptyKotlinAnnotationsProvider() + val annotationsFile = processingEnv.getOptions().get(KAPT_ANNOTATION_OPTION) + if (annotationsFile != null) { + try { + kotlinAnnotationsProvider = FileKotlinAnnotationProvider(File(annotationsFile)) + } + catch (e: IOException) { + kotlinAnnotationsProvider = EmptyKotlinAnnotationsProvider() + } } + else kotlinAnnotationsProvider = EmptyKotlinAnnotationsProvider() processor.init(processingEnv) } @@ -106,7 +115,9 @@ public abstract class AnnotationProcessorWrapper( } override fun getSupportedOptions(): MutableSet { - return processor.getSupportedOptions() + val supportedOptions = processor.getSupportedOptions().toHashSet() + supportedOptions.add(KAPT_ANNOTATION_OPTION) + return supportedOptions } private fun ProcessingEnvironment.err(message: String) { diff --git a/libraries/tools/kotlin-annotation-processing/src/main/kotlin/org/jetbrains/kotlin/annotation/KotlinAnnotationProvider.kt b/libraries/tools/kotlin-annotation-processing/src/main/kotlin/org/jetbrains/kotlin/annotation/KotlinAnnotationProvider.kt index 02600cd64f9..d4b44b19089 100644 --- a/libraries/tools/kotlin-annotation-processing/src/main/kotlin/org/jetbrains/kotlin/annotation/KotlinAnnotationProvider.kt +++ b/libraries/tools/kotlin-annotation-processing/src/main/kotlin/org/jetbrains/kotlin/annotation/KotlinAnnotationProvider.kt @@ -16,6 +16,9 @@ package org.jetbrains.kotlin.annotation +import java.io.File +import java.io.Reader +import java.io.StringReader import javax.tools.FileObject import kotlin.properties.Delegates @@ -34,7 +37,7 @@ public abstract class KotlinAnnotationProvider { readAnnotations() } - protected abstract val serializedAnnotations: String + protected abstract val serializedAnnotations: Reader private fun readAnnotations(): MutableMap> { val shortenedAnnotationCache = hashMapOf() @@ -53,40 +56,42 @@ public abstract class KotlinAnnotationProvider { val annotatedKotlinElements: MutableMap> = hashMapOf() - for (line in serializedAnnotations.lines()) { - if (line.isEmpty()) continue - val lineParts = line.split(' ') + serializedAnnotations.useLines { lines -> + for (line in lines) { + if (line.isEmpty()) continue + val lineParts = line.split(' ') - val type = lineParts[0] - when (type) { - SHORTENED_ANNOTATION -> handleShortenedName(shortenedAnnotationCache, lineParts) - SHORTENED_PACKAGE_NAME -> handleShortenedName(shortenedPackageNameCache, lineParts) + val type = lineParts[0] + when (type) { + SHORTENED_ANNOTATION -> handleShortenedName(shortenedAnnotationCache, lineParts) + SHORTENED_PACKAGE_NAME -> handleShortenedName(shortenedPackageNameCache, lineParts) - ANNOTATED_CLASS, ANNOTATED_FIELD, ANNOTATED_METHOD -> { - val annotationName = expandAnnotation(lineParts[1]) - val classFqName = expandClassName(lineParts[2]).replace('$', '.') - val elementName = if (lineParts.size() == 4) lineParts[3] else null + ANNOTATED_CLASS, ANNOTATED_FIELD, ANNOTATED_METHOD -> { + val annotationName = expandAnnotation(lineParts[1]) + val classFqName = expandClassName(lineParts[2]).replace('$', '.') + val elementName = if (lineParts.size() == 4) lineParts[3] else null - val set = annotatedKotlinElements.getOrPut(annotationName) { hashSetOf() } - set.add(when (type) { - ANNOTATED_CLASS -> AnnotatedClassDescriptor(classFqName) - ANNOTATED_FIELD -> { - val name = elementName ?: throw AssertionError("Name for field must be provided") - AnnotatedFieldDescriptor(classFqName, name) - } - ANNOTATED_METHOD -> { - val name = elementName ?: throw AssertionError("Name for method must be provided") + val set = annotatedKotlinElements.getOrPut(annotationName) { hashSetOf() } + set.add(when (type) { + ANNOTATED_CLASS -> AnnotatedClassDescriptor(classFqName) + ANNOTATED_FIELD -> { + val name = elementName ?: throw AssertionError("Name for field must be provided") + AnnotatedFieldDescriptor(classFqName, name) + } + ANNOTATED_METHOD -> { + val name = elementName ?: throw AssertionError("Name for method must be provided") - if ("" == name) - AnnotatedConstructorDescriptor(classFqName) - else - AnnotatedMethodDescriptor(classFqName, name) - } - else -> throw AssertionError("Unknown type: $type") - }) + if ("" == name) + AnnotatedConstructorDescriptor(classFqName) + else + AnnotatedMethodDescriptor(classFqName, name) + } + else -> throw AssertionError("Unknown type: $type") + }) + } + else -> throw AssertionError("Unknown type: $type") } - else -> throw AssertionError("Unknown type: $type") } } @@ -101,11 +106,11 @@ public abstract class KotlinAnnotationProvider { } -public class FileObjectKotlinAnnotationProvider(val annotationsFileObject: FileObject): KotlinAnnotationProvider() { - override val serializedAnnotations: String - get() = annotationsFileObject.getCharContent(false).toString() +public class FileKotlinAnnotationProvider(val annotationsFile: File): KotlinAnnotationProvider() { + override val serializedAnnotations: Reader + get() = annotationsFile.reader().buffered() } public class EmptyKotlinAnnotationsProvider : KotlinAnnotationProvider() { - override val serializedAnnotations = "" + override val serializedAnnotations = StringReader("") } \ No newline at end of file diff --git a/libraries/tools/kotlin-annotation-processing/src/test/kotlin/org/jetbrains/kotlin/annotation/AnnotationListParseTest.kt b/libraries/tools/kotlin-annotation-processing/src/test/kotlin/org/jetbrains/kotlin/annotation/AnnotationListParseTest.kt index 7337969ae1f..b7565f2628b 100644 --- a/libraries/tools/kotlin-annotation-processing/src/test/kotlin/org/jetbrains/kotlin/annotation/AnnotationListParseTest.kt +++ b/libraries/tools/kotlin-annotation-processing/src/test/kotlin/org/jetbrains/kotlin/annotation/AnnotationListParseTest.kt @@ -80,9 +80,4 @@ public class AnnotationListParseTest { assertEquals(expectedText, actualText) } - public class FileKotlinAnnotationProvider(val annotationsFile: File): KotlinAnnotationProvider() { - override val serializedAnnotations: String - get() = annotationsFile.readText() - } - } \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/AnnotationProcessingManager.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/AnnotationProcessingManager.kt index 2be44215c79..8d19b4843d5 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/AnnotationProcessingManager.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/AnnotationProcessingManager.kt @@ -50,7 +50,7 @@ public class AnnotationProcessingManager( } fun getAnnotationFile(): File { - aptWorkingDir.mkdirs() + if (!aptWorkingDir.exists()) aptWorkingDir.mkdirs() return File(aptWorkingDir, "$WRAPPERS_DIRECTORY/annotations.$taskQualifier.txt") } @@ -72,6 +72,7 @@ public class AnnotationProcessingManager( addGeneratedSourcesOutputToCompilerArgs(javaTask, aptOutputDir) + appendAnnotationsFileLocationArgument() appendAdditionalComplerArgs() } @@ -99,6 +100,12 @@ public class AnnotationProcessingManager( javaTask.source(javaAptSourceDir) } + private fun appendAnnotationsFileLocationArgument() { + javaTask.modifyCompilerArguments { list -> + list.add("-Akapt.annotations=" + getAnnotationFile()) + } + } + private fun appendAdditionalComplerArgs() { val kaptExtension = project.getExtensions().getByType(javaClass()) val args = kaptExtension.getAdditionalArguments(project, androidVariant, getAndroidExtension())