Remove source annotations removing (not needed with KAPT3)

This commit is contained in:
Alexey Tsvetkov
2016-12-13 13:46:30 +03:00
parent 190c038ad8
commit 4fdca24db4
21 changed files with 14 additions and 398 deletions
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.incremental
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.incremental.components.SourceRetentionAnnotationHandler
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
import org.jetbrains.kotlin.modules.TargetId
@@ -1,30 +0,0 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.incremental
import org.jetbrains.kotlin.incremental.components.SourceRetentionAnnotationHandler
class SourceRetentionAnnotationHandlerImpl : SourceRetentionAnnotationHandler {
private val mutableSourceRetentionAnnotations = mutableSetOf<String>()
val sourceRetentionAnnotations: Set<String>
get() = mutableSourceRetentionAnnotations
override fun register(internalName: String) {
mutableSourceRetentionAnnotations += internalName
}
}
@@ -30,7 +30,6 @@ import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl
import org.jetbrains.kotlin.config.IncrementalCompilation
import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.incremental.components.SourceRetentionAnnotationHandler
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents
import org.jetbrains.kotlin.modules.KotlinModuleXmlBuilder
@@ -70,8 +69,7 @@ fun makeModuleFile(name: String, isTest: Boolean, outputDir: File, sourcesToComp
fun makeCompileServices(
incrementalCaches: Map<TargetId, IncrementalCache>,
lookupTracker: LookupTracker,
compilationCanceledStatus: CompilationCanceledStatus?,
sourceRetentionAnnotationHandler: SourceRetentionAnnotationHandler? = null
compilationCanceledStatus: CompilationCanceledStatus?
): Services =
with(Services.Builder()) {
register(IncrementalCompilationComponents::class.java,
@@ -79,9 +77,6 @@ fun makeCompileServices(
compilationCanceledStatus?.let {
register(CompilationCanceledStatus::class.java, it)
}
sourceRetentionAnnotationHandler?.let {
register(SourceRetentionAnnotationHandler::class.java, it)
}
build()
}
@@ -35,7 +35,7 @@ public class ClassBuilderMode {
}
public static ClassBuilderMode full(boolean generateSourceRetentionAnnotations) {
return generateSourceRetentionAnnotations ? KAPT2 : FULL;
return generateSourceRetentionAnnotations ? KAPT : FULL;
}
/**
@@ -47,15 +47,6 @@ public class ClassBuilderMode {
/* sourceRetention = */ false,
/* generateMultiFileFacadePartClasses = */ true);
/**
* Full function bodies, write annotations with the "source" retention.
*/
private final static ClassBuilderMode KAPT2 = new ClassBuilderMode(
/* bodies = */ true,
/* metadata = */ true,
/* sourceRetention = */ true,
/* generateMultiFileFacadePartClasses = */ false);
/**
* Generating light classes: Only function signatures
*/
@@ -37,7 +37,6 @@ import org.jetbrains.kotlin.compiler.plugin.CliOptionProcessingException
import org.jetbrains.kotlin.compiler.plugin.PluginCliOptionProcessingException
import org.jetbrains.kotlin.compiler.plugin.cliPluginUsageString
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.incremental.components.SourceRetentionAnnotationHandler
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.kotlin.DeserializedDescriptorResolver
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion
@@ -267,10 +266,6 @@ class K2JVMCompiler : CLICompiler<K2JVMCompilerArguments>() {
configuration.put(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS, components)
}
}
services.get(SourceRetentionAnnotationHandler::class.java)?.let { handler ->
configuration.put(JVMConfigurationKeys.SOURCE_RETENTION_ANNOTATION_HANDLER, handler)
}
}
/**
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.modules.TargetId
import org.jetbrains.kotlin.daemon.common.CompilerCallbackServicesFacade
import org.jetbrains.kotlin.daemon.common.DummyProfiler
import org.jetbrains.kotlin.daemon.common.Profiler
import org.jetbrains.kotlin.incremental.components.SourceRetentionAnnotationHandler
class RemoteIncrementalCompilationComponentsClient(val facade: CompilerCallbackServicesFacade, eventManger: EventManger, val profiler: Profiler = DummyProfiler()) : IncrementalCompilationComponents {
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.config;
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl;
import org.jetbrains.kotlin.incremental.components.SourceRetentionAnnotationHandler;
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCompilationComponents;
import org.jetbrains.kotlin.modules.Module;
import org.jetbrains.kotlin.script.KotlinScriptDefinition;
@@ -94,9 +93,6 @@ public class JVMConfigurationKeys {
public static final CompilerConfigurationKey<File> MODULE_XML_FILE =
CompilerConfigurationKey.create("path to module.xml");
public static final CompilerConfigurationKey<SourceRetentionAnnotationHandler> SOURCE_RETENTION_ANNOTATION_HANDLER =
CompilerConfigurationKey.create("source retention annotation handler");
public static final CompilerConfigurationKey<String> DECLARATIONS_JSON_PATH =
CompilerConfigurationKey.create("path to declarations output");
@@ -1,21 +0,0 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.incremental.components
interface SourceRetentionAnnotationHandler {
fun register(internalName: String)
}
@@ -55,7 +55,6 @@ import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.daemon.common.isDaemonEnabled
import org.jetbrains.kotlin.incremental.*
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.incremental.components.SourceRetentionAnnotationHandler
import org.jetbrains.kotlin.jps.JpsKotlinCompilerSettings
import org.jetbrains.kotlin.jps.incremental.*
import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache
@@ -206,8 +205,7 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
val project = projectDescriptor.project
val lookupTracker = getLookupTracker(project)
val incrementalCaches = getIncrementalCaches(chunk, context)
val sourceRetentionAnnotationHandler = SourceRetentionAnnotationHandlerImpl()
val environment = createCompileEnvironment(incrementalCaches, lookupTracker, sourceRetentionAnnotationHandler, context)
val environment = createCompileEnvironment(incrementalCaches, lookupTracker, context)
if (!environment.success()) {
environment.reportErrorsTo(messageCollector)
return ABORT
@@ -410,7 +408,6 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
private fun createCompileEnvironment(
incrementalCaches: Map<ModuleBuildTarget, IncrementalCache>,
lookupTracker: LookupTracker,
sourceRetentionAnnotationHandler: SourceRetentionAnnotationHandler?,
context: CompileContext
): JpsCompilerEnvironment {
val compilerServices = with(Services.Builder()) {
@@ -422,9 +419,6 @@ class KotlinBuilder : ModuleLevelBuilder(BuilderCategory.SOURCE_PROCESSOR) {
if (context.cancelStatus.isCanceled) throw CompilationCanceledException()
}
})
sourceRetentionAnnotationHandler?.let {
register(SourceRetentionAnnotationHandler::class.java, it)
}
build()
}
@@ -1,68 +0,0 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.annotation
import org.jetbrains.kotlin.incremental.components.SourceRetentionAnnotationHandler
import java.io.*
import java.util.*
internal class SourceAnnotationsRegistry(private val file: File) : SourceRetentionAnnotationHandler {
private val mutableAnnotations: MutableSet<String> by lazy { readAnnotations() }
val annotations: Set<String>
get() = mutableAnnotations
override fun register(internalName: String) {
mutableAnnotations.add(internalName)
}
fun clear() {
mutableAnnotations.clear()
file.delete()
}
fun flush() {
if (mutableAnnotations.isEmpty()) {
file.delete()
return
}
if (!file.exists()) {
file.parentFile.mkdirs()
file.createNewFile()
}
ObjectOutputStream(BufferedOutputStream(file.outputStream())).use { out ->
out.writeInt(mutableAnnotations.size)
mutableAnnotations.forEach { out.writeUTF(it) }
}
}
private fun readAnnotations(): MutableSet<String> {
val result = HashSet<String>()
if (!file.exists()) return result
ObjectInputStream(BufferedInputStream(file.inputStream())).use { input ->
val size = input.readInt()
repeat(size) {
result.add(input.readUTF())
}
}
return result
}
}
@@ -1,78 +0,0 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.bytecode
import org.jetbrains.org.objectweb.asm.*
import java.io.File
import java.util.*
internal class AnnotationsRemover(annotations: Iterable<String>) {
private val annotations = annotations.mapTo(HashSet()) { "L$it;" }
fun transformClassFile(inputFile: File, outputFile: File) {
assert(inputFile.extension.toLowerCase() == "class") { "Expected class file: $inputFile" }
val bytes = inputFile.readBytes()
val reader = ClassReader(bytes)
val classWriter = ClassWriter(0)
val visitor = ClassAnnotationRemover(classWriter)
reader.accept(visitor, 0)
outputFile.writeBytes(classWriter.toByteArray())
}
inner class ClassAnnotationRemover(classVisitor: ClassVisitor) : ClassVisitor(Opcodes.ASM5, classVisitor) {
override fun visitAnnotation(desc: String?, visible: Boolean): AnnotationVisitor? =
checkAnnotation(desc) { super.visitAnnotation(desc, visible) }
override fun visitTypeAnnotation(typeRef: Int, typePath: TypePath?, desc: String?, visible: Boolean): AnnotationVisitor? =
checkAnnotation(desc) { super.visitTypeAnnotation(typeRef, typePath, desc, visible) }
override fun visitMethod(access: Int, name: String?, desc: String?, signature: String?, exceptions: Array<out String>?): MethodVisitor {
val methodVisitor = super.visitMethod(access, name, desc, signature, exceptions)
return MethodAnnotationRemover(methodVisitor)
}
override fun visitField(access: Int, name: String?, desc: String?, signature: String?, value: Any?): FieldVisitor {
val fieldVisitor = super.visitField(access, name, desc, signature, value)
return FieldAnnotationRemover(fieldVisitor)
}
}
inner class MethodAnnotationRemover(methodVisitor: MethodVisitor) : MethodVisitor(Opcodes.ASM5, methodVisitor) {
override fun visitAnnotation(desc: String?, visible: Boolean): AnnotationVisitor? =
checkAnnotation(desc) { super.visitAnnotation(desc, visible) }
override fun visitTypeAnnotation(typeRef: Int, typePath: TypePath?, desc: String?, visible: Boolean): AnnotationVisitor? =
checkAnnotation(desc) { super.visitTypeAnnotation(typeRef, typePath, desc, visible) }
override fun visitParameterAnnotation(parameter: Int, desc: String?, visible: Boolean): AnnotationVisitor? =
checkAnnotation(desc) { super.visitParameterAnnotation(parameter, desc, visible) }
}
inner class FieldAnnotationRemover(fieldVisitor: FieldVisitor) : FieldVisitor(Opcodes.ASM5, fieldVisitor) {
override fun visitAnnotation(desc: String?, visible: Boolean): AnnotationVisitor? =
checkAnnotation(desc) { super.visitAnnotation(desc, visible) }
override fun visitTypeAnnotation(typeRef: Int, typePath: TypePath?, desc: String?, visible: Boolean): AnnotationVisitor? =
checkAnnotation(desc) { super.visitTypeAnnotation(typeRef, typePath, desc, visible) }
}
private inline fun checkAnnotation(desc: String?, default: () -> AnnotationVisitor?): AnnotationVisitor? {
if (desc in annotations) return null
return default()
}
}
@@ -62,7 +62,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
}
private val kotlinToKaptTasksMap = mutableMapOf<KotlinCompile, KaptTask>()
override fun isApplicable(project: Project, task: KotlinCompile) = Kapt3GradleSubplugin.isEnabled(project)
fun getKaptGeneratedDir(project: Project, sourceSetName: String): File {
@@ -23,7 +23,6 @@ import org.gradle.api.tasks.OutputFiles
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.incremental.IncrementalTaskInputs
import org.gradle.api.tasks.incremental.InputFileDetails
import org.jetbrains.kotlin.bytecode.AnnotationsRemover
import org.jetbrains.kotlin.gradle.plugin.kotlinDebug
import java.io.File
import java.io.ObjectInputStream
@@ -58,12 +57,6 @@ internal open class SyncOutputTask : DefaultTask() {
var kotlinOutputDir: File by Delegates.notNull()
var javaOutputDir: File by Delegates.notNull()
var kotlinTask: KotlinCompile by Delegates.notNull()
private val sourceAnnotations: Set<String> by lazy {
kotlinTask.sourceAnnotationsRegistry?.annotations ?: emptySet()
}
private val annotationsRemover by lazy {
AnnotationsRemover(sourceAnnotations)
}
// OutputDirectory needed for task to be incremental
@get:OutputDirectory
@@ -144,13 +137,7 @@ internal open class SyncOutputTask : DefaultTask() {
if (!fileInKotlinDir.isFile) return
fileInJavaDir.parentFile.mkdirs()
if (sourceAnnotations.isNotEmpty() && fileInKotlinDir.extension.toLowerCase() == "class") {
logger.kotlinDebug { "Removing source annotations from class: $fileInKotlinDir" }
annotationsRemover.transformClassFile(fileInKotlinDir, fileInJavaDir)
}
else {
fileInKotlinDir.copyTo(fileInJavaDir, overwrite = true)
}
fileInKotlinDir.copyTo(fileInJavaDir, overwrite = true)
timestamps[fileInJavaDir] = fileInJavaDir.lastModified()
@@ -27,7 +27,6 @@ import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.compile.AbstractCompile
import org.gradle.api.tasks.incremental.IncrementalTaskInputs
import org.jetbrains.kotlin.annotation.AnnotationFileUpdater
import org.jetbrains.kotlin.annotation.SourceAnnotationsRegistry
import org.jetbrains.kotlin.cli.common.CLICompiler
import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
@@ -165,8 +164,6 @@ open class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(), Kotl
internal val pluginOptions = CompilerPluginOptions()
internal var artifactDifferenceRegistryProvider: ArtifactDifferenceRegistryProvider? = null
internal var artifactFile: File? = null
// created only if kapt2 is active
internal var sourceAnnotationsRegistry: SourceAnnotationsRegistry? = null
override fun findKotlinCompilerJar(project: Project): File? =
findKotlinJvmCompilerJar(project)
@@ -227,7 +224,6 @@ open class KotlinCompile : AbstractKotlinCompile<K2JVMCompilerArguments>(), Kotl
cacheVersions,
reporter,
kaptAnnotationsFileUpdater,
sourceAnnotationsRegistry,
artifactDifferenceRegistryProvider,
artifactFile
)
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.incremental
import org.jetbrains.kotlin.annotation.AnnotationFileUpdater
import org.jetbrains.kotlin.annotation.SourceAnnotationsRegistry
import org.jetbrains.kotlin.build.GeneratedFile
import org.jetbrains.kotlin.build.GeneratedJvmClass
import org.jetbrains.kotlin.cli.common.ExitCode
@@ -97,7 +96,6 @@ internal class IncrementalJvmCompilerRunner(
private val cacheVersions: List<CacheVersion>,
private val reporter: IncReporter,
private var kaptAnnotationsFileUpdater: AnnotationFileUpdater? = null,
private val sourceAnnotationsRegistry: SourceAnnotationsRegistry? = null,
private val artifactDifferenceRegistryProvider: ArtifactDifferenceRegistryProvider? = null,
private val artifactFile: File? = null
) {
@@ -394,7 +392,6 @@ internal class IncrementalJvmCompilerRunner(
}
if (exitCode == ExitCode.OK) {
sourceAnnotationsRegistry?.flush()
cacheVersions.forEach { it.saveIfNeeded() }
}
@@ -462,7 +459,6 @@ internal class IncrementalJvmCompilerRunner(
val outputItemCollector = OutputItemsCollectorImpl()
@Suppress("NAME_SHADOWING")
val messageCollector = MessageCollectorWrapper(messageCollector, outputItemCollector)
sourceAnnotationsRegistry?.clear()
try {
val incrementalCaches = makeIncrementalCachesMap(targets, { listOf<TargetId>() }, getIncrementalCache, { this })
@@ -473,7 +469,7 @@ internal class IncrementalJvmCompilerRunner(
reporter.report { "compiling with args: ${ArgumentUtils.convertArgumentsToStringList(args)}" }
reporter.report { "compiling with classpath: ${classpath.toList().sorted().joinToString()}" }
val compileServices = makeCompileServices(incrementalCaches, lookupTracker, compilationCanceledStatus, sourceAnnotationsRegistry)
val compileServices = makeCompileServices(incrementalCaches, lookupTracker, compilationCanceledStatus)
val exitCode = compiler.exec(messageCollector, compileServices, args)
val generatedFiles = outputItemCollector.generatedFiles(targets, targets.first(), {sourcesToCompile}, {outputDir})
reporter.reportCompileIteration(sourcesToCompile, exitCode)
@@ -1,108 +0,0 @@
package org.jetbrains.kotlin.bytecode
import org.jetbrains.kotlin.cli.common.ExitCode
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
import org.jetbrains.kotlin.com.intellij.openapi.util.io.FileUtil.createTempDirectory
import org.jetbrains.kotlin.gradle.util.checkBytecodeContains
import org.jetbrains.kotlin.gradle.util.checkBytecodeNotContains
import org.junit.After
import org.junit.Test
import org.junit.Assert.*
import org.junit.Before
import java.io.*
import kotlin.properties.Delegates
class AnnotationsRemoverTest {
private var workingDir: File by Delegates.notNull()
@Before
fun setUp() {
workingDir = createTempDirectory(AnnotationsRemoverTest::class.java.simpleName, null)
}
@After
fun tearDown() {
workingDir.deleteRecursively()
}
@Test
fun testRemoveAnnotations() {
// initial build
val sourceDir = File(workingDir, "src").apply { mkdirs() }
val annotationsKt = File(sourceDir, "annotations.kt").apply {
writeText("""
package foo
annotation class Ann1
annotation class Ann2
annotation class Ann3
annotation class Ann4
annotation class Ann5
annotation class NotRemovableAnn1
annotation class NotRemovableAnn2
annotation class NotRemovableAnn3
annotation class NotRemovableAnn4
annotation class NotRemovableAnn5
""".trimIndent())
}
File(sourceDir, "A.kt").apply {
writeText("""
import foo.*
@Ann1
@NotRemovableAnn1
class A {
@get:Ann2
@field:Ann3
@get:NotRemovableAnn2
@field:NotRemovableAnn3
val i = 10
@Ann4
@NotRemovableAnn4
fun m(@Ann5 @NotRemovableAnn5 x: Int) {}
}
""".trimIndent())
}
val annClassRegex = "annotation class (Ann\\d)".toRegex()
val annotationsToRemove = annClassRegex.findAll(annotationsKt.readText()).toList().map { "foo/${it.groupValues[1]}" }
assertEquals(5, annotationsToRemove.size)
val notRemovableAnnClassRegex = "annotation class (NotRemovableAnn\\d)".toRegex()
val notRemovableAnns = notRemovableAnnClassRegex.findAll(annotationsKt.readText()).toList().map { "foo/${it.groupValues[1]}" }
assertEquals(5, notRemovableAnns.size)
val outDir = File(workingDir, "out").apply { mkdirs() }
compileAll(sourceDir, outDir)
val aClass = File(outDir, "A.class")
assert(aClass.exists()) { "$aClass does not exist" }
checkBytecodeContains(aClass, annotationsToRemove)
// remove annotations
val transformedOut = File(workingDir, "transformed").apply { mkdirs() }
val aTransformedClass = File(transformedOut, "A.class")
val remover = AnnotationsRemover(annotationsToRemove)
remover.transformClassFile(aClass, aTransformedClass)
checkBytecodeNotContains(aTransformedClass, annotationsToRemove)
checkBytecodeContains(aTransformedClass, notRemovableAnns)
}
private fun compileAll(inputDir: File, outputDir: File) {
val ktFiles = inputDir.walk()
.filter { it.isFile && it.extension.toLowerCase() == "kt" }
.map { it.absolutePath }
.toList().toTypedArray()
val byteOut = ByteArrayOutputStream()
val exitCode = PrintStream(byteOut).use { err ->
K2JVMCompiler().exec(err, *ktFiles, "-d", outputDir.absolutePath, "-Xadd-compiler-builtins")
}
if (exitCode != ExitCode.OK) {
System.err.print(byteOut.toString())
}
assertEquals(ExitCode.OK, exitCode)
}
}
@@ -34,7 +34,6 @@ import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.config.APPEND_JAVA_SOURCE_ROOTS_HANDLER_KEY
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.fileClasses.NoResolveFileClassesProvider
import org.jetbrains.kotlin.incremental.components.SourceRetentionAnnotationHandler
import org.jetbrains.kotlin.java.model.elements.JeTypeElement
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.psi.KtFile
@@ -56,11 +55,10 @@ class ClasspathBasedAnnotationProcessingExtension(
classesOutputDir: File,
javaSourceRoots: List<File>,
verboseOutput: Boolean,
incrementalDataFile: File?,
sourceRetentionAnnotationHandler: SourceRetentionAnnotationHandler?
) : AbstractAnnotationProcessingExtension(generatedSourcesOutputDir,
incrementalDataFile: File?
) : AbstractAnnotationProcessingExtension(generatedSourcesOutputDir,
classesOutputDir, javaSourceRoots, verboseOutput,
incrementalDataFile, sourceRetentionAnnotationHandler) {
incrementalDataFile) {
override fun loadAnnotationProcessors(): List<Processor> {
val classLoader = URLClassLoader(annotationProcessingClasspath.map { it.toURI().toURL() }.toTypedArray())
return ServiceLoader.load(Processor::class.java, classLoader).toList()
@@ -72,8 +70,7 @@ abstract class AbstractAnnotationProcessingExtension(
val classesOutputDir: File,
val javaSourceRoots: List<File>,
val verboseOutput: Boolean,
val incrementalDataFile: File? = null,
val sourceRetentionAnnotationHandler: SourceRetentionAnnotationHandler? = null
val incrementalDataFile: File? = null
) : AnalysisHandlerExtension {
private companion object {
val LINE_SEPARATOR = System.getProperty("line.separator") ?: "\n"
@@ -201,7 +198,6 @@ abstract class AbstractAnnotationProcessingExtension(
}
val firstRoundAnnotations = RoundAnnotations(
sourceRetentionAnnotationHandler,
bindingContext(),
createTypeMapper())
@@ -141,12 +141,10 @@ class AnnotationProcessingComponentRegistrar : ComponentRegistrar {
// Annotations with the "SOURCE" retention will be written to class files
project.putUserData(IS_KAPT2_ENABLED_KEY, true)
val sourceRetentionAnnotationHandler = configuration[JVMConfigurationKeys.SOURCE_RETENTION_ANNOTATION_HANDLER]
val annotationProcessingExtension = ClasspathBasedAnnotationProcessingExtension(
classpath, apOptions, generatedOutputDirFile, classesOutputDir, javaRoots, verboseOutput,
incrementalDataFile, sourceRetentionAnnotationHandler)
incrementalDataFile)
project.registerService(JeElementRegistry::class.java, JeElementRegistry())
@@ -22,14 +22,12 @@ import org.jetbrains.kotlin.asJava.elements.KtLightAnnotation
import org.jetbrains.kotlin.asJava.findFacadeClass
import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.incremental.components.SourceRetentionAnnotationHandler
import org.jetbrains.kotlin.java.model.internal.getAnnotationsWithInherited
import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.BindingContext
internal class RoundAnnotations(
val sourceRetentionAnnotationHandler: SourceRetentionAnnotationHandler?,
val bindingContext: BindingContext,
val typeMapper: KotlinTypeMapper
) {
@@ -51,7 +49,7 @@ internal class RoundAnnotations(
val analyzedClasses: Set<String>
get() = mutableAnalyzedClasses
fun copy() = RoundAnnotations(sourceRetentionAnnotationHandler, bindingContext, typeMapper)
fun copy() = RoundAnnotations(bindingContext, typeMapper)
fun analyzeFiles(files: Collection<KtFile>) = files.forEach { analyzeFile(it) }
@@ -102,15 +100,6 @@ internal class RoundAnnotations(
for (annotation in declaration.getAnnotationsWithInherited()) {
val fqName = annotation.qualifiedName ?: continue
val ktLightAnnotation = annotation as? KtLightAnnotation
if (ktLightAnnotation != null && sourceRetentionAnnotationHandler != null && ktLightAnnotation.hasSourceRetention) {
val type = bindingContext[BindingContext.ANNOTATION, ktLightAnnotation.kotlinOrigin]?.type
if (type != null) {
val internalName = typeMapper.mapType(type).internalName
sourceRetentionAnnotationHandler.register(internalName)
}
}
if (BLACKLISTED_ANNOTATATIONS.any { fqName.startsWith(it) }) continue
mutableAnnotationsMap.getOrPut(fqName, { mutableListOf() }).add(declaration)
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.codegen.AbstractBytecodeTextTest
import org.jetbrains.kotlin.codegen.CodegenTestUtil
import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
import org.jetbrains.kotlin.incremental.SourceRetentionAnnotationHandlerImpl
import org.jetbrains.kotlin.java.model.elements.JeAnnotationMirror
import org.jetbrains.kotlin.java.model.elements.JeMethodExecutableElement
import org.jetbrains.kotlin.java.model.elements.JeTypeElement
@@ -47,7 +46,7 @@ import javax.lang.model.element.*
class AnnotationProcessingExtensionForTests(
val processors: List<Processor>
) : AbstractAnnotationProcessingExtension(createTempDir(), createTempDir(), listOf(), true,
createIncrementalDataFile(), SourceRetentionAnnotationHandlerImpl()) {
createIncrementalDataFile()) {
override fun loadAnnotationProcessors() = processors
override val options: Map<String, String>
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.annotation.processing.test.processor
import org.intellij.lang.annotations.Language
import org.jetbrains.kotlin.annotation.processing.impl.DisposableRef
import org.jetbrains.kotlin.annotation.processing.impl.KotlinProcessingEnvironment
import org.jetbrains.kotlin.incremental.SourceRetentionAnnotationHandlerImpl
import org.jetbrains.kotlin.java.model.elements.*
import org.jetbrains.kotlin.java.model.types.JeDeclaredType
import org.jetbrains.kotlin.java.model.types.JeMethodExecutableTypeMirror
@@ -255,14 +254,6 @@ class ProcessorTests : AbstractProcessorTest() {
assertEquals(expectedText, text)
}
fun testSourceRetention() {
test("SourceRetention", "*") { set, roundEnv, env -> }
val ext = getKapt2Extension()
val annotationHandler = ext.sourceRetentionAnnotationHandler as SourceRetentionAnnotationHandlerImpl
val annotations = annotationHandler.sourceRetentionAnnotations.sorted()
assertEquals("Source1, Source2, Source3, Source4, Test5\$Source5", annotations.joinToString())
}
fun testKotlinAnnotationDefaultValueFromBinary() = test("DefaultValueFromBinary", "*") { set, roundEnv, env ->
fun check(expectedValue: Boolean, className: String) {
val clazz = env.findClass(className)