Minor: Fix inspection warnings in 'kotlin-annotation-processing'

This commit is contained in:
Yan Zhulanow
2018-10-19 20:17:27 +03:00
parent 17c02a77c7
commit f19c0c3fb9
17 changed files with 454 additions and 404 deletions
+2
View File
@@ -8,6 +8,8 @@
<w>parceler</w> <w>parceler</w>
<w>repl</w> <w>repl</w>
<w>uast</w> <w>uast</w>
<w>unboxed</w>
<w>unmute</w>
</words> </words>
</dictionary> </dictionary>
</component> </component>
@@ -69,7 +69,7 @@ class ClasspathBasedKapt3Extension(
javacOptions: Map<String, String>, javacOptions: Map<String, String>,
annotationProcessorFqNames: List<String>, annotationProcessorFqNames: List<String>,
aptMode: AptMode, aptMode: AptMode,
val useLightAnalysis: Boolean, private val useLightAnalysis: Boolean,
correctErrorTypes: Boolean, correctErrorTypes: Boolean,
mapDiagnosticLocations: Boolean, mapDiagnosticLocations: Boolean,
strictMode: Boolean, strictMode: Boolean,
@@ -106,11 +106,11 @@ class ClasspathBasedKapt3Extension(
abstract class AbstractKapt3Extension( abstract class AbstractKapt3Extension(
val paths: KaptPaths, val paths: KaptPaths,
val options: Map<String, String>, private val options: Map<String, String>,
val javacOptions: Map<String, String>, private val javacOptions: Map<String, String>,
val annotationProcessorFqNames: List<String>, val annotationProcessorFqNames: List<String>,
val aptMode: AptMode, private val aptMode: AptMode,
val pluginInitializedTime: Long, private val pluginInitializedTime: Long,
val logger: MessageCollectorBackedKaptLogger, val logger: MessageCollectorBackedKaptLogger,
val correctErrorTypes: Boolean, val correctErrorTypes: Boolean,
val mapDiagnosticLocations: Boolean, val mapDiagnosticLocations: Boolean,
@@ -149,7 +149,7 @@ abstract class AbstractKapt3Extension(
): AnalysisResult? { ): AnalysisResult? {
if (setAnnotationProcessingComplete()) return null if (setAnnotationProcessingComplete()) return null
fun doNotGenerateCode() = AnalysisResult.Companion.success(BindingContext.EMPTY, module, shouldGenerateCode = false) fun doNotGenerateCode() = AnalysisResult.success(BindingContext.EMPTY, module, shouldGenerateCode = false)
logger.info { "Initial analysis took ${System.currentTimeMillis() - pluginInitializedTime} ms" } logger.info { "Initial analysis took ${System.currentTimeMillis() - pluginInitializedTime} ms" }
@@ -204,7 +204,8 @@ abstract class AbstractKapt3Extension(
bindingTrace.bindingContext, bindingTrace.bindingContext,
module, module,
listOf(paths.sourcesOutputDir), listOf(paths.sourcesOutputDir),
addToEnvironment = true) addToEnvironment = true
)
} }
} }
@@ -231,7 +232,8 @@ abstract class AbstractKapt3Extension(
val targetId = TargetId( val targetId = TargetId(
name = compilerConfiguration[CommonConfigurationKeys.MODULE_NAME] ?: module.name.asString(), name = compilerConfiguration[CommonConfigurationKeys.MODULE_NAME] ?: module.name.asString(),
type = "java-production") type = "java-production"
)
val generationState = GenerationState.Builder( val generationState = GenerationState.Builder(
project, project,
@@ -296,7 +298,8 @@ abstract class AbstractKapt3Extension(
protected open fun saveIncrementalData( protected open fun saveIncrementalData(
kaptContext: KaptContextForStubGeneration, kaptContext: KaptContextForStubGeneration,
messageCollector: MessageCollector, messageCollector: MessageCollector,
converter: ClassFileToSourceStubConverter) { converter: ClassFileToSourceStubConverter
) {
val incrementalDataOutputDir = paths.incrementalDataOutputDir ?: return val incrementalDataOutputDir = paths.incrementalDataOutputDir ?: return
val reportOutputFiles = kaptContext.generationState.configuration.getBoolean(CommonConfigurationKeys.REPORT_OUTPUT_FILES) val reportOutputFiles = kaptContext.generationState.configuration.getBoolean(CommonConfigurationKeys.REPORT_OUTPUT_FILES)
@@ -308,9 +311,9 @@ abstract class AbstractKapt3Extension(
val stubFile = File(paths.stubsOutputDir, stubFileObject.name) val stubFile = File(paths.stubsOutputDir, stubFileObject.name)
val lineMappingsFile = File(stubFile.parentFile, stubFile.nameWithoutExtension + KAPT_METADATA_EXTENSION) val lineMappingsFile = File(stubFile.parentFile, stubFile.nameWithoutExtension + KAPT_METADATA_EXTENSION)
for (file in listOf(stubFile, lineMappingsFile)) { for (outputFile in listOf(stubFile, lineMappingsFile)) {
if (file.exists()) { if (outputFile.exists()) {
messageCollector.report(OUTPUT, OutputMessageUtil.formatOutputMessage(sources, file)) messageCollector.report(OUTPUT, OutputMessageUtil.formatOutputMessage(sources, outputFile))
} }
} }
} }
@@ -346,7 +349,7 @@ private class PrettyWithWorkarounds(private val context: Context, val out: Write
} }
} }
private inline fun <T> measureTimeMillis(block: () -> T) : Pair<Long, T> { private inline fun <T> measureTimeMillis(block: () -> T): Pair<Long, T> {
val start = System.currentTimeMillis() val start = System.currentTimeMillis()
val result = block() val result = block()
return Pair(System.currentTimeMillis() - start, result) return Pair(System.currentTimeMillis() - start, result)
@@ -125,7 +125,7 @@ object Kapt3ConfigurationKeys {
class Kapt3CommandLineProcessor : CommandLineProcessor { class Kapt3CommandLineProcessor : CommandLineProcessor {
companion object { companion object {
val ANNOTATION_PROCESSING_COMPILER_PLUGIN_ID: String = "org.jetbrains.kotlin.kapt3" const val ANNOTATION_PROCESSING_COMPILER_PLUGIN_ID: String = "org.jetbrains.kotlin.kapt3"
val CONFIGURATION = CliOption("configuration", "<encoded>", "Encoded configuration", required = false) val CONFIGURATION = CliOption("configuration", "<encoded>", "Encoded configuration", required = false)
@@ -142,20 +142,28 @@ class Kapt3CommandLineProcessor : CommandLineProcessor {
CliOption("incrementalData", "<path>", "Output path for the incremental data", required = false) CliOption("incrementalData", "<path>", "Output path for the incremental data", required = false)
val ANNOTATION_PROCESSOR_CLASSPATH_OPTION: CliOption = val ANNOTATION_PROCESSOR_CLASSPATH_OPTION: CliOption =
CliOption("apclasspath", "<classpath>", "Annotation processor classpath", CliOption(
required = false, allowMultipleOccurrences = true) "apclasspath", "<classpath>", "Annotation processor classpath",
required = false, allowMultipleOccurrences = true
)
val APT_OPTIONS_OPTION: CliOption = val APT_OPTIONS_OPTION: CliOption =
CliOption("apoptions", "options map", "Encoded annotation processor options", CliOption(
required = false, allowMultipleOccurrences = false) "apoptions", "options map", "Encoded annotation processor options",
required = false, allowMultipleOccurrences = false
)
val JAVAC_CLI_OPTIONS_OPTION: CliOption = val JAVAC_CLI_OPTIONS_OPTION: CliOption =
CliOption("javacArguments", "javac CLI options map", "Encoded javac CLI options", CliOption(
required = false, allowMultipleOccurrences = false) "javacArguments", "javac CLI options map", "Encoded javac CLI options",
required = false, allowMultipleOccurrences = false
)
val ANNOTATION_PROCESSORS_OPTION: CliOption = val ANNOTATION_PROCESSORS_OPTION: CliOption =
CliOption("processors", "<fqname,[fqname2,...]>", "Annotation processor qualified names", CliOption(
required = false, allowMultipleOccurrences = true) "processors", "<fqname,[fqname2,...]>", "Annotation processor qualified names",
required = false, allowMultipleOccurrences = true
)
val VERBOSE_MODE_OPTION: CliOption = val VERBOSE_MODE_OPTION: CliOption =
CliOption("verbose", "true | false", "Enable verbose output", required = false) CliOption("verbose", "true | false", "Enable verbose output", required = false)
@@ -168,18 +176,30 @@ class Kapt3CommandLineProcessor : CommandLineProcessor {
CliOption("aptOnly", "true | false", "Run only annotation processing, do not compile Kotlin files", required = false) CliOption("aptOnly", "true | false", "Run only annotation processing, do not compile Kotlin files", required = false)
val APT_MODE_OPTION: CliOption = val APT_MODE_OPTION: CliOption =
CliOption("aptMode", "apt | stubs | stubsAndApt | compile", CliOption(
"aptMode", "apt | stubs | stubsAndApt | compile",
"Annotation processing mode: only apt, only stub generation, both, or with the subsequent compilation", "Annotation processing mode: only apt, only stub generation, both, or with the subsequent compilation",
required = false) required = false
)
val USE_LIGHT_ANALYSIS_OPTION: CliOption = val USE_LIGHT_ANALYSIS_OPTION: CliOption =
CliOption("useLightAnalysis", "true | false", "Do not analyze declaration bodies if can", required = false) CliOption("useLightAnalysis", "true | false", "Do not analyze declaration bodies if can", required = false)
val CORRECT_ERROR_TYPES_OPTION: CliOption = val CORRECT_ERROR_TYPES_OPTION: CliOption =
CliOption("correctErrorTypes", "true | false", "Replace generated or error types with ones from the generated sources", required = false) CliOption(
"correctErrorTypes",
"true | false",
"Replace generated or error types with ones from the generated sources",
required = false
)
val MAP_DIAGNOSTIC_LOCATIONS_OPTION: CliOption = val MAP_DIAGNOSTIC_LOCATIONS_OPTION: CliOption =
CliOption("mapDiagnosticLocations", "true | false", "Map diagnostic reported on kapt stubs to original locations in Kotlin sources", required = false) CliOption(
"mapDiagnosticLocations",
"true | false",
"Map diagnostic reported on kapt stubs to original locations in Kotlin sources",
required = false
)
val STRICT_MODE_OPTION: CliOption = val STRICT_MODE_OPTION: CliOption =
CliOption("strict", "true | false", "Show errors on incompatibilities during stub generation", required = false) CliOption("strict", "true | false", "Show errors on incompatibilities during stub generation", required = false)
@@ -188,10 +208,12 @@ class Kapt3CommandLineProcessor : CommandLineProcessor {
override val pluginId: String = ANNOTATION_PROCESSING_COMPILER_PLUGIN_ID override val pluginId: String = ANNOTATION_PROCESSING_COMPILER_PLUGIN_ID
override val pluginOptions: Collection<CliOption> = override val pluginOptions: Collection<CliOption> =
listOf(SOURCE_OUTPUT_DIR_OPTION, ANNOTATION_PROCESSOR_CLASSPATH_OPTION, APT_OPTIONS_OPTION, JAVAC_CLI_OPTIONS_OPTION, 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, 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, USE_LIGHT_ANALYSIS_OPTION, CORRECT_ERROR_TYPES_OPTION, ANNOTATION_PROCESSORS_OPTION, INCREMENTAL_DATA_OUTPUT_DIR_OPTION,
CONFIGURATION, MAP_DIAGNOSTIC_LOCATIONS_OPTION, INFO_AS_WARNINGS_OPTION, STRICT_MODE_OPTION) CONFIGURATION, MAP_DIAGNOSTIC_LOCATIONS_OPTION, INFO_AS_WARNINGS_OPTION, STRICT_MODE_OPTION
)
override fun processOption(option: CliOption, value: String, configuration: CompilerConfiguration) { override fun processOption(option: CliOption, value: String, configuration: CompilerConfiguration) {
when (option) { when (option) {
@@ -238,8 +260,7 @@ class Kapt3ComponentRegistrar : ComponentRegistrar {
} }
override fun registerProjectComponents(project: MockProject, configuration: CompilerConfiguration) { override fun registerProjectComponents(project: MockProject, configuration: CompilerConfiguration) {
val aptMode = AptMode.parse(configuration.get(Kapt3ConfigurationKeys.APT_MODE) ?: val aptMode = AptMode.parse(configuration.get(Kapt3ConfigurationKeys.APT_MODE) ?: configuration.get(Kapt3ConfigurationKeys.APT_ONLY))
configuration.get(Kapt3ConfigurationKeys.APT_ONLY))
val isVerbose = configuration.get(Kapt3ConfigurationKeys.VERBOSE_MODE) == "true" val isVerbose = configuration.get(Kapt3ConfigurationKeys.VERBOSE_MODE) == "true"
val infoAsWarnings = configuration.get(Kapt3ConfigurationKeys.INFO_AS_WARNINGS) == "true" val infoAsWarnings = configuration.get(Kapt3ConfigurationKeys.INFO_AS_WARNINGS) == "true"
@@ -365,7 +386,7 @@ class Kapt3ComponentRegistrar : ComponentRegistrar {
bindingTrace: BindingTrace, bindingTrace: BindingTrace,
files: Collection<KtFile> files: Collection<KtFile>
): AnalysisResult? { ): AnalysisResult? {
return AnalysisResult.Companion.success(bindingTrace.bindingContext, module, shouldGenerateCode = false) return AnalysisResult.success(bindingTrace.bindingContext, module, shouldGenerateCode = false)
} }
} }
} }
@@ -38,6 +38,7 @@ class KaptTreeMaker(context: Context, kaptContext: KaptContextForStubGeneration)
val nameTable: Name.Table = Names.instance(context).table val nameTable: Name.Table = Names.instance(context).table
@Suppress("FunctionName")
fun Type(type: Type): JCTree.JCExpression { fun Type(type: Type): JCTree.JCExpression {
convertBuiltinType(type)?.let { return it } convertBuiltinType(type)?.let { return it }
if (type.sort == ARRAY) { if (type.sort == ARRAY) {
@@ -46,14 +47,17 @@ class KaptTreeMaker(context: Context, kaptContext: KaptContextForStubGeneration)
return FqName(type.internalName) return FqName(type.internalName)
} }
@Suppress("FunctionName")
fun FqName(internalOrFqName: String): JCTree.JCExpression { fun FqName(internalOrFqName: String): JCTree.JCExpression {
val path = getQualifiedName(internalOrFqName).convertSpecialFqName().split('.') val path = getQualifiedName(internalOrFqName).convertSpecialFqName().split('.')
assert(path.isNotEmpty()) assert(path.isNotEmpty())
return FqName(path) return FqName(path)
} }
@Suppress("FunctionName")
fun FqName(fqName: FqName) = FqName(fqName.pathSegments().map { it.asString() }) fun FqName(fqName: FqName) = FqName(fqName.pathSegments().map { it.asString() })
@Suppress("FunctionName")
private fun FqName(path: List<String>): JCTree.JCExpression { private fun FqName(path: List<String>): JCTree.JCExpression {
if (path.size == 1) return SimpleName(path.single()) if (path.size == 1) return SimpleName(path.single())
@@ -162,6 +166,7 @@ class KaptTreeMaker(context: Context, kaptContext: KaptContextForStubGeneration)
return TypeIdent(typeTag) return TypeIdent(typeTag)
} }
@Suppress("FunctionName")
fun SimpleName(name: String): JCTree.JCExpression = Ident(name(name)) fun SimpleName(name: String): JCTree.JCExpression = Ident(name(name))
fun name(name: String): Name = nameTable.fromString(name) fun name(name: String): Name = nameTable.fromString(name)
@@ -69,19 +69,19 @@ class ClassFileToSourceStubConverter(
val strictMode: Boolean val strictMode: Boolean
) { ) {
private companion object { private companion object {
private val VISIBILITY_MODIFIERS = (Opcodes.ACC_PUBLIC or Opcodes.ACC_PRIVATE or Opcodes.ACC_PROTECTED).toLong() private const val VISIBILITY_MODIFIERS = (Opcodes.ACC_PUBLIC or Opcodes.ACC_PRIVATE or Opcodes.ACC_PROTECTED).toLong()
private val MODALITY_MODIFIERS = (Opcodes.ACC_FINAL or Opcodes.ACC_ABSTRACT).toLong() private const val MODALITY_MODIFIERS = (Opcodes.ACC_FINAL or Opcodes.ACC_ABSTRACT).toLong()
private val CLASS_MODIFIERS = VISIBILITY_MODIFIERS or MODALITY_MODIFIERS or private const val CLASS_MODIFIERS = VISIBILITY_MODIFIERS or MODALITY_MODIFIERS or
(Opcodes.ACC_DEPRECATED or Opcodes.ACC_INTERFACE or Opcodes.ACC_ANNOTATION or Opcodes.ACC_ENUM or Opcodes.ACC_STATIC).toLong() (Opcodes.ACC_DEPRECATED or Opcodes.ACC_INTERFACE or Opcodes.ACC_ANNOTATION or Opcodes.ACC_ENUM or Opcodes.ACC_STATIC).toLong()
private val METHOD_MODIFIERS = VISIBILITY_MODIFIERS or MODALITY_MODIFIERS or private const val METHOD_MODIFIERS = VISIBILITY_MODIFIERS or MODALITY_MODIFIERS or
(Opcodes.ACC_DEPRECATED or Opcodes.ACC_SYNCHRONIZED or Opcodes.ACC_NATIVE or Opcodes.ACC_STATIC or Opcodes.ACC_STRICT).toLong() (Opcodes.ACC_DEPRECATED or Opcodes.ACC_SYNCHRONIZED or Opcodes.ACC_NATIVE or Opcodes.ACC_STATIC or Opcodes.ACC_STRICT).toLong()
private val FIELD_MODIFIERS = VISIBILITY_MODIFIERS or MODALITY_MODIFIERS or private const val FIELD_MODIFIERS = VISIBILITY_MODIFIERS or MODALITY_MODIFIERS or
(Opcodes.ACC_VOLATILE or Opcodes.ACC_TRANSIENT or Opcodes.ACC_ENUM or Opcodes.ACC_STATIC).toLong() (Opcodes.ACC_VOLATILE or Opcodes.ACC_TRANSIENT or Opcodes.ACC_ENUM or Opcodes.ACC_STATIC).toLong()
private val PARAMETER_MODIFIERS = FIELD_MODIFIERS or Flags.PARAMETER or Flags.VARARGS or Opcodes.ACC_FINAL.toLong() private const val PARAMETER_MODIFIERS = FIELD_MODIFIERS or Flags.PARAMETER or Flags.VARARGS or Opcodes.ACC_FINAL.toLong()
private val BLACKLISTED_ANNOTATIONS = listOf( private val BLACKLISTED_ANNOTATIONS = listOf(
"java.lang.Deprecated", "kotlin.Deprecated", // Deprecated annotations "java.lang.Deprecated", "kotlin.Deprecated", // Deprecated annotations
@@ -135,7 +135,8 @@ class ClassFileToSourceStubConverter(
JavacList.nil(), JavacList.nil(),
null, null,
JavacList.nil(), JavacList.nil(),
JavacList.nil()) JavacList.nil()
)
val topLevel = treeMaker.TopLevelJava9Aware(treeMaker.FqName(NON_EXISTENT_CLASS_NAME.parent()), JavacList.of(nonExistentClass)) val topLevel = treeMaker.TopLevelJava9Aware(treeMaker.FqName(NON_EXISTENT_CLASS_NAME.parent()), JavacList.of(nonExistentClass))
@@ -145,7 +146,7 @@ class ClassFileToSourceStubConverter(
return topLevel return topLevel
} }
class KaptStub(val file: JCCompilationUnit, val kaptMetadata: ByteArray? = null) { class KaptStub(val file: JCCompilationUnit, private val kaptMetadata: ByteArray? = null) {
fun writeMetadataIfNeeded(forSource: File) { fun writeMetadataIfNeeded(forSource: File) {
if (kaptMetadata == null) { if (kaptMetadata == null) {
return return
@@ -166,7 +167,7 @@ class ClassFileToSourceStubConverter(
val descriptor = origin.descriptor ?: return null val descriptor = origin.descriptor ?: return null
// Nested classes will be processed during the outer classes conversion // Nested classes will be processed during the outer classes conversion
if ((descriptor as? ClassDescriptor)?.isNested ?: false) return null if ((descriptor as? ClassDescriptor)?.isNested == true) return null
val lineMappings = KaptLineMappingCollector(kaptContext) val lineMappings = KaptLineMappingCollector(kaptContext)
@@ -245,7 +246,7 @@ class ClassFileToSourceStubConverter(
val shortName = importedFqName.shortName() val shortName = importedFqName.shortName()
if (shortName.asString() == classDeclaration.simpleName.toString()) continue if (shortName.asString() == classDeclaration.simpleName.toString()) continue
val importedReference = resolveImportReference@ run { val importedReference = /* resolveImportReference */ run {
val referenceExpression = getReferenceExpression(importDirective.importedReference) ?: return@run null val referenceExpression = getReferenceExpression(importDirective.importedReference) ?: return@run null
val bindingContext = kaptContext.bindingContext val bindingContext = kaptContext.bindingContext
@@ -300,9 +301,11 @@ class ClassFileToSourceStubConverter(
val isEnum = clazz.isEnum() val isEnum = clazz.isEnum()
val isAnnotation = clazz.isAnnotation() val isAnnotation = clazz.isAnnotation()
val modifiers = convertModifiers(flags, val modifiers = convertModifiers(
flags,
if (isEnum) ElementKind.ENUM else ElementKind.CLASS, if (isEnum) ElementKind.ENUM else ElementKind.CLASS,
packageFqName, clazz.visibleAnnotations, clazz.invisibleAnnotations, descriptor.annotations) packageFqName, clazz.visibleAnnotations, clazz.invisibleAnnotations, descriptor.annotations
)
val isDefaultImpls = clazz.name.endsWith("${descriptor.name.asString()}\$DefaultImpls") val isDefaultImpls = clazz.name.endsWith("${descriptor.name.asString()}\$DefaultImpls")
&& isPublic(clazz.access) && isFinal(clazz.access) && isPublic(clazz.access) && isFinal(clazz.access)
@@ -357,12 +360,15 @@ class ClassFileToSourceStubConverter(
val def = data.correspondingClass?.let { convertClass(it, lineMappings, packageFqName, false) } val def = data.correspondingClass?.let { convertClass(it, lineMappings, packageFqName, false) }
convertField(data.field, clazz, lineMappings, packageFqName, treeMaker.NewClass( convertField(
data.field, clazz, lineMappings, packageFqName, treeMaker.NewClass(
/* enclosing = */ null, /* enclosing = */ null,
/* typeArgs = */ JavacList.nil(), /* typeArgs = */ JavacList.nil(),
/* clazz = */ treeMaker.Ident(treeMaker.name(data.field.name)), /* clazz = */ treeMaker.Ident(treeMaker.name(data.field.name)),
/* args = */ args, /* args = */ args,
/* def = */ def)) /* def = */ def
)
)
} }
val fields = mapJList<FieldNode, JCTree>(clazz.fields) { val fields = mapJList<FieldNode, JCTree>(clazz.fields) {
@@ -395,7 +401,8 @@ class ClassFileToSourceStubConverter(
genericType.typeParameters, genericType.typeParameters,
superTypes.superClass, superTypes.superClass,
superTypes.interfaces, superTypes.interfaces,
enumValues + fields + methods + nestedClasses).keepKdocComments(clazz) enumValues + fields + methods + nestedClasses
).keepKdocComments(clazz)
} }
private class ClassSupertypes(val superClass: JCExpression?, val interfaces: JavacList<JCExpression>) private class ClassSupertypes(val superClass: JCExpression?, val interfaces: JavacList<JCExpression>)
@@ -645,7 +652,8 @@ class ClassFileToSourceStubConverter(
(method.access.toLong() and VISIBILITY_MODIFIERS.inv()) (method.access.toLong() and VISIBILITY_MODIFIERS.inv())
else else
method.access.toLong(), method.access.toLong(),
ElementKind.METHOD, packageFqName, visibleAnnotations, method.invisibleAnnotations, descriptor.annotations) ElementKind.METHOD, packageFqName, visibleAnnotations, method.invisibleAnnotations, descriptor.annotations
)
val asmReturnType = Type.getReturnType(method.desc) val asmReturnType = Type.getReturnType(method.desc)
val jcReturnType = if (isConstructor) null else treeMaker.Type(asmReturnType) val jcReturnType = if (isConstructor) null else treeMaker.Type(asmReturnType)
@@ -670,9 +678,10 @@ class ClassFileToSourceStubConverter(
packageFqName, packageFqName,
info.visibleAnnotations, info.visibleAnnotations,
info.invisibleAnnotations, info.invisibleAnnotations,
Annotations.EMPTY /* TODO */) Annotations.EMPTY /* TODO */
)
val name = info.name.takeIf { isValidIdentifier(it) } ?: "p${index}_" + info.name.hashCode().ushr(1) val name = info.name.takeIf { isValidIdentifier(it) } ?: ("p" + index + "_" + info.name.hashCode().ushr(1))
val type = treeMaker.Type(info.type) val type = treeMaker.Type(info.type)
treeMaker.VarDef(modifiers, treeMaker.name(name), type, null) treeMaker.VarDef(modifiers, treeMaker.name(name), type, null)
} }
@@ -680,8 +689,8 @@ class ClassFileToSourceStubConverter(
val exceptionTypes = mapJList(method.exceptions) { treeMaker.FqName(it) } val exceptionTypes = mapJList(method.exceptions) { treeMaker.FqName(it) }
val valueParametersFromDescriptor = descriptor.valueParameters val valueParametersFromDescriptor = descriptor.valueParameters
val (genericSignature, returnType) = extractMethodSignatureTypes( val (genericSignature, returnType) =
descriptor, exceptionTypes, jcReturnType, method, parameters, valueParametersFromDescriptor) extractMethodSignatureTypes(descriptor, exceptionTypes, jcReturnType, method, parameters, valueParametersFromDescriptor)
val defaultValue = method.annotationDefault?.let { convertLiteralExpression(it) } val defaultValue = method.annotationDefault?.let { convertLiteralExpression(it) }
@@ -748,15 +757,13 @@ class ClassFileToSourceStubConverter(
setterOrigin?.typeReference setterOrigin?.typeReference
}, },
ifNonError = { lazyType() }) ifNonError = { lazyType() })
} } else if (descriptor is FunctionDescriptor && valueParametersFromDescriptor.size == parameters.size) {
else if (descriptor is FunctionDescriptor && valueParametersFromDescriptor.size == parameters.size) {
getNonErrorType(valueParametersFromDescriptor[index].type, METHOD_PARAMETER_TYPE, getNonErrorType(valueParametersFromDescriptor[index].type, METHOD_PARAMETER_TYPE,
ktTypeProvider = { ktTypeProvider = {
(kaptContext.origins[method]?.element as? KtFunction)?.valueParameters?.get(index)?.typeReference (kaptContext.origins[method]?.element as? KtFunction)?.valueParameters?.get(index)?.typeReference
}, },
ifNonError = { lazyType() }) ifNonError = { lazyType() })
} } else {
else {
lazyType() lazyType()
} }
}) })
@@ -850,9 +857,9 @@ class ClassFileToSourceStubConverter(
invisibleAnnotations: List<AnnotationNode>?, invisibleAnnotations: List<AnnotationNode>?,
descriptorAnnotations: Annotations descriptorAnnotations: Annotations
): JCModifiers { ): JCModifiers {
fun convertAndAdd(list: JavacList<JCAnnotation>, anno: AnnotationNode): JavacList<JCAnnotation> { fun convertAndAdd(list: JavacList<JCAnnotation>, annotation: AnnotationNode): JavacList<JCAnnotation> {
val annotationDescriptor = descriptorAnnotations.singleOrNull { checkIfAnnotationValueMatches(anno, AnnotationValue(it)) } val annotationDescriptor = descriptorAnnotations.singleOrNull { checkIfAnnotationValueMatches(annotation, AnnotationValue(it)) }
val annotationTree = convertAnnotation(anno, packageFqName, annotationDescriptor) ?: return list val annotationTree = convertAnnotation(annotation, packageFqName, annotationDescriptor) ?: return list
return list.prepend(annotationTree) return list.prepend(annotationTree)
} }
@@ -922,7 +929,7 @@ class ClassFileToSourceStubConverter(
val args = value?.arguments?.mapNotNull { it.getArgumentExpression() } ?: emptyList() val args = value?.arguments?.mapNotNull { it.getArgumentExpression() } ?: emptyList()
val singleArg = args.singleOrNull() val singleArg = args.singleOrNull()
if (constantValue.isOfPrimiviteType()) { if (constantValue.isOfPrimitiveType()) {
// Do not inline primitive constants // Do not inline primitive constants
tryParseReferenceToIntConstant(singleArg)?.let { return it } tryParseReferenceToIntConstant(singleArg)?.let { return it }
} }
@@ -1115,7 +1122,7 @@ class ClassFileToSourceStubConverter(
} }
} }
private fun Any?.isOfPrimiviteType(): Boolean = when(this) { private fun Any?.isOfPrimitiveType(): Boolean = when (this) {
is Boolean, is Byte, is Int, is Long, is Short, is Char, is Float, is Double -> true is Boolean, is Byte, is Int, is Long, is Short, is Char, is Float, is Double -> true
else -> false else -> false
} }
@@ -90,21 +90,27 @@ class ErrorTypeCorrector(
val baseExpression: JCTree.JCExpression val baseExpression: JCTree.JCExpression
if (target is TypeAliasDescriptor) { when (target) {
is TypeAliasDescriptor -> {
val typeAlias = target.source.getPsi() as? KtTypeAlias val typeAlias = target.source.getPsi() as? KtTypeAlias
val actualType = typeAlias?.getTypeReference() ?: return convert(target.expandedType) val actualType = typeAlias?.getTypeReference() ?: return convert(target.expandedType)
return convert(actualType, typeAlias.getSubstitutions(type)) return convert(actualType, typeAlias.getSubstitutions(type))
} else if (target is ClassConstructorDescriptor) { }
is ClassConstructorDescriptor -> {
val asmType = converter.kaptContext.generationState.typeMapper val asmType = converter.kaptContext.generationState.typeMapper
.mapType(target.constructedClass.defaultType, null, TypeMappingMode.GENERIC_ARGUMENT) .mapType(target.constructedClass.defaultType, null, TypeMappingMode.GENERIC_ARGUMENT)
baseExpression = converter.treeMaker.Type(asmType) baseExpression = converter.treeMaker.Type(asmType)
} else if (target is ClassDescriptor) { }
is ClassDescriptor -> {
// We only get here if some type were an error type. In other words, 'type' is either an error type or its argument, // We only get here if some type were an error type. In other words, 'type' is either an error type or its argument,
// so it's impossible it to be unboxed primitive. // so it's impossible it to be unboxed primitive.
val asmType = converter.kaptContext.generationState.typeMapper.mapType(target.defaultType, null, TypeMappingMode.GENERIC_ARGUMENT) val asmType = converter.kaptContext.generationState.typeMapper
.mapType(target.defaultType, null, TypeMappingMode.GENERIC_ARGUMENT)
baseExpression = converter.treeMaker.Type(asmType) baseExpression = converter.treeMaker.Type(asmType)
} else { }
else -> {
val referencedName = type.referencedName ?: return defaultType val referencedName = type.referencedName ?: return defaultType
val qualifier = type.qualifier val qualifier = type.qualifier
@@ -126,6 +132,7 @@ class ErrorTypeCorrector(
else -> treeMaker.SimpleName(referencedName) else -> treeMaker.SimpleName(referencedName)
} }
} }
}
val arguments = type.typeArguments val arguments = type.typeArguments
if (arguments.isEmpty()) return baseExpression if (arguments.isEmpty()) return baseExpression
@@ -147,8 +154,7 @@ class ErrorTypeCorrector(
val variance = if (typeArgument != null && typeParameter != null) { val variance = if (typeArgument != null && typeParameter != null) {
KotlinTypeMapper.getVarianceForWildcard(typeParameter, typeArgument, typeMappingMode) KotlinTypeMapper.getVarianceForWildcard(typeParameter, typeArgument, typeMappingMode)
} } else {
else {
null null
} }
@@ -183,10 +189,6 @@ class ErrorTypeCorrector(
} }
} }
private fun convertTypeProjection() {
}
private fun convertFunctionType(type: KtFunctionType, substitutions: SubstitutionMap): JCTree.JCExpression { private fun convertFunctionType(type: KtFunctionType, substitutions: SubstitutionMap): JCTree.JCExpression {
val receiverType = type.receiverTypeReference val receiverType = type.receiverTypeReference
var parameterTypes = mapJList(type.parameters) { convert(it.typeReference, substitutions) } var parameterTypes = mapJList(type.parameters) { convert(it.typeReference, substitutions) }
@@ -207,8 +209,8 @@ class ErrorTypeCorrector(
if (typeParameters.size != arguments.size) { if (typeParameters.size != arguments.size) {
val kaptContext = converter.kaptContext val kaptContext = converter.kaptContext
kaptContext.compiler.log.report( val error = kaptContext.kaptError("${typeParameters.size} parameters are expected but ${arguments.size} passed")
kaptContext.kaptError("${typeParameters.size} parameters are expected but ${arguments.size} passed")) kaptContext.compiler.log.report(error)
return emptyMap() return emptyMap()
} }
@@ -87,7 +87,7 @@ class KDocCommentKeeper(private val kaptContext: KaptContextForStubGeneration) {
&& descriptor is PropertyAccessorDescriptor && descriptor is PropertyAccessorDescriptor
&& kaptContext.bindingContext[BindingContext.BACKING_FIELD_REQUIRED, descriptor.correspondingProperty] == true && kaptContext.bindingContext[BindingContext.BACKING_FIELD_REQUIRED, descriptor.correspondingProperty] == true
) { ) {
// Do not place the smae documentation on backing field and property accessors // Do not place documentation on backing field and property accessors
return return
} }
@@ -47,8 +47,8 @@ class KaptLineMappingCollector(private val kaptContext: KaptContextForStubGenera
register(field, clazz.name + "#" + field.name) register(field, clazz.name + "#" + field.name)
} }
fun registerSignature(decl: JCTree.JCMethodDecl, method: MethodNode) { fun registerSignature(declaration: JCTree.JCMethodDecl, method: MethodNode) {
signatureInfo[decl.getJavacSignature()] = method.name + method.desc signatureInfo[declaration.getJavacSignature()] = method.name + method.desc
} }
private fun register(asmNode: Any, fqName: String) { private fun register(asmNode: Any, fqName: String) {
@@ -92,7 +92,7 @@ private class SignatureNode(val kind: ElementKind, val name: String? = null) {
val children: MutableList<SignatureNode> = SmartList<SignatureNode>() val children: MutableList<SignatureNode> = SmartList<SignatureNode>()
} }
class SignatureParser(val treeMaker: KaptTreeMaker) { class SignatureParser(private val treeMaker: KaptTreeMaker) {
class ClassGenericSignature( class ClassGenericSignature(
val typeParameters: JavacList<JCTypeParameter>, val typeParameters: JavacList<JCTypeParameter>,
val superClass: JCExpression, val superClass: JCExpression,
@@ -209,7 +209,8 @@ class SignatureParser(val treeMaker: KaptTreeMaker) {
for (innerClass in innerClasses) { for (innerClass in innerClasses) {
expression = makeExpressionForClassTypeWithArguments( expression = makeExpressionForClassTypeWithArguments(
treeMaker.Select(expression, treeMaker.name(innerClass.name!!)), treeMaker.Select(expression, treeMaker.name(innerClass.name!!)),
innerClass.children) innerClass.children
)
} }
expression expression
@@ -31,7 +31,8 @@ internal class ParameterInfo(
val name: String, val name: String,
val type: Type, val type: Type,
val visibleAnnotations: List<AnnotationNode>?, val visibleAnnotations: List<AnnotationNode>?,
val invisibleAnnotations: List<AnnotationNode>?) val invisibleAnnotations: List<AnnotationNode>?
)
internal fun MethodNode.getParametersInfo(containingClass: ClassNode): List<ParameterInfo> { internal fun MethodNode.getParametersInfo(containingClass: ClassNode): List<ParameterInfo> {
val localVariables = this.localVariables ?: emptyList() val localVariables = this.localVariables ?: emptyList()
@@ -20,7 +20,7 @@ class MessageCollectorBackedKaptLogger(
val messageCollector: MessageCollector = PrintingMessageCollector(System.err, MessageRenderer.PLAIN_FULL_PATHS, isVerbose) val messageCollector: MessageCollector = PrintingMessageCollector(System.err, MessageRenderer.PLAIN_FULL_PATHS, isVerbose)
) : KaptLogger { ) : KaptLogger {
private companion object { private companion object {
val PREFIX = "[kapt] " const val PREFIX = "[kapt] "
} }
override val errorWriter = makeWriter(ERROR) override val errorWriter = makeWriter(ERROR)
@@ -21,7 +21,10 @@ import org.jetbrains.kotlin.cli.common.messages.GroupingMessageCollector
import org.jetbrains.kotlin.cli.common.messages.MessageCollector import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import java.io.Writer import java.io.Writer
class MessageCollectorBackedWriter(val messageCollector: MessageCollector, val severity: CompilerMessageSeverity) : Writer() { class MessageCollectorBackedWriter(
private val messageCollector: MessageCollector,
private val severity: CompilerMessageSeverity
) : Writer() {
override fun write(buffer: CharArray, offset: Int, length: Int) { override fun write(buffer: CharArray, offset: Int, length: Int) {
val message = String(buffer, offset, length).trim().trim('\n', '\r') val message = String(buffer, offset, length).trim().trim('\n', '\r')
if (message.isNotEmpty()) { if (message.isNotEmpty()) {
@@ -26,7 +26,6 @@ import org.jetbrains.org.objectweb.asm.tree.MethodNode
internal fun isEnum(access: Int) = (access and Opcodes.ACC_ENUM) != 0 internal fun isEnum(access: Int) = (access and Opcodes.ACC_ENUM) != 0
internal fun isPublic(access: Int) = (access and Opcodes.ACC_PUBLIC) != 0 internal fun isPublic(access: Int) = (access and Opcodes.ACC_PUBLIC) != 0
internal fun isSynthetic(access: Int) = (access and Opcodes.ACC_SYNTHETIC) != 0 internal fun isSynthetic(access: Int) = (access and Opcodes.ACC_SYNTHETIC) != 0
internal fun isPrivate(access: Int) = (access and Opcodes.ACC_PRIVATE) != 0
internal fun isFinal(access: Int) = (access and Opcodes.ACC_FINAL) != 0 internal fun isFinal(access: Int) = (access and Opcodes.ACC_FINAL) != 0
internal fun isStatic(access: Int) = (access and Opcodes.ACC_STATIC) != 0 internal fun isStatic(access: Int) = (access and Opcodes.ACC_STATIC) != 0
internal fun isAbstract(access: Int) = (access and Opcodes.ACC_ABSTRACT) != 0 internal fun isAbstract(access: Int) = (access and Opcodes.ACC_ABSTRACT) != 0
@@ -74,7 +74,7 @@ abstract class AbstractKotlinKapt3IntegrationTest : CodegenTestCase() {
process: (Set<TypeElement>, RoundEnvironment, ProcessingEnvironment) -> Unit process: (Set<TypeElement>, RoundEnvironment, ProcessingEnvironment) -> Unit
) = testAP(true, name, options, process, *supportedAnnotations) ) = testAP(true, name, options, process, *supportedAnnotations)
protected fun testAP( private fun testAP(
shouldRun: Boolean, shouldRun: Boolean,
name: String, name: String,
options: Map<String, String>, options: Map<String, String>,
@@ -83,7 +83,7 @@ abstract class AbstractKotlinKapt3IntegrationTest : CodegenTestCase() {
) { ) {
this._options = options this._options = options
val ktFileName = File(TEST_DATA_DIR, name + ".kt") val ktFileName = File(TEST_DATA_DIR, "$name.kt")
var started = false var started = false
val processor = object : Processor { val processor = object : Processor {
lateinit var processingEnv: ProcessingEnvironment lateinit var processingEnv: ProcessingEnvironment
@@ -134,8 +134,10 @@ abstract class AbstractKotlinKapt3IntegrationTest : CodegenTestCase() {
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.ALL, *javaSources) createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.ALL, *javaSources)
val project = myEnvironment.project val project = myEnvironment.project
val kapt3Extension = Kapt3ExtensionForTests(project, processors, javaSources.toList(), sourceOutputDir, this.options, val kapt3Extension = Kapt3ExtensionForTests(
stubsOutputDir = stubsDir, incrementalDataOutputDir = incrementalDataDir) project, processors, javaSources.toList(), sourceOutputDir, this.options,
stubsOutputDir = stubsDir, incrementalDataOutputDir = incrementalDataDir
)
AnalysisHandlerExtension.registerExtension(project, kapt3Extension) AnalysisHandlerExtension.registerExtension(project, kapt3Extension)
@@ -146,7 +148,7 @@ abstract class AbstractKotlinKapt3IntegrationTest : CodegenTestCase() {
GenerationUtils.compileFiles(myFiles.psiFiles, myEnvironment, classBuilderFactory).factory GenerationUtils.compileFiles(myFiles.psiFiles, myEnvironment, classBuilderFactory).factory
val actualRaw = kapt3Extension.savedStubs ?: error("Stubs were not saved") val actualRaw = kapt3Extension.savedStubs ?: error("Stubs were not saved")
val actual = StringUtil.convertLineSeparators(actualRaw.trim({ it <= ' ' })) val actual = StringUtil.convertLineSeparators(actualRaw.trim { it <= ' ' })
.trimTrailingWhitespacesAndAddNewlineAtEOF() .trimTrailingWhitespacesAndAddNewlineAtEOF()
.let { AbstractClassFileToSourceStubConverterTest.removeMetadataAnnotationContents(it) } .let { AbstractClassFileToSourceStubConverterTest.removeMetadataAnnotationContents(it) }
@@ -208,7 +208,7 @@ abstract class AbstractKotlinKapt3Test : CodegenTestCase() {
lines.filter { it.startsWith("// $name") }.toList() lines.filter { it.startsWith("// $name") }.toList()
} }
protected fun File.getOptionValues(name: String) = getRawOptionValues(name).map { it.drop("// ".length + name.length).trim() } private fun File.getOptionValues(name: String) = getRawOptionValues(name).map { it.drop("// ".length + name.length).trim() }
protected abstract fun check( protected abstract fun check(
kaptContext: KaptContextForStubGeneration, kaptContext: KaptContextForStubGeneration,
@@ -38,8 +38,10 @@ class KotlinKapt3IntegrationTests : AbstractKotlinKapt3IntegrationTest(), Java9T
) { ) {
super.test(name, *supportedAnnotations, options = options, process = process) super.test(name, *supportedAnnotations, options = options, process = process)
doTestWithJdk9(SingleJUnitTestRunner::class.java, doTestWithJdk9(
KotlinKapt3IntegrationTests::class.java.name + "#test" + getTestName(false)) SingleJUnitTestRunner::class.java,
KotlinKapt3IntegrationTests::class.java.name + "#test" + getTestName(false)
)
} }
@Test @Test
@@ -51,7 +53,7 @@ class KotlinKapt3IntegrationTests : AbstractKotlinKapt3IntegrationTest(), Java9T
} }
@Test @Test
fun testComments() = test("Simple", "test.MyAnnotation") { set, roundEnv, env -> fun testComments() = test("Simple", "test.MyAnnotation") { _, _, env ->
fun commentOf(className: String) = env.elementUtils.getDocComment(env.elementUtils.getTypeElement(className)) fun commentOf(className: String) = env.elementUtils.getDocComment(env.elementUtils.getTypeElement(className))
assert(commentOf("test.Simple") == " * KDoc comment.\n") assert(commentOf("test.Simple") == " * KDoc comment.\n")
@@ -73,7 +75,8 @@ class KotlinKapt3IntegrationTests : AbstractKotlinKapt3IntegrationTest(), Java9T
} }
@Test @Test
fun testStubsAndIncrementalDataForNestedClasses() = bindingsTest("NestedClasses") { stubsOutputDir, incrementalDataOutputDir, bindings -> fun testStubsAndIncrementalDataForNestedClasses() {
bindingsTest("NestedClasses") { stubsOutputDir, incrementalDataOutputDir, bindings ->
assert(File(stubsOutputDir, "test/Simple.java").exists()) assert(File(stubsOutputDir, "test/Simple.java").exists())
assert(!File(stubsOutputDir, "test/Simple/InnerClass.java").exists()) assert(!File(stubsOutputDir, "test/Simple/InnerClass.java").exists())
@@ -87,6 +90,7 @@ class KotlinKapt3IntegrationTests : AbstractKotlinKapt3IntegrationTest(), Java9T
assert(bindings.none { it.key.contains("Companion") }) assert(bindings.none { it.key.contains("Companion") })
assert(bindings.none { it.key.contains("InnerClass") }) assert(bindings.none { it.key.contains("InnerClass") })
} }
}
private fun bindingsTest(name: String, test: (File, File, Map<String, KaptJavaFileObject>) -> Unit) { private fun bindingsTest(name: String, test: (File, File, Map<String, KaptJavaFileObject>) -> Unit) {
test(name, "test.MyAnnotation") { _, _, _ -> test(name, "test.MyAnnotation") { _, _, _ ->