Kapt3: Allow users to disable error type correction (and now it's disabled by default)

This commit is contained in:
Yan Zhulanow
2017-02-06 16:17:15 +03:00
parent 297f8d4161
commit 2553513205
12 changed files with 118 additions and 11 deletions
@@ -186,6 +186,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
}
pluginOptions += SubpluginOption("useLightAnalysis", "${kaptExtension.useLightAnalysis}")
pluginOptions += SubpluginOption("correctErrorTypes", "${kaptExtension.correctErrorTypes}")
pluginOptions += SubpluginOption("stubs", getKaptStubsDir(project, sourceSetName).canonicalPath)
if (project.hasProperty(VERBOSE_OPTION_NAME) && project.property(VERBOSE_OPTION_NAME) == "true") {
@@ -28,6 +28,8 @@ open class KaptExtension {
open var useLightAnalysis: Boolean = true
open var correctErrorTypes: Boolean = false
private var closure: Closure<*>? = null
open fun arguments(closure: Closure<*>) {
@@ -53,10 +53,12 @@ class ClasspathBasedKapt3Extension(
options: Map<String, String>,
aptOnly: Boolean,
val useLightAnalysis: Boolean,
correctErrorTypes: Boolean,
pluginInitializedTime: Long,
logger: KaptLogger
) : AbstractKapt3Extension(compileClasspath, annotationProcessingClasspath, javaSourceRoots, sourcesOutputDir,
classFilesOutputDir, stubsOutputDir, incrementalDataOutputDir, options, aptOnly, pluginInitializedTime, logger) {
classFilesOutputDir, stubsOutputDir, incrementalDataOutputDir, options,
aptOnly, pluginInitializedTime, logger, correctErrorTypes) {
override val analyzePartially: Boolean
get() = useLightAnalysis
@@ -102,7 +104,8 @@ abstract class AbstractKapt3Extension(
val options: Map<String, String>,
val aptOnly: Boolean,
val pluginInitializedTime: Long,
val logger: KaptLogger
val logger: KaptLogger,
val correctErrorTypes: Boolean
) : PartialAnalysisHandlerExtension() {
val compileClasspath = compileClasspath.distinct()
val annotationProcessingClasspath = annotationProcessingClasspath.distinct()
@@ -203,7 +206,8 @@ abstract class AbstractKapt3Extension(
}
private fun generateKotlinSourceStubs(kaptContext: KaptContext, generationState: GenerationState) {
val converter = ClassFileToSourceStubConverter(kaptContext, generationState.typeMapper, generateNonExistentClass = true)
val converter = ClassFileToSourceStubConverter(kaptContext, generationState.typeMapper,
generateNonExistentClass = true, correctErrorTypes = correctErrorTypes)
val (stubGenerationTime, kotlinSourceStubs) = measureTimeMillis {
converter.convert()
@@ -74,6 +74,9 @@ object Kapt3ConfigurationKeys {
val USE_LIGHT_ANALYSIS: CompilerConfigurationKey<String> =
CompilerConfigurationKey.create<String>("do not analyze declaration bodies if can")
val CORRECT_ERROR_TYPES: CompilerConfigurationKey<String> =
CompilerConfigurationKey.create<String>("replace error types with ones from the declaration sources")
}
class Kapt3CommandLineProcessor : CommandLineProcessor {
@@ -108,13 +111,17 @@ class Kapt3CommandLineProcessor : CommandLineProcessor {
val USE_LIGHT_ANALYSIS_OPTION: CliOption =
CliOption("useLightAnalysis", "true | false", "Do not analyze declaration bodies if can", required = false)
val CORRECT_ERROR_TYPES_OPTION: CliOption =
CliOption("correctErrorTypes", "true | false", "Replace generated or error types with ones from the generated sources", required = false)
}
override val pluginId: String = ANNOTATION_PROCESSING_COMPILER_PLUGIN_ID
override val pluginOptions: Collection<CliOption> =
listOf(SOURCE_OUTPUT_DIR_OPTION, ANNOTATION_PROCESSOR_CLASSPATH_OPTION, APT_OPTIONS_OPTION,
CLASS_OUTPUT_DIR_OPTION, VERBOSE_MODE_OPTION, STUBS_OUTPUT_DIR_OPTION, APT_ONLY_OPTION, USE_LIGHT_ANALYSIS_OPTION)
CLASS_OUTPUT_DIR_OPTION, VERBOSE_MODE_OPTION, STUBS_OUTPUT_DIR_OPTION, APT_ONLY_OPTION,
USE_LIGHT_ANALYSIS_OPTION, CORRECT_ERROR_TYPES_OPTION)
override fun processOption(option: CliOption, value: String, configuration: CompilerConfiguration) {
when (option) {
@@ -127,6 +134,7 @@ class Kapt3CommandLineProcessor : CommandLineProcessor {
VERBOSE_MODE_OPTION -> configuration.put(Kapt3ConfigurationKeys.VERBOSE_MODE, value)
APT_ONLY_OPTION -> configuration.put(Kapt3ConfigurationKeys.APT_ONLY, value)
USE_LIGHT_ANALYSIS_OPTION -> configuration.put(Kapt3ConfigurationKeys.USE_LIGHT_ANALYSIS, value)
CORRECT_ERROR_TYPES_OPTION -> configuration.put(Kapt3ConfigurationKeys.CORRECT_ERROR_TYPES, value)
else -> throw CliOptionProcessingException("Unknown option: ${option.name}")
}
}
@@ -177,12 +185,15 @@ class Kapt3ComponentRegistrar : ComponentRegistrar {
val javaSourceRoots = contentRoots.filterIsInstance<JavaSourceRoot>().map { it.file }
val useLightAnalysis = configuration.get(Kapt3ConfigurationKeys.USE_LIGHT_ANALYSIS) == "true"
val correctErrorTypes = configuration.get(Kapt3ConfigurationKeys.CORRECT_ERROR_TYPES) == "true"
Extensions.getRootArea().getExtensionPoint(DefaultErrorMessages.Extension.EP_NAME).registerExtension(DefaultErrorMessagesKapt3())
if (isVerbose) {
logger.info("Kapt3 is enabled.")
logger.info("Do annotation processing only: $isAptOnly")
logger.info("Use light analysis: $useLightAnalysis")
logger.info("Correct error types: $correctErrorTypes")
logger.info("Source output directory: $sourcesOutputDir")
logger.info("Classes output directory: $classFilesOutputDir")
logger.info("Stubs output directory: $stubsOutputDir")
@@ -196,7 +207,7 @@ class Kapt3ComponentRegistrar : ComponentRegistrar {
val kapt3AnalysisCompletedHandlerExtension = ClasspathBasedKapt3Extension(
compileClasspath, apClasspath, javaSourceRoots, sourcesOutputDir, classFilesOutputDir,
stubsOutputDir, incrementalDataOutputDir, apOptions,
isAptOnly, useLightAnalysis, System.currentTimeMillis(), logger)
isAptOnly, useLightAnalysis, correctErrorTypes, System.currentTimeMillis(), logger)
AnalysisHandlerExtension.registerExtension(project, kapt3AnalysisCompletedHandlerExtension)
}
@@ -45,7 +45,8 @@ import com.sun.tools.javac.util.List as JavacList
class ClassFileToSourceStubConverter(
val kaptContext: KaptContext,
val typeMapper: KotlinTypeMapper,
val generateNonExistentClass: Boolean
val generateNonExistentClass: Boolean,
val correctErrorTypes: Boolean
) {
private companion object {
private val VISIBILITY_MODIFIERS = (Opcodes.ACC_PUBLIC or Opcodes.ACC_PRIVATE or Opcodes.ACC_PROTECTED).toLong()
@@ -441,6 +442,10 @@ class ClassFileToSourceStubConverter(
ktTypeProvider: () -> KtTypeReference?,
ifNonError: () -> T
): T {
if (!correctErrorTypes) {
return ifNonError()
}
if (type?.containsErrorTypes() ?: false) {
val ktType = ktTypeProvider()
if (ktType != null) {
@@ -161,7 +161,8 @@ abstract class AbstractKotlinKapt3IntegrationTest : CodegenTestCase() {
stubsOutputDir: File,
incrementalDataOutputDir: File
) : AbstractKapt3Extension(PathUtil.getJdkClassesRoots(), emptyList(), javaSourceRoots, outputDir, outputDir,
stubsOutputDir, incrementalDataOutputDir, options, true, System.currentTimeMillis(), KaptLogger(true)
stubsOutputDir, incrementalDataOutputDir, options, true, System.currentTimeMillis(),
KaptLogger(true), correctErrorTypes = true
) {
internal var savedStubs: String? = null
internal var savedBindings: Map<String, KaptJavaFileObject>? = null
@@ -68,8 +68,13 @@ abstract class AbstractKotlinKapt3Test : CodegenTestCase() {
}
}
protected fun convert(kaptRunner: KaptContext, typeMapper: KotlinTypeMapper, generateNonExistentClass: Boolean): JavacList<JCCompilationUnit> {
val converter = ClassFileToSourceStubConverter(kaptRunner, typeMapper, generateNonExistentClass)
protected fun convert(
kaptRunner: KaptContext,
typeMapper: KotlinTypeMapper,
generateNonExistentClass: Boolean,
correctErrorTypes: Boolean
): JavacList<JCCompilationUnit> {
val converter = ClassFileToSourceStubConverter(kaptRunner, typeMapper, generateNonExistentClass, correctErrorTypes)
return converter.convert()
}
@@ -85,9 +90,10 @@ abstract class AbstractClassFileToSourceStubConverterTest : AbstractKotlinKapt3T
fun isOptionSet(name: String) = wholeFile.useLines { lines -> lines.any { it.trim() == "// $name" } }
val generateNonExistentClass = isOptionSet("NON_EXISTENT_CLASS")
val correctErrorTypes = isOptionSet("CORRECT_ERROR_TYPES")
val validate = !isOptionSet("NO_VALIDATION")
val javaFiles = convert(kaptRunner, typeMapper, generateNonExistentClass)
val javaFiles = convert(kaptRunner, typeMapper, generateNonExistentClass, correctErrorTypes)
if (validate) kaptRunner.compiler.enterTrees(javaFiles)
@@ -104,7 +110,7 @@ abstract class AbstractClassFileToSourceStubConverterTest : AbstractKotlinKapt3T
abstract class AbstractKotlinKaptContextTest : AbstractKotlinKapt3Test() {
override fun check(kaptRunner: KaptContext, typeMapper: KotlinTypeMapper, txtFile: File, wholeFile: File) {
val compilationUnits = convert(kaptRunner, typeMapper, generateNonExistentClass = false)
val compilationUnits = convert(kaptRunner, typeMapper, generateNonExistentClass = false, correctErrorTypes = true)
val sourceOutputDir = Files.createTempDirectory("kaptRunner").toFile()
try {
kaptRunner.doAnnotationProcessing(emptyList(), listOf(JavaKaptContextTest.simpleProcessor()),
@@ -204,6 +204,12 @@ public class ClassFileToSourceStubConverterTestGenerated extends AbstractClassFi
doTest(fileName);
}
@TestMetadata("nonExistentClassWIthoutCorrection.kt")
public void testNonExistentClassWIthoutCorrection() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("plugins/kapt3/testData/converter/nonExistentClassWIthoutCorrection.kt");
doTest(fileName);
}
@TestMetadata("primitiveTypes.kt")
public void testPrimitiveTypes() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("plugins/kapt3/testData/converter/primitiveTypes.kt");
+1
View File
@@ -1,3 +1,4 @@
// CORRECT_ERROR_TYPES
// NON_EXISTENT_CLASS
// NO_VALIDATION
@@ -1,3 +1,4 @@
// CORRECT_ERROR_TYPES
// NON_EXISTENT_CLASS
// NO_VALIDATION
@@ -0,0 +1,13 @@
// NON_EXISTENT_CLASS
// NO_VALIDATION
@Suppress("UNRESOLVED_REFERENCE")
object NonExistentType {
val a: ABCDEF? = null
val b: List<ABCDEF>? = null
val c: (ABCDEF) -> Unit = { f -> }
val d: ABCDEF<String, (List<ABCDEF>) -> Unit>? = null
fun a(a: ABCDEF, s: String): ABCDEF {}
fun b(s: String): ABCDEF {}
}
@@ -0,0 +1,56 @@
@kotlin.Suppress(names = {"UNRESOLVED_REFERENCE"})
public final class NonExistentType {
@org.jetbrains.annotations.Nullable()
private static final error.NonExistentClass a = null;
@org.jetbrains.annotations.Nullable()
private static final java.util.List<error.NonExistentClass> b = null;
@org.jetbrains.annotations.NotNull()
private static final kotlin.jvm.functions.Function1<error.NonExistentClass, kotlin.Unit> c = null;
@org.jetbrains.annotations.Nullable()
private static final error.NonExistentClass d = null;
public static final NonExistentType INSTANCE = null;
@org.jetbrains.annotations.Nullable()
public final error.NonExistentClass getA() {
return null;
}
@org.jetbrains.annotations.Nullable()
public final java.util.List<error.NonExistentClass> getB() {
return null;
}
@org.jetbrains.annotations.NotNull()
public final kotlin.jvm.functions.Function1<error.NonExistentClass, kotlin.Unit> getC() {
return null;
}
@org.jetbrains.annotations.Nullable()
public final error.NonExistentClass getD() {
return null;
}
@org.jetbrains.annotations.NotNull()
public final error.NonExistentClass a(@org.jetbrains.annotations.NotNull()
error.NonExistentClass a, @org.jetbrains.annotations.NotNull()
java.lang.String s) {
return null;
}
@org.jetbrains.annotations.NotNull()
public final error.NonExistentClass b(@org.jetbrains.annotations.NotNull()
java.lang.String s) {
return null;
}
private NonExistentType() {
super();
}
}
////////////////////
package error;
public final class NonExistentClass {
}