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
|
###### 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
|
- [`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
|
## 1.0.3
|
||||||
|
|||||||
+3
-1
@@ -37,6 +37,8 @@ abstract class ExtractionEngineHelper(val operationName: String) {
|
|||||||
onFinish(project.executeWriteCommand<ExtractionResult>(operationName) { config.generateDeclaration() })
|
onFinish(project.executeWriteCommand<ExtractionResult>(operationName) { config.generateDeclaration() })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open fun validate(descriptor: ExtractableCodeDescriptor): ExtractableCodeDescriptorWithConflicts = descriptor.validate()
|
||||||
|
|
||||||
abstract fun configureAndRun(
|
abstract fun configureAndRun(
|
||||||
project: Project,
|
project: Project,
|
||||||
editor: Editor,
|
editor: Editor,
|
||||||
@@ -61,7 +63,7 @@ class ExtractionEngine(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun validateAndRefactor() {
|
fun validateAndRefactor() {
|
||||||
val validationResult = analysisResult.descriptor!!.validate()
|
val validationResult = helper.validate(analysisResult.descriptor!!)
|
||||||
project.checkConflictsInteractively(validationResult.conflicts) {
|
project.checkConflictsInteractively(validationResult.conflicts) {
|
||||||
helper.configureAndRun(project, editor, validationResult) {
|
helper.configureAndRun(project, editor, validationResult) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
+9
-4
@@ -394,8 +394,12 @@ fun ExtractionData.createTemporaryDeclaration(pattern: String): KtNamedDeclarati
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun ExtractionData.createTemporaryCodeBlock(): KtBlockExpression =
|
internal fun ExtractionData.createTemporaryCodeBlock(): KtBlockExpression {
|
||||||
(createTemporaryDeclaration("fun() {\n$0\n}\n") as KtNamedFunction).bodyExpression as 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> {
|
private fun KotlinType.collectReferencedTypes(processTypeArguments: Boolean): List<KotlinType> {
|
||||||
if (!processTypeArguments) return Collections.singletonList(this)
|
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()}")
|
} ?: 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 {
|
fun getDeclarationMessage(declaration: PsiNamedElement, messageKey: String, capitalize: Boolean = true): String {
|
||||||
val message = KotlinRefactoringBundle.message(messageKey, RefactoringUIUtil.getDescription(declaration, true))
|
val message = KotlinRefactoringBundle.message(messageKey, RefactoringUIUtil.getDescription(declaration, true))
|
||||||
return if (capitalize) message.capitalize() else message
|
return if (capitalize) message.capitalize() else message
|
||||||
@@ -749,7 +754,7 @@ fun ExtractableCodeDescriptor.validate(): ExtractableCodeDescriptorWithConflicts
|
|||||||
|
|
||||||
val result = ExtractionGeneratorConfiguration(
|
val result = ExtractionGeneratorConfiguration(
|
||||||
this,
|
this,
|
||||||
ExtractionGeneratorOptions(inTempFile = true, allowExpressionBody = false)
|
ExtractionGeneratorOptions(inTempFile = true, allowExpressionBody = false, target = target)
|
||||||
).generateDeclaration()
|
).generateDeclaration()
|
||||||
|
|
||||||
val valueParameterList = (result.declaration as? KtNamedFunction)?.valueParameterList
|
val valueParameterList = (result.declaration as? KtNamedFunction)?.valueParameterList
|
||||||
|
|||||||
+24
-11
@@ -16,25 +16,38 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.refactoring.introduce.introduceProperty
|
package org.jetbrains.kotlin.idea.refactoring.introduce.introduceProperty
|
||||||
|
|
||||||
import com.intellij.openapi.project.*
|
import com.intellij.openapi.actionSystem.DataContext
|
||||||
import com.intellij.psi.*
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
import com.intellij.openapi.actionSystem.*
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.intellij.openapi.editor.*
|
import com.intellij.openapi.project.Project
|
||||||
import org.jetbrains.kotlin.psi.*
|
import com.intellij.psi.PsiDocumentManager
|
||||||
import org.jetbrains.kotlin.idea.refactoring.introduce.*
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.idea.refactoring.*
|
import com.intellij.psi.PsiFile
|
||||||
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.*
|
|
||||||
import org.jetbrains.kotlin.idea.util.psi.patternMatching.*
|
|
||||||
import com.intellij.openapi.application.*
|
|
||||||
import com.intellij.refactoring.RefactoringActionHandler
|
import com.intellij.refactoring.RefactoringActionHandler
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.CodeInsightUtils
|
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.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.*
|
import java.util.*
|
||||||
|
|
||||||
class KotlinIntroducePropertyHandler(
|
class KotlinIntroducePropertyHandler(
|
||||||
val helper: ExtractionEngineHelper = KotlinIntroducePropertyHandler.InteractiveExtractionHelper
|
val helper: ExtractionEngineHelper = KotlinIntroducePropertyHandler.InteractiveExtractionHelper
|
||||||
): RefactoringActionHandler {
|
): RefactoringActionHandler {
|
||||||
object InteractiveExtractionHelper : ExtractionEngineHelper(INTRODUCE_PROPERTY) {
|
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(
|
override fun configureAndRun(
|
||||||
project: Project,
|
project: Project,
|
||||||
editor: Editor,
|
editor: Editor,
|
||||||
@@ -42,7 +55,7 @@ class KotlinIntroducePropertyHandler(
|
|||||||
onFinish: (ExtractionResult) -> Unit
|
onFinish: (ExtractionResult) -> Unit
|
||||||
) {
|
) {
|
||||||
val descriptor = descriptorWithConflicts.descriptor
|
val descriptor = descriptorWithConflicts.descriptor
|
||||||
val target = propertyTargets.filter { it.isAvailable(descriptor) }.firstOrNull()
|
val target = getExtractionTarget(descriptor)
|
||||||
if (target != null) {
|
if (target != null) {
|
||||||
val options = ExtractionGeneratorOptions.DEFAULT.copy(target = target, delayInitialOccurrenceReplacement = true)
|
val options = ExtractionGeneratorOptions.DEFAULT.copy(target = target, delayInitialOccurrenceReplacement = true)
|
||||||
doRefactor(ExtractionGeneratorConfiguration(descriptor, options), onFinish)
|
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 explicitPreviousSibling = file.findElementByCommentPrefix("// SIBLING:")
|
||||||
val helper = object : ExtractionEngineHelper(INTRODUCE_PROPERTY) {
|
val helper = object : ExtractionEngineHelper(INTRODUCE_PROPERTY) {
|
||||||
|
override fun validate(descriptor: ExtractableCodeDescriptor) = descriptor.validate(extractionTarget)
|
||||||
|
|
||||||
override fun configureAndRun(
|
override fun configureAndRun(
|
||||||
project: Project,
|
project: Project,
|
||||||
editor: Editor,
|
editor: Editor,
|
||||||
|
|||||||
+6
@@ -3100,6 +3100,12 @@ public class ExtractionTestGenerated extends AbstractExtractionTest {
|
|||||||
doIntroducePropertyTest(fileName);
|
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")
|
@TestMetadata("replaceDuplicates.kt")
|
||||||
public void testReplaceDuplicates() throws Exception {
|
public void testReplaceDuplicates() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceProperty/replaceDuplicates.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/introduceProperty/replaceDuplicates.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user