diff --git a/idea/resources/META-INF/extensions/ide.xml b/idea/resources/META-INF/extensions/ide.xml
index 7e614e321b4..26539eeb56e 100644
--- a/idea/resources/META-INF/extensions/ide.xml
+++ b/idea/resources/META-INF/extensions/ide.xml
@@ -67,6 +67,9 @@
+
+
diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/AdditionalExtractableAnalyser.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/AdditionalExtractableAnalyser.kt
new file mode 100644
index 00000000000..346eea996bf
--- /dev/null
+++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/AdditionalExtractableAnalyser.kt
@@ -0,0 +1,20 @@
+/*
+ * 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.kotlin.idea.refactoring.introduce.extractionEngine
+
+import com.intellij.openapi.extensions.ExtensionPointName
+
+/**
+ * Allows to modify ExtractableCodeDescriptor within [ExtractionData.performAnalysis].
+ */
+interface AdditionalExtractableAnalyser {
+
+ fun amendDescriptor(descriptor: ExtractableCodeDescriptor): ExtractableCodeDescriptor
+
+ companion object {
+ val EP_NAME = ExtensionPointName.create("org.jetbrains.kotlin.additionalExtractableAnalyser")
+ }
+}
diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/ExtractableCodeDescriptor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/ExtractableCodeDescriptor.kt
index 1c24fa338c0..d4c1f3e830a 100644
--- a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/ExtractableCodeDescriptor.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/ExtractableCodeDescriptor.kt
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
+import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.idea.core.replaced
import org.jetbrains.kotlin.idea.refactoring.KotlinRefactoringBundle
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.OutputValue.*
@@ -357,7 +358,8 @@ data class ExtractableCodeDescriptor(
val replacementMap: MultiMap,
val controlFlow: ControlFlow,
val returnType: KotlinType,
- val modifiers: List = emptyList()
+ val modifiers: List = emptyList(),
+ val annotations: List = emptyList()
) {
val name: String get() = suggestedNames.firstOrNull() ?: ""
val duplicates: List by lazy { findDuplicates() }
@@ -393,7 +395,8 @@ fun ExtractableCodeDescriptor.copy(
newReplacementMap,
controlFlow.copy(oldToNewParameters),
returnType ?: this.returnType,
- modifiers
+ modifiers,
+ annotations
)
}
diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/extractableAnalysisUtil.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/extractableAnalysisUtil.kt
index 12574c15960..3c67ac1b92a 100644
--- a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/extractableAnalysisUtil.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/extractableAnalysisUtil.kt
@@ -708,6 +708,9 @@ fun ExtractionData.performAnalysis(): AnalysisResult {
descriptor = descriptor.copy(modifiers = listOf(KtTokens.SUSPEND_KEYWORD))
}
+ for (analyser in AdditionalExtractableAnalyser.EP_NAME.extensions) {
+ descriptor = analyser.amendDescriptor(descriptor)
+ }
return AnalysisResult(
descriptor,
diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/extractorUtil.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/extractorUtil.kt
index 9e2b06074df..5e947ce237b 100644
--- a/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/extractorUtil.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/introduce/extractionEngine/extractorUtil.kt
@@ -61,10 +61,16 @@ private fun buildSignature(config: ExtractionGeneratorConfiguration, renderer: D
fun TypeParameter.isReified() = originalDeclaration.hasModifier(KtTokens.REIFIED_KEYWORD)
val shouldBeInline = config.descriptor.typeParameters.any { it.isReified() }
+
+ val annotations = if (config.descriptor.annotations.isEmpty()) {
+ ""
+ } else {
+ config.descriptor.annotations.joinToString(separator = "\n", postfix = "\n") { renderer.renderAnnotation(it) }
+ }
val extraModifiers = config.descriptor.modifiers.map { it.value } +
listOfNotNull(if (shouldBeInline) KtTokens.INLINE_KEYWORD.value else null)
val modifiers = if (visibility.isNotEmpty()) listOf(visibility) + extraModifiers else extraModifiers
- modifier(modifiers.joinToString(separator = " "))
+ modifier(annotations + modifiers.joinToString(separator = " "))
typeParams(
config.descriptor.typeParameters.map {