diff --git a/plugins/kapt3/kapt3.iml b/plugins/kapt3/kapt3.iml
index b87c6efed97..00a9aed3a04 100644
--- a/plugins/kapt3/kapt3.iml
+++ b/plugins/kapt3/kapt3.iml
@@ -13,5 +13,7 @@
+
+
\ No newline at end of file
diff --git a/plugins/kapt3/src/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor b/plugins/kapt3/src/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
new file mode 100644
index 00000000000..501e2a06db1
--- /dev/null
+++ b/plugins/kapt3/src/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
@@ -0,0 +1 @@
+org.jetbrains.kotlin.kapt3.Kapt3CommandLineProcessor
\ No newline at end of file
diff --git a/plugins/kapt3/src/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar b/plugins/kapt3/src/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
new file mode 100644
index 00000000000..3c8e65064a7
--- /dev/null
+++ b/plugins/kapt3/src/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
@@ -0,0 +1 @@
+org.jetbrains.kotlin.kapt3.Kapt3ComponentRegistrar
\ No newline at end of file
diff --git a/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/Kapt3AnalysisCompletedHandlerExtension.kt b/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/Kapt3AnalysisCompletedHandlerExtension.kt
new file mode 100644
index 00000000000..931d82b6aca
--- /dev/null
+++ b/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/Kapt3AnalysisCompletedHandlerExtension.kt
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2010-2016 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.kotlin.kapt3
+
+import com.intellij.openapi.project.Project
+import org.jetbrains.kotlin.analyzer.AnalysisResult
+import org.jetbrains.kotlin.codegen.*
+import org.jetbrains.kotlin.codegen.state.GenerationState
+import org.jetbrains.kotlin.descriptors.ModuleDescriptor
+import org.jetbrains.kotlin.kapt3.diagnostic.ErrorsKapt3
+import org.jetbrains.kotlin.psi.KtFile
+import org.jetbrains.kotlin.resolve.BindingContext
+import org.jetbrains.kotlin.resolve.BindingTrace
+import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
+import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisCompletedHandlerExtension
+import org.jetbrains.org.objectweb.asm.FieldVisitor
+import org.jetbrains.org.objectweb.asm.MethodVisitor
+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 java.io.File
+
+class Kapt3AnalysisCompletedHandlerExtension(
+ val classpath: List,
+ val javaSourceRoots: List,
+ val sourcesOutputDir: File,
+ val classesOutputDir: File,
+ val options: Map,
+ val isVerbose: Boolean
+) : AnalysisCompletedHandlerExtension {
+ override fun analysisCompleted(
+ project: Project,
+ module: ModuleDescriptor,
+ bindingTrace: BindingTrace,
+ files: Collection
+ ): AnalysisResult? {
+ if (files.isEmpty()) {
+ return AnalysisResult.Companion.success(BindingContext.EMPTY, module, shouldGenerateCode = false)
+ }
+
+ val builderFactory = Kapt3BuilderFactory()
+
+ val generationState = GenerationState(
+ project,
+ builderFactory,
+ module,
+ bindingTrace.bindingContext,
+ files.toList(),
+ disableCallAssertions = false,
+ disableParamAssertions = false)
+
+ try {
+ KotlinCodegenFacade.compileCorrectFiles(generationState, CompilationErrorHandler.THROW_EXCEPTION)
+ val compiledClasses = builderFactory.compiledClasses
+ val origins = builderFactory.origins
+ } catch (thr: Throwable) {
+ bindingTrace.report(ErrorsKapt3.KAPT3_PROCESSING_ERROR.on(files.first()))
+ } finally {
+ generationState.destroy()
+ }
+
+ return AnalysisResult.success(BindingContext.EMPTY, module, shouldGenerateCode = false)
+ }
+}
+
+private class Kapt3BuilderFactory : ClassBuilderFactory {
+ val compiledClasses = mutableListOf()
+ val origins = mutableMapOf()
+
+ override fun getClassBuilderMode(): ClassBuilderMode = ClassBuilderMode.KAPT3
+
+ override fun newClassBuilder(origin: JvmDeclarationOrigin): AbstractClassBuilder.Concrete {
+ val classNode = ClassNode()
+ compiledClasses += classNode
+ origins.put(classNode, origin)
+
+ return object : AbstractClassBuilder.Concrete(classNode) {
+ override fun newField(
+ origin: JvmDeclarationOrigin,
+ access: Int,
+ name: String,
+ desc: String,
+ signature: String?,
+ value: Any?
+ ): FieldVisitor {
+ val fieldNode = super.newField(origin, access, name, desc, signature, value) as FieldNode
+ origins.put(fieldNode, origin)
+ return fieldNode
+ }
+
+ override fun newMethod(
+ origin: JvmDeclarationOrigin,
+ access: Int,
+ name: String,
+ desc: String,
+ signature: String?,
+ exceptions: Array?
+ ): MethodVisitor {
+ val methodNode = super.newMethod(origin, access, name, desc, signature, exceptions) as MethodNode
+ origins.put(methodNode, origin)
+ return methodNode
+ }
+ }
+ }
+
+ override fun asText(builder: ClassBuilder) = throw UnsupportedOperationException()
+ override fun asBytes(builder: ClassBuilder) = throw UnsupportedOperationException()
+ override fun close() {}
+}
\ No newline at end of file
diff --git a/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/Kapt3Plugin.kt b/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/Kapt3Plugin.kt
new file mode 100644
index 00000000000..6a75b419af6
--- /dev/null
+++ b/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/Kapt3Plugin.kt
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2010-2016 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.kotlin.kapt3
+
+import com.intellij.mock.MockProject
+import com.intellij.openapi.extensions.Extensions
+import org.jetbrains.kotlin.kapt3.Kapt3ConfigurationKeys.ANNOTATION_PROCESSOR_CLASSPATH
+import org.jetbrains.kotlin.kapt3.Kapt3ConfigurationKeys.APT_OPTIONS
+import org.jetbrains.kotlin.cli.jvm.config.JavaSourceRoot
+import org.jetbrains.kotlin.cli.jvm.config.JvmContentRoot
+import org.jetbrains.kotlin.compiler.plugin.CliOption
+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.config.CompilerConfigurationKey
+import org.jetbrains.kotlin.config.JVMConfigurationKeys
+import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
+import org.jetbrains.kotlin.kapt3.diagnostic.DefaultErrorMessagesKapt3
+import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisCompletedHandlerExtension
+import java.io.File
+
+object Kapt3ConfigurationKeys {
+ val GENERATED_OUTPUT_DIR: CompilerConfigurationKey =
+ CompilerConfigurationKey.create("generated files output directory")
+
+ val CLASS_FILES_OUTPUT_DIR: CompilerConfigurationKey =
+ CompilerConfigurationKey.create("class files output directory")
+
+ val ANNOTATION_PROCESSOR_CLASSPATH: CompilerConfigurationKey> =
+ CompilerConfigurationKey.create>("annotation processor classpath")
+
+ val APT_OPTIONS: CompilerConfigurationKey> =
+ CompilerConfigurationKey.create>("annotation processing options")
+
+ val VERBOSE_MODE: CompilerConfigurationKey =
+ CompilerConfigurationKey.create("verbose mode")
+}
+
+class Kapt3CommandLineProcessor : CommandLineProcessor {
+ companion object {
+ val ANNOTATION_PROCESSING_COMPILER_PLUGIN_ID: String = "org.jetbrains.kotlin.kapt3"
+
+ val GENERATED_OUTPUT_DIR_OPTION: CliOption =
+ CliOption("generated", "", "Output path for the generated files", required = false)
+
+ val CLASS_FILES_OUTPUT_DIR_OPTION: CliOption =
+ CliOption("classes", "", "Output path for the class files", required = false)
+
+ val ANNOTATION_PROCESSOR_CLASSPATH_OPTION: CliOption =
+ CliOption("apclasspath", "", "Annotation processor classpath",
+ required = false, allowMultipleOccurrences = true)
+
+ val APT_OPTIONS_OPTION: CliOption =
+ CliOption("apoption", ":", "Annotation processor option",
+ required = false, allowMultipleOccurrences = true)
+
+ val VERBOSE_MODE_OPTION: CliOption =
+ CliOption("verbose", "true | false", "Enable verbose output", required = false)
+ }
+
+ override val pluginId: String = ANNOTATION_PROCESSING_COMPILER_PLUGIN_ID
+
+ override val pluginOptions: Collection =
+ listOf(GENERATED_OUTPUT_DIR_OPTION, ANNOTATION_PROCESSOR_CLASSPATH_OPTION, APT_OPTIONS_OPTION,
+ CLASS_FILES_OUTPUT_DIR_OPTION, VERBOSE_MODE_OPTION)
+
+ private fun CompilerConfiguration.appendList(option: CompilerConfigurationKey>, value: T) {
+ val paths = getList(option).toMutableList()
+ paths.add(value)
+ put(option, paths)
+ }
+
+ override fun processOption(option: CliOption, value: String, configuration: CompilerConfiguration) {
+ when (option) {
+ ANNOTATION_PROCESSOR_CLASSPATH_OPTION -> configuration.appendList(ANNOTATION_PROCESSOR_CLASSPATH, value)
+ APT_OPTIONS_OPTION -> configuration.appendList(APT_OPTIONS, value)
+ GENERATED_OUTPUT_DIR_OPTION -> configuration.put(Kapt3ConfigurationKeys.GENERATED_OUTPUT_DIR, value)
+ CLASS_FILES_OUTPUT_DIR_OPTION -> configuration.put(Kapt3ConfigurationKeys.CLASS_FILES_OUTPUT_DIR, value)
+ VERBOSE_MODE_OPTION -> configuration.put(Kapt3ConfigurationKeys.VERBOSE_MODE, value)
+ else -> throw CliOptionProcessingException("Unknown option: ${option.name}")
+ }
+ }
+}
+
+class Kapt3ComponentRegistrar : ComponentRegistrar {
+ override fun registerProjectComponents(project: MockProject, configuration: CompilerConfiguration) {
+ val generatedOutputDir = configuration.get(Kapt3ConfigurationKeys.GENERATED_OUTPUT_DIR) ?: return
+ val apClasspath = configuration.get(ANNOTATION_PROCESSOR_CLASSPATH)?.map(::File) ?: return
+
+ val apOptions = (configuration.get(APT_OPTIONS) ?: listOf())
+ .map { it.split(':') }
+ .filter { it.size == 2 }
+ .map { it[0] to it[1] }
+ .toMap()
+
+ val sourcesOutputDir = File(generatedOutputDir)
+ sourcesOutputDir.mkdirs()
+
+ val contentRoots = configuration[JVMConfigurationKeys.CONTENT_ROOTS] ?: emptyList()
+
+ val compileClasspath = contentRoots.filterIsInstance().map { it.file }
+ val classpath = apClasspath + compileClasspath
+
+ val javaSourceRoots = contentRoots.filterIsInstance().map { it.file }
+
+ val classesOutputDir = File(configuration.get(Kapt3ConfigurationKeys.CLASS_FILES_OUTPUT_DIR)
+ ?: configuration[JVMConfigurationKeys.MODULES]!!.first().getOutputDirectory())
+
+ val isVerbose = configuration.get(Kapt3ConfigurationKeys.VERBOSE_MODE) == "true"
+
+ Extensions.getRootArea().getExtensionPoint(DefaultErrorMessages.Extension.EP_NAME).registerExtension(DefaultErrorMessagesKapt3())
+
+ val kapt3AnalysisCompletedHandlerExtension = Kapt3AnalysisCompletedHandlerExtension(
+ classpath, javaSourceRoots, sourcesOutputDir, classesOutputDir, apOptions, isVerbose)
+ AnalysisCompletedHandlerExtension.registerExtension(project, kapt3AnalysisCompletedHandlerExtension)
+ }
+}
\ No newline at end of file
diff --git a/plugins/kapt3/src/KaptJavaCompiler.kt b/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/KaptJavaCompiler.kt
similarity index 100%
rename from plugins/kapt3/src/KaptJavaCompiler.kt
rename to plugins/kapt3/src/org/jetbrains/kotlin/kapt3/KaptJavaCompiler.kt
diff --git a/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/diagnostic/DefaultErrorMessagesKapt3.kt b/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/diagnostic/DefaultErrorMessagesKapt3.kt
new file mode 100644
index 00000000000..49ca8cf88f4
--- /dev/null
+++ b/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/diagnostic/DefaultErrorMessagesKapt3.kt
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2010-2016 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.kotlin.kapt3.diagnostic
+
+import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages
+import org.jetbrains.kotlin.diagnostics.rendering.DiagnosticFactoryToRendererMap
+
+class DefaultErrorMessagesKapt3 : DefaultErrorMessages.Extension {
+
+ private companion object {
+ val MAP = DiagnosticFactoryToRendererMap("AnnotationProcessing")
+
+ init {
+ MAP.put(ErrorsKapt3.KAPT3_PROCESSING_ERROR,
+ "Some error(s) occurred while processing annotations. Please see the error messages above.")
+ }
+ }
+
+ override fun getMap() = MAP
+}
\ No newline at end of file
diff --git a/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/diagnostic/ErrorsKapt3.java b/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/diagnostic/ErrorsKapt3.java
new file mode 100644
index 00000000000..dd3d13fd416
--- /dev/null
+++ b/plugins/kapt3/src/org/jetbrains/kotlin/kapt3/diagnostic/ErrorsKapt3.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2010-2016 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.kotlin.kapt3.diagnostic;
+
+import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0;
+import org.jetbrains.kotlin.diagnostics.Errors;
+import org.jetbrains.kotlin.psi.KtElement;
+
+import static org.jetbrains.kotlin.diagnostics.Severity.ERROR;
+
+public interface ErrorsKapt3 {
+ DiagnosticFactory0 KAPT3_PROCESSING_ERROR = DiagnosticFactory0.create(ERROR);
+
+ @SuppressWarnings("UnusedDeclaration")
+ Object _initializer = new Object() {
+ {
+ Errors.Initializer.initializeFactoryNames(ErrorsKapt3.class);
+ }
+ };
+
+}
\ No newline at end of file