diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInliner/CodeInliner.kt b/idea/src/org/jetbrains/kotlin/idea/codeInliner/CodeInliner.kt index a64526c1e7e..f545a5147af 100644 --- a/idea/src/org/jetbrains/kotlin/idea/codeInliner/CodeInliner.kt +++ b/idea/src/org/jetbrains/kotlin/idea/codeInliner/CodeInliner.kt @@ -20,10 +20,7 @@ import com.intellij.openapi.util.Key import com.intellij.psi.PsiElement import com.intellij.refactoring.rename.RenameProcessor import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.descriptors.CallableDescriptor -import org.jetbrains.kotlin.descriptors.PropertyDescriptor -import org.jetbrains.kotlin.descriptors.PropertySetterDescriptor -import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor +import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.idea.caches.resolve.resolveImportReference @@ -69,16 +66,16 @@ class CodeInliner( val assignment = (qualifiedElement as? KtExpression) ?.getAssignmentByLHS() ?.takeIf { it.operationToken == KtTokens.EQ } - val elementToBeReplaced = assignment ?: qualifiedElement val callableForParameters = if (assignment != null && descriptor is PropertyDescriptor) - descriptor.setter ?: descriptor + descriptor.setter?.takeIf { it.hasBody() } ?: descriptor else descriptor - + val elementToBeReplaced = assignment.takeIf { callableForParameters is PropertySetterDescriptor } ?: qualifiedElement val commentSaver = CommentSaver(elementToBeReplaced, saveLineBreaks = true) // if the value to be inlined is not used and has no side effects we may drop it if (codeToInline.mainExpression != null + && assignment == null && elementToBeReplaced is KtExpression && !elementToBeReplaced.isUsedAsExpression(bindingContext) && !codeToInline.mainExpression.shouldKeepValue(usageCount = 0) diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/propertyAssignment.kt b/idea/testData/quickfix/deprecatedSymbolUsage/propertyAssignment.kt new file mode 100644 index 00000000000..f7c50a3d916 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/propertyAssignment.kt @@ -0,0 +1,19 @@ +// "Replace with 'new'" "true" +// WITH_RUNTIME + +class A { + @Deprecated("msg", ReplaceWith("new")) + var old + get() = new + set(value) { + new = value + } + + var new = "" +} + +fun foo() { + val a = A() + // Works incorrectly yet + a.old = "foo" +} \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/propertyAssignment.kt.after b/idea/testData/quickfix/deprecatedSymbolUsage/propertyAssignment.kt.after new file mode 100644 index 00000000000..3e52a79d7d0 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/propertyAssignment.kt.after @@ -0,0 +1,19 @@ +// "Replace with 'new'" "true" +// WITH_RUNTIME + +class A { + @Deprecated("msg", ReplaceWith("new")) + var old + get() = new + set(value) { + new = value + } + + var new = "" +} + +fun foo() { + val a = A() + // Works incorrectly yet + a.new +} \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/propertyAssignmentDefaultSetter.kt b/idea/testData/quickfix/deprecatedSymbolUsage/propertyAssignmentDefaultSetter.kt new file mode 100644 index 00000000000..c22340a9151 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/propertyAssignmentDefaultSetter.kt @@ -0,0 +1,16 @@ +// "Replace with 'new'" "true" +// WITH_RUNTIME + +class A { + @Deprecated("msg", ReplaceWith("new")) + var old = "" + get() = new + public set + + var new = "" +} + +fun foo() { + val a = A() + a.old = "foo" +} \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/propertyAssignmentDefaultSetter.kt.after b/idea/testData/quickfix/deprecatedSymbolUsage/propertyAssignmentDefaultSetter.kt.after new file mode 100644 index 00000000000..54288980d72 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/propertyAssignmentDefaultSetter.kt.after @@ -0,0 +1,16 @@ +// "Replace with 'new'" "true" +// WITH_RUNTIME + +class A { + @Deprecated("msg", ReplaceWith("new")) + var old = "" + get() = new + public set + + var new = "" +} + +fun foo() { + val a = A() + a.new = "foo" +} \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/propertyAssignmentNoReceiver.kt b/idea/testData/quickfix/deprecatedSymbolUsage/propertyAssignmentNoReceiver.kt new file mode 100644 index 00000000000..92d55d213af --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/propertyAssignmentNoReceiver.kt @@ -0,0 +1,21 @@ +// "Replace with 'new'" "true" +// WITH_RUNTIME + +class A { + @Deprecated("msg", ReplaceWith("new")) + var old + get() = new + set(value) { + new = value + } + + var new = "" +} + +fun foo() { + val a = A() + a.apply { + // Works incorrectly yet + old = "foo" + } +} \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/propertyAssignmentNoReceiver.kt.after b/idea/testData/quickfix/deprecatedSymbolUsage/propertyAssignmentNoReceiver.kt.after new file mode 100644 index 00000000000..85df2797aec --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/propertyAssignmentNoReceiver.kt.after @@ -0,0 +1,21 @@ +// "Replace with 'new'" "true" +// WITH_RUNTIME + +class A { + @Deprecated("msg", ReplaceWith("new")) + var old + get() = new + set(value) { + new = value + } + + var new = "" +} + +fun foo() { + val a = A() + a.apply { + // Works incorrectly yet + new + } +} \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/propertyAssignmentNoSetter.kt b/idea/testData/quickfix/deprecatedSymbolUsage/propertyAssignmentNoSetter.kt new file mode 100644 index 00000000000..ae61e0280e6 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/propertyAssignmentNoSetter.kt @@ -0,0 +1,15 @@ +// "Replace with 'new'" "true" +// WITH_RUNTIME + +class A { + @Deprecated("msg", ReplaceWith("new")) + var old = "" + get() = new + + var new = "" +} + +fun foo() { + val a = A() + a.old = "foo" +} \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/propertyAssignmentNoSetter.kt.after b/idea/testData/quickfix/deprecatedSymbolUsage/propertyAssignmentNoSetter.kt.after new file mode 100644 index 00000000000..df20f4f027c --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/propertyAssignmentNoSetter.kt.after @@ -0,0 +1,15 @@ +// "Replace with 'new'" "true" +// WITH_RUNTIME + +class A { + @Deprecated("msg", ReplaceWith("new")) + var old = "" + get() = new + + var new = "" +} + +fun foo() { + val a = A() + a.new = "foo" +} \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/propertyModification.kt b/idea/testData/quickfix/deprecatedSymbolUsage/propertyModification.kt new file mode 100644 index 00000000000..fcf1c65f48d --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/propertyModification.kt @@ -0,0 +1,18 @@ +// "Replace with 'new'" "true" +// WITH_RUNTIME + +class A { + @Deprecated("msg", ReplaceWith("new")) + var old + get() = new + set(value) { + new = value + } + + var new = "" +} + +fun foo() { + val a = A() + a.old += "foo" +} \ No newline at end of file diff --git a/idea/testData/quickfix/deprecatedSymbolUsage/propertyModification.kt.after b/idea/testData/quickfix/deprecatedSymbolUsage/propertyModification.kt.after new file mode 100644 index 00000000000..3e2e07c1fc1 --- /dev/null +++ b/idea/testData/quickfix/deprecatedSymbolUsage/propertyModification.kt.after @@ -0,0 +1,18 @@ +// "Replace with 'new'" "true" +// WITH_RUNTIME + +class A { + @Deprecated("msg", ReplaceWith("new")) + var old + get() = new + set(value) { + new = value + } + + var new = "" +} + +fun foo() { + val a = A() + a.new += "foo" +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index 74515ae994d..bb6ecafe0c7 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -5222,6 +5222,36 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest(fileName); } + @TestMetadata("propertyAssignment.kt") + public void testPropertyAssignment() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/propertyAssignment.kt"); + doTest(fileName); + } + + @TestMetadata("propertyAssignmentDefaultSetter.kt") + public void testPropertyAssignmentDefaultSetter() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/propertyAssignmentDefaultSetter.kt"); + doTest(fileName); + } + + @TestMetadata("propertyAssignmentNoReceiver.kt") + public void testPropertyAssignmentNoReceiver() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/propertyAssignmentNoReceiver.kt"); + doTest(fileName); + } + + @TestMetadata("propertyAssignmentNoSetter.kt") + public void testPropertyAssignmentNoSetter() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/propertyAssignmentNoSetter.kt"); + doTest(fileName); + } + + @TestMetadata("propertyModification.kt") + public void testPropertyModification() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/propertyModification.kt"); + doTest(fileName); + } + @TestMetadata("propertyToMethod.kt") public void testPropertyToMethod() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/deprecatedSymbolUsage/propertyToMethod.kt");