Introduce Property: Fix extraction of expressions referring to primary constructor parameters
#KT-12294 Fixed (cherry picked from commit 78212a4)
This commit is contained in:
@@ -117,6 +117,7 @@ These artifacts include extensions for the types available in the latter JDKs, s
|
||||
|
||||
###### Issues fixed
|
||||
|
||||
- [`KT-12294`](https://youtrack.jetbrains.com/issue/KT-12294) Introduce Property: Fix extraction of expressions referring to primary constructor parameters
|
||||
- [`KT-12413`](https://youtrack.jetbrains.com/issue/KT-12413) Change Signature: Fix bogus warning about unresolved type parameters/invalid functional type replacement
|
||||
|
||||
## 1.0.3
|
||||
|
||||
+3
-1
@@ -37,6 +37,8 @@ abstract class ExtractionEngineHelper(val operationName: String) {
|
||||
onFinish(project.executeWriteCommand<ExtractionResult>(operationName) { config.generateDeclaration() })
|
||||
}
|
||||
|
||||
open fun validate(descriptor: ExtractableCodeDescriptor): ExtractableCodeDescriptorWithConflicts = descriptor.validate()
|
||||
|
||||
abstract fun configureAndRun(
|
||||
project: Project,
|
||||
editor: Editor,
|
||||
@@ -61,7 +63,7 @@ class ExtractionEngine(
|
||||
}
|
||||
|
||||
fun validateAndRefactor() {
|
||||
val validationResult = analysisResult.descriptor!!.validate()
|
||||
val validationResult = helper.validate(analysisResult.descriptor!!)
|
||||
project.checkConflictsInteractively(validationResult.conflicts) {
|
||||
helper.configureAndRun(project, editor, validationResult) {
|
||||
try {
|
||||
|
||||
+9
-4
@@ -394,8 +394,12 @@ fun ExtractionData.createTemporaryDeclaration(pattern: String): KtNamedDeclarati
|
||||
}
|
||||
}
|
||||
|
||||
internal fun ExtractionData.createTemporaryCodeBlock(): KtBlockExpression =
|
||||
(createTemporaryDeclaration("fun() {\n$0\n}\n") as KtNamedFunction).bodyExpression as KtBlockExpression
|
||||
internal fun ExtractionData.createTemporaryCodeBlock(): KtBlockExpression {
|
||||
if (options.extractAsProperty) {
|
||||
return ((createTemporaryDeclaration("val = {\n$0\n}\n") as KtProperty).initializer as KtLambdaExpression).bodyExpression!!
|
||||
}
|
||||
return (createTemporaryDeclaration("fun() {\n$0\n}\n") as KtNamedFunction).bodyExpression as KtBlockExpression
|
||||
}
|
||||
|
||||
private fun KotlinType.collectReferencedTypes(processTypeArguments: Boolean): List<KotlinType> {
|
||||
if (!processTypeArguments) return Collections.singletonList(this)
|
||||
@@ -739,7 +743,8 @@ internal fun KtNamedDeclaration.getGeneratedBody() =
|
||||
}
|
||||
} ?: throw AssertionError("Couldn't get block body for this declaration: ${getElementTextWithContext()}")
|
||||
|
||||
fun ExtractableCodeDescriptor.validate(): ExtractableCodeDescriptorWithConflicts {
|
||||
@JvmOverloads
|
||||
fun ExtractableCodeDescriptor.validate(target: ExtractionTarget = ExtractionTarget.FUNCTION): ExtractableCodeDescriptorWithConflicts {
|
||||
fun getDeclarationMessage(declaration: PsiNamedElement, messageKey: String, capitalize: Boolean = true): String {
|
||||
val message = KotlinRefactoringBundle.message(messageKey, RefactoringUIUtil.getDescription(declaration, true))
|
||||
return if (capitalize) message.capitalize() else message
|
||||
@@ -749,7 +754,7 @@ fun ExtractableCodeDescriptor.validate(): ExtractableCodeDescriptorWithConflicts
|
||||
|
||||
val result = ExtractionGeneratorConfiguration(
|
||||
this,
|
||||
ExtractionGeneratorOptions(inTempFile = true, allowExpressionBody = false)
|
||||
ExtractionGeneratorOptions(inTempFile = true, allowExpressionBody = false, target = target)
|
||||
).generateDeclaration()
|
||||
|
||||
val valueParameterList = (result.declaration as? KtNamedFunction)?.valueParameterList
|
||||
|
||||
+24
-11
@@ -16,25 +16,38 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.refactoring.introduce.introduceProperty
|
||||
|
||||
import com.intellij.openapi.project.*
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.openapi.actionSystem.*
|
||||
import com.intellij.openapi.editor.*
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.*
|
||||
import org.jetbrains.kotlin.idea.refactoring.*
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.*
|
||||
import org.jetbrains.kotlin.idea.util.psi.patternMatching.*
|
||||
import com.intellij.openapi.application.*
|
||||
import com.intellij.openapi.actionSystem.DataContext
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.refactoring.RefactoringActionHandler
|
||||
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils
|
||||
import org.jetbrains.kotlin.idea.refactoring.KotlinRefactoringBundle
|
||||
import org.jetbrains.kotlin.idea.refactoring.getExtractionContainers
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.*
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.selectElementsWithTargetSibling
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.showErrorHint
|
||||
import org.jetbrains.kotlin.idea.refactoring.introduce.showErrorHintByKey
|
||||
import org.jetbrains.kotlin.idea.util.psi.patternMatching.toRange
|
||||
import org.jetbrains.kotlin.psi.KtBlockExpression
|
||||
import org.jetbrains.kotlin.psi.KtClassBody
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
import java.util.*
|
||||
|
||||
class KotlinIntroducePropertyHandler(
|
||||
val helper: ExtractionEngineHelper = KotlinIntroducePropertyHandler.InteractiveExtractionHelper
|
||||
): RefactoringActionHandler {
|
||||
object InteractiveExtractionHelper : ExtractionEngineHelper(INTRODUCE_PROPERTY) {
|
||||
private fun getExtractionTarget(descriptor: ExtractableCodeDescriptor) =
|
||||
propertyTargets.filter { it.isAvailable(descriptor) }.firstOrNull()
|
||||
|
||||
override fun validate(descriptor: ExtractableCodeDescriptor) =
|
||||
descriptor.validate(getExtractionTarget(descriptor) ?: ExtractionTarget.FUNCTION)
|
||||
|
||||
override fun configureAndRun(
|
||||
project: Project,
|
||||
editor: Editor,
|
||||
@@ -42,7 +55,7 @@ class KotlinIntroducePropertyHandler(
|
||||
onFinish: (ExtractionResult) -> Unit
|
||||
) {
|
||||
val descriptor = descriptorWithConflicts.descriptor
|
||||
val target = propertyTargets.filter { it.isAvailable(descriptor) }.firstOrNull()
|
||||
val target = getExtractionTarget(descriptor)
|
||||
if (target != null) {
|
||||
val options = ExtractionGeneratorOptions.DEFAULT.copy(target = target, delayInitialOccurrenceReplacement = true)
|
||||
doRefactor(ExtractionGeneratorConfiguration(descriptor, options), onFinish)
|
||||
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
// EXTRACTION_TARGET: property with initializer
|
||||
class Foo(s: String) {
|
||||
val l = <selection>(s + "1")</selection>.length
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
// EXTRACTION_TARGET: property with initializer
|
||||
class Foo(s: String) {
|
||||
private val s = (s + "1")
|
||||
|
||||
val l = s.length
|
||||
}
|
||||
@@ -216,6 +216,8 @@ abstract class AbstractExtractionTest() : KotlinLightCodeInsightFixtureTestCase(
|
||||
}
|
||||
val explicitPreviousSibling = file.findElementByCommentPrefix("// SIBLING:")
|
||||
val helper = object : ExtractionEngineHelper(INTRODUCE_PROPERTY) {
|
||||
override fun validate(descriptor: ExtractableCodeDescriptor) = descriptor.validate(extractionTarget)
|
||||
|
||||
override fun configureAndRun(
|
||||
project: Project,
|
||||
editor: Editor,
|
||||
|
||||
+6
@@ -3100,6 +3100,12 @@ public class ExtractionTestGenerated extends AbstractExtractionTest {
|
||||
doIntroducePropertyTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("primaryConstructorParameterReference.kt")
|
||||
public void testPrimaryConstructorParameterReference() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceProperty/primaryConstructorParameterReference.kt");
|
||||
doIntroducePropertyTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("replaceDuplicates.kt")
|
||||
public void testReplaceDuplicates() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceProperty/replaceDuplicates.kt");
|
||||
|
||||
Reference in New Issue
Block a user