kapt: Light class stub producer in compiler
This commit is contained in:
@@ -14,7 +14,8 @@
|
||||
<orderEntry type="library" name="kotlin-runtime" level="project" />
|
||||
<orderEntry type="module" module-name="frontend.java" />
|
||||
<orderEntry type="module" module-name="compiler-tests" scope="TEST" />
|
||||
<orderEntry type="module" module-name="cli" scope="TEST" />
|
||||
<orderEntry type="module" module-name="cli" />
|
||||
<orderEntry type="library" scope="TEST" name="idea-full" level="project" />
|
||||
<orderEntry type="module" module-name="light-classes" />
|
||||
</component>
|
||||
</module>
|
||||
+14
-3
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.JetCallableDeclaration
|
||||
import org.jetbrains.kotlin.psi.JetDeclaration
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisCompletedHandlerExtension
|
||||
import java.io.BufferedWriter
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
@@ -47,7 +48,9 @@ public object AnnotationCollectorConfigurationKeys {
|
||||
public val ANNOTATION_FILTER_LIST: CompilerConfigurationKey<List<String>> =
|
||||
CompilerConfigurationKey.create<List<String>>("annotation filter regular expressions")
|
||||
public val OUTPUT_FILENAME: CompilerConfigurationKey<String> =
|
||||
CompilerConfigurationKey.create<String>("output file")
|
||||
CompilerConfigurationKey.create<String>("annotation file name")
|
||||
public val STUBS_PATH: CompilerConfigurationKey<String> =
|
||||
CompilerConfigurationKey.create<String>("stubs output directory")
|
||||
}
|
||||
|
||||
public class AnnotationCollectorCommandLineProcessor : CommandLineProcessor {
|
||||
@@ -59,11 +62,14 @@ public class AnnotationCollectorCommandLineProcessor : CommandLineProcessor {
|
||||
|
||||
public val OUTPUT_FILENAME_OPTION: CliOption =
|
||||
CliOption("output", "<path>", "File in which annotated declarations will be placed", required = false)
|
||||
|
||||
public val STUBS_PATH_OPTION: CliOption =
|
||||
CliOption("stubs", "<path>", "Output path for stubs.", required = false)
|
||||
}
|
||||
|
||||
override val pluginId: String = ANNOTATION_COLLECTOR_COMPILER_PLUGIN_ID
|
||||
|
||||
override val pluginOptions: Collection<CliOption> = listOf(ANNOTATION_FILTER_LIST_OPTION, OUTPUT_FILENAME_OPTION)
|
||||
override val pluginOptions: Collection<CliOption> = listOf(ANNOTATION_FILTER_LIST_OPTION, OUTPUT_FILENAME_OPTION, STUBS_PATH_OPTION)
|
||||
|
||||
override fun processOption(option: CliOption, value: String, configuration: CompilerConfiguration) {
|
||||
when (option) {
|
||||
@@ -72,6 +78,7 @@ public class AnnotationCollectorCommandLineProcessor : CommandLineProcessor {
|
||||
configuration.put(AnnotationCollectorConfigurationKeys.ANNOTATION_FILTER_LIST, annotations)
|
||||
}
|
||||
OUTPUT_FILENAME_OPTION -> configuration.put(AnnotationCollectorConfigurationKeys.OUTPUT_FILENAME, value)
|
||||
STUBS_PATH_OPTION -> configuration.put(AnnotationCollectorConfigurationKeys.STUBS_PATH, value)
|
||||
else -> throw CliOptionProcessingException("Unknown option: ${option.name}")
|
||||
}
|
||||
}
|
||||
@@ -81,11 +88,15 @@ public class AnnotationCollectorComponentRegistrar : ComponentRegistrar {
|
||||
public override fun registerProjectComponents(project: MockProject, configuration: CompilerConfiguration) {
|
||||
val annotationFilterList = configuration.get(AnnotationCollectorConfigurationKeys.ANNOTATION_FILTER_LIST)
|
||||
val outputFilename = configuration.get(AnnotationCollectorConfigurationKeys.OUTPUT_FILENAME)
|
||||
|
||||
if (outputFilename != null) {
|
||||
val collectorExtension = AnnotationCollectorExtension(annotationFilterList, outputFilename)
|
||||
ClassBuilderInterceptorExtension.registerExtension(project, collectorExtension)
|
||||
}
|
||||
|
||||
val stubs = configuration.get(AnnotationCollectorConfigurationKeys.STUBS_PATH)
|
||||
if (stubs != null) {
|
||||
AnalysisCompletedHandlerExtension.registerExtension(project, StubProducerExtension(File(stubs)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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.kotlin.annotation
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.cli.common.CLICompiler
|
||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||
import org.jetbrains.kotlin.cli.common.output.outputUtils.writeAllTo
|
||||
import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.codegen.state.Progress
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.psi.JetFile
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.BindingTraceContext
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisCompletedHandlerExtension
|
||||
import org.jetbrains.org.objectweb.asm.ClassWriter
|
||||
import java.io.File
|
||||
|
||||
public class StubProducerExtension(val stubsOutputDir: File) : AnalysisCompletedHandlerExtension {
|
||||
|
||||
override fun analysisCompleted(project: Project, module: ModuleDescriptor, bindingContext: BindingContext, files: Collection<JetFile>) {
|
||||
val forExtraDiagnostics = BindingTraceContext()
|
||||
|
||||
val generationState = GenerationState(
|
||||
project,
|
||||
StubClassBuilderFactory(),
|
||||
Progress.DEAF,
|
||||
module,
|
||||
bindingContext,
|
||||
files.toArrayList(),
|
||||
/*disableCallAssertions =*/ false,
|
||||
/*disableParamAssertions =*/ false,
|
||||
GenerationState.GenerateClassFilter.GENERATE_ALL,
|
||||
/*disableInline =*/ false,
|
||||
/*disableOptimization =*/ false,
|
||||
/*packagesWithObsoleteParts =*/ null,
|
||||
/*moduleId =*/ null,
|
||||
forExtraDiagnostics,
|
||||
/*outDirectory =*/ null)
|
||||
|
||||
KotlinCodegenFacade.compileCorrectFiles(generationState, CompilationErrorHandler.THROW_EXCEPTION)
|
||||
|
||||
if (!stubsOutputDir.exists()) stubsOutputDir.mkdirs()
|
||||
generationState.getFactory().writeAllTo(stubsOutputDir)
|
||||
|
||||
generationState.destroy()
|
||||
throw CLICompiler.CompilationInterruptedException(ExitCode.OK)
|
||||
}
|
||||
}
|
||||
|
||||
private class StubClassBuilderFactory : ClassBuilderFactory {
|
||||
|
||||
override fun getClassBuilderMode() = ClassBuilderMode.LIGHT_CLASSES
|
||||
|
||||
override fun newClassBuilder(origin: JvmDeclarationOrigin) = AbstractClassBuilder.Concrete(
|
||||
ClassWriter(ClassWriter.COMPUTE_FRAMES or ClassWriter.COMPUTE_MAXS))
|
||||
|
||||
override fun asText(builder: ClassBuilder) = throw UnsupportedOperationException("BINARIES generator asked for text")
|
||||
|
||||
override fun asBytes(builder: ClassBuilder): ByteArray {
|
||||
val visitor = builder.getVisitor() as ClassWriter
|
||||
return visitor.toByteArray()
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user