Kapt lite
diff --git a/.idea/dictionaries/yan.xml b/.idea/dictionaries/yan.xml
index b6690ed..f39332f 100644
--- a/.idea/dictionaries/yan.xml
+++ b/.idea/dictionaries/yan.xml
@@ -7,13 +7,18 @@
<w>hacky</w>
<w>impls</w>
<w>kapt</w>
+ <w>kaptlite</w>
<w>kotlinc</w>
<w>parceler</w>
+ <w>renderable</w>
<w>repl</w>
+ <w>subplugin</w>
+ <w>testdata</w>
<w>uast</w>
<w>unbox</w>
<w>unboxed</w>
<w>unmute</w>
+ <w>xplugin</w>
</words>
</dictionary>
</component>
\ No newline at end of file
diff --git a/build-common/src/org/jetbrains/kotlin/incremental/JavaClassesTrackerImpl.kt b/build-common/src/org/jetbrains/kotlin/incremental/JavaClassesTrackerImpl.kt
index 4e42947..62df046 100644
--- a/build-common/src/org/jetbrains/kotlin/incremental/JavaClassesTrackerImpl.kt
+++ b/build-common/src/org/jetbrains/kotlin/incremental/JavaClassesTrackerImpl.kt
@@ -61,7 +61,12 @@
classDescriptors.add(classDescriptor)
}
- override fun onCompletedAnalysis(module: ModuleDescriptor) {
+ override fun onCompletedAnalysis(module: ModuleDescriptor, discardAnalysisResults: Boolean) {
+ if (discardAnalysisResults) {
+ classDescriptors.clear()
+ return
+ }
+
for (classId in cache.getObsoleteJavaClasses() + untrackedJavaClasses) {
// Just force the loading obsolete classes
// We assume here that whenever an LazyJavaClassDescriptor instances is created
diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassBuilderMode.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassBuilderMode.java
index 01fab5e..4f72322 100644
--- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassBuilderMode.java
+++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ClassBuilderMode.java
@@ -23,6 +23,8 @@
public final boolean generateMetadata;
public final boolean generateSourceRetentionAnnotations;
public final boolean generateMultiFileFacadePartClasses;
+ public final boolean generateAnnotationForJvmOverloads;
+ public final boolean replaceAnonymousTypesInSignatures;
public final boolean mightBeIncorrectCode;
private ClassBuilderMode(
@@ -30,12 +32,16 @@
boolean generateMetadata,
boolean generateSourceRetentionAnnotations,
boolean generateMultiFileFacadePartClasses,
+ boolean generateAnnotationForJvmOverloads,
+ boolean replaceAnonymousTypesInSignatures,
boolean mightBeIncorrectCode
) {
this.generateBodies = generateBodies;
this.generateMetadata = generateMetadata;
this.generateSourceRetentionAnnotations = generateSourceRetentionAnnotations;
this.generateMultiFileFacadePartClasses = generateMultiFileFacadePartClasses;
+ this.generateAnnotationForJvmOverloads = generateAnnotationForJvmOverloads;
+ this.replaceAnonymousTypesInSignatures = replaceAnonymousTypesInSignatures;
this.mightBeIncorrectCode = mightBeIncorrectCode;
}
@@ -47,6 +53,8 @@
/* metadata = */ true,
/* sourceRetention = */ false,
/* generateMultiFileFacadePartClasses = */ true,
+ /* generateAnnotationForJvmOverloads = */ false,
+ /* replaceAnonymousTypesInSignatures = */ false,
/* mightBeIncorrectCode = */ false);
/**
@@ -57,6 +65,8 @@
/* metadata = */ true,
/* sourceRetention = */ false,
/* generateMultiFileFacadePartClasses = */ true,
+ /* generateAnnotationForJvmOverloads = */ false,
+ /* replaceAnonymousTypesInSignatures = */ false,
/* mightBeIncorrectCode = */ false);
/**
@@ -67,6 +77,8 @@
/* metadata = */ false,
/* sourceRetention = */ true,
/* generateMultiFileFacadePartClasses = */ false,
+ /* generateAnnotationForJvmOverloads = */ false,
+ /* replaceAnonymousTypesInSignatures = */ false,
/* mightBeIncorrectCode = */ true);
/**
@@ -77,6 +89,17 @@
/* metadata = */ true,
/* sourceRetention = */ true,
/* generateMultiFileFacadePartClasses = */ true,
+ /* generateAnnotationForJvmOverloads = */ true,
+ /* replaceAnonymousTypesInSignatures = */ false,
+ /* mightBeIncorrectCode = */ true);
+
+ public final static ClassBuilderMode KAPT_LITE = new ClassBuilderMode(
+ /* bodies = */ false,
+ /* metadata = */ true,
+ /* sourceRetention = */ true,
+ /* generateMultiFileFacadePartClasses = */ true,
+ /* generateAnnotationForJvmOverloads = */ false,
+ /* replaceAnonymousTypesInSignatures = */ true,
/* mightBeIncorrectCode = */ true);
private final static ClassBuilderMode LIGHT_ANALYSIS_FOR_TESTS = new ClassBuilderMode(
@@ -84,6 +107,8 @@
/* metadata = */ true,
/* sourceRetention = */ false,
/* generateMultiFileFacadePartClasses = */ true,
+ /* generateAnnotationForJvmOverloads = */ false,
+ /* replaceAnonymousTypesInSignatures = */ false,
/* mightBeIncorrectCode = */ true);
@TestOnly
diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/DefaultParameterValueSubstitutor.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/DefaultParameterValueSubstitutor.kt
index d05dc98..5c279ee 100644
--- a/compiler/backend/src/org/jetbrains/kotlin/codegen/DefaultParameterValueSubstitutor.kt
+++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/DefaultParameterValueSubstitutor.kt
@@ -152,7 +152,7 @@
AnnotationCodegen.forMethod(mv, memberCodegen, state).genAnnotations(functionDescriptor, signature.returnType)
- if (state.classBuilderMode == ClassBuilderMode.KAPT3) {
+ if (state.classBuilderMode.generateAnnotationForJvmOverloads) {
mv.visitAnnotation(ANNOTATION_TYPE_DESCRIPTOR_FOR_JVM_OVERLOADS_GENERATED_METHODS, false)
}
diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java
index a6651f1..8153792 100644
--- a/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java
+++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/PropertyCodegen.java
@@ -386,7 +386,7 @@
}
KotlinType kotlinType = isDelegate ? getDelegateTypeForProperty(propertyDescriptor, bindingContext) : propertyDescriptor.getType();
- Type type = typeMapper.mapType(kotlinType);
+ Type type = typeMapper.mapType(typeMapper.patchAnonymousTypeIfNeeded(kotlinType));
ClassBuilder builder = v;
diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.kt
index 35f2245..c74c4f0 100644
--- a/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.kt
+++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/state/KotlinTypeMapper.kt
@@ -72,6 +72,7 @@
import org.jetbrains.kotlin.types.checker.convertVariance
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.*
import org.jetbrains.kotlin.types.model.*
+import org.jetbrains.kotlin.types.typeUtil.builtIns
import org.jetbrains.kotlin.util.OperatorNameConventions
import org.jetbrains.org.objectweb.asm.Opcodes.*
import org.jetbrains.org.objectweb.asm.Type
@@ -195,19 +196,72 @@
}
private fun mapReturnType(descriptor: CallableDescriptor, sw: JvmSignatureWriter?, returnType: KotlinType): Type {
+ val patchedType = patchAnonymousTypeIfNeeded(returnType)
+
val isAnnotationMethod = isAnnotationClass(descriptor.containingDeclaration)
if (sw == null || sw.skipGenericSignature()) {
- return mapType(returnType, sw, TypeMappingMode.getModeForReturnTypeNoGeneric(isAnnotationMethod))
+ return mapType(patchedType, sw, TypeMappingMode.getModeForReturnTypeNoGeneric(isAnnotationMethod))
}
- val typeMappingModeFromAnnotation = extractTypeMappingModeFromAnnotation(descriptor, returnType, isAnnotationMethod)
+ val typeMappingModeFromAnnotation = extractTypeMappingModeFromAnnotation(descriptor, patchedType, isAnnotationMethod)
if (typeMappingModeFromAnnotation != null) {
- return mapType(returnType, sw, typeMappingModeFromAnnotation)
+ return mapType(patchedType, sw, typeMappingModeFromAnnotation)
}
- val mappingMode = TypeMappingMode.getOptimalModeForReturnType(returnType, isAnnotationMethod)
+ val mappingMode = TypeMappingMode.getOptimalModeForReturnType(patchedType, isAnnotationMethod)
- return mapType(returnType, sw, mappingMode)
+ return mapType(patchedType, sw, mappingMode)
+ }
+
+ fun patchAnonymousTypeIfNeeded(type: KotlinType): KotlinType {
+ if (!classBuilderMode.replaceAnonymousTypesInSignatures) {
+ return type
+ }
+
+ val declaration = type.constructor.declarationDescriptor ?: return type
+
+ if (KotlinBuiltIns.isArray(type)) {
+ val elementTypeProjection = type.arguments.singleOrNull()
+ if (elementTypeProjection != null && !elementTypeProjection.isStarProjection) {
+ return type.builtIns.getArrayType(
+ elementTypeProjection.projectionKind,
+ patchAnonymousTypeIfNeeded(elementTypeProjection.type)
+ )
+ }
+ }
+
+ if (isAnonymousObject(declaration) || isLocal(declaration)) {
+ return patchAnonymousTypeIfNeeded(chooseBestNonAnonymousSuperType(type))
+ }
+
+ if (type.arguments.isEmpty()) {
+ return type
+ }
+
+ val arguments = type.arguments.map { typeArg ->
+ if (typeArg.isStarProjection)
+ return@map typeArg
+
+ TypeProjectionImpl(typeArg.projectionKind, patchAnonymousTypeIfNeeded(typeArg.type))
+ }
+
+ return type.replace(newArguments = arguments)
+ }
+
+ private fun chooseBestNonAnonymousSuperType(type: KotlinType): KotlinType {
+ // It doesn't really matter what particular type there will be. It just needs to be stable enough.
+
+ val sortedSuperTypes = type.constructor.supertypes
+ .sortedBy { it.constructor.declarationDescriptor?.name?.asString() ?: "" }
+
+ for (superType in sortedSuperTypes) {
+ val classDescriptor = superType.constructor.declarationDescriptor
+ if (classDescriptor is ClassDescriptor && classDescriptor.kind != ClassKind.INTERFACE) {
+ return superType
+ }
+ }
+
+ return sortedSuperTypes.firstOrNull() ?: type.builtIns.anyType
}
fun mapSupertype(type: KotlinType, signatureVisitor: JvmSignatureWriter?): Type {
diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/JavaClassesTracker.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/JavaClassesTracker.kt
index ba6c0ee..765496c 100644
--- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/JavaClassesTracker.kt
+++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/JavaClassesTracker.kt
@@ -22,10 +22,10 @@
interface JavaClassesTracker {
fun reportClass(classDescriptor: JavaClassDescriptor)
- fun onCompletedAnalysis(module: ModuleDescriptor)
+ fun onCompletedAnalysis(module: ModuleDescriptor, discardAnalysisResults: Boolean)
object Default : JavaClassesTracker {
override fun reportClass(classDescriptor: JavaClassDescriptor) {}
- override fun onCompletedAnalysis(module: ModuleDescriptor) {}
+ override fun onCompletedAnalysis(module: ModuleDescriptor, discardAnalysisResults: Boolean) {}
}
}
diff --git a/generators/build.gradle.kts b/generators/build.gradle.kts
index b5da3a2..066274e 100644
--- a/generators/build.gradle.kts
+++ b/generators/build.gradle.kts
@@ -25,6 +25,7 @@
compile(projectTests(":plugins:android-extensions-ide"))
compile(projectTests(":kotlin-annotation-processing"))
compile(projectTests(":kotlin-annotation-processing-cli"))
+ compile(projectTests(":kapt-lite:kapt-lite-compiler-plugin"))
compile(projectTests(":kotlin-allopen-compiler-plugin"))
compile(projectTests(":kotlin-noarg-compiler-plugin"))
compile(projectTests(":kotlin-sam-with-receiver-compiler-plugin"))
diff --git a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt
index 1fd77a3..5d93e2d 100644
--- a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt
+++ b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.generators.tests
+import org.jetbrains.kaptlite.test.AbstractStubGeneratorTest
import org.jetbrains.kotlin.AbstractDataFlowValueRenderingTest
import org.jetbrains.kotlin.addImport.AbstractAddImportTest
import org.jetbrains.kotlin.allopen.AbstractBytecodeListingTestForAllOpen
@@ -1224,6 +1225,12 @@
}
}
+ testGroup("plugins/kapt-lite/kapt-lite-compiler-plugin/test", "plugins/kapt-lite/kapt-lite-compiler-plugin/testData") {
+ testClass<AbstractStubGeneratorTest>() {
+ model("stubs")
+ }
+ }
+
testGroup("plugins/kapt3/kapt3-compiler/test", "plugins/kapt3/kapt3-compiler/testData") {
testClass<AbstractClassFileToSourceStubConverterTest> {
model("converter")
diff --git a/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinGradleSubplugin.kt b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinGradleSubplugin.kt
index b56d24b..bfedc49 100644
--- a/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinGradleSubplugin.kt
+++ b/libraries/tools/kotlin-gradle-plugin-api/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinGradleSubplugin.kt
@@ -29,17 +29,19 @@
class FilesSubpluginOption(
key: String,
- val files: Iterable<File>,
+ val files: Lazy<Iterable<File>>,
val kind: FilesOptionKind = FilesOptionKind.INTERNAL,
- lazyValue: Lazy<String> = lazy { files.joinToString(File.pathSeparator) { it.canonicalPath } }
+ lazyValue: Lazy<String> = lazy { files.value.joinToString(File.pathSeparator) { it.canonicalPath } }
) : SubpluginOption(key, lazyValue) {
+ constructor(key: String, files: Iterable<File>) : this(key, lazyOf(files))
+
constructor(
key: String,
files: List<File>,
kind: FilesOptionKind = FilesOptionKind.INTERNAL,
value: String? = null
- ) : this(key, files, kind, lazy { value ?: files.joinToString(File.pathSeparator) { it.canonicalPath } })
+ ) : this(key, lazyOf(files), kind, lazy { value ?: files.joinToString(File.pathSeparator) { it.canonicalPath } })
}
class CompositeSubpluginOption(
diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kaptlite/KaptLiteGradleSubplugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kaptlite/KaptLiteGradleSubplugin.kt
new file mode 100644
index 0000000..5695707
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/kaptlite/KaptLiteGradleSubplugin.kt
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kotlin.gradle.internal.kaptlite
+
+import org.gradle.api.Plugin
+import org.gradle.api.Project
+import org.gradle.api.tasks.compile.AbstractCompile
+import org.gradle.api.tasks.compile.JavaCompile
+import org.jetbrains.kotlin.gradle.dsl.KotlinCommonOptions
+import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin
+import org.jetbrains.kotlin.gradle.plugin.*
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
+import java.io.File
+
+class KaptLiteGradleSubplugin : Plugin<Project> {
+ companion object {
+ fun isEnabled(project: Project) = project.plugins.findPlugin(KaptLiteGradleSubplugin::class.java) != null
+ }
+
+ override fun apply(project: Project) {
+ KaptLiteKotlinGradleSubplugin().run {
+ project.configurations.create(KaptLiteKotlinGradleSubplugin.JAVAC_PLUGIN_CONFIGURATION_NAME).apply {
+ val kotlinPluginVersion = project.getKotlinPluginVersion()
+ if (kotlinPluginVersion != null) {
+ dependencies.add(project.dependencies.create("org.jetbrains.kotlin:kapt-lite-javac-plugin:$kotlinPluginVersion"))
+ } else {
+ project.logger.error("Kotlin plugin should be enabled before 'kotlin-kapt-lite'")
+ }
+ }
+ }
+ }
+}
+
+class KaptLiteKotlinGradleSubplugin : KotlinGradleSubplugin<AbstractCompile> {
+ companion object {
+ const val JAVAC_PLUGIN_CONFIGURATION_NAME = "kotlinKaptLiteJavacPluginClasspath"
+ }
+
+ override fun isApplicable(project: Project, task: AbstractCompile): Boolean {
+ return task is KotlinCompile && KaptLiteGradleSubplugin.isEnabled(project)
+ }
+
+ override fun apply(
+ project: Project,
+ kotlinCompile: AbstractCompile,
+ javaCompile: AbstractCompile?,
+ variantData: Any?,
+ androidProjectHandler: Any?,
+ kotlinCompilation: KotlinCompilation<KotlinCommonOptions>?
+ ): List<SubpluginOption> {
+ fun reportError(message: String) = project.logger.error(project.path + ": " + message)
+
+ val baseName = getBaseName(kotlinCompile)
+
+ if (Kapt3GradleSubplugin.isEnabled(project)) {
+ reportError("'kotlin-kapt' and 'kotlin-kapt-lite' plugins can not work together. Remove one.")
+ return emptyList()
+ }
+
+ if (javaCompile !is JavaCompile) {
+ reportError("Java compile task is absent or incompatible. Kapt-lite requires 'JavaCompile' in order to work properly.")
+ return emptyList()
+ }
+
+ val kotlinPluginVersion = project.getKotlinPluginVersion()
+ if (kotlinPluginVersion == null) {
+ reportError("Kotlin plugin is not enabled.")
+ return emptyList()
+ }
+
+ val javacProcessorDependencies = javaCompile.options.annotationProcessorPath
+ if (javacProcessorDependencies == null) {
+ reportError("Annotation processor dependencies are not set.")
+ return emptyList()
+ }
+
+ run /* Register Javac plugin */ {
+ val javacPluginConfiguration = project.configurations.getByName(JAVAC_PLUGIN_CONFIGURATION_NAME)
+ javaCompile.options.annotationProcessorPath = javacProcessorDependencies + javacPluginConfiguration
+ javaCompile.options.compilerArgs.add("-Xplugin:KaptJavacPlugin")
+ }
+
+ val stubsOutputDir = getKaptStubsOutputPath(project, baseName)
+ javaCompile.source(stubsOutputDir)
+
+ return listOf(
+ FilesSubpluginOption("stubs", listOf(stubsOutputDir))
+ )
+ }
+
+ private fun getKaptStubsOutputPath(project: Project, baseName: String): File {
+ val dirNameForSourceSet = if (baseName.isEmpty()) "main" else baseName
+ return File(project.buildDir, "tmp/kaptLite/stubs/$dirNameForSourceSet")
+ }
+
+ private fun getBaseName(kotlinCompile: AbstractCompile): String {
+ val name = kotlinCompile.name
+ assert(name.startsWith("compile") && name.endsWith("Kotlin"))
+ return name.drop("compile".length).dropLast("Kotlin".length).decapitalize()
+ }
+
+ override fun getCompilerPluginId(): String = "org.jetbrains.kotlin.kaptlite"
+
+ override fun getPluginArtifact(): SubpluginArtifact {
+ return SubpluginArtifact("org.jetbrains.kotlin", "kapt-lite-compiler-plugin-embeddable")
+ }
+}
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/kotlin-kapt-lite.properties b/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/kotlin-kapt-lite.properties
new file mode 100644
index 0000000..7cbc8fe
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/kotlin-kapt-lite.properties
@@ -0,0 +1 @@
+implementation-class=org.jetbrains.kotlin.gradle.internal.kaptlite.KaptLiteGradleSubplugin
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.jetbrains.kotlin.kaptlite.properties b/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.jetbrains.kotlin.kaptlite.properties
new file mode 100644
index 0000000..7cbc8fe
--- /dev/null
+++ b/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.jetbrains.kotlin.kaptlite.properties
@@ -0,0 +1 @@
+implementation-class=org.jetbrains.kotlin.gradle.internal.kaptlite.KaptLiteGradleSubplugin
\ No newline at end of file
diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/services/org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin b/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/services/org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin
index e6839bb..f53be8e 100644
--- a/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/services/org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin
+++ b/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/services/org.jetbrains.kotlin.gradle.plugin.KotlinGradleSubplugin
@@ -1,3 +1,4 @@
org.jetbrains.kotlin.gradle.internal.AndroidSubplugin
org.jetbrains.kotlin.gradle.internal.Kapt3KotlinGradleSubplugin
+org.jetbrains.kotlin.gradle.internal.kaptlite.KaptLiteKotlinGradleSubplugin
org.jetbrains.kotlin.gradle.scripting.internal.ScriptingKotlinGradleSubplugin
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/build.gradle.kts b/plugins/kapt-lite/kapt-lite-compiler-plugin/build.gradle.kts
new file mode 100644
index 0000000..ef86814
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/build.gradle.kts
@@ -0,0 +1,42 @@
+description = "Lightweight annotation processing support – Kotlin compiler plugin"
+
+plugins {
+ kotlin("jvm")
+ id("jps-compatible")
+}
+
+dependencies {
+ compileOnly(project(":compiler:plugin-api"))
+ compileOnly(project(":compiler:cli"))
+ compileOnly(project(":compiler:frontend"))
+ compileOnly(project(":compiler:backend"))
+
+ compileOnly(project(":kapt-lite:kapt-lite-kdoc"))
+ embedded(project(":kapt-lite:kapt-lite-kdoc")) { isTransitive = false }
+
+ compileOnly(project(":kapt-lite:kapt-lite-signature-parser"))
+ embedded(project(":kapt-lite:kapt-lite-signature-parser")) { isTransitive = false }
+
+ compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
+ compileOnly(intellijDep()) { includeJars("asm-all", rootProject = rootProject) }
+
+ testCompile(toolsJar())
+ testCompile(commonDep("junit:junit"))
+ testCompile(projectTests(":compiler:tests-common"))
+ testCompile(intellijCoreDep()) { includeJars("intellij-core") }
+}
+
+sourceSets {
+ "main" { projectDefault() }
+ "test" { projectDefault() }
+}
+
+runtimeJar()
+sourcesJar()
+javadocJar()
+
+testsJar {}
+
+projectTest {
+ workingDir = rootDir
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor b/plugins/kapt-lite/kapt-lite-compiler-plugin/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
new file mode 100644
index 0000000..d9a838c
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
@@ -0,0 +1 @@
+org.jetbrains.kaptlite.KaptLiteCommandLineProcessor
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar b/plugins/kapt-lite/kapt-lite-compiler-plugin/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
new file mode 100644
index 0000000..67c1d62
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
@@ -0,0 +1 @@
+org.jetbrains.kaptlite.KaptLiteComponentRegistrar
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/KaptLiteAnalysisHandlerExtension.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/KaptLiteAnalysisHandlerExtension.kt
new file mode 100644
index 0000000..9fceda9
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/KaptLiteAnalysisHandlerExtension.kt
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kaptlite
+
+import com.intellij.openapi.project.Project
+import org.jetbrains.kaptlite.diagnostic.DefaultErrorMessagesKaptLite
+import org.jetbrains.kaptlite.diagnostic.ErrorsKaptLite
+import org.jetbrains.kaptlite.stubs.GeneratorOutput
+import org.jetbrains.kaptlite.stubs.StubGenerator
+import org.jetbrains.kaptlite.stubs.util.CodeScope
+import org.jetbrains.kotlin.analyzer.AnalysisResult
+import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
+import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
+import org.jetbrains.kotlin.cli.common.messages.MessageCollector
+import org.jetbrains.kotlin.cli.common.messages.OutputMessageUtil
+import org.jetbrains.kotlin.codegen.ClassBuilderMode
+import org.jetbrains.kotlin.codegen.CompilationErrorHandler
+import org.jetbrains.kotlin.codegen.KotlinCodegenFacade
+import org.jetbrains.kotlin.codegen.OriginCollectingClassBuilderFactory
+import org.jetbrains.kotlin.codegen.state.GenerationState
+import org.jetbrains.kotlin.config.CommonConfigurationKeys
+import org.jetbrains.kotlin.config.CompilerConfiguration
+import org.jetbrains.kotlin.descriptors.ModuleDescriptor
+import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
+import org.jetbrains.kotlin.diagnostics.reportFromPlugin
+import org.jetbrains.kotlin.modules.TargetId
+import org.jetbrains.kotlin.psi.KtFile
+import org.jetbrains.kotlin.resolve.BindingContext
+import org.jetbrains.kotlin.resolve.BindingTrace
+import org.jetbrains.kotlin.resolve.DelegatingBindingTrace
+import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension
+import java.io.File
+import java.io.PrintStream
+import kotlin.system.measureTimeMillis
+
+class KaptLiteAnalysisHandlerExtension(
+ configuration: CompilerConfiguration,
+ private val options: KaptLiteOptions,
+ override val messageCollector: MessageCollector
+) : AbstractKaptLiteAnalysisHandlerExtension(configuration) {
+ override fun getOutput(state: GenerationState): GeneratorOutput = RealFileGeneratorOutput(state, options.stubsOutputDir)
+
+ private class RealFileGeneratorOutput(private val state: GenerationState, private val outputDir: File) : GeneratorOutput {
+ private val messageCollector = state.configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE)
+
+ override fun produce(internalName: String, path: String, block: CodeScope.() -> Unit) {
+ val file = File(outputDir, path)
+ file.parentFile.mkdirs()
+ file.outputStream().use { os ->
+ val scope = CodeScope(PrintStream(os))
+ scope.block()
+ }
+
+ if (state.configuration.getBoolean(CommonConfigurationKeys.REPORT_OUTPUT_FILES)) {
+ val sourceFiles = state.factory["$internalName.class"]?.sourceFiles ?: emptyList()
+ if (sourceFiles.isNotEmpty()) {
+ messageCollector.report(CompilerMessageSeverity.OUTPUT, OutputMessageUtil.formatOutputMessage(sourceFiles, file))
+ }
+ }
+ }
+ }
+}
+
+abstract class AbstractKaptLiteAnalysisHandlerExtension(private val configuration: CompilerConfiguration) : AnalysisHandlerExtension {
+ abstract val messageCollector: MessageCollector
+
+ abstract fun getOutput(state: GenerationState): GeneratorOutput
+
+ override fun analysisCompleted(
+ project: Project, module: ModuleDescriptor,
+ bindingTrace: BindingTrace, files: Collection<KtFile>
+ ): AnalysisResult? {
+ if (DiagnosticUtils.hasError(bindingTrace.bindingContext.diagnostics)) {
+ return AnalysisResult.compilationError(bindingTrace.bindingContext)
+ }
+
+ if (!generateStubs(project, module, bindingTrace.bindingContext, files.toList())) {
+ return AnalysisResult.compilationError(bindingTrace.bindingContext)
+ }
+ return null
+ }
+
+ private fun generateStubs(
+ project: Project,
+ module: ModuleDescriptor,
+ bindingContext: BindingContext,
+ files: List<KtFile>
+ ): Boolean {
+ val builderFactory = OriginCollectingClassBuilderFactory(ClassBuilderMode.KAPT_LITE)
+
+ val moduleName = configuration[CommonConfigurationKeys.MODULE_NAME] ?: module.name.asString()
+ val targetId = TargetId(moduleName, "java-production")
+
+ val generationState = GenerationState.Builder(project, builderFactory, module, bindingContext, files, configuration)
+ .targetId(targetId)
+ .isIrBackend(false)
+ .build()
+
+ val diagnosticsTrace = DelegatingBindingTrace(bindingContext, "For kapt-lite diagnostics in ${this::class.java}", false)
+
+ try {
+ KotlinCodegenFacade.compileCorrectFiles(generationState, CompilationErrorHandler.THROW_EXCEPTION)
+
+ val time = measureTimeMillis {
+ val compiledClasses = builderFactory.compiledClasses
+ val origins = builderFactory.origins
+ StubGenerator(diagnosticsTrace, compiledClasses, origins, generationState).use { stubGenerator ->
+ stubGenerator.generate(getOutput(generationState))
+ }
+ }
+
+ diagnosticsTrace.reportFromPlugin(ErrorsKaptLite.TIME.on(files[0], "${time}ms"), DefaultErrorMessagesKaptLite)
+ } finally {
+ generationState.destroy()
+ }
+
+ return !AnalyzerWithCompilerReport.Companion.reportDiagnostics(diagnosticsTrace.bindingContext.diagnostics, messageCollector)
+ }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/KaptLiteClassBuilderInterceptorExtension.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/KaptLiteClassBuilderInterceptorExtension.kt
new file mode 100644
index 0000000..90a468a
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/KaptLiteClassBuilderInterceptorExtension.kt
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kaptlite
+
+import com.intellij.psi.PsiElement
+import org.jetbrains.kotlin.codegen.ClassBuilder
+import org.jetbrains.kotlin.codegen.ClassBuilderFactory
+import org.jetbrains.kotlin.codegen.DelegatingClassBuilder
+import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension
+import org.jetbrains.kotlin.diagnostics.DiagnosticSink
+import org.jetbrains.kotlin.resolve.BindingContext
+import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
+import org.jetbrains.org.objectweb.asm.FieldVisitor
+import org.jetbrains.org.objectweb.asm.MethodVisitor
+
+typealias OriginConsumer = MutableMap<String, JvmDeclarationOrigin>
+
+class KaptLiteClassBuilderInterceptorExtension(private val originConsumer: OriginConsumer) : ClassBuilderInterceptorExtension {
+ override fun interceptClassBuilderFactory(
+ interceptedFactory: ClassBuilderFactory,
+ bindingContext: BindingContext,
+ diagnostics: DiagnosticSink
+ ): ClassBuilderFactory {
+ return KaptLiteClassBuilderFactory(interceptedFactory, originConsumer)
+ }
+}
+
+private class KaptLiteClassBuilderFactory(
+ private val delegateFactory: ClassBuilderFactory,
+ private val originConsumer: OriginConsumer
+) : ClassBuilderFactory {
+ override fun getClassBuilderMode() = delegateFactory.classBuilderMode
+
+ override fun newClassBuilder(origin: JvmDeclarationOrigin): ClassBuilder {
+ return KaptLiteClassBuilder(delegateFactory.newClassBuilder(origin), origin, originConsumer)
+ }
+
+ override fun asText(builder: ClassBuilder?): String? {
+ return delegateFactory.asText((builder as KaptLiteClassBuilder).delegateBuilder)
+ }
+
+ override fun asBytes(builder: ClassBuilder?): ByteArray? {
+ return delegateFactory.asBytes((builder as KaptLiteClassBuilder).delegateBuilder)
+ }
+
+ override fun close() {
+ delegateFactory.close()
+ }
+}
+
+private class KaptLiteClassBuilder(
+ val delegateBuilder: ClassBuilder,
+ private val origin: JvmDeclarationOrigin,
+ private val originConsumer: OriginConsumer
+) : DelegatingClassBuilder() {
+ override fun getDelegate() = delegateBuilder
+
+ private lateinit var className: String
+
+ override fun defineClass(
+ origin: PsiElement?,
+ version: Int,
+ access: Int,
+ name: String,
+ signature: String?,
+ superName: String,
+ interfaces: Array<out String>
+ ) {
+ className = name
+ originConsumer[name] = this.origin
+ super.defineClass(origin, version, access, name, signature, superName, interfaces)
+ }
+
+ override fun newField(
+ origin: JvmDeclarationOrigin,
+ access: Int,
+ name: String,
+ desc: String,
+ signature: String?,
+ value: Any?
+ ): FieldVisitor {
+ originConsumer["$className#$name"] = origin
+ return super.newField(origin, access, name, desc, signature, value)
+ }
+
+ override fun newMethod(
+ origin: JvmDeclarationOrigin,
+ access: Int,
+ name: String,
+ desc: String,
+ signature: String?,
+ exceptions: Array<out String>?
+ ): MethodVisitor {
+ originConsumer["$className#$name$desc"] = origin
+ return super.newMethod(origin, access, name, desc, signature, exceptions)
+ }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/KaptLiteCliOption.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/KaptLiteCliOption.kt
new file mode 100644
index 0000000..b60e84e
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/KaptLiteCliOption.kt
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kaptlite
+
+import org.jetbrains.kotlin.compiler.plugin.AbstractCliOption
+
+enum class KaptLiteCliOption(
+ override val optionName: String,
+ override val valueDescription: String,
+ override val description: String,
+ override val allowMultipleOccurrences: Boolean = false
+) : AbstractCliOption {
+ STUBS_OUTPUT_DIR("stubs", "<path>", "Output path for kapt stubs");
+
+ override val required: Boolean = false
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/KaptLiteOptions.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/KaptLiteOptions.kt
new file mode 100644
index 0000000..e878e00
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/KaptLiteOptions.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kaptlite
+
+import org.jetbrains.kotlin.config.CompilerConfigurationKey
+import java.io.File
+
+val KAPT_LITE_OPTIONS = CompilerConfigurationKey.create<KaptLiteOptions.Builder>("Kapt-lite options")
+
+class KaptLiteOptions(val stubsOutputDir: File) {
+ class Builder {
+ var stubsOutputDir: File? = null
+
+ fun build(): KaptLiteOptions? {
+ val stubsOutputDir = this.stubsOutputDir ?: return null
+ return KaptLiteOptions(stubsOutputDir)
+ }
+ }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/KaptLitePlugin.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/KaptLitePlugin.kt
new file mode 100644
index 0000000..a8beb00
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/KaptLitePlugin.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kaptlite
+
+import com.intellij.mock.MockProject
+import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
+import org.jetbrains.kotlin.cli.common.messages.MessageRenderer
+import org.jetbrains.kotlin.cli.common.messages.PrintingMessageCollector
+import org.jetbrains.kotlin.compiler.plugin.AbstractCliOption
+import org.jetbrains.kotlin.compiler.plugin.CliOptionProcessingException
+import org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
+import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
+import org.jetbrains.kotlin.config.CompilerConfiguration
+import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension
+import java.io.File
+
+class KaptLiteCommandLineProcessor : CommandLineProcessor {
+ override val pluginId: String
+ get() = "org.jetbrains.kotlin.kaptlite"
+
+ override val pluginOptions: Collection<AbstractCliOption>
+ get() = KaptLiteCliOption.values().asList()
+
+ override fun processOption(option: AbstractCliOption, value: String, configuration: CompilerConfiguration) {
+ if (option !is KaptLiteCliOption) {
+ throw CliOptionProcessingException("Unknown option: ${option.optionName}")
+ }
+
+ val options = configuration[KAPT_LITE_OPTIONS]
+ ?: KaptLiteOptions.Builder().also { configuration.put(KAPT_LITE_OPTIONS, it) }
+
+ when (option) {
+ KaptLiteCliOption.STUBS_OUTPUT_DIR -> {
+ options.stubsOutputDir = File(value)
+ }
+ }
+ }
+}
+
+class KaptLiteComponentRegistrar : ComponentRegistrar {
+ override fun registerProjectComponents(project: MockProject, configuration: CompilerConfiguration) {
+ val options = configuration[KAPT_LITE_OPTIONS]?.build() ?: return
+
+ val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
+ ?: PrintingMessageCollector(System.err, MessageRenderer.PLAIN_FULL_PATHS, false)
+
+ AnalysisHandlerExtension.registerExtension(project, KaptLiteAnalysisHandlerExtension(configuration, options, messageCollector))
+ }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/diagnostic/DefaultErrorMessagesKaptLite.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/diagnostic/DefaultErrorMessagesKaptLite.kt
new file mode 100644
index 0000000..5620069
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/diagnostic/DefaultErrorMessagesKaptLite.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2010-2015 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.kaptlite.diagnostic
+
+import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
+import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticFactoryToRendererMap
+import org.jetbrains.kotlin.diagnostics.rendering.Renderers
+
+object DefaultErrorMessagesKaptLite : DefaultErrorMessages.Extension {
+ private val MAP = DiagnosticFactoryToRendererMap("KaptLite")
+ override fun getMap() = MAP
+
+ init {
+ MAP.put(
+ ErrorsKaptLite.KAPT_INCOMPATIBLE_NAME,
+ "Name ''{0}'' is forbidden in kapt. Use only Java-compatible names",
+ Renderers.TO_STRING
+ )
+
+ MAP.put(
+ ErrorsKaptLite.KAPT_NESTED_NAME_CLASH,
+ "Class name ''{0}'' is forbidden in kapt. Java prohibits name clashes with outer classes",
+ Renderers.TO_STRING
+ )
+
+ MAP.put(
+ ErrorsKaptLite.TIME,
+ "Time spent in stub generation: ''{0}''",
+ Renderers.TO_STRING
+ )
+ }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/diagnostic/ErrorsKaptLite.java b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/diagnostic/ErrorsKaptLite.java
new file mode 100644
index 0000000..556d6c8
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/diagnostic/ErrorsKaptLite.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2010-2015 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.kaptlite.diagnostic;
+
+import com.intellij.psi.PsiElement;
+import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1;
+import org.jetbrains.kotlin.diagnostics.Errors;
+
+import static org.jetbrains.kotlin.diagnostics.Severity.ERROR;
+import static org.jetbrains.kotlin.diagnostics.Severity.WARNING;
+
+public interface ErrorsKaptLite {
+ DiagnosticFactory1<PsiElement, String> KAPT_INCOMPATIBLE_NAME = DiagnosticFactory1.create(ERROR);
+ DiagnosticFactory1<PsiElement, String> KAPT_NESTED_NAME_CLASH = DiagnosticFactory1.create(ERROR);
+ DiagnosticFactory1<PsiElement, String> TIME = DiagnosticFactory1.create(WARNING);
+
+ @SuppressWarnings("UnusedDeclaration")
+ Object _initializer = new Object() {
+ {
+ Errors.Initializer.initializeFactoryNames(ErrorsKaptLite.class);
+ }
+ };
+
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/ClassFileLoader.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/ClassFileLoader.kt
new file mode 100644
index 0000000..0a1712a
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/ClassFileLoader.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kaptlite.stubs
+
+import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
+import org.jetbrains.org.objectweb.asm.tree.ClassNode
+import java.util.*
+import kotlin.collections.HashMap
+
+internal const val JAVA_LANG_OBJECT = "java/lang/Object"
+
+class ClassFileLoader(private val inputs: List<GeneratorInput>) {
+ private val cached = HashMap<String, Optional<ClassNode>>()
+
+ fun load(internalName: String, cache: Boolean = false): ClassNode? {
+ val cachedNode = cached[internalName]
+ if (cachedNode != null) {
+ return cachedNode.get()
+ }
+
+ val file = inputs.firstNotNullResult { it.find(internalName) } ?: return null
+ val classNode = file.readClass()
+
+ if (cache) {
+ cached[internalName] = Optional.of(classNode)
+ }
+
+ return classNode
+ }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/GeneratorInput.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/GeneratorInput.kt
new file mode 100644
index 0000000..fa29f57
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/GeneratorInput.kt
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kaptlite.stubs
+
+import org.jetbrains.org.objectweb.asm.ClassReader
+import org.jetbrains.org.objectweb.asm.tree.ClassNode
+import java.io.Closeable
+import java.io.File
+import java.util.zip.ZipEntry
+import java.util.zip.ZipFile
+
+interface ClassFile {
+ val internalName: String
+ fun readClass(): ClassNode
+}
+
+interface GeneratorInput : Closeable {
+ fun iterate(block: (ClassFile) -> Unit)
+ fun find(internalName: String): ClassFile?
+}
+
+class CompiledFilesGeneratorInput(compiledFiles: List<ClassNode>) : GeneratorInput {
+ private val compiledFiles: Map<String, ClassFile> = run {
+ val map = LinkedHashMap<String, ClassFile>(compiledFiles.size)
+ compiledFiles.forEach { map[it.name] = CompiledClassFile(it) }
+ return@run map
+ }
+
+ override fun iterate(block: (ClassFile) -> Unit) {
+ compiledFiles.values.forEach(block)
+ }
+
+ override fun find(internalName: String) = compiledFiles[internalName]
+
+ override fun close() {}
+
+ private class CompiledClassFile(private val classNode: ClassNode) : ClassFile {
+ override val internalName: String = classNode.name
+ override fun readClass() = classNode
+ }
+}
+
+abstract class ByteClassFile : ClassFile {
+ abstract fun readBytes(): ByteArray
+
+ override fun readClass(): ClassNode {
+ val bytes = readBytes()
+ val classNode = ClassNode()
+ ClassReader(bytes).accept(classNode, ClassReader.SKIP_CODE or ClassReader.SKIP_FRAMES)
+ return classNode
+ }
+}
+
+class DirectoryGeneratorInput(private val dir: File) : GeneratorInput {
+ override fun iterate(block: (ClassFile) -> Unit) {
+ for (file in dir.walk()) {
+ if (!file.isFile) {
+ continue
+ }
+
+ val path = file.toRelativeString(dir)
+ if (!path.endsWith(".class")) {
+ continue
+ }
+
+ val internalName = path.dropLast(".class".length)
+ block(RealClassFile(internalName, file))
+ }
+ }
+
+ override fun find(internalName: String): ClassFile? {
+ val file = File(dir, "$internalName.class")
+ if (file.exists()) {
+ return RealClassFile(internalName, file)
+ }
+
+ return null
+ }
+
+ override fun close() {}
+
+ private class RealClassFile(override val internalName: String, val file: File) : ByteClassFile() {
+ override fun readBytes() = file.readBytes()
+ }
+}
+
+class JarGeneratorInput(file: File) : GeneratorInput {
+ private val zipFile = ZipFile(file)
+
+ override fun iterate(block: (ClassFile) -> Unit) {
+ for (entry in zipFile.entries()) {
+ if (entry.isDirectory) {
+ continue
+ }
+
+ val name = entry.name
+ if (!name.endsWith(".class")) {
+ continue
+ }
+
+ val internalName = name.dropLast(".class".length)
+ block(ZipEntryClassFile(internalName, entry))
+ }
+ }
+
+ override fun find(internalName: String): ClassFile? {
+ val entry = zipFile.getEntry("$internalName.class") ?: return null
+ return ZipEntryClassFile(internalName, entry)
+ }
+
+ override fun close() {
+ zipFile.close()
+ }
+
+ private inner class ZipEntryClassFile(override val internalName: String, private val entry: ZipEntry) : ByteClassFile() {
+ override fun readBytes(): ByteArray {
+ return zipFile.getInputStream(entry).use { it.readBytes() }
+ }
+ }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/GeneratorOutput.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/GeneratorOutput.kt
new file mode 100644
index 0000000..dc3e3c6
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/GeneratorOutput.kt
@@ -0,0 +1,12 @@
+/*
+ * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kaptlite.stubs
+
+import org.jetbrains.kaptlite.stubs.util.CodeScope
+
+interface GeneratorOutput {
+ fun produce(internalName: String, path: String, block: CodeScope.() -> Unit)
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/StubChecker.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/StubChecker.kt
new file mode 100644
index 0000000..5365658
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/StubChecker.kt
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kaptlite.stubs
+
+import com.intellij.lang.java.lexer.JavaLexer
+import com.intellij.pom.java.LanguageLevel
+import com.intellij.psi.PsiElement
+import org.jetbrains.kaptlite.diagnostic.DefaultErrorMessagesKaptLite
+import org.jetbrains.kaptlite.diagnostic.ErrorsKaptLite
+import org.jetbrains.kaptlite.signature.ClassSignature
+import org.jetbrains.kaptlite.signature.SigType
+import org.jetbrains.kaptlite.signature.SigTypeArgument
+import org.jetbrains.kaptlite.stubs.model.JavaAnnotationStub
+import org.jetbrains.kaptlite.stubs.model.JavaClassStub
+import org.jetbrains.kaptlite.stubs.model.JavaMethodStub
+import org.jetbrains.kaptlite.stubs.util.JavaClassName
+import org.jetbrains.kotlin.codegen.state.GenerationState
+import org.jetbrains.kotlin.config.JvmTarget
+import org.jetbrains.kotlin.diagnostics.Diagnostic
+import org.jetbrains.kotlin.diagnostics.DiagnosticSink
+import org.jetbrains.kotlin.diagnostics.reportFromPlugin
+import org.jetbrains.kotlin.psi.KtConstructor
+import org.jetbrains.kotlin.psi.KtFunctionLiteral
+import org.jetbrains.kotlin.psi.KtNamedDeclaration
+import org.jetbrains.kotlin.psi.KtObjectDeclaration
+import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
+
+class StubChecker(private val state: GenerationState, private val diagnostics: DiagnosticSink) {
+ private val languageLevel = when (state.target) {
+ JvmTarget.JVM_1_6 -> LanguageLevel.JDK_1_6
+ JvmTarget.JVM_1_8 -> LanguageLevel.JDK_1_8
+ JvmTarget.JVM_9 -> LanguageLevel.JDK_1_9
+ JvmTarget.JVM_10 -> LanguageLevel.JDK_10
+ JvmTarget.JVM_11 -> LanguageLevel.JDK_11
+ JvmTarget.JVM_12 -> LanguageLevel.JDK_12
+ }
+
+ fun checkClass(
+ name: JavaClassName, signature: ClassSignature,
+ enumValues: List<JavaClassStub.JavaEnumValue>,
+ annotations: List<JavaAnnotationStub>,
+ origin: JvmDeclarationOrigin
+ ): Boolean {
+ return checkName(name, origin)
+ && checkType(signature.superClass, origin)
+ && signature.interfaces.all { checkType(it, origin) }
+ && signature.typeParameters.all { checkName(it.name, origin) && it.bounds.all { bound -> checkType(bound, origin) } }
+ && enumValues.all { checkName(it.name, origin) }
+ && checkAnnotations(annotations, origin)
+ }
+
+ fun checkField(name: String, type: SigType, annotations: List<JavaAnnotationStub>, origin: JvmDeclarationOrigin): Boolean {
+ // TODO check field initializer
+ return checkName(name, origin) && checkType(type, origin) && checkAnnotations(annotations, origin)
+ }
+
+ fun checkMethod(
+ name: String, data: JavaMethodStub.MethodData,
+ annotations: List<JavaAnnotationStub>,
+ origin: JvmDeclarationOrigin
+ ): Boolean {
+ return checkName(name, origin)
+ && data.typeParameters.all { checkName(it.name, origin) && it.bounds.all { bound -> checkType(bound, origin) } }
+ && data.parameters.all { checkName(it.name, origin) && checkType(it.type, origin) }
+ && data.exceptionTypes.all { checkType(it, origin) }
+ && checkType(data.returnType, origin)
+ && checkAnnotations(annotations, origin)
+ }
+
+ private fun checkAnnotations(annotations: List<JavaAnnotationStub>, origin: JvmDeclarationOrigin): Boolean {
+ // TODO check annotation args
+ return annotations.all { checkName(it.name, origin) }
+ }
+
+ private fun checkName(name: JavaClassName, origin: JvmDeclarationOrigin): Boolean {
+ return (name.packageName.isEmpty() || name.packageName.split('.').all { checkName(it, origin) })
+ && name.className.split('.').all { checkName(it, origin) }
+ }
+
+ private fun checkName(name: String, origin: JvmDeclarationOrigin): Boolean {
+ if (!isValidIdentifier(name, languageLevel)) {
+ report(origin) { ErrorsKaptLite.KAPT_INCOMPATIBLE_NAME.on(it, name) }
+ return false
+ }
+
+ return true
+ }
+
+ private fun checkType(type: SigType, origin: JvmDeclarationOrigin): Boolean {
+ return when (type) {
+ is SigType.TypeVariable -> checkName(type.name, origin)
+ is SigType.Array -> checkType(type.elementType, origin)
+ is SigType.Class -> type.fqName.split('.').all { checkName(it, origin) }
+ is SigType.Nested -> checkType(type.outer, origin) && checkName(type.name, origin)
+ is SigType.Generic -> checkType(type.base, origin) && type.args.all { checkTypeArgument(it, origin) }
+ is SigType.Primitive -> true
+ }
+ }
+
+ private fun checkTypeArgument(arg: SigTypeArgument, origin: JvmDeclarationOrigin): Boolean {
+ return when (arg) {
+ SigTypeArgument.Unbound -> true
+ is SigTypeArgument.Invariant -> checkType(arg.type, origin)
+ is SigTypeArgument.Extends -> checkType(arg.type, origin)
+ is SigTypeArgument.Super -> checkType(arg.type, origin)
+ }
+ }
+
+ private fun report(origin: JvmDeclarationOrigin, factory: (PsiElement) -> Diagnostic) {
+ val reportElement = findReportElement(origin)
+ val diagnostic = factory(reportElement)
+ diagnostics.reportFromPlugin(diagnostic, DefaultErrorMessagesKaptLite)
+ }
+
+ private fun findReportElement(origin: JvmDeclarationOrigin): PsiElement {
+ val element = origin.element
+
+ when (element) {
+ is KtObjectDeclaration -> element.getObjectKeyword()?.let { return it }
+ is KtConstructor<*> -> element.getConstructorKeyword()?.let { return it }
+ is KtFunctionLiteral -> return element.lBrace
+ }
+
+ if (element is KtNamedDeclaration) {
+ val identifier = element.nameIdentifier
+ if (identifier != null) {
+ return identifier
+ }
+ } else if (element != null) {
+ return element
+ }
+
+ return state.files.first()
+ }
+
+ fun isValidIdentifier(name: String, languageLevel: LanguageLevel = LanguageLevel.JDK_1_8): Boolean {
+ if (JavaLexer.isKeyword(name, languageLevel) || name.isEmpty() || !Character.isJavaIdentifierStart(name.first())) {
+ return false
+ }
+
+ for (i in 1 until name.length) {
+ if (!Character.isJavaIdentifierPart(name[i])) {
+ return false
+ }
+ }
+
+ return true
+ }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/StubGenerator.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/StubGenerator.kt
new file mode 100644
index 0000000..f342c5a
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/StubGenerator.kt
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kaptlite.stubs
+
+import org.jetbrains.kaptlite.stubs.model.JavaClassStub
+import org.jetbrains.kaptlite.stubs.util.append
+import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
+import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot
+import org.jetbrains.kotlin.codegen.state.GenerationState
+import org.jetbrains.kotlin.diagnostics.DiagnosticSink
+import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
+import org.jetbrains.org.objectweb.asm.tree.ClassNode
+import java.io.Closeable
+
+class StubGenerator(
+ diagnostics: DiagnosticSink,
+ compiledClasses: List<ClassNode>,
+ origins: Map<Any, JvmDeclarationOrigin>,
+ state: GenerationState
+) : Closeable {
+ private val compiledFilesInput = CompiledFilesGeneratorInput(compiledClasses)
+
+ private val classpathInputs = run {
+ val contentRoots = state.configuration[CLIConfigurationKeys.CONTENT_ROOTS] ?: emptyList()
+ val classpathRoots = contentRoots.filterIsInstance<JvmClasspathRoot>()
+ classpathRoots.map { if (it.file.isDirectory) DirectoryGeneratorInput(it.file) else JarGeneratorInput(it.file) }
+ }
+
+ private val inputs = listOf(compiledFilesInput) + classpathInputs
+
+ private val loader = ClassFileLoader(inputs)
+ private val context = StubGeneratorContext(loader, diagnostics, state, origins)
+
+ fun generate(output: GeneratorOutput) {
+ compiledFilesInput.iterate { classFile ->
+ generate(classFile, output)
+ }
+ }
+
+ override fun close() {
+ inputs.forEach { it.close() }
+ }
+
+ private fun generate(file: ClassFile, output: GeneratorOutput) {
+ val cls = parse(file) ?: return
+ output(file.internalName, cls, output)
+ }
+
+ private fun parse(file: ClassFile): JavaClassStub? {
+ val node = context.loader.load(file.internalName) ?: return null
+ for (innerClass in node.innerClasses) {
+ if (innerClass.name == file.internalName) {
+ // Only top-level classes should be parsed
+ return null
+ }
+ }
+
+ return JavaClassStub.parse(context, node, JavaClassStub.NestingKind.TOP_LEVEL)
+ }
+
+ private fun output(internalName: String, cls: JavaClassStub, output: GeneratorOutput) {
+ val targetDirPath = cls.name.packageName.replace('.', '/')
+ val targetFilePath = (if (targetDirPath.isEmpty()) "" else "$targetDirPath/") + cls.name.className + ".java"
+
+ output.produce(internalName, targetFilePath) {
+ append("/**").newLine()
+ append(" * This file was generated by the kapt-lite stub generator.").newLine()
+ append(" * Do not change it manually.").newLine()
+ append(" */").newLine()
+
+ if (cls.name.packageName.isNotEmpty()) {
+ append("package ").append(cls.name.packageName).append(';')
+ newLine().newLine()
+ } else {
+ // We have to add package/import directives before declarations.
+ // Otherwise, the file comment will become a class one.
+ append("import java.lang.Object;")
+ newLine().newLine()
+ }
+
+ append(cls)
+ }
+ }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/StubGeneratorContext.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/StubGeneratorContext.kt
new file mode 100644
index 0000000..52ff1e4
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/StubGeneratorContext.kt
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kaptlite.stubs
+
+import com.intellij.openapi.vfs.StandardFileSystems
+import com.intellij.psi.PsiClass
+import com.intellij.psi.PsiJavaFile
+import com.intellij.psi.PsiManager
+import org.jetbrains.kaptlite.stubs.util.JavaClassName
+import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
+import org.jetbrains.kotlin.cli.jvm.config.JavaSourceRoot
+import org.jetbrains.kotlin.codegen.state.GenerationState
+import org.jetbrains.kotlin.config.LanguageVersionSettings
+import org.jetbrains.kotlin.diagnostics.DiagnosticSink
+import org.jetbrains.kotlin.resolve.BindingContext
+import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
+import org.jetbrains.org.objectweb.asm.tree.ClassNode
+import org.jetbrains.org.objectweb.asm.tree.FieldNode
+import org.jetbrains.org.objectweb.asm.tree.MethodNode
+import org.kotlin.kaptlite.kdoc.KDocParsingHelper
+
+class StubGeneratorContext(
+ val loader: ClassFileLoader,
+ diagnostics: DiagnosticSink,
+ private val state: GenerationState,
+ private val origins: Map<Any, JvmDeclarationOrigin>
+) {
+ val checker = StubChecker(state, diagnostics)
+
+ private val javaClassNameMappings: Map<String, JavaClassName> = run {
+ val contentRoots = state.configuration[CLIConfigurationKeys.CONTENT_ROOTS] ?: emptyList()
+ val javaSourceRoots = contentRoots.filterIsInstance<JavaSourceRoot>()
+ if (javaSourceRoots.isEmpty()) {
+ return@run emptyMap()
+ }
+
+ val psiManager = PsiManager.getInstance(state.project)
+ val mappings = HashMap<String, JavaClassName>()
+
+ for (root in javaSourceRoots) {
+ root.file.walk().filter { it.isFile && it.extension == "java" }.forEach {
+ val vFile = StandardFileSystems.local().findFileByPath(it.absolutePath)
+ if (vFile != null) {
+ val javaFile = psiManager.findFile(vFile) as? PsiJavaFile
+ if (javaFile != null) {
+ mappings.putAll(collectNameMappings(javaFile))
+ }
+ }
+ }
+ }
+
+ mappings
+ }
+
+ val bindingContext: BindingContext
+ get() = state.bindingContext
+
+ val languageVersionSettings: LanguageVersionSettings
+ get() = state.languageVersionSettings
+
+ fun getKDocComment(kind: KDocParsingHelper.DeclarationKind, origin: JvmDeclarationOrigin): String? {
+ return KDocParsingHelper.getKDocComment(kind, origin, bindingContext)
+ }
+
+ fun getClassOrigin(node: ClassNode): JvmDeclarationOrigin {
+ return origins[node] ?: JvmDeclarationOrigin.NO_ORIGIN
+ }
+
+ fun getMethodOrigin(node: MethodNode): JvmDeclarationOrigin {
+ return origins[node] ?: JvmDeclarationOrigin.NO_ORIGIN
+ }
+
+ fun getFieldOrigin(node: FieldNode): JvmDeclarationOrigin {
+ return origins[node] ?: JvmDeclarationOrigin.NO_ORIGIN
+ }
+
+ fun getClassName(internalName: String): JavaClassName {
+ if ('$' !in internalName) {
+ return getClassNameSimple(internalName)
+ }
+
+ javaClassNameMappings[internalName]?.let { return it }
+ loader.load(internalName, cache = true)?.let { return getClassName(it) }
+ return getClassNameSimple(internalName)
+ }
+
+ fun getClassName(classNode: ClassNode): JavaClassName {
+ val internalName = classNode.name
+
+ for (innerClass in classNode.innerClasses) {
+ if (innerClass.name == internalName) {
+ val innerName = innerClass.innerName
+ val outerName = innerClass.outerName
+ if (innerName == null || outerName == null) {
+ return getClassNameForAnonymousClass(classNode)
+ }
+
+ return JavaClassName.Nested(getClassName(outerName), innerName)
+ }
+ }
+
+ return getClassNameSimple(internalName)
+ }
+
+ private fun getClassNameForAnonymousClass(classNode: ClassNode): JavaClassName {
+ val superName = classNode.superName ?: JAVA_LANG_OBJECT
+ if (superName == JAVA_LANG_OBJECT) {
+ val interfaces = classNode.interfaces?.sorted() ?: emptyList()
+ val firstInterface = interfaces.firstOrNull()
+ if (firstInterface != null) {
+ return getClassName(firstInterface)
+ }
+ }
+
+ return getClassName(superName)
+ }
+
+ private fun getClassNameSimple(internalName: String): JavaClassName {
+ val packageName = internalName.substringBeforeLast('/', missingDelimiterValue = "").replace('/', '.')
+ val simpleName = if (packageName.isEmpty()) internalName else internalName.drop(packageName.length + 1)
+ return JavaClassName.TopLevel(packageName, simpleName)
+ }
+
+ private fun collectNameMappings(javaFile: PsiJavaFile): Map<String, JavaClassName> {
+ val mappings = HashMap<String, JavaClassName>()
+ val packageName = javaFile.packageName
+
+ fun process(javaClass: PsiClass) {
+ val className = getClassName(packageName, javaClass)
+ if (className != null) {
+ mappings[className.getInternalName()] = className
+ }
+ }
+
+ for (javaClass in javaFile.classes) {
+ process(javaClass)
+ javaClass.allInnerClasses.forEach { process(it) }
+ }
+
+ return mappings
+ }
+
+ private fun getClassName(packageName: String, javaClass: PsiClass): JavaClassName? {
+ val chunks = mutableListOf<String>()
+
+ var current: PsiClass? = javaClass
+ while (current != null) {
+ val name = current.name ?: return null
+ chunks.add(name)
+ current = current.containingClass
+ }
+
+ val reversed = chunks.asReversed()
+ var className: JavaClassName = JavaClassName.TopLevel(packageName, reversed.first())
+ for (index in 1 until reversed.size) {
+ className = JavaClassName.Nested(className, reversed[index])
+ }
+ return className
+ }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/model/JavaAnnotationStub.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/model/JavaAnnotationStub.kt
new file mode 100644
index 0000000..f7f19df
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/model/JavaAnnotationStub.kt
@@ -0,0 +1,219 @@
+/*
+ * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kaptlite.stubs.model
+
+import org.jetbrains.kaptlite.signature.SigType
+import org.jetbrains.kaptlite.stubs.StubGeneratorContext
+import org.jetbrains.kaptlite.stubs.util.*
+import org.jetbrains.org.objectweb.asm.Opcodes
+import org.jetbrains.org.objectweb.asm.tree.AnnotationNode
+import org.jetbrains.org.objectweb.asm.Type
+
+class JavaAnnotationStub(val name: JavaClassName, val values: List<JavaAnnotationValue>) : Renderable {
+ companion object {
+ fun parse(
+ context: StubGeneratorContext,
+ access: Int,
+ visibleAnnotations: List<AnnotationNode>?,
+ invisibleAnnotations: List<AnnotationNode>?
+ ): List<JavaAnnotationStub> {
+ val visible = visibleAnnotations ?: emptyList()
+ val invisible = invisibleAnnotations ?: emptyList()
+
+ val annotations = ArrayList<JavaAnnotationStub>(visible.size + invisible.size)
+ visible.forEach { annotations += parse(context, it) }
+ invisible.forEach { annotations += parse(context, it) }
+
+ if (access.test(Opcodes.ACC_DEPRECATED)) {
+ if (annotations.none { it.name.packageName == "java.lang" && it.name.className == "Deprecated" }) {
+ annotations += JavaAnnotationStub(JavaClassName.TopLevel("java.lang", "Deprecated"), emptyList())
+ }
+ }
+
+ return annotations
+ }
+
+ fun parse(context: StubGeneratorContext, node: AnnotationNode): JavaAnnotationStub {
+ val internalName = Type.getType(node.desc).internalName
+ val name = context.getClassName(internalName)
+ val values = parseValues(context, node.values ?: emptyList())
+ return JavaAnnotationStub(name, values)
+ }
+
+ private fun parseValues(context: StubGeneratorContext, values: List<Any?>): List<JavaAnnotationValue> {
+ val result = ArrayList<JavaAnnotationValue>(values.size / 2)
+ for (index in 0 until values.size / 2) {
+ val name = values[index * 2] as? String ?: continue
+ val value = JavaValue.parse(context, values[index * 2 + 1])
+ result += JavaAnnotationValue(name, value)
+ }
+ return result
+ }
+ }
+
+ override fun CodeScope.render() {
+ append('@')
+ append(name)
+ appendList(values, prefix = "(", postfix = ")")
+ }
+}
+
+class JavaAnnotationValue(val name: String, val value: JavaValue) : Renderable {
+ override fun CodeScope.render() {
+ append(name).append(" = ")
+ append(value)
+ }
+}
+
+sealed class JavaValue : Renderable {
+ companion object {
+ fun parse(context: StubGeneratorContext, value: Any?): JavaValue {
+ return when (value) {
+ is Byte -> VByte(value)
+ is Boolean -> VBoolean(value)
+ is Char -> VChar(value)
+ is Short -> VShort(value)
+ is Int -> VInt(value)
+ is Long -> VLong(value)
+ is Float -> VFloat(value)
+ is Double -> VDouble(value)
+ is String -> VString(value)
+ is Type -> VType(parseType(context, value))
+ is Array<*> -> {
+ if (value.size != 2 || value[0] !is String || value[1] !is String) {
+ error("Unexpected enum value: " + value.contentDeepToString())
+ }
+
+ val enum = context.getClassName(Type.getType(value[0] as String).internalName)
+ VEnumEntry(enum, value[1] as String)
+ }
+ is AnnotationNode -> return VAnnotation(JavaAnnotationStub.parse(context, value))
+ is List<*> -> VArray(value.map { parse(context, it) })
+ else -> error("Unexpected value type $value")
+ }
+ }
+ }
+
+ class VByte(private val value: Byte) : JavaValue() {
+ override fun CodeScope.render() {
+ append(value.toString())
+ }
+ }
+
+ class VBoolean(private val value: Boolean) : JavaValue() {
+ override fun CodeScope.render() {
+ append(if (value) "true" else "false")
+ }
+ }
+
+ class VChar(private val value: Char) : JavaValue() {
+ override fun CodeScope.render() {
+ append("'${escape(value)}'")
+ }
+ }
+
+ class VShort(private val value: Short) : JavaValue() {
+ override fun CodeScope.render() {
+ append(value.toString())
+ }
+ }
+
+ class VInt(private val value: Int) : JavaValue() {
+ override fun CodeScope.render() {
+ append(value.toString())
+ }
+ }
+
+ class VLong(private val value: Long) : JavaValue() {
+ override fun CodeScope.render() {
+ append(value.toString()).append('L')
+ }
+ }
+
+ class VFloat(private val value: Float) : JavaValue() {
+ override fun CodeScope.render() {
+ when {
+ value.isNaN() -> append("java.lang.Float.NaN")
+ value == Float.POSITIVE_INFINITY -> append("java.lang.Float.POSITIVE_INFINITY")
+ value == Float.NEGATIVE_INFINITY -> append("java.lang.Float.NEGATIVE_INFINITY")
+ else -> append(value.toString()).append('f')
+ }
+ }
+ }
+
+ class VDouble(private val value: Double) : JavaValue() {
+ override fun CodeScope.render() {
+ when {
+ value.isNaN() -> append("java.lang.Double.NaN")
+ value == Double.POSITIVE_INFINITY -> append("java.lang.Double.POSITIVE_INFINITY")
+ value == Double.NEGATIVE_INFINITY -> append("java.lang.Double.NEGATIVE_INFINITY")
+ else -> append(value.toString())
+ }
+ }
+ }
+
+ class VString(private val value: String) : JavaValue() {
+ override fun CodeScope.render() {
+ val escaped = buildString {
+ for (char in value) {
+ append(escape(char))
+ }
+ }
+ append("\"$escaped\"")
+ }
+ }
+
+ class VType(private val type: SigType) : JavaValue() {
+ override fun CodeScope.render() {
+ append(type).append(".class")
+ }
+ }
+
+ class VEnumEntry(private val enum: JavaClassName, private val value: String) : JavaValue() {
+ override fun CodeScope.render() {
+ append(enum).append('.').append(value)
+ }
+ }
+
+ class VAnnotation(private val value: JavaAnnotationStub) : JavaValue() {
+ override fun CodeScope.render() {
+ append(value)
+ }
+ }
+
+ class VArray(private val values: List<JavaValue>) : JavaValue() {
+ override fun CodeScope.render() {
+ append('{').appendList(values).append('}')
+ }
+ }
+
+ class VExpressionUnsafe(private val value: String) : JavaValue() {
+ override fun CodeScope.render() {
+ append(value)
+ }
+ }
+
+ object VNull : JavaValue() {
+ override fun CodeScope.render() {
+ append("null")
+ }
+ }
+}
+
+private fun escape(char: Char): String {
+ return when (char) {
+ '\t' -> "\\t"
+ '\b' -> "\\b"
+ '\n' -> "\\n"
+ '\r' -> "\\r"
+ '\u000c' -> "\\f"
+ '\'' -> "\\'"
+ '"' -> "\\\""
+ '\\' -> "\\\\"
+ in ' '..'~' -> "$char"
+ else -> String.format("\\u%04x", char.toInt())
+ }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/model/JavaClassStub.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/model/JavaClassStub.kt
new file mode 100644
index 0000000..9044301
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/model/JavaClassStub.kt
@@ -0,0 +1,222 @@
+/*
+ * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kaptlite.stubs.model
+
+import org.jetbrains.kaptlite.stubs.JAVA_LANG_OBJECT
+import org.jetbrains.kaptlite.signature.ClassSignature
+import org.jetbrains.kaptlite.signature.SigType
+import org.jetbrains.kaptlite.signature.SignatureParser
+import org.jetbrains.kaptlite.signature.isJavaLangObject
+import org.jetbrains.kaptlite.stubs.StubGeneratorContext
+import org.jetbrains.kaptlite.stubs.util.*
+import org.jetbrains.kotlin.descriptors.ClassDescriptor
+import org.jetbrains.kotlin.descriptors.ClassKind
+import org.jetbrains.org.objectweb.asm.Opcodes
+import org.jetbrains.org.objectweb.asm.Type
+import org.jetbrains.org.objectweb.asm.tree.ClassNode
+import org.kotlin.kaptlite.kdoc.KDocParsingHelper
+import javax.lang.model.element.Modifier
+import kotlin.collections.ArrayList
+
+class JavaClassStub(
+ val name: JavaClassName,
+ private val modifiers: Set<Modifier>,
+ private val kind: TypeKind,
+ private val signature: ClassSignature,
+ private val enumValues: List<JavaEnumValue>,
+ private val methods: List<JavaMethodStub>,
+ private val fields: List<JavaFieldStub>,
+ private val nestedClasses: List<JavaClassStub>,
+ private val annotations: List<JavaAnnotationStub>,
+ private val javadoc: String?
+) : Renderable {
+ enum class NestingKind {
+ TOP_LEVEL, NESTED, INNER
+ }
+
+ companion object {
+ fun parse(context: StubGeneratorContext, node: ClassNode, nestingKind: NestingKind): JavaClassStub? {
+ if (node.isSynthetic) {
+ return null
+ }
+
+ val origin = context.getClassOrigin(node)
+
+ val descriptor = origin.descriptor
+ val isDefaultImpls = descriptor is ClassDescriptor
+ && descriptor.kind == ClassKind.INTERFACE
+ && node.isPublic && node.isFinal
+ && node.name.endsWith("${descriptor.name.asString()}\$DefaultImpls")
+
+ // DefaultImpls without any contents don't have INNERCLASS'es inside it (and inside the parent interface)
+ if (isDefaultImpls && (nestingKind == NestingKind.TOP_LEVEL || (node.fields.isEmpty() && node.methods.isEmpty()))) {
+ return null
+ }
+
+ val name = context.getClassName(node)
+
+ val typeKind = getTypeKind(node.access)
+ val signature = parseClassSignature(context, node)
+ val constructorData = JavaMethodStub.ConstructorData(emptyList(), emptyList()) // getConstructorData(context, node)
+
+ val methods = (node.methods ?: emptyList())
+ .mapNotNullTo(mutableListOf()) {
+ JavaMethodStub.parse(context, it, node, name, nestingKind == NestingKind.INNER, constructorData)
+ }
+
+ if (methods.none { it.isConstructor } && typeKind == TypeKind.CLASS) {
+ methods += JavaMethodStub(
+ name = name.className,
+ modifiers = setOf(Modifier.PRIVATE),
+ isConstructor = true,
+ data = JavaMethodStub.MethodData(emptyList(), emptyList(), SigType.Primitive.VOID, emptyList()),
+ annotations = emptyList(),
+ javadoc = null,
+ constructorData = constructorData
+ )
+ }
+
+ val enumValues = (node.fields ?: emptyList())
+ .filter { it.isEnumValue }
+ .mapNotNull { field ->
+ val valueOrigin = context.getFieldOrigin(field)
+ JavaEnumValue(field.name, context.getKDocComment(KDocParsingHelper.DeclarationKind.FIELD, valueOrigin))
+ }
+
+ val fields = (node.fields ?: emptyList())
+ .filter { !it.isEnumValue }
+ .mapNotNull { JavaFieldStub.parse(context, it) }
+
+ val nestedClasses = ArrayList<JavaClassStub>(0)
+ for (innerClass in node.innerClasses) {
+ if (innerClass.outerName == node.name) {
+ if (enumValues.any { it.name == innerClass.innerName }) {
+ continue
+ }
+
+ val childNode = context.loader.load(innerClass.name) ?: continue
+ val childNestingKind = when {
+ nestingKind == NestingKind.INNER || isInner(childNode, node) -> NestingKind.INNER
+ else -> NestingKind.NESTED
+ }
+ val childClass = parse(context, childNode, childNestingKind) ?: continue
+ nestedClasses += childClass
+ }
+ }
+
+ // kotlin.jvm.JvmName is applicable to file facades but not applicable to classes
+ val annotations = JavaAnnotationStub.parse(context, node.access, node.visibleAnnotations, node.invisibleAnnotations)
+ .filter { it.name.toString() != "kotlin.jvm.JvmName" }
+
+ val javadoc = context.getKDocComment(KDocParsingHelper.DeclarationKind.CLASS, origin)
+
+ var modifiers = parseModifiers(node)
+ if (nestingKind == NestingKind.NESTED) {
+ modifiers = modifiers + Modifier.STATIC
+ }
+
+ if (!context.checker.checkClass(name, signature, enumValues, annotations, origin)) {
+ return null
+ }
+
+ return JavaClassStub(
+ name,
+ modifiers, typeKind,
+ signature,
+ enumValues, methods, fields, nestedClasses,
+ annotations,
+ javadoc
+ )
+ }
+
+ private fun isInner(node: ClassNode, owner: ClassNode): Boolean {
+ val thisField = node.fields.find { it.name == "this$0" } ?: return false
+ return Type.getType(thisField.desc).internalName == owner.name
+ }
+
+ private fun parseClassSignature(context: StubGeneratorContext, node: ClassNode): ClassSignature {
+ return if (node.signature == null) {
+ val superClass = parseType(context, (node.superName ?: JAVA_LANG_OBJECT))
+ val interfaces = (node.interfaces ?: emptyList()).map { parseType(context, it) }
+ ClassSignature(emptyList(), superClass, interfaces)
+ } else {
+ val signature = SignatureParser.parseClassSignature(node.signature)
+ return ClassSignature(
+ typeParameters = signature.typeParameters.map { it.copy(bounds = it.bounds.patchTypes(context)) },
+ superClass = signature.superClass.patchType(context),
+ interfaces = signature.interfaces.patchTypes(context)
+ )
+ }
+ }
+
+ private fun getTypeKind(access: Int): TypeKind {
+ if (access.test(Opcodes.ACC_ANNOTATION)) return TypeKind.ANNOTATION
+ if (access.test(Opcodes.ACC_INTERFACE)) return TypeKind.INTERFACE
+ if (access.test(Opcodes.ACC_ENUM)) return TypeKind.ENUM
+ return TypeKind.CLASS
+ }
+ }
+
+ class JavaEnumValue(val name: String, val javadoc: String?)
+
+ enum class TypeKind(val keyword: String) {
+ INTERFACE("interface"), ANNOTATION("@interface"), ENUM("enum"), CLASS("class")
+ }
+
+ override fun CodeScope.render() {
+ appendJavadoc(javadoc)
+ appendList(annotations, "\n", postfix = "\n")
+ appendModifiers(modifiers).append(' ')
+ append(kind.keyword).append(' ').append(name.className)
+ appendList(signature.typeParameters, prefix = "<", postfix = ">") { append(it) }
+ if (kind == TypeKind.CLASS && !signature.superClass.isJavaLangObject) {
+ append(" extends ").append(signature.superClass)
+ }
+ if (kind != TypeKind.ANNOTATION) {
+ val keyword = if (kind == TypeKind.INTERFACE) "extends" else "implements"
+ appendList(signature.interfaces, prefix = " $keyword ") { append(it) }
+ }
+
+ append(' ').block {
+ var isFirst = true
+
+ if (kind == TypeKind.ENUM) {
+ val implMethods = methods
+ .filter { it.modifiers.contains(Modifier.ABSTRACT) }
+ .map { it.copy(modifiers = it.modifiers - Modifier.ABSTRACT) }
+
+ val constructorParameters = methods.asSequence()
+ .filter { it.isConstructor }
+ .minBy { it.data.parameters.size }?.data?.parameters
+ ?: emptyList()
+
+ for (value in enumValues) {
+ appendJavadoc(value.javadoc)
+ append(value.name)
+ appendList(constructorParameters, prefix = "(", postfix = ")") { append(it.type.defaultValue) }
+
+ if (implMethods.isNotEmpty()) {
+ append(' ').block {
+ appendList(implMethods, "\n\n")
+ }
+ }
+
+ append(',').newLine()
+ }
+ append(";")
+ isFirst = false
+ }
+
+ appendList(fields, "\n", prefix = if (!isFirst) "\n\n" else "")
+ isFirst = isFirst && fields.isEmpty()
+
+ appendList(methods, "\n\n", prefix = if (!isFirst) "\n\n" else "")
+ isFirst = isFirst && methods.isEmpty()
+
+ appendList(nestedClasses, "\n\n", prefix = if (!isFirst) "\n\n" else "")
+ }
+ }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/model/JavaFieldStub.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/model/JavaFieldStub.kt
new file mode 100644
index 0000000..5eb545b
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/model/JavaFieldStub.kt
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kaptlite.stubs.model
+
+import org.jetbrains.kaptlite.signature.SigType
+import org.jetbrains.kaptlite.signature.SignatureParser
+import org.jetbrains.kaptlite.stubs.StubGeneratorContext
+import org.jetbrains.kaptlite.stubs.util.*
+import org.jetbrains.kotlin.builtins.KotlinBuiltIns
+import org.jetbrains.kotlin.descriptors.ClassDescriptor
+import org.jetbrains.kotlin.descriptors.PropertyDescriptor
+import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor
+import org.jetbrains.kotlin.psi.KtProperty
+import org.jetbrains.kotlin.psi.KtPsiUtil
+import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
+import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
+import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
+import org.jetbrains.org.objectweb.asm.Type
+import org.jetbrains.org.objectweb.asm.tree.FieldNode
+import org.kotlin.kaptlite.kdoc.KDocParsingHelper
+import javax.lang.model.element.Modifier
+
+class JavaFieldStub(
+ private val name: String,
+ private val modifiers: Set<Modifier>,
+ private val type: SigType,
+ private val initializer: JavaValue?,
+ private val annotations: List<JavaAnnotationStub>,
+ private val javadoc: String?
+) : Renderable {
+ companion object {
+ fun parse(context: StubGeneratorContext, node: FieldNode): JavaFieldStub? {
+ if (node.isSynthetic) {
+ return null
+ }
+
+ val origin = context.getFieldOrigin(node)
+ val name = node.name
+ val type = parseType(context, node)
+
+ val initializer = getEnhancedFieldInitializer(context, node, origin) ?: parseInitializer(context, node, type)
+ val annotations = JavaAnnotationStub.parse(context, node.access, node.visibleAnnotations, node.invisibleAnnotations)
+ val javadoc = context.getKDocComment(KDocParsingHelper.DeclarationKind.FIELD, origin)
+
+ if (!context.checker.checkField(name, type, annotations, origin)) {
+ return null
+ }
+
+ return JavaFieldStub(name, parseModifiers(node), type, initializer, annotations, javadoc)
+ }
+
+ private fun getEnhancedFieldInitializer(context: StubGeneratorContext, node: FieldNode, origin: JvmDeclarationOrigin): JavaValue? {
+ val value = node.value
+
+ if (value != null && isSimpleValue(value)) {
+ val propertyDescriptor = origin.descriptor as? PropertyDescriptor
+ val ktProperty = origin.element as? KtProperty
+ val initializer = ktProperty?.initializer
+ if (propertyDescriptor != null && propertyDescriptor.compileTimeInitializer != null) {
+ if (ktProperty != null && !ktProperty.hasDelegate() && initializer != null) {
+ val expression = KtPsiUtil.deparenthesize(initializer)
+ val descriptor = expression.getResolvedCall(context.bindingContext)?.resultingDescriptor
+ if (descriptor is JavaPropertyDescriptor && descriptor.isConst && !isBuiltInConst(descriptor)) {
+ return JavaValue.VExpressionUnsafe(descriptor.fqNameSafe.asString())
+ }
+ }
+ }
+ }
+
+ return null
+ }
+
+ private fun isBuiltInConst(descriptor: PropertyDescriptor): Boolean {
+ val containingClassDescriptor = descriptor.containingDeclaration as? ClassDescriptor ?: return false
+ if (!containingClassDescriptor.isCompanionObject) {
+ return false
+ }
+
+ val classDescriptor = containingClassDescriptor.containingDeclaration as? ClassDescriptor ?: return false
+ return KotlinBuiltIns.isPrimitiveType(classDescriptor.defaultType)
+ }
+
+ private fun isSimpleValue(value: Any?): Boolean {
+ return when (value) {
+ is Byte, is Short, is Int, is Long, is Char, is Boolean, is Float, is Double -> true
+ is String -> true
+ is List<*> -> value.isNotEmpty() && isSimpleValue(value.first())
+ else -> false
+ }
+ }
+
+ private fun parseInitializer(context: StubGeneratorContext, node: FieldNode, type: SigType): JavaValue? {
+ val value = node.value ?: return if (node.isStatic) type.defaultValue else null
+
+ if (node.desc == "Z") {
+ return JavaValue.VBoolean(value != 0)
+ }
+
+ return JavaValue.parse(context, value)
+ }
+
+ private fun parseType(context: StubGeneratorContext, node: FieldNode): SigType {
+ val signature = node.signature
+ return if (signature == null) {
+ parseType(context, Type.getType(node.desc)).patchType(context)
+ } else {
+ SignatureParser.parseFieldSignature(signature).patchType(context)
+ }
+ }
+ }
+
+ override fun CodeScope.render() {
+ appendJavadoc(javadoc)
+ appendList(annotations, "\n", postfix = "\n")
+ appendModifiers(modifiers).append(' ')
+ append(type).append(' ')
+ append(name)
+ if (initializer != null) {
+ append(" = ")
+ append(initializer)
+ }
+ append(';')
+ }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/model/JavaMethodStub.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/model/JavaMethodStub.kt
new file mode 100644
index 0000000..5309149
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/model/JavaMethodStub.kt
@@ -0,0 +1,351 @@
+/*
+ * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kaptlite.stubs.model
+
+import org.jetbrains.kaptlite.signature.SigParameter
+import org.jetbrains.kaptlite.signature.SigType
+import org.jetbrains.kaptlite.signature.SigTypeParameter
+import org.jetbrains.kaptlite.signature.SignatureParser
+import org.jetbrains.kaptlite.stubs.StubGeneratorContext
+import org.jetbrains.kaptlite.stubs.util.*
+import org.jetbrains.kotlin.codegen.AsmUtil
+import org.jetbrains.kotlin.codegen.state.getInlineClassSignatureManglingSuffix
+import org.jetbrains.kotlin.descriptors.*
+import org.jetbrains.kotlin.load.java.JvmAbi.DEFAULT_IMPLS_SUFFIX
+import org.jetbrains.kotlin.load.java.JvmAbi.IMPL_SUFFIX_FOR_INLINE_CLASS_MEMBERS
+import org.jetbrains.kotlin.resolve.InlineClassDescriptorResolver.isSpecializedEqualsMethod
+import org.jetbrains.kotlin.resolve.InlineClassDescriptorResolver.isSynthesizedBoxOrUnboxMethod
+import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
+import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
+import org.jetbrains.kotlin.resolve.jvm.isInlineClassThatRequiresMangling
+import org.jetbrains.org.objectweb.asm.Opcodes
+import org.jetbrains.org.objectweb.asm.Type
+import org.jetbrains.org.objectweb.asm.tree.ClassNode
+import org.jetbrains.org.objectweb.asm.tree.MethodNode
+import org.kotlin.kaptlite.kdoc.KDocParsingHelper
+import javax.lang.model.element.Modifier
+
+data class JavaMethodStub(
+ val name: String,
+ val modifiers: Set<Modifier>,
+ val isConstructor: Boolean,
+ val data: MethodData,
+ private val annotations: List<JavaAnnotationStub>,
+ private val javadoc: String?,
+ private val constructorData: ConstructorData
+) : Renderable {
+ class ConstructorData(val uninitializedFields: List<UninitializedField>, val superConstructorArgs: List<JavaValue>)
+
+ class MethodData(
+ val typeParameters: List<SigTypeParameter>,
+ val parameters: List<JavaParameterStub>,
+ val returnType: SigType,
+ val exceptionTypes: List<SigType>
+ )
+
+ companion object {
+ fun parse(
+ context: StubGeneratorContext, node: MethodNode,
+ owner: ClassNode, ownerName: JavaClassName, ownerIsInner: Boolean, constructorData: ConstructorData
+ ): JavaMethodStub? {
+ if (node.isStaticInitializer || node.isBridge || node.isSynthetic || isEnumGeneratedMember(node, owner)) {
+ return null
+ }
+
+ val isConstructor = node.isConstructor
+ val name = if (isConstructor) ownerName.className else node.name
+
+ val origin = context.getMethodOrigin(node)
+ val descriptor = origin.descriptor
+ if (descriptor != null && hasInlineClassesInSignature(descriptor, node)) {
+ return null
+ }
+
+ val data = parseData(context, node, owner, ownerIsInner, origin)
+
+ val annotations = JavaAnnotationStub.parse(context, node.access, node.visibleAnnotations, node.invisibleAnnotations)
+ val javadoc = context.getKDocComment(KDocParsingHelper.DeclarationKind.METHOD, origin)
+
+ if (!context.checker.checkMethod(name, data, annotations, origin)) {
+ return null
+ }
+
+ return JavaMethodStub(name, parseModifiers(node), isConstructor, data, annotations, javadoc, constructorData)
+ }
+
+ private fun hasInlineClassesInSignature(descriptor: DeclarationDescriptor, node: MethodNode): Boolean {
+ if (descriptor is CallableMemberDescriptor) {
+ if (isSynthesizedBoxOrUnboxMethod(descriptor) || isSpecializedEqualsMethod(descriptor)) {
+ return true
+ }
+
+ val manglingSuffix = getInlineClassSignatureManglingSuffix(descriptor)
+ if (manglingSuffix != null) {
+ return true
+ }
+ }
+
+ if (descriptor is CallableDescriptor) {
+ val containingClass = descriptor.containingDeclaration
+ if (node.name.endsWith(IMPL_SUFFIX_FOR_INLINE_CLASS_MEMBERS) && containingClass.isInlineClassThatRequiresMangling()) {
+ return true
+ }
+ }
+
+ return false
+ }
+
+ private fun isEnumGeneratedMember(node: MethodNode, owner: ClassNode): Boolean {
+ if (!owner.isEnum) {
+ return false
+ }
+
+ val enumName = owner.name
+ return when {
+ node.name == "values" && node.desc == "()[L$enumName;" -> true
+ node.name == "valueOf" && node.desc == "(Ljava/lang/String;)L$enumName;" -> true
+ else -> false
+ }
+ }
+
+ private fun parseData(
+ context: StubGeneratorContext,
+ node: MethodNode, owner: ClassNode, ownerIsInner: Boolean,
+ origin: JvmDeclarationOrigin
+ ): MethodData {
+ val methodType = Type.getMethodType(node.desc)
+ val rawParameterTypes = parseArgumentTypes(context, methodType, node, owner, ownerIsInner)
+ val parameterNames = getParameterNamesFromSource(context, node, owner, rawParameterTypes.size, origin)
+ ?: (rawParameterTypes.indices).map { "p$it" }
+ val rawParameters = rawParameterTypes.mapIndexed { index, type -> SigParameter(parameterNames[index], type) }
+
+ return if (node.signature == null) {
+ val parameters = rawParameters.mapIndexed { index, param ->
+ parseParameter(context, node, param, index, rawParameters.size)
+ }
+ val returnType = parseType(context, methodType.returnType)
+ val exceptionTypes = node.exceptions.map { parseType(context, it) }
+ MethodData(emptyList(), parameters, returnType, exceptionTypes)
+ } else {
+ val signature = SignatureParser.parseMethodSignature(node.signature, rawParameters)
+ val parameters = signature.parameters.mapIndexed { index, param ->
+ parseParameter(context, node, param.copy(type = param.type.patchType(context)), index, rawParameters.size)
+ }
+ MethodData(
+ signature.typeParameters.map { it.copy(bounds = it.bounds.patchTypes(context)) },
+ parameters,
+ signature.returnType.patchType(context),
+ signature.exceptionTypes.patchTypes(context)
+ )
+ }
+ }
+
+ private fun parseArgumentTypes(
+ context: StubGeneratorContext,
+ type: Type, node: MethodNode,
+ owner: ClassNode, ownerIsInner: Boolean
+ ): List<SigType> {
+ val types = type.argumentTypes.map { parseType(context, it) }
+
+ if (node.isConstructor) {
+ if (ownerIsInner) {
+ assert(type.argumentTypes.isNotEmpty())
+ return types.drop(1)
+ } else if (owner.isEnum) {
+ assert(type.argumentTypes.size >= 2)
+ assert(type.argumentTypes[0].descriptor == "Ljava/lang/String;")
+ assert(type.argumentTypes[1].sort == Type.INT)
+ return types.drop(2)
+ }
+ }
+
+ return types
+ }
+
+ private fun getParameterNamesFromSource(
+ context: StubGeneratorContext,
+ node: MethodNode, owner: ClassNode,
+ parameterCount: Int,
+ origin: JvmDeclarationOrigin
+ ): List<String>? {
+ val descriptor = origin.descriptor as? FunctionDescriptor ?: return null
+
+ fun getReceiverParameterName(): String {
+ return AsmUtil.getNameForReceiverParameter(descriptor, context.bindingContext, context.languageVersionSettings)
+ }
+
+ if (descriptor.valueParameters.any { it.name.isSpecial }) {
+ return null
+ }
+
+ val parameterNames = when (descriptor) {
+ is PropertyGetterDescriptor -> if (descriptor.isExtension) listOf(getReceiverParameterName()) else emptyList()
+ is PropertySetterDescriptor -> {
+ val parameterName = descriptor.valueParameters.singleOrNull()?.name?.takeIf { !it.isSpecial } ?: return null
+
+ when {
+ descriptor.isExtension -> {
+ val receiverParameterName = getReceiverParameterName()
+ if (receiverParameterName == parameterName.asString()) {
+ return null
+ }
+ listOf(receiverParameterName, parameterName.asString())
+ }
+ else -> listOf(parameterName.asString())
+ }
+ }
+ else -> {
+ val ordinaryParameterNames = descriptor.valueParameters.map { it.name.asString() }
+ when {
+ descriptor.isExtension -> {
+ val receiverParameterName = getReceiverParameterName()
+ if (receiverParameterName in ordinaryParameterNames) {
+ return null
+ }
+ listOf(getReceiverParameterName()) + ordinaryParameterNames
+ }
+ else -> ordinaryParameterNames
+ }
+ }
+ }
+
+ val prefix = ArrayList<String>(1)
+
+ if (isDefaultImplsMethod(descriptor, node, owner)) {
+ if (descriptor.valueParameters.any { it.name.asString() == AsmUtil.THIS_IN_DEFAULT_IMPLS }) {
+ // In theory, we can invent some good unique name here, but... nevermind.
+ return null
+ }
+ prefix += AsmUtil.THIS_IN_DEFAULT_IMPLS
+ }
+
+ val delta = when {
+ isEnumConstructor(descriptor) -> 2
+ isInnerClassConstructor(descriptor) -> 1
+ else -> 0
+ }
+
+ val expectedNameCount = parameterNames.size + prefix.size + delta
+ if (expectedNameCount != parameterCount) {
+ return null
+ }
+
+ return prefix + parameterNames
+ }
+
+ private fun parseParameter(
+ context: StubGeneratorContext,
+ node: MethodNode,
+ param: SigParameter,
+ index: Int, count: Int
+ ): JavaParameterStub {
+ val isVarargs = node.isVarargs && index == count - 1 && param.type is SigType.Array
+ val visibleAnnotations = node.visibleParameterAnnotations?.getOrNull(index)
+ val invisibleAnnotations = node.invisibleParameterAnnotations?.getOrNull(index)
+ val annotations = JavaAnnotationStub.parse(context, 0, visibleAnnotations, invisibleAnnotations)
+ val patchedType = param.type.patchType(context).fixVarargType(isVarargs)
+ return JavaParameterStub(param.name, patchedType, 0, isVarargs, annotations)
+ }
+
+ private fun SigType.fixVarargType(isVarargs: Boolean): SigType {
+ if (isVarargs) {
+ val arrayType = this as SigType.Array
+ return arrayType.elementType
+ }
+
+ return this
+ }
+
+ private fun isEnumConstructor(descriptor: FunctionDescriptor): Boolean {
+ val containingClass = descriptor.containingDeclaration as? ClassDescriptor ?: return false
+ return containingClass.kind == ClassKind.ENUM_CLASS && descriptor is ConstructorDescriptor
+ }
+
+ private fun isInnerClassConstructor(descriptor: FunctionDescriptor): Boolean {
+ val containingClass = descriptor.containingDeclaration as? ClassDescriptor ?: return false
+ return containingClass.kind == ClassKind.CLASS && containingClass.isInner && descriptor is ConstructorDescriptor
+ }
+
+ private fun isDefaultImplsMethod(descriptor: FunctionDescriptor, node: MethodNode, owner: ClassNode): Boolean {
+ if (!owner.name.endsWith(DEFAULT_IMPLS_SUFFIX) || node.isAbstract) {
+ return false
+ }
+
+ val containingClass = descriptor.containingDeclaration as? ClassDescriptor ?: return false
+ return containingClass.kind == ClassKind.INTERFACE
+ }
+ }
+
+ override fun CodeScope.render() {
+ appendJavadoc(javadoc)
+ appendList(annotations, "\n", postfix = "\n")
+ appendModifiers(modifiers).append(' ')
+ appendList(data.typeParameters, prefix = "<", postfix = "> ") { append(it) }
+ if (!isConstructor) {
+ append(data.returnType).append(' ')
+ }
+ append(name)
+ append('(')
+ appendList(data.parameters)
+ append(')')
+
+ if (data.exceptionTypes.isNotEmpty()) {
+ appendList(data.exceptionTypes, prefix = " throws ") { append(it) }
+ }
+
+ if (Modifier.ABSTRACT !in modifiers) {
+ val uninitializedFields = constructorData.uninitializedFields
+ val superConstructorArgs = constructorData.superConstructorArgs
+
+ if (!data.returnType.isVoid || isConstructor && (uninitializedFields.isNotEmpty() || superConstructorArgs.isNotEmpty())) {
+ append(' ').block {
+ if (isConstructor) {
+ if (superConstructorArgs.isNotEmpty()) {
+ append("super(")
+ appendList(superConstructorArgs)
+ append(");")
+ }
+
+ appendList(uninitializedFields, "\n", prefix = if (superConstructorArgs.isNotEmpty()) "\n" else "") {
+ append("this.").append(it.name).append(" = ").append(it.type.defaultValue).append(';')
+ }
+ }
+ if (!data.returnType.isVoid) {
+ newLineIfNeeded()
+ append("return ").append(data.returnType.defaultValue).append(';')
+ }
+ }
+ } else {
+ append(" {}")
+ }
+ } else {
+ append(';')
+ }
+ }
+}
+
+class UninitializedField(val name: String, val type: SigType)
+
+class JavaParameterStub(
+ val name: String,
+ val type: SigType,
+ private val access: Int,
+ private val isVarargs: Boolean,
+ private val annotations: List<JavaAnnotationStub>
+) : Renderable {
+ override fun CodeScope.render() {
+ appendList(annotations, " ", postfix = " ")
+ if ((access and Opcodes.ACC_FINAL) != 0) {
+ append("final ")
+ }
+ append(type)
+ if (isVarargs) {
+ append("...")
+ }
+ append(' ')
+ append(name)
+ }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/util/CodeScope.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/util/CodeScope.kt
new file mode 100644
index 0000000..a8d0305
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/util/CodeScope.kt
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kaptlite.stubs.util
+
+import org.jetbrains.kaptlite.signature.SigType
+import org.jetbrains.kaptlite.signature.SigTypeArgument
+import org.jetbrains.kaptlite.signature.SigTypeParameter
+import javax.lang.model.element.Modifier
+
+interface Renderable {
+ fun CodeScope.render()
+}
+
+class CodeScope(private val appendable: Appendable, val indent: String = " ") {
+ private var depth: Int = 0
+ private var lastNewLine = false
+
+ fun append(c: Char): CodeScope {
+ if (c == '\n') {
+ newLine()
+ } else {
+ appendable.append(c)
+ }
+ lastNewLine = c == '\n'
+ return this
+ }
+
+ fun append(str: CharSequence): CodeScope {
+ var isFirst = true
+ for (line in str.lineSequence()) {
+ if (isFirst) {
+ isFirst = false
+ } else {
+ newLine()
+ }
+
+ appendable.append(line)
+ }
+ lastNewLine = str.lastOrNull() == '\n'
+ return this
+ }
+
+ fun newLine(): CodeScope {
+ appendable.append(System.lineSeparator())
+ for (i in 1..depth) {
+ appendable.append(indent)
+ }
+ lastNewLine = true
+ return this
+ }
+
+ fun newLineIfNeeded(): CodeScope {
+ if (!lastNewLine) {
+ newLine()
+ }
+ return this
+ }
+
+ fun incDepth(): CodeScope {
+ depth += 1
+ return this
+ }
+
+ fun decDepth(): CodeScope {
+ depth -= 1
+ return this
+ }
+}
+
+fun CodeScope.block(block: CodeScope.() -> Unit) {
+ append("{")
+ incDepth()
+ newLine()
+ block()
+ decDepth()
+ newLine()
+ append("}")
+}
+
+fun CodeScope.append(renderable: Renderable): CodeScope {
+ with(renderable) { render() }
+ return this
+}
+
+fun CodeScope.append(type: SigType): CodeScope {
+ when (type) {
+ is SigType.TypeVariable -> append(type.name)
+ is SigType.Array -> append(type.elementType).append("[]")
+ is SigType.Primitive -> append(type.javaName)
+ is SigType.Class -> append(type.fqName)
+ is SigType.Nested -> append(type.outer).append('.').append(type.name)
+ is SigType.Generic -> {
+ append(type.base)
+ appendList(type.args, prefix = "<", postfix = ">") { append(it) }
+ }
+ }
+ return this
+}
+
+fun CodeScope.append(param: SigTypeParameter): CodeScope {
+ append(param.name)
+ appendList(param.bounds, " & ", prefix = " extends ") { append(it) }
+ return this
+}
+
+fun CodeScope.append(arg: SigTypeArgument): CodeScope {
+ when (arg) {
+ SigTypeArgument.Unbound -> append('?')
+ is SigTypeArgument.Invariant -> append(arg.type)
+ is SigTypeArgument.Extends -> append("? extends ").append(arg.type)
+ is SigTypeArgument.Super -> append("? super ").append(arg.type)
+ }
+ return this
+}
+
+fun <T : Renderable> CodeScope.appendList(
+ list: Collection<T>,
+ separator: String = ", ",
+ prefix: String = "",
+ postfix: String = ""
+): CodeScope {
+ return appendList(list, separator, prefix, postfix) { append(it) }
+}
+
+fun <T> CodeScope.appendList(
+ list: Collection<T>,
+ separator: String = ", ",
+ prefix: String = "",
+ postfix: String = "",
+ block: CodeScope.(T) -> Unit
+): CodeScope {
+ if (list.isEmpty()) {
+ return this
+ }
+
+ append(prefix)
+ var isFirst = true
+ for (item in list) {
+ if (isFirst) {
+ isFirst = false
+ } else {
+ append(separator)
+ }
+
+ block(item)
+ }
+ append(postfix)
+ return this
+}
+
+fun CodeScope.appendModifiers(modifiers: Set<Modifier>): CodeScope {
+ appendList(modifiers, " ") { append(it.toString()) }
+ return this
+}
+
+fun CodeScope.appendJavadoc(text: String?): CodeScope {
+ if (text != null && text.isNotBlank()) {
+ append("/**").newLine()
+ for (line in text.lineSequence()) {
+ append(" * ").append(line).newLine()
+ }
+ append(" */").newLine()
+ }
+
+ return this
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/util/parseModifiers.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/util/parseModifiers.kt
new file mode 100644
index 0000000..41e770f
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/util/parseModifiers.kt
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kaptlite.stubs.util
+
+import org.jetbrains.org.objectweb.asm.Opcodes
+import org.jetbrains.org.objectweb.asm.tree.*
+import java.util.EnumSet
+import javax.lang.model.element.Modifier
+
+fun Int.test(flag: Int): Boolean {
+ return (this and flag) > 0
+}
+
+val ClassNode.isPublic: Boolean get() = access.test(Opcodes.ACC_PUBLIC)
+val ClassNode.isFinal: Boolean get() = access.test(Opcodes.ACC_FINAL)
+val ClassNode.isSynthetic: Boolean get() = access.test(Opcodes.ACC_SYNTHETIC)
+val ClassNode.isEnum: Boolean get() = access.test(Opcodes.ACC_ENUM)
+
+val FieldNode.isSynthetic: Boolean get() = access.test(Opcodes.ACC_SYNTHETIC)
+val FieldNode.isStatic: Boolean get() = access.test(Opcodes.ACC_STATIC)
+val FieldNode.isEnumValue: Boolean get() = access.test(Opcodes.ACC_ENUM)
+
+val MethodNode.isSynthetic: Boolean get() = access.test(Opcodes.ACC_SYNTHETIC)
+val MethodNode.isBridge: Boolean get() = access.test(Opcodes.ACC_BRIDGE)
+val MethodNode.isVarargs: Boolean get() = access.test(Opcodes.ACC_VARARGS)
+val MethodNode.isAbstract: Boolean get() = access.test(Opcodes.ACC_ABSTRACT)
+val MethodNode.isStaticInitializer: Boolean get() = name == "<clinit>"
+val MethodNode.isConstructor: Boolean get() = name == "<init>"
+
+private fun parseVisibilityModifiers(access: Int, consumer: EnumSet<Modifier>) {
+ if (access.test(Opcodes.ACC_PUBLIC)) consumer.add(Modifier.PUBLIC)
+ if (access.test(Opcodes.ACC_PROTECTED)) consumer.add(Modifier.PROTECTED)
+ if (access.test(Opcodes.ACC_PRIVATE)) consumer.add(Modifier.PRIVATE)
+}
+
+private fun parseModalityModifiers(access: Int, consumer: EnumSet<Modifier>) {
+ val isEnum = access.test(Opcodes.ACC_ENUM)
+ if (access.test(Opcodes.ACC_FINAL) && !isEnum) consumer.add(Modifier.FINAL)
+ if (access.test(Opcodes.ACC_ABSTRACT) && !isEnum) consumer.add(Modifier.ABSTRACT)
+}
+
+fun parseModifiers(node: ClassNode): Set<Modifier> {
+ val access = node.access
+ val modifiers = EnumSet.noneOf(Modifier::class.java)
+ parseVisibilityModifiers(access, modifiers)
+ parseModalityModifiers(access, modifiers)
+ return modifiers
+}
+
+fun parseModifiers(node: MethodNode): Set<Modifier> {
+ val access = node.access
+ val modifiers = EnumSet.noneOf(Modifier::class.java)
+ parseVisibilityModifiers(access, modifiers)
+ parseModalityModifiers(access, modifiers)
+ if (access.test(Opcodes.ACC_SYNCHRONIZED)) modifiers.add(Modifier.SYNCHRONIZED)
+ if (access.test(Opcodes.ACC_NATIVE)) modifiers.add(Modifier.NATIVE)
+ if (access.test(Opcodes.ACC_STRICT)) modifiers.add(Modifier.STRICTFP)
+ if (access.test(Opcodes.ACC_STATIC)) modifiers.add(Modifier.STATIC)
+ return modifiers
+}
+
+fun parseModifiers(node: FieldNode): Set<Modifier> {
+ val access = node.access
+ val modifiers = EnumSet.noneOf(Modifier::class.java)
+ parseVisibilityModifiers(access, modifiers)
+ parseModalityModifiers(access, modifiers)
+ if (access.test(Opcodes.ACC_VOLATILE)) modifiers.add(Modifier.VOLATILE)
+ if (access.test(Opcodes.ACC_TRANSIENT)) modifiers.add(Modifier.TRANSIENT)
+ if (access.test(Opcodes.ACC_STATIC)) modifiers.add(Modifier.STATIC)
+ return modifiers
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/util/typeUtils.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/util/typeUtils.kt
new file mode 100644
index 0000000..fdbc981
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/src/org/jetbrains/kaptlite/stubs/util/typeUtils.kt
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kaptlite.stubs.util
+
+import org.jetbrains.kaptlite.stubs.model.JavaValue
+import org.jetbrains.kaptlite.stubs.model.JavaValue.*
+import org.jetbrains.kaptlite.signature.SigType
+import org.jetbrains.kaptlite.signature.SigTypeArgument
+import org.jetbrains.kaptlite.stubs.StubGeneratorContext
+import org.jetbrains.org.objectweb.asm.Type
+
+sealed class JavaClassName(val packageName: String, val className: String) : Renderable {
+ abstract fun getInternalName(): String
+
+ class TopLevel(packageName: String, simpleName: String) : JavaClassName(packageName, simpleName) {
+ override fun CodeScope.render() {
+ if (packageName.isNotEmpty()) {
+ append(packageName).append('.')
+ }
+ append(className)
+ }
+
+ override fun getInternalName() = if (packageName.isEmpty()) className else packageName.replace('.', '/') + '/' + className
+ override fun toString() = if (packageName.isNotEmpty()) "$packageName.$className" else className
+ }
+
+ class Nested(private val outer: JavaClassName, simpleName: String) : JavaClassName(outer.packageName, simpleName) {
+ override fun CodeScope.render() {
+ append(outer).append('.').append(className)
+ }
+
+ override fun getInternalName() = outer.getInternalName() + "$" + className
+ override fun toString() = "$outer.$className"
+ }
+}
+
+fun parseType(context: StubGeneratorContext, internalName: String): SigType {
+ return parseType(context, Type.getObjectType(internalName))
+}
+
+fun parseType(context: StubGeneratorContext, type: Type): SigType {
+ return when (type.sort) {
+ Type.ARRAY -> SigType.Array(parseType(context, type.elementType))
+ Type.OBJECT -> {
+ val className = context.getClassName(type.internalName)
+ SigType.Class(className.toString())
+ }
+ else -> SigType.Primitive.get(type.descriptor.single())
+ }
+}
+
+fun List<SigType>.patchTypes(context: StubGeneratorContext): List<SigType> {
+ return this.map { it.patchType(context) }
+}
+
+fun SigType.patchType(context: StubGeneratorContext): SigType {
+ return when (this) {
+ is SigType.Primitive, is SigType.TypeVariable -> this
+ is SigType.Array -> SigType.Array(elementType.patchType(context))
+ is SigType.Class -> {
+ val internalName = fqName.replace('.', '/')
+ SigType.Class(context.getClassName(internalName).toString())
+ }
+ is SigType.Nested -> SigType.Nested(outer.patchType(context), name)
+ is SigType.Generic -> SigType.Generic(base.patchType(context), args.map { arg ->
+ when (arg) {
+ SigTypeArgument.Unbound -> arg
+ is SigTypeArgument.Invariant -> SigTypeArgument.Invariant(arg.type.patchType(context))
+ is SigTypeArgument.Extends -> SigTypeArgument.Extends(arg.type.patchType(context))
+ is SigTypeArgument.Super -> SigTypeArgument.Super(arg.type.patchType(context))
+ }
+ })
+ }
+}
+
+val SigType.defaultValue: JavaValue
+ get() = when (this) {
+ is SigType.Primitive -> {
+ when (this) {
+ SigType.Primitive.VOID -> VNull
+ SigType.Primitive.BYTE -> VByte(0)
+ SigType.Primitive.SHORT -> VShort(0)
+ SigType.Primitive.INT -> VInt(0)
+ SigType.Primitive.LONG -> VLong(0)
+ SigType.Primitive.BOOLEAN -> VBoolean(false)
+ SigType.Primitive.CHAR -> VChar('\u0000')
+ SigType.Primitive.FLOAT -> VFloat(0f)
+ SigType.Primitive.DOUBLE -> VDouble(0.0)
+ else -> error("Unknown primitive type")
+ }
+ }
+ else -> VNull
+ }
+
+val SigType.isVoid: Boolean
+ get() = this === SigType.Primitive.VOID
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/test/org/jetbrains/kaptlite/test/AbstractStubGeneratorTest.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/test/org/jetbrains/kaptlite/test/AbstractStubGeneratorTest.kt
new file mode 100644
index 0000000..0632d34
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/test/org/jetbrains/kaptlite/test/AbstractStubGeneratorTest.kt
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kaptlite.test
+
+import com.intellij.compiler.JavaInMemoryCompiler
+import org.jetbrains.kaptlite.AbstractKaptLiteAnalysisHandlerExtension
+import org.jetbrains.kaptlite.KaptLiteClassBuilderInterceptorExtension
+import org.jetbrains.kaptlite.stubs.GeneratorOutput
+import org.jetbrains.kaptlite.stubs.util.CodeScope
+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
+import org.jetbrains.kotlin.cli.common.messages.MessageCollector
+import org.jetbrains.kotlin.cli.jvm.compiler.CliBindingTrace
+import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
+import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration
+import org.jetbrains.kotlin.codegen.CodegenTestCase
+import org.jetbrains.kotlin.codegen.CodegenTestCase.TestFile
+import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension
+import org.jetbrains.kotlin.codegen.state.GenerationState
+import org.jetbrains.kotlin.config.CompilerConfiguration
+import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
+import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension
+import org.jetbrains.kotlin.test.ConfigurationKind
+import org.jetbrains.kotlin.test.KotlinTestUtils
+import java.io.File
+import java.util.*
+import javax.lang.model.element.NestingKind
+import javax.tools.DiagnosticListener
+import javax.tools.JavaFileObject
+import javax.tools.SimpleJavaFileObject
+import javax.tools.ToolProvider
+import kotlin.collections.ArrayList
+
+abstract class AbstractStubGeneratorTest : CodegenTestCase() {
+ companion object {
+ private const val KOTLIN_METADATA_GROUP = "[a-z0-9]+ = (\\{.+?\\}|[0-9]+)"
+ private val KOTLIN_METADATA_REGEX = "@kotlin\\.Metadata\\(($KOTLIN_METADATA_GROUP)(, $KOTLIN_METADATA_GROUP)*\\)".toRegex()
+
+ private fun removeMetadataAnnotationContents(test: String): String {
+ return test.replace(KOTLIN_METADATA_REGEX, "@kotlin.Metadata()")
+ }
+ }
+
+ private val origins = mutableMapOf<String, JvmDeclarationOrigin>()
+
+ override fun setupEnvironment(environment: KotlinCoreEnvironment) {
+ ClassBuilderInterceptorExtension.registerExtension(environment.project, KaptLiteClassBuilderInterceptorExtension(origins))
+ }
+
+ override fun tearDown() {
+ origins.clear()
+ super.tearDown()
+ }
+
+ override fun doMultiFileTest(wholeFile: File, files: List<TestFile>) {
+ createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.ALL, *listOfNotNull(writeJavaFiles(files)).toTypedArray())
+
+ val messageCollector = object : MessageCollector {
+ val errors = ArrayList<String>(0)
+
+ override fun hasErrors() = errors.isNotEmpty()
+ override fun clear() = errors.clear()
+
+ override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation?) {
+ if (severity.isError) {
+ errors += message
+ }
+ }
+ }
+
+ val analysisHandlerExtension = KaptLiteAnalysisHandlerExtensionForTests(myEnvironment.configuration, messageCollector)
+ AnalysisHandlerExtension.registerExtension(myEnvironment.project, analysisHandlerExtension)
+
+ loadMultiFiles(files)
+
+ val trace = CliBindingTrace()
+ analyzeFilesWithJavaIntegration(
+ myEnvironment.project,
+ myFiles.psiFiles,
+ trace,
+ myEnvironment.configuration,
+ myEnvironment::createPackagePartProvider
+ )
+
+ val expectedFile = File(wholeFile.parentFile, wholeFile.nameWithoutExtension + ".txt")
+
+ if (messageCollector.hasErrors()) {
+ KotlinTestUtils.assertEqualsToFile(expectedFile, messageCollector.errors.joinToString("\n"))
+ return
+ }
+
+ checkGeneratorOutput(analysisHandlerExtension.output, expectedFile, files)
+ }
+
+ private fun checkGeneratorOutput(output: TestGeneratorOutput, expectedFile: File, files: List<TestFile>) {
+ val filesContent = output.files
+ .sortedBy { it.name }
+ .joinToString("\n\n") { "// FILE: " + it.name + "\n" + it.content }
+ .lineSequence()
+ .map { line -> if (line.isBlank()) "" else line }
+ .joinToString("\n")
+ .let(::removeMetadataAnnotationContents)
+
+ val diagnostics = checkWithJavac(output.files + files.filter { it.name.endsWith(".java") })
+
+ val actualContent = buildString {
+ append(filesContent)
+ if (diagnostics.isNotEmpty()) {
+ appendln().appendln().append(diagnostics)
+ }
+ }
+
+ KotlinTestUtils.assertEqualsToFile(expectedFile, actualContent)
+ }
+
+ private fun checkWithJavac(files: List<TestFile>): String {
+ val locale = Locale.US
+ val compiler = ToolProvider.getSystemJavaCompiler()
+ val diagnostics = mutableListOf<String>()
+
+ val diagnosticListener = DiagnosticListener<JavaFileObject> { diagnostic ->
+ val path = diagnostic.source.name
+ val line = diagnostic.lineNumber
+ val column = diagnostic.columnNumber
+ val message = diagnostic.getMessage(locale)
+ diagnostics += "$path[$line:$column]: $message"
+ }
+
+ val fileManager = JavaInMemoryCompiler.JavaMemFileManager()
+ val javaFiles = files.map { createJavaFile(it) }
+ val task = compiler.getTask(null, fileManager, diagnosticListener, null, null, javaFiles)
+ task.call()
+
+ return diagnostics.joinToString("\n")
+ }
+
+ private fun createJavaFile(file: TestFile): SimpleJavaFileObject {
+ val uri = File(file.name).toURI()
+ return object : SimpleJavaFileObject(uri, JavaFileObject.Kind.SOURCE) {
+ private fun unsupported(): Nothing = throw UnsupportedOperationException("File is read-only")
+
+ override fun getName() = file.name
+ override fun getNestingKind() = NestingKind.TOP_LEVEL
+
+ override fun openInputStream() = file.content.byteInputStream()
+ override fun getCharContent(ignoreEncodingErrors: Boolean) = file.content
+
+ override fun openWriter() = unsupported()
+ override fun openOutputStream() = unsupported()
+ override fun delete() = unsupported()
+ }
+ }
+}
+
+class KaptLiteAnalysisHandlerExtensionForTests(
+ configuration: CompilerConfiguration,
+ override val messageCollector: MessageCollector
+) : AbstractKaptLiteAnalysisHandlerExtension(configuration) {
+ val output = TestGeneratorOutput()
+ override fun getOutput(state: GenerationState) = output
+}
+
+class TestGeneratorOutput : GeneratorOutput {
+ val files = mutableListOf<TestFile>()
+
+ override fun produce(internalName: String, path: String, block: CodeScope.() -> Unit) {
+ val sb = StringBuilder()
+ CodeScope(sb).block()
+ files += TestFile(path, sb.toString())
+ }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/test/org/jetbrains/kaptlite/test/StubGeneratorTestGenerated.java b/plugins/kapt-lite/kapt-lite-compiler-plugin/test/org/jetbrains/kaptlite/test/StubGeneratorTestGenerated.java
new file mode 100644
index 0000000..ece6dc4
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/test/org/jetbrains/kaptlite/test/StubGeneratorTestGenerated.java
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kaptlite.test;
+
+import com.intellij.testFramework.TestDataPath;
+import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
+import org.jetbrains.kotlin.test.KotlinTestUtils;
+import org.jetbrains.kotlin.test.TargetBackend;
+import org.jetbrains.kotlin.test.TestMetadata;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+import java.util.regex.Pattern;
+
+/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */
+@SuppressWarnings("all")
+@TestMetadata("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs")
+@TestDataPath("$PROJECT_ROOT")
+@RunWith(JUnit3RunnerWithInners.class)
+public class StubGeneratorTestGenerated extends AbstractStubGeneratorTest {
+ private void runTest(String testDataFilePath) throws Exception {
+ KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
+ }
+
+ @TestMetadata("abstractList.kt")
+ public void testAbstractList() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/abstractList.kt");
+ }
+
+ public void testAllFilesPresentInStubs() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
+ }
+
+ @TestMetadata("annotationDeclarationSiteTargets.kt")
+ public void testAnnotationDeclarationSiteTargets() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/annotationDeclarationSiteTargets.kt");
+ }
+
+ @TestMetadata("customPropertyDelegates.kt")
+ public void testCustomPropertyDelegates() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/customPropertyDelegates.kt");
+ }
+
+ @TestMetadata("dataClasses.kt")
+ public void testDataClasses() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/dataClasses.kt");
+ }
+
+ @TestMetadata("declarations.kt")
+ public void testDeclarations() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/declarations.kt");
+ }
+
+ @TestMetadata("defaultPackage.kt")
+ public void testDefaultPackage() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/defaultPackage.kt");
+ }
+
+ @TestMetadata("deprecated.kt")
+ public void testDeprecated() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/deprecated.kt");
+ }
+
+ @TestMetadata("enums.kt")
+ public void testEnums() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/enums.kt");
+ }
+
+ @TestMetadata("facades.kt")
+ public void testFacades() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/facades.kt");
+ }
+
+ @TestMetadata("fieldInitializers.kt")
+ public void testFieldInitializers() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/fieldInitializers.kt");
+ }
+
+ @TestMetadata("flags.kt")
+ public void testFlags() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/flags.kt");
+ }
+
+ @TestMetadata("generics.kt")
+ public void testGenerics() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/generics.kt");
+ }
+
+ @TestMetadata("implicitReturnTypes.kt")
+ public void testImplicitReturnTypes() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/implicitReturnTypes.kt");
+ }
+
+ @TestMetadata("inheritance.kt")
+ public void testInheritance() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/inheritance.kt");
+ }
+
+ @TestMetadata("inlineClasses.kt")
+ public void testInlineClasses() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/inlineClasses.kt");
+ }
+
+ @TestMetadata("interfaceDelegates.kt")
+ public void testInterfaceDelegates() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/interfaceDelegates.kt");
+ }
+
+ @TestMetadata("javaNested.kt")
+ public void testJavaNested() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javaNested.kt");
+ }
+
+ @TestMetadata("javadoc.kt")
+ public void testJavadoc() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javadoc.kt");
+ }
+
+ @TestMetadata("javadocFormatting.kt")
+ public void testJavadocFormatting() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javadocFormatting.kt");
+ }
+
+ @TestMetadata("jvmField.kt")
+ public void testJvmField() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmField.kt");
+ }
+
+ @TestMetadata("jvmName.kt")
+ public void testJvmName() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmName.kt");
+ }
+
+ @TestMetadata("jvmOverloads.kt")
+ public void testJvmOverloads() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmOverloads.kt");
+ }
+
+ @TestMetadata("jvmThrows.kt")
+ public void testJvmThrows() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmThrows.kt");
+ }
+
+ @TestMetadata("lateinit.kt")
+ public void testLateinit() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/lateinit.kt");
+ }
+
+ @TestMetadata("multiFileFacades.kt")
+ public void testMultiFileFacades() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/multiFileFacades.kt");
+ }
+
+ @TestMetadata("nestedSameName.kt")
+ public void testNestedSameName() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/nestedSameName.kt");
+ }
+
+ @TestMetadata("parameterNames.kt")
+ public void testParameterNames() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/parameterNames.kt");
+ }
+
+ @TestMetadata("primitiveLiterals.kt")
+ public void testPrimitiveLiterals() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/primitiveLiterals.kt");
+ }
+
+ @TestMetadata("propertyDelegates.kt")
+ public void testPropertyDelegates() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/propertyDelegates.kt");
+ }
+
+ @TestMetadata("sealedClasses.kt")
+ public void testSealedClasses() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/sealedClasses.kt");
+ }
+
+ @TestMetadata("simple.kt")
+ public void testSimple() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/simple.kt");
+ }
+
+ @TestMetadata("specialJavaKeywords.kt")
+ public void testSpecialJavaKeywords() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/specialJavaKeywords.kt");
+ }
+
+ @TestMetadata("suspendMain.kt")
+ public void testSuspendMain() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendMain.kt");
+ }
+
+ @TestMetadata("suspendWithRuntime.kt")
+ public void testSuspendWithRuntime() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendWithRuntime.kt");
+ }
+
+ @TestMetadata("suspendWithoutRuntime.kt")
+ public void testSuspendWithoutRuntime() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendWithoutRuntime.kt");
+ }
+
+ @TestMetadata("varargs.kt")
+ public void testVarargs() throws Exception {
+ runTest("plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/varargs.kt");
+ }
+}
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/abstractList.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/abstractList.kt
new file mode 100644
index 0000000..8282724
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/abstractList.kt
@@ -0,0 +1,7 @@
+// WITH_RUNTIME
+package abstractList
+
+class MappedList<out T, R>(val list: List<T>, private val function: (T) -> R) : AbstractList<R>(), List<R> {
+ override fun get(index: Int) = function(list[index])
+ override val size get() = list.size
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/abstractList.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/abstractList.txt
new file mode 100644
index 0000000..c87969d
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/abstractList.txt
@@ -0,0 +1,30 @@
+// FILE: abstractList/MappedList.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package abstractList;
+
+@kotlin.Metadata()
+public final class MappedList<T, R> extends kotlin.collections.AbstractList<R> implements java.util.List<R>, kotlin.jvm.internal.markers.KMappedMarker {
+ @org.jetbrains.annotations.NotNull
+ private final java.util.List<T> list;
+ private final kotlin.jvm.functions.Function1<T, R> function;
+
+ public R get(int index) {
+ return null;
+ }
+
+ public int getSize() {
+ return 0;
+ }
+
+ @org.jetbrains.annotations.NotNull
+ public final java.util.List<T> getList() {
+ return null;
+ }
+
+ public MappedList(@org.jetbrains.annotations.NotNull java.util.List<? extends T> list, @org.jetbrains.annotations.NotNull kotlin.jvm.functions.Function1<? super T, ? extends R> function) {}
+}
+
+abstractList/MappedList.java[26:193]: variable list might not have been initialized
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/annotationDeclarationSiteTargets.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/annotationDeclarationSiteTargets.kt
new file mode 100644
index 0000000..f9c328d
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/annotationDeclarationSiteTargets.kt
@@ -0,0 +1,25 @@
+package test
+
+@Target(AnnotationTarget.FIELD)
+annotation class FieldAnno
+
+@Target(AnnotationTarget.PROPERTY)
+annotation class PropertyAnno
+
+@Target(AnnotationTarget.VALUE_PARAMETER)
+annotation class ParameterAnno
+
+annotation class Anno
+
+class Foo(@FieldAnno @PropertyAnno @ParameterAnno @Anno val a: String)
+
+class Bar {
+ @FieldAnno @PropertyAnno @Anno
+ val a: String = ""
+}
+
+class Baz {
+ @FieldAnno @Anno
+ @JvmField
+ val a: String = ""
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/customPropertyDelegates.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/customPropertyDelegates.kt
new file mode 100644
index 0000000..6b9f12d
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/customPropertyDelegates.kt
@@ -0,0 +1,38 @@
+// WITH_RUNTIME
+
+package test
+
+import kotlin.properties.ReadWriteProperty
+import kotlin.reflect.KProperty
+
+inline fun charSequence(key: String? = null) = object : BundleProperty<CharSequence>(key) {
+ override fun getValue(bundle: Any, key: String): CharSequence? = TODO()
+ override fun setValue(bundle: Any, key: String, value: CharSequence) {}
+}
+
+abstract class NullableBundleProperty<EE>(private val key: String?) : ReadWriteProperty<Any, EE?> {
+ private inline fun KProperty<*>.toKey(): String {
+ return toString()
+ }
+
+ override fun getValue(thisRef: Any, property: KProperty<*>): EE? = getValue(thisRef, key ?: property.toKey())
+ override fun setValue(thisRef: Any, property: KProperty<*>, value: EE?) {
+ setNullableValue(thisRef, key ?: property.toKey(), value)
+ }
+
+ abstract fun getValue(bundle: Any, key: String): EE?
+ abstract fun setNullableValue(bundle: Any, key: String, value: EE?)
+}
+
+abstract class BundleProperty<AA>(key: String?) : NullableBundleProperty<AA>(key) {
+ final override fun setValue(thisRef: Any, property: KProperty<*>, value: AA?) {
+ super.setValue(thisRef, property, value)
+ }
+
+ final override fun getValue(thisRef: Any, property: KProperty<*>): AA = super.getValue(thisRef, property)!!
+ final override fun setNullableValue(bundle: Any, key: String, value: AA?) {
+ setValue(bundle, key, value!!)
+ }
+
+ abstract fun setValue(bundle: Any, key: String, value: AA)
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/customPropertyDelegates.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/customPropertyDelegates.txt
new file mode 100644
index 0000000..c2733e1
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/customPropertyDelegates.txt
@@ -0,0 +1,73 @@
+// FILE: test/BundleProperty.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package test;
+
+@kotlin.Metadata()
+public abstract class BundleProperty<AA> extends test.NullableBundleProperty<AA> {
+ public final void setValue(@org.jetbrains.annotations.NotNull java.lang.Object thisRef, @org.jetbrains.annotations.NotNull kotlin.reflect.KProperty<?> property, @org.jetbrains.annotations.Nullable AA value) {}
+
+ public final AA getValue(@org.jetbrains.annotations.NotNull java.lang.Object thisRef, @org.jetbrains.annotations.NotNull kotlin.reflect.KProperty<?> property) {
+ return null;
+ }
+
+ public final void setNullableValue(@org.jetbrains.annotations.NotNull java.lang.Object bundle, @org.jetbrains.annotations.NotNull java.lang.String key, @org.jetbrains.annotations.Nullable AA value) {}
+
+ public abstract void setValue(@org.jetbrains.annotations.NotNull java.lang.Object bundle, @org.jetbrains.annotations.NotNull java.lang.String key, AA value);
+
+ public BundleProperty(@org.jetbrains.annotations.Nullable java.lang.String key) {}
+}
+
+// FILE: test/CustomPropertyDelegatesKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package test;
+
+@kotlin.Metadata()
+public final class CustomPropertyDelegatesKt {
+ @org.jetbrains.annotations.NotNull
+ public static final test.BundleProperty<java.lang.CharSequence> charSequence(@org.jetbrains.annotations.Nullable java.lang.String key) {
+ return null;
+ }
+
+ private CustomPropertyDelegatesKt() {}
+}
+
+// FILE: test/NullableBundleProperty.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package test;
+
+@kotlin.Metadata()
+public abstract class NullableBundleProperty<EE> implements kotlin.properties.ReadWriteProperty<java.lang.Object, EE> {
+ private final java.lang.String key;
+
+ private final java.lang.String toKey(@org.jetbrains.annotations.NotNull kotlin.reflect.KProperty<?> $this$toKey) {
+ return null;
+ }
+
+ @org.jetbrains.annotations.Nullable
+ public EE getValue(@org.jetbrains.annotations.NotNull java.lang.Object thisRef, @org.jetbrains.annotations.NotNull kotlin.reflect.KProperty<?> property) {
+ return null;
+ }
+
+ public void setValue(@org.jetbrains.annotations.NotNull java.lang.Object thisRef, @org.jetbrains.annotations.NotNull kotlin.reflect.KProperty<?> property, @org.jetbrains.annotations.Nullable EE value) {}
+
+ @org.jetbrains.annotations.Nullable
+ public abstract EE getValue(@org.jetbrains.annotations.NotNull java.lang.Object bundle, @org.jetbrains.annotations.NotNull java.lang.String key);
+
+ public abstract void setNullableValue(@org.jetbrains.annotations.NotNull java.lang.Object bundle, @org.jetbrains.annotations.NotNull java.lang.String key, @org.jetbrains.annotations.Nullable EE value);
+
+ public NullableBundleProperty(@org.jetbrains.annotations.Nullable java.lang.String key) {}
+}
+
+test/BundleProperty.java[19:85]: constructor NullableBundleProperty in class test.NullableBundleProperty<EE> cannot be applied to given types;
+ required: java.lang.String
+ found: no arguments
+ reason: actual and formal argument lists differ in length
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/dataClasses.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/dataClasses.kt
new file mode 100644
index 0000000..d3d0659
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/dataClasses.kt
@@ -0,0 +1,13 @@
+package dataClasses
+
+data class User(val firstName: String, val lastName: String, val age: Int) {
+ enum class Foo {
+ FOO, BAR
+ }
+
+ interface Intf {
+ fun foo() {}
+ }
+}
+
+data class Either<F, S>(val first: F, val second: S)
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/dataClasses.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/dataClasses.txt
new file mode 100644
index 0000000..b6d0d2a
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/dataClasses.txt
@@ -0,0 +1,135 @@
+// FILE: dataClasses/Either.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package dataClasses;
+
+@kotlin.Metadata()
+public final class Either<F, S> {
+ private final F first;
+ private final S second;
+
+ public final F getFirst() {
+ return null;
+ }
+
+ public final S getSecond() {
+ return null;
+ }
+
+ public Either(F first, S second) {}
+
+ public final F component1() {
+ return null;
+ }
+
+ public final S component2() {
+ return null;
+ }
+
+ @org.jetbrains.annotations.NotNull
+ public final dataClasses.Either<F, S> copy(F first, S second) {
+ return null;
+ }
+
+ @org.jetbrains.annotations.NotNull
+ public java.lang.String toString() {
+ return null;
+ }
+
+ public int hashCode() {
+ return 0;
+ }
+
+ public boolean equals(@org.jetbrains.annotations.Nullable java.lang.Object other) {
+ return false;
+ }
+}
+
+// FILE: dataClasses/User.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package dataClasses;
+
+@kotlin.Metadata()
+public final class User {
+ @org.jetbrains.annotations.NotNull
+ private final java.lang.String firstName;
+ @org.jetbrains.annotations.NotNull
+ private final java.lang.String lastName;
+ private final int age;
+
+ @org.jetbrains.annotations.NotNull
+ public final java.lang.String getFirstName() {
+ return null;
+ }
+
+ @org.jetbrains.annotations.NotNull
+ public final java.lang.String getLastName() {
+ return null;
+ }
+
+ public final int getAge() {
+ return 0;
+ }
+
+ public User(@org.jetbrains.annotations.NotNull java.lang.String firstName, @org.jetbrains.annotations.NotNull java.lang.String lastName, int age) {}
+
+ @org.jetbrains.annotations.NotNull
+ public final java.lang.String component1() {
+ return null;
+ }
+
+ @org.jetbrains.annotations.NotNull
+ public final java.lang.String component2() {
+ return null;
+ }
+
+ public final int component3() {
+ return 0;
+ }
+
+ @org.jetbrains.annotations.NotNull
+ public final dataClasses.User copy(@org.jetbrains.annotations.NotNull java.lang.String firstName, @org.jetbrains.annotations.NotNull java.lang.String lastName, int age) {
+ return null;
+ }
+
+ @org.jetbrains.annotations.NotNull
+ public java.lang.String toString() {
+ return null;
+ }
+
+ public int hashCode() {
+ return 0;
+ }
+
+ public boolean equals(@org.jetbrains.annotations.Nullable java.lang.Object other) {
+ return false;
+ }
+
+ @kotlin.Metadata()
+ public static enum Foo {
+ FOO,
+ BAR,
+ ;
+
+ private Foo() {}
+ }
+
+ @kotlin.Metadata()
+ public abstract static interface Intf {
+ public abstract void foo();
+
+ @kotlin.Metadata()
+ public final static class DefaultImpls {
+ public static void foo(dataClasses.User.Intf $this) {}
+
+ private DefaultImpls() {}
+ }
+ }
+}
+
+dataClasses/User.java[29:152]: variable firstName might not have been initialized
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/declarations.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/declarations.kt
new file mode 100644
index 0000000..eb9e9e6
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/declarations.kt
@@ -0,0 +1,83 @@
+package declarations
+
+class Foo {
+ val a: Int = 0
+ fun foo() {}
+ fun bar(str: String, num: Int) {}
+
+ class Nested {
+ fun nested() {}
+
+ class Nested2 {
+ fun nested2() {}
+ }
+ }
+
+ inner class Inner {
+ fun inner() {}
+
+ inner class Inner2 {
+ fun inner2() {}
+ }
+ }
+
+ interface NestedIntf {
+ fun nestedIntf(x: Int) {}
+ }
+
+ enum class NestedEnum {
+ GOOD, BAD
+ }
+
+ annotation class Anno(val value: String)
+}
+
+interface Intf {
+ val a: Int
+ fun foo() {}
+ fun bar(str: String, num: Int)
+
+ fun fooImpl(a: Int, b: String) {}
+ suspend fun barImpl(a: Int, b: String) {}
+}
+
+annotation class Anno(val a: String, val b: Int, val c: IntArray)
+annotation class ValueAnno(val value: String)
+
+enum class FooEnum {
+ FOO, BAR
+}
+
+enum class FooEnum2 {
+ FOO, BAR;
+
+ enum class NestedEnum {
+ GOOD, BAD
+ }
+}
+
+object Obj
+
+class ClassWithCompanion {
+ companion object {
+ fun foo() {}
+ }
+}
+
+class ClassWithNamedCompanion {
+ companion object Com {
+ fun foo() {}
+ }
+}
+
+class InterfaceWithCompanion {
+ companion object {
+ fun foo() {}
+ }
+}
+
+class InterfaceWithNamedCompanion {
+ companion object ComIntf {
+ fun foo() {}
+ }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/declarations.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/declarations.txt
new file mode 100644
index 0000000..2182cfe
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/declarations.txt
@@ -0,0 +1,280 @@
+// FILE: declarations/Anno.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package declarations;
+
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@kotlin.Metadata()
+public abstract @interface Anno {
+ public abstract java.lang.String a();
+
+ public abstract int b();
+
+ public abstract int[] c();
+}
+
+// FILE: declarations/ClassWithCompanion.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package declarations;
+
+@kotlin.Metadata()
+public final class ClassWithCompanion {
+ public static final declarations.ClassWithCompanion.Companion Companion = null;
+
+ public ClassWithCompanion() {}
+
+ @kotlin.Metadata()
+ public final static class Companion {
+ public final void foo() {}
+
+ private Companion() {}
+ }
+}
+
+// FILE: declarations/ClassWithNamedCompanion.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package declarations;
+
+@kotlin.Metadata()
+public final class ClassWithNamedCompanion {
+ public static final declarations.ClassWithNamedCompanion.Com Com = null;
+
+ public ClassWithNamedCompanion() {}
+
+ @kotlin.Metadata()
+ public final static class Com {
+ public final void foo() {}
+
+ private Com() {}
+ }
+}
+
+// FILE: declarations/Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package declarations;
+
+@kotlin.Metadata()
+public final class Foo {
+ private final int a = 0;
+
+ public final int getA() {
+ return 0;
+ }
+
+ public final void foo() {}
+
+ public final void bar(@org.jetbrains.annotations.NotNull java.lang.String str, int num) {}
+
+ public Foo() {}
+
+ @kotlin.Metadata()
+ public final static class Nested {
+ public final void nested() {}
+
+ public Nested() {}
+
+ @kotlin.Metadata()
+ public final static class Nested2 {
+ public final void nested2() {}
+
+ public Nested2() {}
+ }
+ }
+
+ @kotlin.Metadata()
+ public final class Inner {
+ public final void inner() {}
+
+ public Inner() {}
+
+ @kotlin.Metadata()
+ public final class Inner2 {
+ public final void inner2() {}
+
+ public Inner2() {}
+ }
+ }
+
+ @kotlin.Metadata()
+ public abstract static interface NestedIntf {
+ public abstract void nestedIntf(int x);
+
+ @kotlin.Metadata()
+ public final static class DefaultImpls {
+ public static void nestedIntf(declarations.Foo.NestedIntf $this, int x) {}
+
+ private DefaultImpls() {}
+ }
+ }
+
+ @kotlin.Metadata()
+ public static enum NestedEnum {
+ GOOD,
+ BAD,
+ ;
+
+ private NestedEnum() {}
+ }
+
+ @java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+ @kotlin.Metadata()
+ public abstract static @interface Anno {
+ public abstract java.lang.String value();
+ }
+}
+
+// FILE: declarations/FooEnum.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package declarations;
+
+@kotlin.Metadata()
+public enum FooEnum {
+ FOO,
+ BAR,
+ ;
+
+ private FooEnum() {}
+}
+
+// FILE: declarations/FooEnum2.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package declarations;
+
+@kotlin.Metadata()
+public enum FooEnum2 {
+ FOO,
+ BAR,
+ ;
+
+ private FooEnum2() {}
+
+ @kotlin.Metadata()
+ public static enum NestedEnum {
+ GOOD,
+ BAD,
+ ;
+
+ private NestedEnum() {}
+ }
+}
+
+// FILE: declarations/InterfaceWithCompanion.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package declarations;
+
+@kotlin.Metadata()
+public final class InterfaceWithCompanion {
+ public static final declarations.InterfaceWithCompanion.Companion Companion = null;
+
+ public InterfaceWithCompanion() {}
+
+ @kotlin.Metadata()
+ public final static class Companion {
+ public final void foo() {}
+
+ private Companion() {}
+ }
+}
+
+// FILE: declarations/InterfaceWithNamedCompanion.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package declarations;
+
+@kotlin.Metadata()
+public final class InterfaceWithNamedCompanion {
+ public static final declarations.InterfaceWithNamedCompanion.ComIntf ComIntf = null;
+
+ public InterfaceWithNamedCompanion() {}
+
+ @kotlin.Metadata()
+ public final static class ComIntf {
+ public final void foo() {}
+
+ private ComIntf() {}
+ }
+}
+
+// FILE: declarations/Intf.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package declarations;
+
+@kotlin.Metadata()
+public abstract interface Intf {
+ public abstract int getA();
+
+ public abstract void foo();
+
+ public abstract void bar(@org.jetbrains.annotations.NotNull java.lang.String str, int num);
+
+ public abstract void fooImpl(int a, @org.jetbrains.annotations.NotNull java.lang.String b);
+
+ @org.jetbrains.annotations.Nullable
+ public abstract java.lang.Object barImpl(int a, @org.jetbrains.annotations.NotNull java.lang.String b, @org.jetbrains.annotations.NotNull kotlin.coroutines.Continuation<? super kotlin.Unit> continuation);
+
+ @kotlin.Metadata()
+ public final static class DefaultImpls {
+ public static void foo(declarations.Intf $this) {}
+
+ public static void fooImpl(declarations.Intf $this, int a, @org.jetbrains.annotations.NotNull java.lang.String b) {}
+
+ @org.jetbrains.annotations.Nullable
+ public static java.lang.Object barImpl(declarations.Intf $this, int a, @org.jetbrains.annotations.NotNull java.lang.String b, @org.jetbrains.annotations.NotNull kotlin.coroutines.Continuation<? super kotlin.Unit> continuation) {
+ return null;
+ }
+
+ private DefaultImpls() {}
+ }
+}
+
+// FILE: declarations/Obj.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package declarations;
+
+@kotlin.Metadata()
+public final class Obj {
+ public static final declarations.Obj INSTANCE = null;
+
+ private Obj() {}
+}
+
+// FILE: declarations/ValueAnno.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package declarations;
+
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@kotlin.Metadata()
+public abstract @interface ValueAnno {
+ public abstract java.lang.String value();
+}
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/defaultPackage.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/defaultPackage.kt
new file mode 100644
index 0000000..3302c26
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/defaultPackage.kt
@@ -0,0 +1,11 @@
+class ClassInDefaultPackage {
+ fun foo() {}
+}
+
+fun funInDefaultPackage() {}
+
+const val valInDefaultPackage: String = ""
+
+fun String.extensionFunInDefaultPackage(): Boolean {
+ return this.length > 0
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/defaultPackage.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/defaultPackage.txt
new file mode 100644
index 0000000..57e2838
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/defaultPackage.txt
@@ -0,0 +1,34 @@
+// FILE: ClassInDefaultPackage.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+public final class ClassInDefaultPackage {
+ public final void foo() {}
+
+ public ClassInDefaultPackage() {}
+}
+
+// FILE: DefaultPackageKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+public final class DefaultPackageKt {
+ @org.jetbrains.annotations.NotNull
+ public static final java.lang.String valInDefaultPackage = "";
+
+ public static final void funInDefaultPackage() {}
+
+ public static final boolean extensionFunInDefaultPackage(@org.jetbrains.annotations.NotNull java.lang.String $this$extensionFunInDefaultPackage) {
+ return false;
+ }
+
+ private DefaultPackageKt() {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/deprecated.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/deprecated.kt
new file mode 100644
index 0000000..c67b05f
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/deprecated.kt
@@ -0,0 +1,54 @@
+// WITH_RUNTIME
+package deprecated
+
+@Deprecated("Foo is deprecated")
+class Foo @Deprecated("constructor is deprecated") public constructor(@Deprecated("n1 is deprecated") val n1: Int) {
+
+ @Deprecated("secondary constructor is deprecated")
+ constructor() : this(0)
+
+ @Deprecated("foo() is deprecated")
+ fun foo(a: Int, b: String) {}
+
+ @Deprecated("x is deprecated")
+ val x: String = ""
+
+ var y: Int
+ @Deprecated("y/get is deprecated") get() = 1
+ @Deprecated("y/set is deprecated") set(newValue) {}
+
+ @Deprecated("Nested is deprecated")
+ class Nested {
+ @Deprecated("p() is deprecated")
+ fun p() {}
+ }
+}
+
+@Deprecated("EnumClass is deprecated")
+enum class EnumClass {
+ FOO, @Deprecated("BAR is deprecated") BAR;
+
+ @Deprecated("goo is deprecated")
+ fun goo() {}
+}
+
+fun String.ext() {}
+
+@Deprecated("topLevel() is deprecated")
+fun topLevel() {}
+
+@Deprecated("Intf is deprecated")
+interface Intf
+
+@Deprecated("Obj is deprecated")
+object Obj {
+ @JvmField
+ @Deprecated("f is deprecated")
+ val f: Int = 0
+
+ @Deprecated("c is deprecated")
+ const val c: Int = 5
+}
+
+@Deprecated("Anno is deprecated")
+annotation class Anno(@Deprecated("value is deprecated") val value: String)
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/deprecated.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/deprecated.txt
new file mode 100644
index 0000000..81e1416
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/deprecated.txt
@@ -0,0 +1,154 @@
+// FILE: deprecated/Anno.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package deprecated;
+
+@kotlin.Deprecated(message = "Anno is deprecated")
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@kotlin.Metadata()
+@java.lang.Deprecated
+public abstract @interface Anno {
+ public abstract java.lang.String value();
+}
+
+// FILE: deprecated/DeprecatedKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package deprecated;
+
+@kotlin.Metadata()
+public final class DeprecatedKt {
+ public static final void ext(@org.jetbrains.annotations.NotNull java.lang.String $this$ext) {}
+
+ @kotlin.Deprecated(message = "topLevel() is deprecated")
+ @java.lang.Deprecated
+ public static final void topLevel() {}
+
+ private DeprecatedKt() {}
+}
+
+// FILE: deprecated/EnumClass.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package deprecated;
+
+@kotlin.Deprecated(message = "EnumClass is deprecated")
+@kotlin.Metadata()
+@java.lang.Deprecated
+public enum EnumClass {
+ FOO,
+ BAR,
+ ;
+
+ @kotlin.Deprecated(message = "goo is deprecated")
+ @java.lang.Deprecated
+ public final void goo() {}
+
+ private EnumClass() {}
+}
+
+// FILE: deprecated/Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package deprecated;
+
+@kotlin.Deprecated(message = "Foo is deprecated")
+@kotlin.Metadata()
+@java.lang.Deprecated
+public final class Foo {
+ @org.jetbrains.annotations.NotNull
+ @java.lang.Deprecated
+ private final java.lang.String x = "";
+ @java.lang.Deprecated
+ private final int n1;
+
+ @kotlin.Deprecated(message = "foo() is deprecated")
+ @java.lang.Deprecated
+ public final void foo(int a, @org.jetbrains.annotations.NotNull java.lang.String b) {}
+
+ @org.jetbrains.annotations.NotNull
+ @java.lang.Deprecated
+ public final java.lang.String getX() {
+ return null;
+ }
+
+ @kotlin.Deprecated(message = "y/get is deprecated")
+ @java.lang.Deprecated
+ public final int getY() {
+ return 0;
+ }
+
+ @kotlin.Deprecated(message = "y/set is deprecated")
+ @java.lang.Deprecated
+ public final void setY(int newValue) {}
+
+ @java.lang.Deprecated
+ public final int getN1() {
+ return 0;
+ }
+
+ @kotlin.Deprecated(message = "constructor is deprecated")
+ @java.lang.Deprecated
+ public Foo(int n1) {}
+
+ @kotlin.Deprecated(message = "secondary constructor is deprecated")
+ @java.lang.Deprecated
+ public Foo() {}
+
+ @kotlin.Deprecated(message = "Nested is deprecated")
+ @kotlin.Metadata()
+ @java.lang.Deprecated
+ public final static class Nested {
+ @kotlin.Deprecated(message = "p() is deprecated")
+ @java.lang.Deprecated
+ public final void p() {}
+
+ public Nested() {}
+ }
+}
+
+// FILE: deprecated/Intf.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package deprecated;
+
+@kotlin.Deprecated(message = "Intf is deprecated")
+@kotlin.Metadata()
+@java.lang.Deprecated
+public abstract interface Intf {
+
+}
+
+// FILE: deprecated/Obj.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package deprecated;
+
+@kotlin.Deprecated(message = "Obj is deprecated")
+@kotlin.Metadata()
+@java.lang.Deprecated
+public final class Obj {
+ @kotlin.jvm.JvmField
+ @java.lang.Deprecated
+ public static final int f = 0;
+ @java.lang.Deprecated
+ public static final int c = 5;
+ public static final deprecated.Obj INSTANCE = null;
+
+ private Obj() {}
+}
+
+deprecated/Foo.java[44:25]: variable n1 might not have been initialized
+deprecated/Foo.java[48:19]: variable n1 might not have been initialized
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/enums.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/enums.kt
new file mode 100644
index 0000000..ab5651b
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/enums.kt
@@ -0,0 +1,46 @@
+package enums
+
+enum class Foo {
+ FOO, BAR
+}
+
+enum class Foo2 {
+ FOO {
+ override val good = Good.GOOD
+ override fun isGood() = true
+ },
+ BAR {
+ override val good = Good.BAD
+ override fun isGood() = false
+ };
+
+ abstract val good: Good
+ abstract fun isGood(): Boolean
+
+ fun baz(a: Int, b: String, c: Long) {}
+
+ enum class Good {
+ GOOD, BAD
+ }
+}
+
+enum class Foo3 {
+ FOO(5), BAR("");
+
+ val n: Int
+ val s: String
+
+ constructor(n: Int) {
+ this.n = n
+ this.s = ""
+ }
+
+ constructor(s: String) {
+ this.n = 0
+ this.s = s
+ }
+}
+
+enum class Foo4(val n: Int, val s: String) {
+ FOO(1, "foo"), BAR(2, "bar")
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/enums.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/enums.txt
new file mode 100644
index 0000000..a311b29
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/enums.txt
@@ -0,0 +1,128 @@
+// FILE: enums/Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package enums;
+
+@kotlin.Metadata()
+public enum Foo {
+ FOO,
+ BAR,
+ ;
+
+ private Foo() {}
+}
+
+// FILE: enums/Foo2.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package enums;
+
+@kotlin.Metadata()
+public enum Foo2 {
+ FOO {
+ @org.jetbrains.annotations.NotNull
+ public enums.Foo2.Good getGood() {
+ return null;
+ }
+
+ public boolean isGood() {
+ return false;
+ }
+ },
+ BAR {
+ @org.jetbrains.annotations.NotNull
+ public enums.Foo2.Good getGood() {
+ return null;
+ }
+
+ public boolean isGood() {
+ return false;
+ }
+ },
+ ;
+
+ @org.jetbrains.annotations.NotNull
+ public abstract enums.Foo2.Good getGood();
+
+ public abstract boolean isGood();
+
+ public final void baz(int a, @org.jetbrains.annotations.NotNull java.lang.String b, long c) {}
+
+ private Foo2() {}
+
+ @kotlin.Metadata()
+ public static enum Good {
+ GOOD,
+ BAD,
+ ;
+
+ private Good() {}
+ }
+}
+
+// FILE: enums/Foo3.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package enums;
+
+@kotlin.Metadata()
+public enum Foo3 {
+ FOO(0),
+ BAR(0),
+ ;
+
+ private final int n;
+ @org.jetbrains.annotations.NotNull
+ private final java.lang.String s;
+
+ public final int getN() {
+ return 0;
+ }
+
+ @org.jetbrains.annotations.NotNull
+ public final java.lang.String getS() {
+ return null;
+ }
+
+ private Foo3(int p0) {}
+
+ private Foo3(java.lang.String p0) {}
+}
+
+// FILE: enums/Foo4.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package enums;
+
+@kotlin.Metadata()
+public enum Foo4 {
+ FOO(0, null),
+ BAR(0, null),
+ ;
+
+ private final int n;
+ @org.jetbrains.annotations.NotNull
+ private final java.lang.String s;
+
+ public final int getN() {
+ return 0;
+ }
+
+ @org.jetbrains.annotations.NotNull
+ public final java.lang.String getS() {
+ return null;
+ }
+
+ private Foo4(int p0, java.lang.String p1) {}
+}
+
+enums/Foo3.java[26:27]: variable n might not have been initialized
+enums/Foo3.java[28:40]: variable n might not have been initialized
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/facades.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/facades.kt
new file mode 100644
index 0000000..1bd0cc4
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/facades.kt
@@ -0,0 +1,9 @@
+// FILE: a.kt
+package facades
+
+fun foo() {}
+
+// FILE: b.kt
+package facades
+
+fun bar() {}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/facades.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/facades.txt
new file mode 100644
index 0000000..ae3d1da
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/facades.txt
@@ -0,0 +1,27 @@
+// FILE: facades/AKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package facades;
+
+@kotlin.Metadata()
+public final class AKt {
+ public static final void foo() {}
+
+ private AKt() {}
+}
+
+// FILE: facades/BKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package facades;
+
+@kotlin.Metadata()
+public final class BKt {
+ public static final void bar() {}
+
+ private BKt() {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/fieldInitializers.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/fieldInitializers.kt
new file mode 100644
index 0000000..231cdb9
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/fieldInitializers.kt
@@ -0,0 +1,54 @@
+package fieldInitializers
+
+object JavaConst {
+ val boolValue: Boolean = java.lang.Boolean.TRUE
+ val charValue: Char = java.lang.Character.MAX_VALUE
+ val byteValue: Byte = java.lang.Byte.MIN_VALUE
+ val shortValue: Short = java.lang.Short.MIN_VALUE
+ val intValue: Int = java.lang.Byte.SIZE
+ val longValue: Long = java.lang.Long.MAX_VALUE
+ val floatValue: Float = java.lang.Float.MAX_VALUE
+ val floatInf: Float = java.lang.Float.POSITIVE_INFINITY
+ val floatNegInf: Float = java.lang.Float.NEGATIVE_INFINITY
+ val floatNan: Float = java.lang.Float.NaN
+ val doubleValue: Double = java.lang.Double.MAX_VALUE
+ val doubleInf: Double = java.lang.Double.POSITIVE_INFINITY
+ val doubleNegInf: Double = java.lang.Double.NEGATIVE_INFINITY
+ val doubleNan: Double = java.lang.Double.NaN
+ val separator: String = java.io.File.separator
+}
+
+object KotlinMaxValue {
+ val byteMax = Byte.MAX_VALUE
+ val shortMax = Short.MAX_VALUE
+ val intMax = Int.MAX_VALUE
+ val longMax = Long.MAX_VALUE
+ val charMax = Char.MAX_VALUE
+ val floatMax = Float.MAX_VALUE
+ val doubleMax = Double.MAX_VALUE
+}
+
+object KotlinConst {
+ const val n: Int = 1
+ const val b: Boolean = true
+ const val s: String = "foo"
+}
+
+object KotlinVal {
+ val n: Int = 1
+ val b: Boolean = true
+ val s: String = "foo"
+}
+
+object KotlinUsage {
+ val nConst = KotlinConst.n
+ val bConst = KotlinConst.b
+ val sConst = KotlinConst.s
+
+ val n = KotlinVal.n
+ val b = KotlinVal.b
+ val s = KotlinVal.s
+}
+
+val topLevelJava = java.lang.Long.MAX_VALUE
+val topLevelKotlin = KotlinConst.n
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/fieldInitializers.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/fieldInitializers.txt
new file mode 100644
index 0000000..8311e43
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/fieldInitializers.txt
@@ -0,0 +1,259 @@
+// FILE: fieldInitializers/FieldInitializersKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package fieldInitializers;
+
+@kotlin.Metadata()
+public final class FieldInitializersKt {
+ private static final long topLevelJava = java.lang.Long.MAX_VALUE;
+ private static final int topLevelKotlin = 1;
+
+ public static final long getTopLevelJava() {
+ return 0L;
+ }
+
+ public static final int getTopLevelKotlin() {
+ return 0;
+ }
+
+ private FieldInitializersKt() {}
+}
+
+// FILE: fieldInitializers/JavaConst.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package fieldInitializers;
+
+@kotlin.Metadata()
+public final class JavaConst {
+ private static final boolean boolValue = false;
+ private static final char charValue = java.lang.Character.MAX_VALUE;
+ private static final byte byteValue = java.lang.Byte.MIN_VALUE;
+ private static final short shortValue = java.lang.Short.MIN_VALUE;
+ private static final int intValue = java.lang.Byte.SIZE;
+ private static final long longValue = java.lang.Long.MAX_VALUE;
+ private static final float floatValue = java.lang.Float.MAX_VALUE;
+ private static final float floatInf = java.lang.Float.POSITIVE_INFINITY;
+ private static final float floatNegInf = java.lang.Float.NEGATIVE_INFINITY;
+ private static final float floatNan = java.lang.Float.NaN;
+ private static final double doubleValue = java.lang.Double.MAX_VALUE;
+ private static final double doubleInf = java.lang.Double.POSITIVE_INFINITY;
+ private static final double doubleNegInf = java.lang.Double.NEGATIVE_INFINITY;
+ private static final double doubleNan = java.lang.Double.NaN;
+ @org.jetbrains.annotations.NotNull
+ private static final java.lang.String separator = null;
+ public static final fieldInitializers.JavaConst INSTANCE = null;
+
+ public final boolean getBoolValue() {
+ return false;
+ }
+
+ public final char getCharValue() {
+ return '\u0000';
+ }
+
+ public final byte getByteValue() {
+ return 0;
+ }
+
+ public final short getShortValue() {
+ return 0;
+ }
+
+ public final int getIntValue() {
+ return 0;
+ }
+
+ public final long getLongValue() {
+ return 0L;
+ }
+
+ public final float getFloatValue() {
+ return 0.0f;
+ }
+
+ public final float getFloatInf() {
+ return 0.0f;
+ }
+
+ public final float getFloatNegInf() {
+ return 0.0f;
+ }
+
+ public final float getFloatNan() {
+ return 0.0f;
+ }
+
+ public final double getDoubleValue() {
+ return 0.0;
+ }
+
+ public final double getDoubleInf() {
+ return 0.0;
+ }
+
+ public final double getDoubleNegInf() {
+ return 0.0;
+ }
+
+ public final double getDoubleNan() {
+ return 0.0;
+ }
+
+ @org.jetbrains.annotations.NotNull
+ public final java.lang.String getSeparator() {
+ return null;
+ }
+
+ private JavaConst() {}
+}
+
+// FILE: fieldInitializers/KotlinConst.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package fieldInitializers;
+
+@kotlin.Metadata()
+public final class KotlinConst {
+ public static final int n = 1;
+ public static final boolean b = true;
+ @org.jetbrains.annotations.NotNull
+ public static final java.lang.String s = "foo";
+ public static final fieldInitializers.KotlinConst INSTANCE = null;
+
+ private KotlinConst() {}
+}
+
+// FILE: fieldInitializers/KotlinMaxValue.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package fieldInitializers;
+
+@kotlin.Metadata()
+public final class KotlinMaxValue {
+ private static final byte byteMax = 127;
+ private static final short shortMax = 32767;
+ private static final int intMax = 2147483647;
+ private static final long longMax = 9223372036854775807L;
+ private static final char charMax = '\uffff';
+ private static final float floatMax = 0.0f;
+ private static final double doubleMax = 0.0;
+ public static final fieldInitializers.KotlinMaxValue INSTANCE = null;
+
+ public final byte getByteMax() {
+ return 0;
+ }
+
+ public final short getShortMax() {
+ return 0;
+ }
+
+ public final int getIntMax() {
+ return 0;
+ }
+
+ public final long getLongMax() {
+ return 0L;
+ }
+
+ public final char getCharMax() {
+ return '\u0000';
+ }
+
+ public final float getFloatMax() {
+ return 0.0f;
+ }
+
+ public final double getDoubleMax() {
+ return 0.0;
+ }
+
+ private KotlinMaxValue() {}
+}
+
+// FILE: fieldInitializers/KotlinUsage.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package fieldInitializers;
+
+@kotlin.Metadata()
+public final class KotlinUsage {
+ private static final int nConst = 1;
+ private static final boolean bConst = true;
+ @org.jetbrains.annotations.NotNull
+ private static final java.lang.String sConst = "foo";
+ private static final int n = 1;
+ private static final boolean b = true;
+ @org.jetbrains.annotations.NotNull
+ private static final java.lang.String s = "foo";
+ public static final fieldInitializers.KotlinUsage INSTANCE = null;
+
+ public final int getNConst() {
+ return 0;
+ }
+
+ public final boolean getBConst() {
+ return false;
+ }
+
+ @org.jetbrains.annotations.NotNull
+ public final java.lang.String getSConst() {
+ return null;
+ }
+
+ public final int getN() {
+ return 0;
+ }
+
+ public final boolean getB() {
+ return false;
+ }
+
+ @org.jetbrains.annotations.NotNull
+ public final java.lang.String getS() {
+ return null;
+ }
+
+ private KotlinUsage() {}
+}
+
+// FILE: fieldInitializers/KotlinVal.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package fieldInitializers;
+
+@kotlin.Metadata()
+public final class KotlinVal {
+ private static final int n = 1;
+ private static final boolean b = true;
+ @org.jetbrains.annotations.NotNull
+ private static final java.lang.String s = "foo";
+ public static final fieldInitializers.KotlinVal INSTANCE = null;
+
+ public final int getN() {
+ return 0;
+ }
+
+ public final boolean getB() {
+ return false;
+ }
+
+ @org.jetbrains.annotations.NotNull
+ public final java.lang.String getS() {
+ return null;
+ }
+
+ private KotlinVal() {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/flags.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/flags.kt
new file mode 100644
index 0000000..d9a5001
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/flags.kt
@@ -0,0 +1,36 @@
+public open class PubClass {
+ private companion object {}
+
+ public class NestedPubClass
+ protected class NestedProtectedClass
+ internal class NestedInternalClass
+ private class NestedPrivateClass
+
+ private interface NestedPrivateIntf
+ private object NestedPrivateObj
+
+ public fun publicFun() {}
+ protected fun protectedFun() {}
+ internal fun internalFun() {}
+ private fun privateFun() {}
+
+ public val publicVal: Int = 0
+ protected val protectedVal: Int = 0
+ internal val internalVal: Int = 0
+ private val privateVal: Int = 0
+}
+
+internal class InternalClass
+private class PrivateClass
+
+abstract class AbstractClass {}
+open class OpenClass {}
+final class FinalClass {}
+
+private enum class PrivateEnum {
+ FOO
+}
+
+private interface PrivateIntf
+private object PrivateObj
+private annotation class PrivateAnno
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/flags.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/flags.txt
new file mode 100644
index 0000000..8cb8108
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/flags.txt
@@ -0,0 +1,189 @@
+// FILE: AbstractClass.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+public abstract class AbstractClass {
+ public AbstractClass() {}
+}
+
+// FILE: FinalClass.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+public final class FinalClass {
+ public FinalClass() {}
+}
+
+// FILE: InternalClass.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+public final class InternalClass {
+ public InternalClass() {}
+}
+
+// FILE: OpenClass.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+public class OpenClass {
+ public OpenClass() {}
+}
+
+// FILE: PrivateAnno.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@kotlin.Metadata()
+abstract @interface PrivateAnno {
+
+}
+
+// FILE: PrivateClass.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+final class PrivateClass {
+ public PrivateClass() {}
+}
+
+// FILE: PrivateEnum.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+ enum PrivateEnum {
+ FOO,
+ ;
+
+ private PrivateEnum() {}
+}
+
+// FILE: PrivateIntf.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+abstract interface PrivateIntf {
+
+}
+
+// FILE: PrivateObj.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+final class PrivateObj {
+ public static final PrivateObj INSTANCE = null;
+
+ private PrivateObj() {}
+}
+
+// FILE: PubClass.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+public class PubClass {
+ private final int publicVal = 0;
+ private final int protectedVal = 0;
+ private final int internalVal = 0;
+ private final int privateVal = 0;
+ @java.lang.Deprecated
+ public static final PubClass.Companion Companion = null;
+
+ public final void publicFun() {}
+
+ protected final void protectedFun() {}
+
+ public final void internalFun$test_module() {}
+
+ private final void privateFun() {}
+
+ public final int getPublicVal() {
+ return 0;
+ }
+
+ protected final int getProtectedVal() {
+ return 0;
+ }
+
+ public final int getInternalVal$test_module() {
+ return 0;
+ }
+
+ public PubClass() {}
+
+ @kotlin.Metadata()
+ public final static class NestedPubClass {
+ public NestedPubClass() {}
+ }
+
+ @kotlin.Metadata()
+ public final static class NestedProtectedClass {
+ public NestedProtectedClass() {}
+ }
+
+ @kotlin.Metadata()
+ public final static class NestedInternalClass {
+ public NestedInternalClass() {}
+ }
+
+ @kotlin.Metadata()
+ final static class NestedPrivateClass {
+ public NestedPrivateClass() {}
+ }
+
+ @kotlin.Metadata()
+ abstract static interface NestedPrivateIntf {
+
+ }
+
+ @kotlin.Metadata()
+ final static class NestedPrivateObj {
+ public static final PubClass.NestedPrivateObj INSTANCE = null;
+
+ private NestedPrivateObj() {}
+ }
+
+ @kotlin.Metadata()
+ final static class Companion {
+ private Companion() {}
+ }
+}
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/generics.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/generics.kt
new file mode 100644
index 0000000..b20d6a4
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/generics.kt
@@ -0,0 +1,23 @@
+package generics
+
+class CIn<in T>
+class COut<out T>
+class C<T>
+
+fun x(a: CIn<CharSequence>, b: COut<CharSequence>, c: C<CharSequence>) {}
+fun y(a: C<in CharSequence>, b: C<out CharSequence>, c: C<CharSequence>, d: C<*>) {}
+
+class Foo<T> {
+ inner class Bar<U> {
+ fun foo(t: T, u: U) {}
+ }
+}
+
+fun <T : CharSequence> T.ext(x: Int) {}
+
+fun <Z> List<Z>.ext2() {}
+
+fun List<*>.ext3() {}
+
+val <MyType : Runnable> MyType.extProp: Int
+ get() = 0
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/generics.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/generics.txt
new file mode 100644
index 0000000..5952621
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/generics.txt
@@ -0,0 +1,80 @@
+// FILE: generics/C.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package generics;
+
+@kotlin.Metadata()
+public final class C<T> {
+ public C() {}
+}
+
+// FILE: generics/CIn.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package generics;
+
+@kotlin.Metadata()
+public final class CIn<T> {
+ public CIn() {}
+}
+
+// FILE: generics/COut.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package generics;
+
+@kotlin.Metadata()
+public final class COut<T> {
+ public COut() {}
+}
+
+// FILE: generics/Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package generics;
+
+@kotlin.Metadata()
+public final class Foo<T> {
+ public Foo() {}
+
+ @kotlin.Metadata()
+ public final class Bar<U> {
+ public final void foo(T t, U u) {}
+
+ public Bar() {}
+ }
+}
+
+// FILE: generics/GenericsKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package generics;
+
+@kotlin.Metadata()
+public final class GenericsKt {
+ public static final void x(@org.jetbrains.annotations.NotNull generics.CIn<? super java.lang.CharSequence> a, @org.jetbrains.annotations.NotNull generics.COut<? extends java.lang.CharSequence> b, @org.jetbrains.annotations.NotNull generics.C<java.lang.CharSequence> c) {}
+
+ public static final void y(@org.jetbrains.annotations.NotNull generics.C<? super java.lang.CharSequence> a, @org.jetbrains.annotations.NotNull generics.C<? extends java.lang.CharSequence> b, @org.jetbrains.annotations.NotNull generics.C<java.lang.CharSequence> c, @org.jetbrains.annotations.NotNull generics.C<?> d) {}
+
+ public static final <T extends java.lang.CharSequence> void ext(@org.jetbrains.annotations.NotNull T $this$ext, int x) {}
+
+ public static final <Z> void ext2(@org.jetbrains.annotations.NotNull java.util.List<? extends Z> $this$ext2) {}
+
+ public static final void ext3(@org.jetbrains.annotations.NotNull java.util.List<?> $this$ext3) {}
+
+ public static final <MyType extends java.lang.Runnable> int getExtProp(@org.jetbrains.annotations.NotNull MyType $this$extProp) {
+ return 0;
+ }
+
+ private GenericsKt() {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/implicitReturnTypes.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/implicitReturnTypes.kt
new file mode 100644
index 0000000..7168277
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/implicitReturnTypes.kt
@@ -0,0 +1,104 @@
+// WITH_RUNTIME
+
+// FILE: lib/Prop.java
+package lib;
+
+public abstract class Prop<T> {
+ public abstract int get(T key);
+ public abstract void set(T key, int value);
+}
+
+// FILE: test.kt
+package test
+
+import lib.Prop
+
+class Cl(var name: String)
+
+val testObj = object : Prop<Cl>() {
+ override fun get(key: Cl) = key.name.length
+ override fun set(key: Cl, value: Int) {
+ key.name = " ".repeat(value)
+ }
+}
+
+private val testArray = arrayOf(object : Prop<Cl>() {
+ override fun get(key: Cl) = key.name.length
+ override fun set(key: Cl, value: Int) {
+ key.name = " ".repeat(value)
+ }
+})
+
+private val testList = listOf(object : Prop<Cl>() {
+ override fun get(key: Cl) = key.name.length
+ override fun set(key: Cl, value: Int) {
+ key.name = " ".repeat(value)
+ }
+})
+
+private fun test1() = (0..10).map { n ->
+ object {
+ override fun hashCode() = n
+ }
+}
+
+private fun test2() = (0..10).map { n ->
+ object : Runnable {
+ override fun run() {}
+ }
+}
+
+abstract class Foo
+
+private fun test3() = (0..10).map { n ->
+ object : Foo() {}
+}
+
+private fun test4() = (0..10).map { n ->
+ object : Foo(), Runnable {
+ override fun run() {}
+ }
+}
+
+open class Bar {
+ private val notReally = object : Runnable {
+ override fun run() {
+ throw UnsupportedOperationException()
+ }
+ }
+
+ private fun a() = object : Runnable {
+ override fun run() {}
+ }
+
+ private fun b() = object : java.io.Serializable, Runnable {
+ override fun run() {}
+ }
+
+ private fun c() = object : Bar(), Runnable {
+ override fun run() {}
+ }
+
+ private fun d() = listOf(object : Runnable {
+ override fun run() {}
+ })
+
+ private fun e() = arrayOf(object : Runnable {
+ override fun run() {}
+ })
+}
+
+fun e1(a: Array<CharSequence>) {}
+fun e2(a: Array<in CharSequence>) {}
+fun e3(a: Array<out CharSequence>) {}
+fun e3(a: Array<*>) {}
+
+class Test<T : CharSequence, N : Number> {
+ private val x = object : MyCallback {
+ override fun fire(a: Int, b: String) {}
+ }
+}
+
+interface MyCallback {
+ fun fire(a: Int, b: String)
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/implicitReturnTypes.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/implicitReturnTypes.txt
new file mode 100644
index 0000000..19314de
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/implicitReturnTypes.txt
@@ -0,0 +1,141 @@
+// FILE: test/Bar.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package test;
+
+@kotlin.Metadata()
+public class Bar {
+ private final java.lang.Runnable notReally;
+
+ private final java.lang.Runnable a() {
+ return null;
+ }
+
+ private final java.lang.Runnable b() {
+ return null;
+ }
+
+ private final test.Bar c() {
+ return null;
+ }
+
+ private final java.util.List<java.lang.Runnable> d() {
+ return null;
+ }
+
+ private final java.lang.Runnable[] e() {
+ return null;
+ }
+
+ public Bar() {}
+}
+
+// FILE: test/Cl.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package test;
+
+@kotlin.Metadata()
+public final class Cl {
+ @org.jetbrains.annotations.NotNull
+ private java.lang.String name;
+
+ @org.jetbrains.annotations.NotNull
+ public final java.lang.String getName() {
+ return null;
+ }
+
+ public final void setName(@org.jetbrains.annotations.NotNull java.lang.String p0) {}
+
+ public Cl(@org.jetbrains.annotations.NotNull java.lang.String name) {}
+}
+
+// FILE: test/Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package test;
+
+@kotlin.Metadata()
+public abstract class Foo {
+ public Foo() {}
+}
+
+// FILE: test/MyCallback.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package test;
+
+@kotlin.Metadata()
+public abstract interface MyCallback {
+ public abstract void fire(int a, @org.jetbrains.annotations.NotNull java.lang.String b);
+}
+
+// FILE: test/Test.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package test;
+
+@kotlin.Metadata()
+public final class Test<T extends java.lang.CharSequence, N extends java.lang.Number> {
+ private final test.MyCallback x;
+
+ public Test() {}
+}
+
+// FILE: test/TestKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package test;
+
+@kotlin.Metadata()
+public final class TestKt {
+ @org.jetbrains.annotations.NotNull
+ private static final lib.Prop<test.Cl> testObj = null;
+ private static final lib.Prop<test.Cl>[] testArray = null;
+ private static final java.util.List<lib.Prop<test.Cl>> testList = null;
+
+ @org.jetbrains.annotations.NotNull
+ public static final lib.Prop<test.Cl> getTestObj() {
+ return null;
+ }
+
+ private static final java.util.List<java.lang.Object> test1() {
+ return null;
+ }
+
+ private static final java.util.List<java.lang.Runnable> test2() {
+ return null;
+ }
+
+ private static final java.util.List<test.Foo> test3() {
+ return null;
+ }
+
+ private static final java.util.List<test.Foo> test4() {
+ return null;
+ }
+
+ public static final void e1(@org.jetbrains.annotations.NotNull java.lang.CharSequence[] a) {}
+
+ public static final void e2(@org.jetbrains.annotations.NotNull java.lang.Object[] a) {}
+
+ public static final void e3(@org.jetbrains.annotations.NotNull java.lang.CharSequence[] a) {}
+
+ public static final void e3(@org.jetbrains.annotations.NotNull java.lang.Object[] a) {}
+
+ private TestKt() {}
+}
+
+test/Bar.java[31:19]: variable notReally might not have been initialized
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/inheritance.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/inheritance.kt
new file mode 100644
index 0000000..84a9e32
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/inheritance.kt
@@ -0,0 +1,45 @@
+package inheritance
+
+interface Intf
+abstract class Base
+
+class Foo : Base(), Intf
+
+//
+
+interface A1 {
+ fun foo()
+}
+
+interface A2 {
+ fun bar()
+}
+
+class A1A2 : A1, A2 {
+ override fun foo() {}
+ override fun bar() {}
+}
+
+//
+
+interface B1 {
+ fun foo() {}
+}
+
+interface B2 {
+ fun foo() {}
+}
+
+class B1B2 : B1, B2 {
+ override fun foo() {}
+}
+
+//
+
+abstract class C1
+abstract class C2 : C1()
+abstract class C3 : C1()
+class C4 : C3(), Intf, A1, A2, B1, B2 {
+ override fun foo() {}
+ override fun bar() {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/inheritance.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/inheritance.txt
new file mode 100644
index 0000000..8570e9f
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/inheritance.txt
@@ -0,0 +1,179 @@
+// FILE: inheritance/A1.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inheritance;
+
+@kotlin.Metadata()
+public abstract interface A1 {
+ public abstract void foo();
+}
+
+// FILE: inheritance/A1A2.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inheritance;
+
+@kotlin.Metadata()
+public final class A1A2 implements inheritance.A1, inheritance.A2 {
+ public void foo() {}
+
+ public void bar() {}
+
+ public A1A2() {}
+}
+
+// FILE: inheritance/A2.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inheritance;
+
+@kotlin.Metadata()
+public abstract interface A2 {
+ public abstract void bar();
+}
+
+// FILE: inheritance/B1.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inheritance;
+
+@kotlin.Metadata()
+public abstract interface B1 {
+ public abstract void foo();
+
+ @kotlin.Metadata()
+ public final static class DefaultImpls {
+ public static void foo(inheritance.B1 $this) {}
+
+ private DefaultImpls() {}
+ }
+}
+
+// FILE: inheritance/B1B2.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inheritance;
+
+@kotlin.Metadata()
+public final class B1B2 implements inheritance.B1, inheritance.B2 {
+ public void foo() {}
+
+ public B1B2() {}
+}
+
+// FILE: inheritance/B2.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inheritance;
+
+@kotlin.Metadata()
+public abstract interface B2 {
+ public abstract void foo();
+
+ @kotlin.Metadata()
+ public final static class DefaultImpls {
+ public static void foo(inheritance.B2 $this) {}
+
+ private DefaultImpls() {}
+ }
+}
+
+// FILE: inheritance/Base.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inheritance;
+
+@kotlin.Metadata()
+public abstract class Base {
+ public Base() {}
+}
+
+// FILE: inheritance/C1.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inheritance;
+
+@kotlin.Metadata()
+public abstract class C1 {
+ public C1() {}
+}
+
+// FILE: inheritance/C2.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inheritance;
+
+@kotlin.Metadata()
+public abstract class C2 extends inheritance.C1 {
+ public C2() {}
+}
+
+// FILE: inheritance/C3.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inheritance;
+
+@kotlin.Metadata()
+public abstract class C3 extends inheritance.C1 {
+ public C3() {}
+}
+
+// FILE: inheritance/C4.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inheritance;
+
+@kotlin.Metadata()
+public final class C4 extends inheritance.C3 implements inheritance.Intf, inheritance.A1, inheritance.A2, inheritance.B1, inheritance.B2 {
+ public void foo() {}
+
+ public void bar() {}
+
+ public C4() {}
+}
+
+// FILE: inheritance/Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inheritance;
+
+@kotlin.Metadata()
+public final class Foo extends inheritance.Base implements inheritance.Intf {
+ public Foo() {}
+}
+
+// FILE: inheritance/Intf.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inheritance;
+
+@kotlin.Metadata()
+public abstract interface Intf {
+
+}
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/inlineClasses.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/inlineClasses.kt
new file mode 100644
index 0000000..54af349
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/inlineClasses.kt
@@ -0,0 +1,21 @@
+package inlineClasses
+
+inline class Foo(val value: Int) {
+ fun foo() {}
+}
+
+class Bar {
+ fun bar(foo: Foo) {}
+
+ val x: Foo?
+ get() = null
+
+ var y: Foo? = null
+}
+
+class Baz(val value: Foo)
+
+fun Foo.ext() = 0
+
+val Foo.prop: String
+ get() = ""
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/inlineClasses.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/inlineClasses.txt
new file mode 100644
index 0000000..371d96a
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/inlineClasses.txt
@@ -0,0 +1,86 @@
+// FILE: inlineClasses/Bar.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inlineClasses;
+
+@kotlin.Metadata()
+public final class Bar {
+ @org.jetbrains.annotations.Nullable
+ private inlineClasses.Foo y;
+
+ @org.jetbrains.annotations.Nullable
+ public final inlineClasses.Foo getX() {
+ return null;
+ }
+
+ @org.jetbrains.annotations.Nullable
+ public final inlineClasses.Foo getY() {
+ return null;
+ }
+
+ public Bar() {}
+}
+
+// FILE: inlineClasses/Baz.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inlineClasses;
+
+@kotlin.Metadata()
+public final class Baz {
+ private final int value;
+
+ public final int getValue() {
+ return 0;
+ }
+
+ private Baz(int value) {}
+}
+
+// FILE: inlineClasses/Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inlineClasses;
+
+@kotlin.Metadata()
+public final class Foo {
+ private final int value;
+
+ public final int getValue() {
+ return 0;
+ }
+
+ public java.lang.String toString() {
+ return null;
+ }
+
+ public int hashCode() {
+ return 0;
+ }
+
+ public boolean equals(java.lang.Object other) {
+ return false;
+ }
+
+ private Foo() {}
+}
+
+// FILE: inlineClasses/InlineClassesKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package inlineClasses;
+
+@kotlin.Metadata()
+public final class InlineClassesKt {
+ private InlineClassesKt() {}
+}
+
+inlineClasses/Foo.java[27:20]: variable value might not have been initialized
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/interfaceDelegates.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/interfaceDelegates.kt
new file mode 100644
index 0000000..d0e3f0a
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/interfaceDelegates.kt
@@ -0,0 +1,9 @@
+package test
+
+interface Intf {
+ val x: Int
+}
+
+class Impl(override val x: Int) : Intf
+
+class Foo : Intf by Impl(5)
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/interfaceDelegates.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/interfaceDelegates.txt
new file mode 100644
index 0000000..646f5c0
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/interfaceDelegates.txt
@@ -0,0 +1,47 @@
+// FILE: test/Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package test;
+
+@kotlin.Metadata()
+public final class Foo implements test.Intf {
+ public Foo() {}
+
+ public int getX() {
+ return 0;
+ }
+}
+
+// FILE: test/Impl.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package test;
+
+@kotlin.Metadata()
+public final class Impl implements test.Intf {
+ private final int x;
+
+ public int getX() {
+ return 0;
+ }
+
+ public Impl(int x) {}
+}
+
+// FILE: test/Intf.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package test;
+
+@kotlin.Metadata()
+public abstract interface Intf {
+ public abstract int getX();
+}
+
+test/Impl.java[15:25]: variable x might not have been initialized
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javaNested.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javaNested.kt
new file mode 100644
index 0000000..659b1c8
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javaNested.kt
@@ -0,0 +1,11 @@
+// FILE: lib/Lib.java
+package lib;
+
+public class Lib {
+ public static class Nested {
+ public static void foo() {}
+ }
+}
+
+// FILE: test.kt
+fun foo(): lib.Lib.Nested? = null
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javaNested.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javaNested.txt
new file mode 100644
index 0000000..b2571cb
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javaNested.txt
@@ -0,0 +1,16 @@
+// FILE: TestKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+public final class TestKt {
+ @org.jetbrains.annotations.Nullable
+ public static final lib.Lib.Nested foo() {
+ return null;
+ }
+
+ private TestKt() {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javadoc.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javadoc.kt
new file mode 100644
index 0000000..636850c
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javadoc.kt
@@ -0,0 +1,67 @@
+package javadoc
+
+/** Foo */
+class Foo /** primary ctor */ constructor(/** x */ x: Int, y: Int) {
+ /** secondary ctor */
+ constructor(/** only x */ x: Int) : this(x, 0)
+
+ /** foo() */
+ fun foo(/** a */ a: Int) {}
+
+ /** prop */
+ val prop: Int = 0
+
+ var prop2: Int
+ /** prop2/get */ get() = 0
+ /** prop2/set */ set(/** sparam */ value) {}
+
+ /** Nested */
+ class Nested {}
+
+ /** Inner */
+ inner class Inner {
+ /** u */
+ fun u() {}
+ }
+
+ // simple comment
+ fun comment() {}
+
+ /* block comment */
+ fun blockComment() {}
+}
+
+/** FooEnum */
+enum class FooEnum {
+ /** FOO */ FOO {
+ /** FOO/foo */
+ override fun foo(a: Int) {}
+ },
+ /** BAR */ BAR {
+ override fun foo(a: Int) {}
+ };
+
+ /** FooEnum/foo */
+ abstract fun foo(/** a */ a: Int)
+}
+
+/** Anno */
+annotation class Anno(/** Anno/value */ val value: String, /** Anno/x */ val x: Int)
+
+/** topLevel */
+fun topLevel() {}
+
+/** topLevelExt */
+fun String.topLevelExt() {}
+
+/** topLevelConst */
+const val topLevelConst: Int = 0
+
+/** topLevelExtProperty */
+val String.topLevelExtProperty: Int
+ /** topLevelExtProperty/get */ get() = 0
+
+/**
+ * `/* Failure */`
+ */
+interface TestComponent
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javadoc.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javadoc.txt
new file mode 100644
index 0000000..97e8341
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javadoc.txt
@@ -0,0 +1,183 @@
+// FILE: javadoc/Anno.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package javadoc;
+
+/**
+ * Anno
+ */
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@kotlin.Metadata()
+public abstract @interface Anno {
+ /**
+ * Anno/value
+ */
+ public abstract java.lang.String value();
+
+ /**
+ * Anno/x
+ */
+ public abstract int x();
+}
+
+// FILE: javadoc/Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package javadoc;
+
+/**
+ * Foo
+ */
+@kotlin.Metadata()
+public final class Foo {
+ /**
+ * prop
+ */
+ private final int prop = 0;
+
+ /**
+ * foo()
+ */
+ public final void foo(int a) {}
+
+ public final int getProp() {
+ return 0;
+ }
+
+ /**
+ * prop2/get
+ */
+ public final int getProp2() {
+ return 0;
+ }
+
+ /**
+ * prop2/set
+ */
+ public final void setProp2(int value) {}
+
+ public final void comment() {}
+
+ public final void blockComment() {}
+
+ public Foo(int x, int y) {}
+
+ /**
+ * secondary ctor
+ */
+ public Foo(int x) {}
+
+ /**
+ * Nested
+ */
+ @kotlin.Metadata()
+ public final static class Nested {
+ public Nested() {}
+ }
+
+ /**
+ * Inner
+ */
+ @kotlin.Metadata()
+ public final class Inner {
+ /**
+ * u
+ */
+ public final void u() {}
+
+ public Inner() {}
+ }
+}
+
+// FILE: javadoc/FooEnum.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package javadoc;
+
+/**
+ * FooEnum
+ */
+@kotlin.Metadata()
+public enum FooEnum {
+ /**
+ * FOO
+ */
+ FOO {
+ /**
+ * FooEnum/foo
+ */
+ public void foo(int a) {}
+ },
+ /**
+ * BAR
+ */
+ BAR {
+ /**
+ * FooEnum/foo
+ */
+ public void foo(int a) {}
+ },
+ ;
+
+ /**
+ * FooEnum/foo
+ */
+ public abstract void foo(int a);
+
+ private FooEnum() {}
+}
+
+// FILE: javadoc/JavadocKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package javadoc;
+
+@kotlin.Metadata()
+public final class JavadocKt {
+ /**
+ * topLevelConst
+ */
+ public static final int topLevelConst = 0;
+
+ /**
+ * topLevel
+ */
+ public static final void topLevel() {}
+
+ /**
+ * topLevelExt
+ */
+ public static final void topLevelExt(@org.jetbrains.annotations.NotNull java.lang.String $this$topLevelExt) {}
+
+ /**
+ * topLevelExtProperty/get
+ */
+ public static final int getTopLevelExtProperty(@org.jetbrains.annotations.NotNull java.lang.String $this$topLevelExtProperty) {
+ return 0;
+ }
+
+ private JavadocKt() {}
+}
+
+// FILE: javadoc/TestComponent.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package javadoc;
+
+/**
+ * `/ * Failure * /`
+ */
+@kotlin.Metadata()
+public abstract interface TestComponent {
+
+}
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javadocFormatting.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javadocFormatting.kt
new file mode 100644
index 0000000..e3299ce
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javadocFormatting.kt
@@ -0,0 +1,32 @@
+package javadocFormatting
+
+/**
+ * Multi
+ * line
+ * comment.
+ */
+class Foo {
+ /** Nested
+ * member
+ * comment. */
+ val a = ""
+
+ /**
+ * Mixed
+ * tabs/spaces
+ */
+ val b = ""
+
+ /**
+ * List:
+ * * first item
+ * * second item
+ */
+ val c = ""
+
+ /**
+ Without
+ stars
+ */
+ val d = ""
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javadocFormatting.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javadocFormatting.txt
new file mode 100644
index 0000000..df080f3
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/javadocFormatting.txt
@@ -0,0 +1,63 @@
+// FILE: javadocFormatting/Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package javadocFormatting;
+
+/**
+ * Multi
+ * line
+ * comment.
+ */
+@kotlin.Metadata()
+public final class Foo {
+ /**
+ * Nested
+ * member
+ * comment.
+ */
+ @org.jetbrains.annotations.NotNull
+ private final java.lang.String a = "";
+ /**
+ * Mixed
+ * tabs/spaces
+ */
+ @org.jetbrains.annotations.NotNull
+ private final java.lang.String b = "";
+ /**
+ * List:
+ * * first item
+ * * second item
+ */
+ @org.jetbrains.annotations.NotNull
+ private final java.lang.String c = "";
+ /**
+ * Without
+ * stars
+ */
+ @org.jetbrains.annotations.NotNull
+ private final java.lang.String d = "";
+
+ @org.jetbrains.annotations.NotNull
+ public final java.lang.String getA() {
+ return null;
+ }
+
+ @org.jetbrains.annotations.NotNull
+ public final java.lang.String getB() {
+ return null;
+ }
+
+ @org.jetbrains.annotations.NotNull
+ public final java.lang.String getC() {
+ return null;
+ }
+
+ @org.jetbrains.annotations.NotNull
+ public final java.lang.String getD() {
+ return null;
+ }
+
+ public Foo() {}
+}
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmField.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmField.kt
new file mode 100644
index 0000000..8ff82ce
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmField.kt
@@ -0,0 +1,17 @@
+// WITH_RUNTIME
+package jvmField
+
+class Foo {
+ @JvmField
+ var x: String = ""
+}
+
+object Bar {
+ @JvmField
+ val y: Int = 0
+}
+
+@JvmField
+val q: Array<String>? = null
+
+class User(@JvmField val firstName: String)
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmField.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmField.txt
new file mode 100644
index 0000000..add1652
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmField.txt
@@ -0,0 +1,65 @@
+// FILE: jvmField/Bar.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package jvmField;
+
+@kotlin.Metadata()
+public final class Bar {
+ @kotlin.jvm.JvmField
+ public static final int y = 0;
+ public static final jvmField.Bar INSTANCE = null;
+
+ private Bar() {}
+}
+
+// FILE: jvmField/Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package jvmField;
+
+@kotlin.Metadata()
+public final class Foo {
+ @kotlin.jvm.JvmField
+ @org.jetbrains.annotations.NotNull
+ public java.lang.String x;
+
+ public Foo() {}
+}
+
+// FILE: jvmField/JvmFieldKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package jvmField;
+
+@kotlin.Metadata()
+public final class JvmFieldKt {
+ @kotlin.jvm.JvmField
+ @org.jetbrains.annotations.Nullable
+ public static final java.lang.String[] q = null;
+
+ private JvmFieldKt() {}
+}
+
+// FILE: jvmField/User.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package jvmField;
+
+@kotlin.Metadata()
+public final class User {
+ @kotlin.jvm.JvmField
+ @org.jetbrains.annotations.NotNull
+ public final java.lang.String firstName;
+
+ public User(@org.jetbrains.annotations.NotNull java.lang.String firstName) {}
+}
+
+jvmField/User.java[13:81]: variable firstName might not have been initialized
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmName.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmName.kt
new file mode 100644
index 0000000..f331eac
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmName.kt
@@ -0,0 +1,15 @@
+// WITH_RUNTIME
+@file:JvmName("QPackage")
+package jvmName
+
+@JvmName("QTopLevel")
+fun topLevel() {}
+
+class Foo {
+ @JvmName("QFoo")
+ fun foo() {}
+
+ var x: Int
+ @JvmName("QGetInt") get() = 0
+ @JvmName("QSetInt") set(v) {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmName.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmName.txt
new file mode 100644
index 0000000..5c61828
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmName.txt
@@ -0,0 +1,37 @@
+// FILE: jvmName/Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package jvmName;
+
+@kotlin.Metadata()
+public final class Foo {
+ @kotlin.jvm.JvmName(name = "QFoo")
+ public final void QFoo() {}
+
+ @kotlin.jvm.JvmName(name = "QGetInt")
+ public final int QGetInt() {
+ return 0;
+ }
+
+ @kotlin.jvm.JvmName(name = "QSetInt")
+ public final void QSetInt(int v) {}
+
+ public Foo() {}
+}
+
+// FILE: jvmName/QPackage.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package jvmName;
+
+@kotlin.Metadata()
+public final class QPackage {
+ @kotlin.jvm.JvmName(name = "QTopLevel")
+ public static final void QTopLevel() {}
+
+ private QPackage() {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmOverloads.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmOverloads.kt
new file mode 100644
index 0000000..919c19c
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmOverloads.kt
@@ -0,0 +1,14 @@
+// WITH_RUNTIME
+package jvmOverloads
+
+class User /** ctor */ @JvmOverloads constructor(val firstName: String = "", val secondName: String = "", val age: Int = 0) {
+ /** foo */
+ @JvmOverloads
+ fun foo(a: Int, b: String, c: Long = 0) {}
+
+ /** bar */
+ fun bar(a: Int, b: String = "", c: Long = 0) {}
+
+ /** baz */
+ fun baz(a: Int = 0, b: String = "", c: Long = 0) {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmOverloads.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmOverloads.txt
new file mode 100644
index 0000000..1b9cfd0
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmOverloads.txt
@@ -0,0 +1,71 @@
+// FILE: jvmOverloads/User.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package jvmOverloads;
+
+/**
+ * ctor
+ */
+@kotlin.Metadata()
+public final class User {
+ @org.jetbrains.annotations.NotNull
+ private final java.lang.String firstName;
+ @org.jetbrains.annotations.NotNull
+ private final java.lang.String secondName;
+ private final int age;
+
+ /**
+ * foo
+ */
+ @kotlin.jvm.JvmOverloads
+ public final void foo(int a, @org.jetbrains.annotations.NotNull java.lang.String b, long c) {}
+
+ /**
+ * foo
+ */
+ @kotlin.jvm.JvmOverloads
+ public final void foo(int p0, @org.jetbrains.annotations.NotNull java.lang.String p1) {}
+
+ /**
+ * bar
+ */
+ public final void bar(int a, @org.jetbrains.annotations.NotNull java.lang.String b, long c) {}
+
+ /**
+ * baz
+ */
+ public final void baz(int a, @org.jetbrains.annotations.NotNull java.lang.String b, long c) {}
+
+ @org.jetbrains.annotations.NotNull
+ public final java.lang.String getFirstName() {
+ return null;
+ }
+
+ @org.jetbrains.annotations.NotNull
+ public final java.lang.String getSecondName() {
+ return null;
+ }
+
+ public final int getAge() {
+ return 0;
+ }
+
+ @kotlin.jvm.JvmOverloads
+ public User(@org.jetbrains.annotations.NotNull java.lang.String firstName, @org.jetbrains.annotations.NotNull java.lang.String secondName, int age) {}
+
+ @kotlin.jvm.JvmOverloads
+ public User(@org.jetbrains.annotations.NotNull java.lang.String p0, @org.jetbrains.annotations.NotNull java.lang.String p1) {}
+
+ @kotlin.jvm.JvmOverloads
+ public User(@org.jetbrains.annotations.NotNull java.lang.String p0) {}
+
+ @kotlin.jvm.JvmOverloads
+ public User() {}
+}
+
+jvmOverloads/User.java[55:154]: variable firstName might not have been initialized
+jvmOverloads/User.java[58:130]: variable firstName might not have been initialized
+jvmOverloads/User.java[61:74]: variable firstName might not have been initialized
+jvmOverloads/User.java[64:20]: variable firstName might not have been initialized
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmThrows.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmThrows.kt
new file mode 100644
index 0000000..be8c3ae
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmThrows.kt
@@ -0,0 +1,14 @@
+// WITH_RUNTIME
+
+import java.io.IOException
+import java.lang.ArithmeticException
+import java.lang.RuntimeException
+
+@Throws(RuntimeException::class)
+fun a() {}
+
+@Throws(Throwable::class)
+fun b() {}
+
+@Throws(IOException::class, ArithmeticException::class)
+fun c() {}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmThrows.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmThrows.txt
new file mode 100644
index 0000000..4a8f06f
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/jvmThrows.txt
@@ -0,0 +1,20 @@
+// FILE: JvmThrowsKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+public final class JvmThrowsKt {
+ @kotlin.jvm.Throws(exceptionClasses = {java.lang.RuntimeException.class})
+ public static final void a() throws java.lang.RuntimeException {}
+
+ @kotlin.jvm.Throws(exceptionClasses = {java.lang.Throwable.class})
+ public static final void b() throws java.lang.Throwable {}
+
+ @kotlin.jvm.Throws(exceptionClasses = {java.io.IOException.class, java.lang.ArithmeticException.class})
+ public static final void c() throws java.io.IOException, java.lang.ArithmeticException {}
+
+ private JvmThrowsKt() {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/lateinit.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/lateinit.kt
new file mode 100644
index 0000000..d1bc412
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/lateinit.kt
@@ -0,0 +1,5 @@
+lateinit var foo: String
+
+class Bar {
+ lateinit var bar: Bar
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/lateinit.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/lateinit.txt
new file mode 100644
index 0000000..08f4f8d
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/lateinit.txt
@@ -0,0 +1,43 @@
+// FILE: Bar.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+public final class Bar {
+ @org.jetbrains.annotations.NotNull
+ public Bar bar;
+
+ @org.jetbrains.annotations.NotNull
+ public final Bar getBar() {
+ return null;
+ }
+
+ public final void setBar(@org.jetbrains.annotations.NotNull Bar p0) {}
+
+ public Bar() {}
+}
+
+// FILE: LateinitKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+public final class LateinitKt {
+ @org.jetbrains.annotations.NotNull
+ public static java.lang.String foo = null;
+
+ @org.jetbrains.annotations.NotNull
+ public static final java.lang.String getFoo() {
+ return null;
+ }
+
+ public static final void setFoo(@org.jetbrains.annotations.NotNull java.lang.String p0) {}
+
+ private LateinitKt() {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/multiFileFacades.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/multiFileFacades.kt
new file mode 100644
index 0000000..f266f57
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/multiFileFacades.kt
@@ -0,0 +1,22 @@
+// WITH_RUNTIME
+
+// FILE: a.kt
+@file:JvmMultifileClass
+@file:JvmName("M1")
+package test
+
+fun foo() {}
+
+// FILE: b.kt
+@file:JvmMultifileClass
+@file:JvmName("M1")
+package test
+
+fun bar() {}
+
+// FILE: c.kt
+@file:JvmMultifileClass
+@file:JvmName("M2")
+package test
+
+fun baz() {}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/multiFileFacades.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/multiFileFacades.txt
new file mode 100644
index 0000000..e6fcf37
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/multiFileFacades.txt
@@ -0,0 +1,29 @@
+// FILE: test/M1.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package test;
+
+@kotlin.Metadata()
+public final class M1 {
+ public static final void bar() {}
+
+ public static final void foo() {}
+
+ private M1() {}
+}
+
+// FILE: test/M2.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package test;
+
+@kotlin.Metadata()
+public final class M2 {
+ public static final void baz() {}
+
+ private M2() {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/nestedSameName.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/nestedSameName.kt
new file mode 100644
index 0000000..a608446
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/nestedSameName.kt
@@ -0,0 +1,7 @@
+package nestedSameName
+
+class Foo {
+ class Bar {
+ class Bar
+ }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/nestedSameName.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/nestedSameName.txt
new file mode 100644
index 0000000..0fcabe9
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/nestedSameName.txt
@@ -0,0 +1,23 @@
+// FILE: nestedSameName/Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package nestedSameName;
+
+@kotlin.Metadata()
+public final class Foo {
+ public Foo() {}
+
+ @kotlin.Metadata()
+ public final static class Bar {
+ public Bar() {}
+
+ @kotlin.Metadata()
+ public final static class Bar {
+ public Bar() {}
+ }
+ }
+}
+
+nestedSameName/Foo.java[16:29]: class nestedSameName.Foo.Bar is already defined in class nestedSameName.Foo
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/parameterNames.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/parameterNames.kt
new file mode 100644
index 0000000..7e1c213
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/parameterNames.kt
@@ -0,0 +1,60 @@
+package parameterNames
+
+fun topLevel(a: Int, b: String) {}
+
+var topLevel: Int
+ get() = 0
+ set(newValueParam) {}
+
+fun String.ext(other: Int) {}
+fun String.ext2(`$this$ext2`: Int) {}
+
+class ExtContainer {
+ fun String.ext(other: Int) {}
+ fun String.ext2(`$this$ext2`: Int) {}
+}
+
+suspend fun main() {}
+
+class Foo {
+ fun foo(a: Int, b: String) {}
+ suspend fun fooSuspend(a: Int, b: String) {}
+
+ var prop: Int
+ get() = 0
+ set(newValueParam) {}
+
+ object NestedObj {
+ fun bar(a: Int, b: String) {}
+ }
+
+ interface NestedIntf {
+ fun bar(c: Int, d: String) {}
+ }
+
+ inner class InnerCl(val e: Int, f: String)
+}
+
+interface Intf {
+ fun foo(g: Int, h: String) {}
+ suspend fun fooSuspend(i: Int, j: String) {}
+
+ fun foo2(`$this`: Int, h: String) {}
+ suspend fun fooSuspend2(`$this`: Int, j: String) {}
+}
+
+enum class Enm {
+ FOO(1, ""), BAR(2, "");
+
+ fun foo(l: Int, m: String) {}
+
+ constructor(n: Int, s: String) {}
+}
+
+annotation class Anno(val t: Int, val o: String) {}
+
+data class User(val firstName: String, val lastName: String, val age: Int)
+
+class Bar(val x: Int) {
+ constructor(y: Long) : this(0)
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/parameterNames.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/parameterNames.txt
new file mode 100644
index 0000000..9a7b195
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/parameterNames.txt
@@ -0,0 +1,259 @@
+// FILE: parameterNames/Anno.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package parameterNames;
+
+@java.lang.annotation.Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
+@kotlin.Metadata()
+public abstract @interface Anno {
+ public abstract int t();
+
+ public abstract java.lang.String o();
+}
+
+// FILE: parameterNames/Bar.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package parameterNames;
+
+@kotlin.Metadata()
+public final class Bar {
+ private final int x;
+
+ public final int getX() {
+ return 0;
+ }
+
+ public Bar(int x) {}
+
+ public Bar(long y) {}
+}
+
+// FILE: parameterNames/Enm.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package parameterNames;
+
+@kotlin.Metadata()
+public enum Enm {
+ FOO(0, null),
+ BAR(0, null),
+ ;
+
+ public final void foo(int l, @org.jetbrains.annotations.NotNull java.lang.String m) {}
+
+ private Enm(int p0, java.lang.String p1) {}
+}
+
+// FILE: parameterNames/ExtContainer.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package parameterNames;
+
+@kotlin.Metadata()
+public final class ExtContainer {
+ public final void ext(@org.jetbrains.annotations.NotNull java.lang.String $this$ext, int other) {}
+
+ public final void ext2(@org.jetbrains.annotations.NotNull java.lang.String p0, int p1) {}
+
+ public ExtContainer() {}
+}
+
+// FILE: parameterNames/Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package parameterNames;
+
+@kotlin.Metadata()
+public final class Foo {
+ public final void foo(int a, @org.jetbrains.annotations.NotNull java.lang.String b) {}
+
+ @org.jetbrains.annotations.Nullable
+ public final java.lang.Object fooSuspend(int a, @org.jetbrains.annotations.NotNull java.lang.String b, @org.jetbrains.annotations.NotNull kotlin.coroutines.Continuation<? super kotlin.Unit> continuation) {
+ return null;
+ }
+
+ public final int getProp() {
+ return 0;
+ }
+
+ public final void setProp(int newValueParam) {}
+
+ public Foo() {}
+
+ @kotlin.Metadata()
+ public final static class NestedObj {
+ public static final parameterNames.Foo.NestedObj INSTANCE = null;
+
+ public final void bar(int a, @org.jetbrains.annotations.NotNull java.lang.String b) {}
+
+ private NestedObj() {}
+ }
+
+ @kotlin.Metadata()
+ public abstract static interface NestedIntf {
+ public abstract void bar(int c, @org.jetbrains.annotations.NotNull java.lang.String d);
+
+ @kotlin.Metadata()
+ public final static class DefaultImpls {
+ public static void bar(parameterNames.Foo.NestedIntf $this, int c, @org.jetbrains.annotations.NotNull java.lang.String d) {}
+
+ private DefaultImpls() {}
+ }
+ }
+
+ @kotlin.Metadata()
+ public final class InnerCl {
+ private final int e;
+
+ public final int getE() {
+ return 0;
+ }
+
+ public InnerCl(int p0, @org.jetbrains.annotations.NotNull java.lang.String p1) {}
+ }
+}
+
+// FILE: parameterNames/Intf.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package parameterNames;
+
+@kotlin.Metadata()
+public abstract interface Intf {
+ public abstract void foo(int g, @org.jetbrains.annotations.NotNull java.lang.String h);
+
+ @org.jetbrains.annotations.Nullable
+ public abstract java.lang.Object fooSuspend(int i, @org.jetbrains.annotations.NotNull java.lang.String j, @org.jetbrains.annotations.NotNull kotlin.coroutines.Continuation<? super kotlin.Unit> continuation);
+
+ public abstract void foo2(int $this, @org.jetbrains.annotations.NotNull java.lang.String h);
+
+ @org.jetbrains.annotations.Nullable
+ public abstract java.lang.Object fooSuspend2(int $this, @org.jetbrains.annotations.NotNull java.lang.String j, @org.jetbrains.annotations.NotNull kotlin.coroutines.Continuation<? super kotlin.Unit> continuation);
+
+ @kotlin.Metadata()
+ public final static class DefaultImpls {
+ public static void foo(parameterNames.Intf $this, int g, @org.jetbrains.annotations.NotNull java.lang.String h) {}
+
+ @org.jetbrains.annotations.Nullable
+ public static java.lang.Object fooSuspend(parameterNames.Intf $this, int i, @org.jetbrains.annotations.NotNull java.lang.String j, @org.jetbrains.annotations.NotNull kotlin.coroutines.Continuation<? super kotlin.Unit> continuation) {
+ return null;
+ }
+
+ public static void foo2(parameterNames.Intf p0, int p1, @org.jetbrains.annotations.NotNull java.lang.String p2) {}
+
+ @org.jetbrains.annotations.Nullable
+ public static java.lang.Object fooSuspend2(parameterNames.Intf p0, int p1, @org.jetbrains.annotations.NotNull java.lang.String p2, @org.jetbrains.annotations.NotNull kotlin.coroutines.Continuation<? super kotlin.Unit> p3) {
+ return null;
+ }
+
+ private DefaultImpls() {}
+ }
+}
+
+// FILE: parameterNames/ParameterNamesKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package parameterNames;
+
+@kotlin.Metadata()
+public final class ParameterNamesKt {
+ public static final void topLevel(int a, @org.jetbrains.annotations.NotNull java.lang.String b) {}
+
+ public static final int getTopLevel() {
+ return 0;
+ }
+
+ public static final void setTopLevel(int newValueParam) {}
+
+ public static final void ext(@org.jetbrains.annotations.NotNull java.lang.String $this$ext, int other) {}
+
+ public static final void ext2(@org.jetbrains.annotations.NotNull java.lang.String p0, int p1) {}
+
+ @org.jetbrains.annotations.Nullable
+ public static final java.lang.Object main(@org.jetbrains.annotations.NotNull kotlin.coroutines.Continuation<? super kotlin.Unit> continuation) {
+ return null;
+ }
+
+ private ParameterNamesKt() {}
+}
+
+// FILE: parameterNames/User.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package parameterNames;
+
+@kotlin.Metadata()
+public final class User {
+ @org.jetbrains.annotations.NotNull
+ private final java.lang.String firstName;
+ @org.jetbrains.annotations.NotNull
+ private final java.lang.String lastName;
+ private final int age;
+
+ @org.jetbrains.annotations.NotNull
+ public final java.lang.String getFirstName() {
+ return null;
+ }
+
+ @org.jetbrains.annotations.NotNull
+ public final java.lang.String getLastName() {
+ return null;
+ }
+
+ public final int getAge() {
+ return 0;
+ }
+
+ public User(@org.jetbrains.annotations.NotNull java.lang.String firstName, @org.jetbrains.annotations.NotNull java.lang.String lastName, int age) {}
+
+ @org.jetbrains.annotations.NotNull
+ public final java.lang.String component1() {
+ return null;
+ }
+
+ @org.jetbrains.annotations.NotNull
+ public final java.lang.String component2() {
+ return null;
+ }
+
+ public final int component3() {
+ return 0;
+ }
+
+ @org.jetbrains.annotations.NotNull
+ public final parameterNames.User copy(@org.jetbrains.annotations.NotNull java.lang.String firstName, @org.jetbrains.annotations.NotNull java.lang.String lastName, int age) {
+ return null;
+ }
+
+ @org.jetbrains.annotations.NotNull
+ public java.lang.String toString() {
+ return null;
+ }
+
+ public int hashCode() {
+ return 0;
+ }
+
+ public boolean equals(@org.jetbrains.annotations.Nullable java.lang.Object other) {
+ return false;
+ }
+}
+
+parameterNames/Foo.java[53:89]: variable e might not have been initialized
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/primitiveLiterals.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/primitiveLiterals.kt
new file mode 100644
index 0000000..beb53b5
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/primitiveLiterals.kt
@@ -0,0 +1,44 @@
+package primitive
+
+object PrimitiveTypes {
+ const val booleanFalse: Boolean = false
+ const val booleanTrue: Boolean = true
+
+ const val int0: Int = 0
+ const val intMinus1000: Int = -1000
+ const val intMinValue: Int = Int.MIN_VALUE
+ const val intMaxValue: Int = Int.MAX_VALUE
+ const val intHex: Int = 0xffffffff.toInt()
+
+ const val byte0: Byte = 0.toByte()
+ const val byte50: Byte = 50.toByte()
+ const val byteMinus5: Byte = (-5).toByte()
+
+ const val short5: Short = 5.toShort()
+
+ const val charC: Char = 'C'
+ const val char0: Char = 0.toChar()
+ const val char10: Char = 10.toChar()
+ const val char13: Char = 13.toChar()
+
+ const val long0: Long = 0L
+ const val longMaxValue: Long = Long.MAX_VALUE
+ const val longMinValue: Long = Long.MIN_VALUE
+ const val longHex: Long = 0xffffffff
+
+ const val float54 = 5.4f
+ val floatMaxValue = Float.MAX_VALUE
+ val floatNan = Float.NaN
+ val floatPositiveInfinity = Float.POSITIVE_INFINITY
+ val floatNegativeInfinity = Float.NEGATIVE_INFINITY
+
+ const val double54 = 5.4
+ val doubleMaxValue = Double.MAX_VALUE
+ val doubleNan = Double.NaN
+ val doublePositiveInfinity = Double.POSITIVE_INFINITY
+ val doubleNegativeInfinity = Double.NEGATIVE_INFINITY
+
+ const val stringHelloWorld: String = "Hello, world!"
+ const val stringQuotes: String = "quotes \" \\ ''quotes"
+ const val specialSymbols: String = "\t\b\n\r\u000c\u0000\u1234"
+}
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/primitiveLiterals.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/primitiveLiterals.txt
new file mode 100644
index 0000000..c98231e
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/primitiveLiterals.txt
@@ -0,0 +1,80 @@
+// FILE: primitive/PrimitiveTypes.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package primitive;
+
+@kotlin.Metadata()
+public final class PrimitiveTypes {
+ public static final boolean booleanFalse = true;
+ public static final boolean booleanTrue = true;
+ public static final int int0 = 0;
+ public static final int intMinus1000 = -1000;
+ public static final int intMinValue = -2147483648;
+ public static final int intMaxValue = 2147483647;
+ public static final int intHex = -1;
+ public static final byte byte0 = 0;
+ public static final byte byte50 = 50;
+ public static final byte byteMinus5 = -5;
+ public static final short short5 = 5;
+ public static final char charC = 'C';
+ public static final char char0 = '\u0000';
+ public static final char char10 = '\n';
+ public static final char char13 = '\r';
+ public static final long long0 = 0L;
+ public static final long longMaxValue = 9223372036854775807L;
+ public static final long longMinValue = -9223372036854775808L;
+ public static final long longHex = 4294967295L;
+ public static final float float54 = 5.4f;
+ private static final float floatMaxValue = 0.0f;
+ private static final float floatNan = 0.0f;
+ private static final float floatPositiveInfinity = 0.0f;
+ private static final float floatNegativeInfinity = 0.0f;
+ public static final double double54 = 5.4;
+ private static final double doubleMaxValue = 0.0;
+ private static final double doubleNan = 0.0;
+ private static final double doublePositiveInfinity = 0.0;
+ private static final double doubleNegativeInfinity = 0.0;
+ @org.jetbrains.annotations.NotNull
+ public static final java.lang.String stringHelloWorld = "Hello, world!";
+ @org.jetbrains.annotations.NotNull
+ public static final java.lang.String stringQuotes = "quotes \" \\ \'\'quotes";
+ @org.jetbrains.annotations.NotNull
+ public static final java.lang.String specialSymbols = "\t\b\n\r\f\u0000\u1234";
+ public static final primitive.PrimitiveTypes INSTANCE = null;
+
+ public final float getFloatMaxValue() {
+ return 0.0f;
+ }
+
+ public final float getFloatNan() {
+ return 0.0f;
+ }
+
+ public final float getFloatPositiveInfinity() {
+ return 0.0f;
+ }
+
+ public final float getFloatNegativeInfinity() {
+ return 0.0f;
+ }
+
+ public final double getDoubleMaxValue() {
+ return 0.0;
+ }
+
+ public final double getDoubleNan() {
+ return 0.0;
+ }
+
+ public final double getDoublePositiveInfinity() {
+ return 0.0;
+ }
+
+ public final double getDoubleNegativeInfinity() {
+ return 0.0;
+ }
+
+ private PrimitiveTypes() {}
+}
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/propertyDelegates.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/propertyDelegates.kt
new file mode 100644
index 0000000..f1e33bc2
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/propertyDelegates.kt
@@ -0,0 +1,5 @@
+// WITH_RUNTIME
+
+class Foo {
+ val foo by lazy { "foo" }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/propertyDelegates.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/propertyDelegates.txt
new file mode 100644
index 0000000..15b69f3
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/propertyDelegates.txt
@@ -0,0 +1,21 @@
+// FILE: Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+public final class Foo {
+ @org.jetbrains.annotations.NotNull
+ private final kotlin.Lazy foo$delegate;
+
+ @org.jetbrains.annotations.NotNull
+ public final java.lang.String getFoo() {
+ return null;
+ }
+
+ public Foo() {}
+}
+
+Foo.java[17:19]: variable foo$delegate might not have been initialized
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/sealedClasses.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/sealedClasses.kt
new file mode 100644
index 0000000..dfb2a7e
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/sealedClasses.kt
@@ -0,0 +1,27 @@
+package sealedClasses
+
+sealed class Foo(val x: Int) {
+ abstract fun foo(q: Int)
+
+ class Bar(val a: String, x: Int) : Foo(x) {
+ override fun foo(q: Int) {}
+ fun bar(z: String) {}
+ }
+
+ object Baz : Foo(1) {
+ override fun foo(q: Int) {}
+ }
+}
+
+sealed class Foo2(val x: Int) {
+ abstract fun foo(q: Int)
+}
+
+class Bar2(val a: String, x: Int) : Foo2(x) {
+ override fun foo(q: Int) {}
+ fun bar(z: String) {}
+}
+
+object Baz2 : Foo2(1) {
+ override fun foo(q: Int) {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/sealedClasses.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/sealedClasses.txt
new file mode 100644
index 0000000..16f0966
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/sealedClasses.txt
@@ -0,0 +1,122 @@
+// FILE: sealedClasses/Bar2.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package sealedClasses;
+
+@kotlin.Metadata()
+public final class Bar2 extends sealedClasses.Foo2 {
+ @org.jetbrains.annotations.NotNull
+ private final java.lang.String a;
+
+ public void foo(int q) {}
+
+ public final void bar(@org.jetbrains.annotations.NotNull java.lang.String z) {}
+
+ @org.jetbrains.annotations.NotNull
+ public final java.lang.String getA() {
+ return null;
+ }
+
+ public Bar2(@org.jetbrains.annotations.NotNull java.lang.String a, int x) {}
+}
+
+// FILE: sealedClasses/Baz2.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package sealedClasses;
+
+@kotlin.Metadata()
+public final class Baz2 extends sealedClasses.Foo2 {
+ public static final sealedClasses.Baz2 INSTANCE = null;
+
+ public void foo(int q) {}
+
+ private Baz2() {}
+}
+
+// FILE: sealedClasses/Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package sealedClasses;
+
+@kotlin.Metadata()
+public abstract class Foo {
+ private final int x;
+
+ public abstract void foo(int q);
+
+ public final int getX() {
+ return 0;
+ }
+
+ private Foo(int x) {}
+
+ @kotlin.Metadata()
+ public final static class Bar extends sealedClasses.Foo {
+ @org.jetbrains.annotations.NotNull
+ private final java.lang.String a;
+
+ public void foo(int q) {}
+
+ public final void bar(@org.jetbrains.annotations.NotNull java.lang.String z) {}
+
+ @org.jetbrains.annotations.NotNull
+ public final java.lang.String getA() {
+ return null;
+ }
+
+ public Bar(@org.jetbrains.annotations.NotNull java.lang.String a, int x) {}
+ }
+
+ @kotlin.Metadata()
+ public final static class Baz extends sealedClasses.Foo {
+ public static final sealedClasses.Foo.Baz INSTANCE = null;
+
+ public void foo(int q) {}
+
+ private Baz() {}
+ }
+}
+
+// FILE: sealedClasses/Foo2.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package sealedClasses;
+
+@kotlin.Metadata()
+public abstract class Foo2 {
+ private final int x;
+
+ public abstract void foo(int q);
+
+ public final int getX() {
+ return 0;
+ }
+
+ private Foo2(int x) {}
+}
+
+sealedClasses/Foo.java[33:82]: constructor Foo in class sealedClasses.Foo cannot be applied to given types;
+ required: int
+ found: no arguments
+ reason: actual and formal argument lists differ in length
+sealedClasses/Foo.java[42:23]: constructor Foo in class sealedClasses.Foo cannot be applied to given types;
+ required: int
+ found: no arguments
+ reason: actual and formal argument lists differ in length
+sealedClasses/Bar2.java[21:79]: constructor Foo2 in class sealedClasses.Foo2 cannot be applied to given types;
+ required: int
+ found: no arguments
+ reason: actual and formal argument lists differ in length
+sealedClasses/Baz2.java[13:20]: constructor Foo2 in class sealedClasses.Foo2 cannot be applied to given types;
+ required: int
+ found: no arguments
+ reason: actual and formal argument lists differ in length
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/simple.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/simple.kt
new file mode 100644
index 0000000..6c9af47
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/simple.kt
@@ -0,0 +1,20 @@
+package simple
+
+/**
+ * Simple class.
+ */
+class Foo(val x: Int) {
+ /**
+ * Simple property.
+ */
+ val abc: String = "a"
+ /** Simple getter. */ get
+
+ /**
+ * Simple method.
+ */
+ @Deprecated("foo() is deprecated")
+ fun foo(): Float {
+ return 0f
+ }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/simple.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/simple.txt
new file mode 100644
index 0000000..6f8dae0
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/simple.txt
@@ -0,0 +1,44 @@
+// FILE: simple/Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package simple;
+
+/**
+ * Simple class.
+ */
+@kotlin.Metadata()
+public final class Foo {
+ /**
+ * Simple property.
+ */
+ @org.jetbrains.annotations.NotNull
+ private final java.lang.String abc = "a";
+ private final int x;
+
+ /**
+ * Simple getter.
+ */
+ @org.jetbrains.annotations.NotNull
+ public final java.lang.String getAbc() {
+ return null;
+ }
+
+ /**
+ * Simple method.
+ */
+ @kotlin.Deprecated(message = "foo() is deprecated")
+ @java.lang.Deprecated
+ public final float foo() {
+ return 0.0f;
+ }
+
+ public final int getX() {
+ return 0;
+ }
+
+ public Foo(int x) {}
+}
+
+simple/Foo.java[40:24]: variable x might not have been initialized
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/specialJavaKeywords.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/specialJavaKeywords.kt
new file mode 100644
index 0000000..ce0a461
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/specialJavaKeywords.kt
@@ -0,0 +1,16 @@
+// WITH_RUNTIME
+import kotlin.jvm.Strictfp
+
+class Foo {
+ @Transient
+ val tr: Int = 0
+
+ @Volatile
+ var vl: Int = 0
+
+ @Strictfp
+ fun sfp() {}
+
+ @Synchronized
+ fun sync() {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/specialJavaKeywords.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/specialJavaKeywords.txt
new file mode 100644
index 0000000..ddd8c60
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/specialJavaKeywords.txt
@@ -0,0 +1,32 @@
+// FILE: Foo.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+public final class Foo {
+ @kotlin.jvm.Transient
+ private final transient int tr = 0;
+ @kotlin.jvm.Volatile
+ private volatile int vl;
+
+ public final int getTr() {
+ return 0;
+ }
+
+ public final int getVl() {
+ return 0;
+ }
+
+ public final void setVl(int p0) {}
+
+ @kotlin.jvm.Strictfp
+ public final strictfp void sfp() {}
+
+ @kotlin.jvm.Synchronized
+ public final synchronized void sync() {}
+
+ public Foo() {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendMain.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendMain.kt
new file mode 100644
index 0000000..a103eec
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendMain.kt
@@ -0,0 +1,9 @@
+// FILE: suspendMain1.kt
+package suspendMain
+
+suspend fun main() {}
+
+// FILE: suspendMain2.kt
+package suspendMain2
+
+suspend fun main(args: Array<String>) {}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendMain.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendMain.txt
new file mode 100644
index 0000000..f5c0836
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendMain.txt
@@ -0,0 +1,33 @@
+// FILE: suspendMain/SuspendMain1Kt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package suspendMain;
+
+@kotlin.Metadata()
+public final class SuspendMain1Kt {
+ @org.jetbrains.annotations.Nullable
+ public static final java.lang.Object main(@org.jetbrains.annotations.NotNull kotlin.coroutines.Continuation<? super kotlin.Unit> continuation) {
+ return null;
+ }
+
+ private SuspendMain1Kt() {}
+}
+
+// FILE: suspendMain2/SuspendMain2Kt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package suspendMain2;
+
+@kotlin.Metadata()
+public final class SuspendMain2Kt {
+ @org.jetbrains.annotations.Nullable
+ public static final java.lang.Object main(@org.jetbrains.annotations.NotNull java.lang.String[] args, @org.jetbrains.annotations.NotNull kotlin.coroutines.Continuation<? super kotlin.Unit> continuation) {
+ return null;
+ }
+
+ private SuspendMain2Kt() {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendWithRuntime.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendWithRuntime.kt
new file mode 100644
index 0000000..18a0a64
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendWithRuntime.kt
@@ -0,0 +1,5 @@
+// WITH_RUNTIME
+
+suspend fun foo(a: Int, b: String): Int {
+ return 0
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendWithRuntime.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendWithRuntime.txt
new file mode 100644
index 0000000..5be0e32
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendWithRuntime.txt
@@ -0,0 +1,16 @@
+// FILE: SuspendWithRuntimeKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+public final class SuspendWithRuntimeKt {
+ @org.jetbrains.annotations.Nullable
+ public static final java.lang.Object foo(int a, @org.jetbrains.annotations.NotNull java.lang.String b, @org.jetbrains.annotations.NotNull kotlin.coroutines.Continuation<? super java.lang.Integer> continuation) {
+ return null;
+ }
+
+ private SuspendWithRuntimeKt() {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendWithoutRuntime.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendWithoutRuntime.kt
new file mode 100644
index 0000000..ce43b49
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendWithoutRuntime.kt
@@ -0,0 +1,3 @@
+suspend fun foo(a: Int, b: String): Int {
+ return 0
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendWithoutRuntime.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendWithoutRuntime.txt
new file mode 100644
index 0000000..a011b15
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/suspendWithoutRuntime.txt
@@ -0,0 +1,16 @@
+// FILE: SuspendWithoutRuntimeKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+import java.lang.Object;
+
+@kotlin.Metadata()
+public final class SuspendWithoutRuntimeKt {
+ @org.jetbrains.annotations.Nullable
+ public static final java.lang.Object foo(int a, @org.jetbrains.annotations.NotNull java.lang.String b, @org.jetbrains.annotations.NotNull kotlin.coroutines.Continuation<? super java.lang.Integer> continuation) {
+ return null;
+ }
+
+ private SuspendWithoutRuntimeKt() {}
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/varargs.kt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/varargs.kt
new file mode 100644
index 0000000..92c13ca
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/varargs.kt
@@ -0,0 +1,3 @@
+package foo
+
+fun foo(a: Int, vararg b: String) {}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/varargs.txt b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/varargs.txt
new file mode 100644
index 0000000..9c1f0f9
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-compiler-plugin/testData/stubs/varargs.txt
@@ -0,0 +1,13 @@
+// FILE: foo/VarargsKt.java
+/**
+ * This file was generated by the kapt-lite stub generator.
+ * Do not change it manually.
+ */
+package foo;
+
+@kotlin.Metadata()
+public final class VarargsKt {
+ public static final void foo(int a, @org.jetbrains.annotations.NotNull java.lang.String... b) {}
+
+ private VarargsKt() {}
+}
diff --git a/plugins/kapt-lite/kapt-lite-javac-plugin/build.gradle.kts b/plugins/kapt-lite/kapt-lite-javac-plugin/build.gradle.kts
new file mode 100644
index 0000000..b3c4870
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-javac-plugin/build.gradle.kts
@@ -0,0 +1,21 @@
+description = "Lightweight annotation processing support – Java compiler plugin"
+
+plugins {
+ `java`
+ id("jps-compatible")
+}
+
+dependencies {
+ compileOnly(toolsJar())
+}
+
+sourceSets {
+ "main" { projectDefault() }
+ "test" { }
+}
+
+publish()
+
+runtimeJar()
+sourcesJar()
+javadocJar()
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-javac-plugin/resources/META-INF/services/com.sun.source.util.Plugin b/plugins/kapt-lite/kapt-lite-javac-plugin/resources/META-INF/services/com.sun.source.util.Plugin
new file mode 100644
index 0000000..68c7b8e
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-javac-plugin/resources/META-INF/services/com.sun.source.util.Plugin
@@ -0,0 +1 @@
+org.jetbrains.kaptlite.javac.KaptJavacPlugin
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-javac-plugin/src/org/jetbrains/kaptlite/javac/KaptJavacPlugin.java b/plugins/kapt-lite/kapt-lite-javac-plugin/src/org/jetbrains/kaptlite/javac/KaptJavacPlugin.java
new file mode 100644
index 0000000..5bf025f
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-javac-plugin/src/org/jetbrains/kaptlite/javac/KaptJavacPlugin.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kaptlite.javac;
+
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.util.JavacTask;
+import com.sun.source.util.Plugin;
+import com.sun.source.util.TaskEvent;
+import com.sun.source.util.TaskListener;
+import com.sun.tools.javac.parser.Tokens;
+import com.sun.tools.javac.tree.DocCommentTable;
+import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
+import com.sun.tools.javac.util.List;
+
+public class KaptJavacPlugin implements Plugin {
+ @Override
+ public String getName() {
+ return "KaptJavacPlugin";
+ }
+
+ @Override
+ public void init(JavacTask task, String... args) {
+ task.addTaskListener(new TaskListener() {
+ private boolean annotationProcessingFinished = false;
+
+ @Override
+ public void started(TaskEvent e) {
+ if (e.getKind() == TaskEvent.Kind.ENTER && annotationProcessingFinished) {
+ CompilationUnitTree unit = e.getCompilationUnit();
+ if (unit instanceof JCCompilationUnit) {
+ patch((JCCompilationUnit) unit);
+ }
+ }
+ }
+
+ @Override
+ public void finished(TaskEvent e) {
+ if (e.getKind() == TaskEvent.Kind.ANNOTATION_PROCESSING) {
+ annotationProcessingFinished = true;
+ }
+ }
+ });
+ }
+
+ private static void patch(JCCompilationUnit unit) {
+ if (isKaptStubFile(unit)) {
+ unit.pid = null;
+ unit.docComments = null;
+ unit.defs = List.nil();
+ }
+ }
+
+ private static boolean isKaptStubFile(JCCompilationUnit unit) {
+ DocCommentTable docs = unit.docComments;
+ if (docs == null) {
+ return false;
+ }
+
+ Tokens.Comment comment = docs.getComment(unit);
+ if (comment == null) {
+ return false;
+ }
+
+ String text = comment.getText();
+ return text.contains("This file was generated by the kapt-lite stub generator.")
+ && text.contains("Do not change it manually.");
+ }
+}
diff --git a/plugins/kapt-lite/kapt-lite-kdoc/build.gradle.kts b/plugins/kapt-lite/kapt-lite-kdoc/build.gradle.kts
new file mode 100644
index 0000000..be246c4
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-kdoc/build.gradle.kts
@@ -0,0 +1,19 @@
+description = "Lightweight annotation processing support – KDoc parser"
+
+plugins {
+ kotlin("jvm")
+ id("jps-compatible")
+}
+
+dependencies {
+ compileOnly(project(":compiler:frontend"))
+ compileOnly(project(":compiler:backend"))
+
+ compileOnly(intellijCoreDep()) { includeJars("intellij-core") }
+ compileOnly(intellijDep()) { includeJars("asm-all", rootProject = rootProject) }
+}
+
+sourceSets {
+ "main" { projectDefault() }
+ "test" { }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-kdoc/src/KDocParsingHelper.kt b/plugins/kapt-lite/kapt-lite-kdoc/src/KDocParsingHelper.kt
new file mode 100644
index 0000000..47e2492
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-kdoc/src/KDocParsingHelper.kt
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.kotlin.kaptlite.kdoc
+
+import com.intellij.psi.PsiElement
+import com.intellij.psi.PsiRecursiveElementVisitor
+import com.intellij.psi.impl.source.tree.LeafPsiElement
+import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
+import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
+import org.jetbrains.kotlin.kdoc.lexer.KDocTokens
+import org.jetbrains.kotlin.kdoc.psi.api.KDoc
+import org.jetbrains.kotlin.psi.KtClassOrObject
+import org.jetbrains.kotlin.psi.KtDeclaration
+import org.jetbrains.kotlin.psi.KtObjectDeclaration
+import org.jetbrains.kotlin.psi.KtProperty
+import org.jetbrains.kotlin.resolve.BindingContext
+import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
+
+object KDocParsingHelper {
+ enum class DeclarationKind {
+ CLASS, METHOD, FIELD
+ }
+
+ fun getKDocComment(kind: DeclarationKind, origin: JvmDeclarationOrigin, bindingContext: BindingContext): String? {
+ val psiElement = origin.element as? KtDeclaration ?: return null
+ val descriptor = origin.descriptor
+ val docComment = psiElement.docComment ?: return null
+
+ if (descriptor is ConstructorDescriptor && psiElement is KtClassOrObject) {
+ // We don't want the class comment to be duplicated on <init>()
+ return null
+ }
+
+ if (kind == DeclarationKind.METHOD
+ && psiElement is KtProperty
+ && descriptor is PropertyAccessorDescriptor
+ && bindingContext[BindingContext.BACKING_FIELD_REQUIRED, descriptor.correspondingProperty] == true
+ ) {
+ // Do not place documentation on backing field and property accessors
+ return null
+ }
+
+ if (kind == DeclarationKind.FIELD && psiElement is KtObjectDeclaration && descriptor == null) {
+ // Do not write KDoc on object instance field
+ return null
+ }
+
+ return escapeNestedComments(extractCommentText(docComment))
+ }
+
+ private fun escapeNestedComments(text: String): String {
+ val result = StringBuilder()
+
+ var index = 0
+ var commentLevel = 0
+
+ while (index < text.length) {
+ val currentChar = text[index]
+ fun nextChar() = text.getOrNull(index + 1)
+
+ if (currentChar == '/' && nextChar() == '*') {
+ commentLevel++
+ index++
+ result.append("/ *")
+ } else if (currentChar == '*' && nextChar() == '/') {
+ commentLevel = maxOf(0, commentLevel - 1)
+ index++
+ result.append("* /")
+ } else {
+ result.append(currentChar)
+ }
+
+ index++
+ }
+
+ return result.toString()
+ }
+
+ private fun extractCommentText(docComment: KDoc): String {
+ return buildString {
+ docComment.accept(object : PsiRecursiveElementVisitor() {
+ override fun visitElement(element: PsiElement) {
+ if (element is LeafPsiElement) {
+ if (element.isKDocLeadingAsterisk()) {
+ val indent = takeLastWhile { it == ' ' || it == '\t' }.length
+ if (indent > 0) {
+ delete(length - indent, length)
+ }
+ } else if (!element.isKDocStart() && !element.isKDocEnd()) {
+ append(element.text)
+ }
+ }
+
+ super.visitElement(element)
+ }
+ })
+ }.trimIndent().trim()
+ }
+
+ private fun LeafPsiElement.isKDocStart() = elementType == KDocTokens.START
+ private fun LeafPsiElement.isKDocEnd() = elementType == KDocTokens.END
+ private fun LeafPsiElement.isKDocLeadingAsterisk() = elementType == KDocTokens.LEADING_ASTERISK
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-signature-parser/build.gradle.kts b/plugins/kapt-lite/kapt-lite-signature-parser/build.gradle.kts
new file mode 100644
index 0000000..9817857
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-signature-parser/build.gradle.kts
@@ -0,0 +1,14 @@
+plugins {
+ kotlin("jvm")
+ id("jps-compatible")
+}
+
+dependencies {
+ compile(kotlinStdlib())
+ compileOnly(intellijDep()) { includeJars("asm-all", rootProject = rootProject) }
+}
+
+sourceSets {
+ "main" { projectDefault() }
+ "test" { }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-signature-parser/src/SignatureNode.kt b/plugins/kapt-lite/kapt-lite-signature-parser/src/SignatureNode.kt
new file mode 100644
index 0000000..69d283b
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-signature-parser/src/SignatureNode.kt
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kaptlite.signature
+
+/*
+ Root (Class)
+ * TypeParameter
+ + SuperClass
+ * Interface
+
+ Root (Method)
+ * TypeParameter
+ * ParameterType
+ + ReturnType
+ * ExceptionType
+
+ Root (Field)
+ + SuperClass
+
+ TypeParameter < Root
+ + ClassBound
+ * InterfaceBound
+
+ ParameterType < Root
+ + Type
+
+ ReturnType < Root
+ + Type
+
+ Type :: ClassType | TypeVariable | PrimitiveType | ArrayType
+
+ ClassBound < TypeParameter
+ + ClassType
+
+ InterfaceBound < TypeParameter
+ ? ClassType
+ ? TypeVariable
+
+ TypeVariable < InterfaceBound
+
+ SuperClass < TopLevel
+ ! ClassType
+
+ Interface < TopLevel
+ ! ClassType
+
+ ClassType < *
+ * TypeArgument
+ * InnerClass
+
+ InnerClass < ClassType
+ ! TypeArgument
+
+ TypeArgument < ClassType | InnerClass
+ + ClassType
+ */
+
+internal enum class ElementKind {
+ Root, TypeParameter, ClassBound, InterfaceBound, SuperClass, Interface, TypeArgument, ParameterType, ReturnType, ExceptionType,
+ ClassType, InnerClass, TypeVariable, PrimitiveType, ArrayType
+}
+
+internal class SignatureNode(val kind: ElementKind, val name: String? = null) {
+ val children: MutableList<SignatureNode> = ArrayList(1)
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-signature-parser/src/SignatureParser.kt b/plugins/kapt-lite/kapt-lite-signature-parser/src/SignatureParser.kt
new file mode 100644
index 0000000..40e4a1d
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-signature-parser/src/SignatureParser.kt
@@ -0,0 +1,241 @@
+/*
+ * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kaptlite.signature
+
+import org.jetbrains.org.objectweb.asm.signature.SignatureReader
+import org.jetbrains.kaptlite.signature.ElementKind.*
+
+data class ClassSignature(
+ val typeParameters: List<SigTypeParameter>,
+ val superClass: SigType,
+ val interfaces: List<SigType>
+)
+
+data class MethodSignature(
+ val typeParameters: List<SigTypeParameter>,
+ val parameters: List<SigParameter>,
+ val exceptionTypes: List<SigType>,
+ val returnType: SigType
+)
+
+data class SigParameter(val name: String, val type: SigType)
+data class SigTypeParameter(val name: String, val bounds: List<SigType>)
+
+sealed class SigType {
+ class Primitive private constructor(val javaName: String, val descriptor: Char) : SigType() {
+ companion object {
+ val VOID = Primitive("void", 'V')
+ val BYTE = Primitive("byte", 'B')
+ val SHORT = Primitive("short", 'S')
+ val INT = Primitive("int", 'I')
+ val LONG = Primitive("long", 'J')
+ val BOOLEAN = Primitive("boolean", 'Z')
+ val CHAR = Primitive("char", 'C')
+ val FLOAT = Primitive("float", 'F')
+ val DOUBLE = Primitive("double", 'D')
+
+ private val ALL = listOf(VOID, BYTE, SHORT, INT, LONG, BOOLEAN, CHAR, FLOAT, DOUBLE)
+ .map { it.descriptor to it }.toMap()
+
+ fun get(descriptor: Char): Primitive = ALL.getValue(descriptor)
+ }
+ }
+
+ class TypeVariable(val name: String) : SigType()
+ class Array(val elementType: SigType) : SigType()
+ class Class(val fqName: String) : SigType()
+ class Nested(val outer: SigType, val name: String) : SigType()
+ class Generic(val base: SigType, val args: List<SigTypeArgument>) : SigType()
+}
+
+val SigType.isJavaLangObject: Boolean
+ get() = this is SigType.Class && this.fqName == Object::class.java.name
+
+sealed class SigTypeArgument {
+ object Unbound : SigTypeArgument()
+ class Invariant(val type: SigType) : SigTypeArgument()
+ class Extends(val type: SigType) : SigTypeArgument()
+ class Super(val type: SigType) : SigTypeArgument()
+}
+
+object SignatureParser {
+ fun parseClassSignature(signature: String): ClassSignature {
+ val root = parse(signature)
+ val sigTypeParameters = ArrayList<SignatureNode>(1)
+ val sigSuperClasses = ArrayList<SignatureNode>(1)
+ val sigInterfaces = ArrayList<SignatureNode>(1)
+ root.split(sigTypeParameters, TypeParameter, sigSuperClasses, SuperClass, sigInterfaces, Interface)
+
+ val typeParameters = sigTypeParameters.map { parseTypeParameter(it) }
+ val superClass = parseType(sigSuperClasses.single().children.single())
+ val interfaces = sigInterfaces.map { parseType(it.children.single()) }
+ return ClassSignature(typeParameters, superClass, interfaces)
+ }
+
+ fun parseMethodSignature(
+ signature: String,
+ rawParameters: List<SigParameter>? = null,
+ parameterTypeTransformer: (Int, () -> SigType) -> SigType = { _, f -> f() }
+ ): MethodSignature {
+ val root = parse(signature)
+ val sigTypeParameters = ArrayList<SignatureNode>(1)
+ val sigParameterTypes = ArrayList<SignatureNode>(2)
+ val sigExceptionTypes = ArrayList<SignatureNode>(0)
+ val sigReturnTypes = ArrayList<SignatureNode>(1)
+
+ root.split(
+ sigTypeParameters, TypeParameter,
+ sigParameterTypes, ParameterType,
+ sigExceptionTypes, ExceptionType,
+ sigReturnTypes, ReturnType
+ )
+
+ val typeParameters = sigTypeParameters.map { parseTypeParameter(it) }
+
+ val parameters = if (rawParameters != null) {
+ assert(rawParameters.size >= sigParameterTypes.size)
+ val offset = rawParameters.size - sigParameterTypes.size
+ sigParameterTypes.mapIndexed { index, param ->
+ val rawParameter = rawParameters[index + offset]
+ val transformedType = parameterTypeTransformer(index) { parseType(param.children.single()) }
+ SigParameter(rawParameter.name, transformedType)
+ }
+ } else {
+ sigParameterTypes.mapIndexed { index, param ->
+ SigParameter("p$index", parseType(param.children.single()))
+ }
+ }
+
+ val exceptionTypes = sigExceptionTypes.map { parseType(it) }
+ val returnType = parseType(sigReturnTypes.single().children.single())
+ return MethodSignature(typeParameters, parameters, exceptionTypes, returnType)
+ }
+
+ fun parseFieldSignature(signature: String): SigType {
+ val root = parse(signature)
+ val superClass = root.children.single()
+ assert(superClass.kind == SuperClass)
+ return parseType(superClass.children.single())
+ }
+
+ private fun parseTypeParameter(node: SignatureNode): SigTypeParameter {
+ assert(node.kind == TypeParameter)
+
+ val sigClassBounds = ArrayList<SignatureNode>(1)
+ val sigInterfaceBounds = ArrayList<SignatureNode>(1)
+ node.split(sigClassBounds, ClassBound, sigInterfaceBounds, InterfaceBound)
+ assert(sigClassBounds.size <= 1)
+
+ val classBound = sigClassBounds.firstOrNull()?.let { parseBound(it) }?.takeIf { !it.isJavaLangObject }
+ val interfaceBounds = sigInterfaceBounds.map { parseBound(it) }
+ val allBounds = if (classBound != null) listOf(classBound) + interfaceBounds else interfaceBounds
+ return SigTypeParameter(node.name!!, allBounds)
+ }
+
+ private fun parseBound(node: SignatureNode): SigType {
+ assert(node.kind == ClassBound || node.kind == InterfaceBound)
+ return parseType(node.children.single())
+ }
+
+ private fun parseType(node: SignatureNode): SigType {
+ return when (node.kind) {
+ ClassType -> {
+ val typeArgs = mutableListOf<SignatureNode>()
+ val innerClasses = mutableListOf<SignatureNode>()
+ node.split(typeArgs, TypeArgument, innerClasses, InnerClass)
+
+ val baseType = SigType.Class(node.name!!.replace('/', '.'))
+ var type = parseGenericArgs(baseType, typeArgs)
+ if (innerClasses.isEmpty()) return type
+
+ for (innerClass in innerClasses) {
+ val nestedType = SigType.Nested(type, innerClass.name!!)
+ type = parseGenericArgs(nestedType, innerClass.children)
+ }
+
+ type
+ }
+ TypeVariable -> SigType.TypeVariable(node.name!!)
+ ArrayType -> SigType.Array(parseType(node.children.single()))
+ PrimitiveType -> SigType.Primitive.get(node.name!!.single())
+ else -> error("Unsupported type: $node")
+ }
+ }
+
+ private fun parseGenericArgs(base: SigType, args: List<SignatureNode>): SigType {
+ if (args.isEmpty()) {
+ return base
+ }
+
+ return SigType.Generic(base, args.map { arg ->
+ assert(arg.kind == TypeArgument) { "Unexpected kind ${arg.kind}, $TypeArgument expected" }
+ val variance = arg.name ?: return@map SigTypeArgument.Unbound
+
+ val argType = parseType(arg.children.single())
+ when (variance.single()) {
+ '=' -> SigTypeArgument.Invariant(argType)
+ '+' -> SigTypeArgument.Extends(argType)
+ '-' -> SigTypeArgument.Super(argType)
+ else -> error("Unknown variance, '=', '+' or '-' expected")
+ }
+ })
+ }
+
+ private fun parse(signature: String): SignatureNode {
+ val parser = SignatureParserVisitor()
+ SignatureReader(signature).accept(parser)
+ return parser.root
+ }
+}
+
+private fun SignatureNode.split(l1: MutableList<SignatureNode>, e1: ElementKind, l2: MutableList<SignatureNode>, e2: ElementKind) {
+ for (child in children) {
+ when (val kind = child.kind) {
+ e1 -> l1 += child
+ e2 -> l2 += child
+ else -> error("Unknown kind: $kind")
+ }
+ }
+}
+
+private fun SignatureNode.split(
+ l1: MutableList<SignatureNode>,
+ e1: ElementKind,
+ l2: MutableList<SignatureNode>,
+ e2: ElementKind,
+ l3: MutableList<SignatureNode>,
+ e3: ElementKind
+) {
+ for (child in children) {
+ when (val kind = child.kind) {
+ e1 -> l1 += child
+ e2 -> l2 += child
+ e3 -> l3 += child
+ else -> error("Unknown kind: $kind")
+ }
+ }
+}
+
+private fun SignatureNode.split(
+ l1: MutableList<SignatureNode>,
+ e1: ElementKind,
+ l2: MutableList<SignatureNode>,
+ e2: ElementKind,
+ l3: MutableList<SignatureNode>,
+ e3: ElementKind,
+ l4: MutableList<SignatureNode>,
+ e4: ElementKind
+) {
+ for (child in children) {
+ when (val kind = child.kind) {
+ e1 -> l1 += child
+ e2 -> l2 += child
+ e3 -> l3 += child
+ e4 -> l4 += child
+ else -> error("Unknown kind: $kind")
+ }
+ }
+}
\ No newline at end of file
diff --git a/plugins/kapt-lite/kapt-lite-signature-parser/src/SignatureParserVisitor.kt b/plugins/kapt-lite/kapt-lite-signature-parser/src/SignatureParserVisitor.kt
new file mode 100644
index 0000000..7d9ec71
--- /dev/null
+++ b/plugins/kapt-lite/kapt-lite-signature-parser/src/SignatureParserVisitor.kt
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
+ */
+
+package org.jetbrains.kaptlite.signature
+
+import org.jetbrains.org.objectweb.asm.Opcodes
+import org.jetbrains.org.objectweb.asm.signature.SignatureVisitor
+import org.jetbrains.kaptlite.signature.ElementKind.*
+import java.util.*
+
+internal class SignatureParserVisitor : SignatureVisitor(Opcodes.API_VERSION) {
+ val root = SignatureNode(Root)
+ private val stack = ArrayDeque<SignatureNode>(5).apply { add(root) }
+
+ private fun popUntil(kind: ElementKind?) {
+ if (kind != null) {
+ while (stack.peek().kind != kind) {
+ stack.pop()
+ }
+ }
+ }
+
+ private fun popUntil(vararg kinds: ElementKind) {
+ while (stack.peek().kind !in kinds) {
+ stack.pop()
+ }
+ }
+
+ private fun push(kind: ElementKind, parent: ElementKind? = null, name: String? = null) {
+ popUntil(parent)
+
+ val newNode = SignatureNode(kind, name)
+ stack.peek().children += newNode
+ stack.push(newNode)
+ }
+
+ override fun visitSuperclass(): SignatureVisitor {
+ push(SuperClass, parent = Root)
+ return super.visitSuperclass()
+ }
+
+ override fun visitInterface(): SignatureVisitor {
+ push(Interface, parent = Root)
+ return super.visitInterface()
+ }
+
+ override fun visitFormalTypeParameter(name: String) {
+ push(TypeParameter, parent = Root, name = name)
+ }
+
+ override fun visitClassBound(): SignatureVisitor {
+ push(ClassBound, parent = TypeParameter)
+ return super.visitClassBound()
+ }
+
+ override fun visitInterfaceBound(): SignatureVisitor {
+ push(InterfaceBound, parent = TypeParameter)
+ return super.visitInterfaceBound()
+ }
+
+ override fun visitTypeArgument() {
+ popUntil(ClassType, InnerClass)
+ push(TypeArgument)
+ }
+
+ override fun visitTypeArgument(variance: Char): SignatureVisitor {
+ popUntil(ClassType, InnerClass)
+ push(TypeArgument, name = variance.toString())
+ return super.visitTypeArgument(variance)
+ }
+
+ override fun visitInnerClassType(name: String) {
+ push(InnerClass, name = name, parent = ClassType)
+ }
+
+ override fun visitParameterType(): SignatureVisitor {
+ push(ParameterType, parent = Root)
+ return super.visitParameterType()
+ }
+
+ override fun visitReturnType(): SignatureVisitor {
+ push(ReturnType, parent = Root)
+ return super.visitReturnType()
+ }
+
+ override fun visitExceptionType(): SignatureVisitor {
+ push(ExceptionType, parent = Root)
+ return super.visitExceptionType()
+ }
+
+ override fun visitClassType(name: String) {
+ push(ClassType, name = name)
+ }
+
+ override fun visitTypeVariable(name: String) {
+ push(TypeVariable, name = name)
+ }
+
+ override fun visitBaseType(descriptor: Char) {
+ push(PrimitiveType, name = descriptor.toString())
+ }
+
+ override fun visitArrayType(): SignatureVisitor {
+ push(ArrayType)
+ return super.visitArrayType()
+ }
+
+ override fun visitEnd() {
+ while (stack.peek().kind != ClassType) {
+ stack.pop()
+ }
+ stack.pop()
+ }
+}
diff --git a/plugins/kapt3/kapt3-compiler/build.gradle.kts b/plugins/kapt3/kapt3-compiler/build.gradle.kts
index cb13628..72f2a66 100644
--- a/plugins/kapt3/kapt3-compiler/build.gradle.kts
+++ b/plugins/kapt3/kapt3-compiler/build.gradle.kts
@@ -13,6 +13,9 @@
testCompileOnly(intellijDep()) { includeJars("platform-api", "platform-impl") }
+ compileOnly(project(":kapt-lite:kapt-lite-kdoc"))
+ embedded(project(":kapt-lite:kapt-lite-kdoc")) { isTransitive = false }
+
Platform[192].orHigher {
testRuntime(intellijPluginDep("java"))
}
diff --git a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/KDocCommentKeeper.kt b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/KDocCommentKeeper.kt
index a937c40..d908cd6 100644
--- a/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/KDocCommentKeeper.kt
+++ b/plugins/kapt3/kapt3-compiler/src/org/jetbrains/kotlin/kapt3/stubs/KDocCommentKeeper.kt
@@ -16,24 +16,17 @@
package org.jetbrains.kotlin.kapt3.stubs
-import com.intellij.psi.PsiElement
-import com.intellij.psi.PsiRecursiveElementVisitor
-import com.intellij.psi.impl.source.tree.LeafPsiElement
import com.sun.tools.javac.parser.Tokens
import com.sun.tools.javac.tree.DCTree
import com.sun.tools.javac.tree.DocCommentTable
import com.sun.tools.javac.tree.JCTree
import com.sun.tools.javac.tree.TreeScanner
-import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
-import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
import org.jetbrains.kotlin.kapt3.KaptContextForStubGeneration
-import org.jetbrains.kotlin.kdoc.lexer.KDocTokens
-import org.jetbrains.kotlin.kdoc.psi.api.KDoc
-import org.jetbrains.kotlin.psi.*
-import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.org.objectweb.asm.Opcodes
+import org.jetbrains.org.objectweb.asm.tree.ClassNode
import org.jetbrains.org.objectweb.asm.tree.FieldNode
import org.jetbrains.org.objectweb.asm.tree.MethodNode
+import org.kotlin.kaptlite.kdoc.KDocParsingHelper
class KDocCommentKeeper(private val kaptContext: KaptContextForStubGeneration) {
private val docCommentTable = KaptDocCommentTable()
@@ -73,84 +66,16 @@
fun saveKDocComment(tree: JCTree, node: Any) {
val origin = kaptContext.origins[node] ?: return
- val psiElement = origin.element as? KtDeclaration ?: return
- val descriptor = origin.descriptor
- val docComment = psiElement.docComment ?: return
-
- if (descriptor is ConstructorDescriptor && psiElement is KtClassOrObject) {
- // We don't want the class comment to be duplicated on <init>()
- return
+ val kind = when (node) {
+ is ClassNode -> KDocParsingHelper.DeclarationKind.CLASS
+ is MethodNode -> KDocParsingHelper.DeclarationKind.METHOD
+ is FieldNode -> KDocParsingHelper.DeclarationKind.FIELD
+ else -> return
}
- if (node is MethodNode
- && psiElement is KtProperty
- && descriptor is PropertyAccessorDescriptor
- && kaptContext.bindingContext[BindingContext.BACKING_FIELD_REQUIRED, descriptor.correspondingProperty] == true
- ) {
- // Do not place documentation on backing field and property accessors
- return
- }
-
- if (node is FieldNode && psiElement is KtObjectDeclaration && descriptor == null) {
- // Do not write KDoc on object instance field
- return
- }
-
- docCommentTable.putComment(tree, KDocComment(escapeNestedComments(extractCommentText(docComment))))
+ val text = KDocParsingHelper.getKDocComment(kind, origin, kaptContext.bindingContext) ?: return
+ docCommentTable.putComment(tree, KDocComment(text))
}
-
- private fun escapeNestedComments(text: String): String {
- val result = StringBuilder()
-
- var index = 0
- var commentLevel = 0
-
- while (index < text.length) {
- val currentChar = text[index]
- fun nextChar() = text.getOrNull(index + 1)
-
- if (currentChar == '/' && nextChar() == '*') {
- commentLevel++
- index++
- result.append("/ *")
- } else if (currentChar == '*' && nextChar() == '/') {
- commentLevel = maxOf(0, commentLevel - 1)
- index++
- result.append("* /")
- } else {
- result.append(currentChar)
- }
-
- index++
- }
-
- return result.toString()
- }
-
- private fun extractCommentText(docComment: KDoc): String {
- return buildString {
- docComment.accept(object : PsiRecursiveElementVisitor() {
- override fun visitElement(element: PsiElement) {
- if (element is LeafPsiElement) {
- if (element.isKDocLeadingAsterisk()) {
- val indent = takeLastWhile { it == ' ' || it == '\t' }.length
- if (indent > 0) {
- delete(length - indent, length)
- }
- } else if (!element.isKDocStart() && !element.isKDocEnd()) {
- append(element.text)
- }
- }
-
- super.visitElement(element)
- }
- })
- }.trimIndent().trim()
- }
-
- private fun LeafPsiElement.isKDocStart() = elementType == KDocTokens.START
- private fun LeafPsiElement.isKDocEnd() = elementType == KDocTokens.END
- private fun LeafPsiElement.isKDocLeadingAsterisk() = elementType == KDocTokens.LEADING_ASTERISK
}
private class KDocComment(val body: String) : Tokens.Comment {
diff --git a/prepare/kapt-lite-compiler-plugin-embeddable/build.gradle.kts b/prepare/kapt-lite-compiler-plugin-embeddable/build.gradle.kts
new file mode 100644
index 0000000..3fb76e1
--- /dev/null
+++ b/prepare/kapt-lite-compiler-plugin-embeddable/build.gradle.kts
@@ -0,0 +1,18 @@
+import org.gradle.jvm.tasks.Jar
+
+description = "Lightweight annotation processing support – Kotlin compiler plugin (for using with embeddable compiler)"
+
+plugins {
+ `java`
+}
+
+dependencies {
+ embedded(project(":kapt-lite:kapt-lite-compiler-plugin")) { isTransitive = false }
+}
+
+publish()
+
+runtimeJar(rewriteDefaultJarDepsToShadedCompiler())
+
+sourcesJar()
+javadocJar()
diff --git a/settings.gradle b/settings.gradle
index 531b68e7..6b0ffb8 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -189,6 +189,11 @@
":kotlin-annotation-processing-runtime",
":kotlin-annotation-processing-gradle",
":kotlin-annotation-processing-embeddable",
+ ":kapt-lite:kapt-lite-signature-parser",
+ ":kapt-lite:kapt-lite-kdoc",
+ ":kapt-lite:kapt-lite-compiler-plugin",
+ ":kapt-lite:kapt-lite-compiler-plugin-embeddable",
+ ":kapt-lite:kapt-lite-javac-plugin",
":kotlin-daemon-embeddable",
":examples:kotlin-jsr223-local-example",
":examples:kotlin-jsr223-daemon-local-eval-example",
@@ -370,6 +375,11 @@
project(':kotlin-script-util').projectDir = "$rootDir/libraries/tools/kotlin-script-util" as File
project(':kotlin-annotation-processing-gradle').projectDir = "$rootDir/libraries/tools/kotlin-annotation-processing" as File
project(':kotlin-annotation-processing-embeddable').projectDir = "$rootDir/prepare/kotlin-annotation-processing-embeddable" as File
+project(':kapt-lite:kapt-lite-signature-parser').projectDir = "$rootDir/plugins/kapt-lite/kapt-lite-signature-parser" as File
+project(':kapt-lite:kapt-lite-kdoc').projectDir = "$rootDir/plugins/kapt-lite/kapt-lite-kdoc" as File
+project(':kapt-lite:kapt-lite-compiler-plugin').projectDir = "$rootDir/plugins/kapt-lite/kapt-lite-compiler-plugin" as File
+project(':kapt-lite:kapt-lite-compiler-plugin-embeddable').projectDir = "$rootDir/prepare/kapt-lite-compiler-plugin-embeddable" as File
+project(':kapt-lite:kapt-lite-javac-plugin').projectDir = "$rootDir/plugins/kapt-lite/kapt-lite-javac-plugin" as File
project(':kotlin-daemon-embeddable').projectDir = "$rootDir/prepare/kotlin-daemon-embeddable" as File
project(':kotlin-annotation-processing').projectDir = "$rootDir/plugins/kapt3/kapt3-compiler" as File
project(':kotlin-annotation-processing-cli').projectDir = "$rootDir/plugins/kapt3/kapt3-cli" as File