diff --git a/idea/resources-en/intentionDescriptions/ConvertVariableAssignmentToExpressionIntention/after.kt.template b/idea/resources-en/intentionDescriptions/ConvertVariableAssignmentToExpressionIntention/after.kt.template
new file mode 100644
index 00000000000..4fe4d69f0fd
--- /dev/null
+++ b/idea/resources-en/intentionDescriptions/ConvertVariableAssignmentToExpressionIntention/after.kt.template
@@ -0,0 +1,4 @@
+var x = 5
+fun foo() {
+ 10.also { x = it }
+}
diff --git a/idea/resources-en/intentionDescriptions/ConvertVariableAssignmentToExpressionIntention/before.kt.template b/idea/resources-en/intentionDescriptions/ConvertVariableAssignmentToExpressionIntention/before.kt.template
new file mode 100644
index 00000000000..225a7542552
--- /dev/null
+++ b/idea/resources-en/intentionDescriptions/ConvertVariableAssignmentToExpressionIntention/before.kt.template
@@ -0,0 +1,4 @@
+var x = 5
+fun foo() {
+ x = 10
+}
diff --git a/idea/resources-en/intentionDescriptions/ConvertVariableAssignmentToExpressionIntention/description.html b/idea/resources-en/intentionDescriptions/ConvertVariableAssignmentToExpressionIntention/description.html
new file mode 100644
index 00000000000..ac3371c0ee1
--- /dev/null
+++ b/idea/resources-en/intentionDescriptions/ConvertVariableAssignmentToExpressionIntention/description.html
@@ -0,0 +1,5 @@
+
+
+This intention converts a variable assignment to a variable assignment expression.
+
+
diff --git a/idea/resources-en/messages/KotlinBundle.properties b/idea/resources-en/messages/KotlinBundle.properties
index 80172210454..af7bccededd 100644
--- a/idea/resources-en/messages/KotlinBundle.properties
+++ b/idea/resources-en/messages/KotlinBundle.properties
@@ -1749,6 +1749,7 @@ convert.to.0.as.1=Convert to ''{0} as {1}''
convert.to.0.unsafecast.1=Convert to ''{0}.unsafeCast<{1}>()''
convert.to.unsafecast.call=Convert to unsafeCast() call
convert.to.array.parameter=Convert to array parameter
+convert.to.assignment.expression=Convert assignment to assignment expression
create.kotlin.subclass=Create Kotlin subclass
use.destructuring.declaration=Use destructuring declaration
implement.as.constructor.parameter=Implement as constructor parameter
diff --git a/idea/resources/META-INF/inspections.xml b/idea/resources/META-INF/inspections.xml
index 807d17d26d0..b2e699faaa6 100644
--- a/idea/resources/META-INF/inspections.xml
+++ b/idea/resources/META-INF/inspections.xml
@@ -585,6 +585,11 @@
Kotlin
+
+ org.jetbrains.kotlin.idea.intentions.ConvertVariableAssignmentToExpressionIntention
+ Kotlin
+
+
org.jetbrains.kotlin.idea.intentions.MergeIfsIntention
Kotlin
diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertVariableAssignmentToExpressionIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertVariableAssignmentToExpressionIntention.kt
new file mode 100644
index 00000000000..f1096e68397
--- /dev/null
+++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertVariableAssignmentToExpressionIntention.kt
@@ -0,0 +1,29 @@
+/*
+ * 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.intentions
+
+import com.intellij.openapi.editor.Editor
+import org.jetbrains.kotlin.idea.KotlinBundle
+import org.jetbrains.kotlin.idea.references.KtSimpleReference
+import org.jetbrains.kotlin.lexer.KtTokens
+import org.jetbrains.kotlin.psi.*
+
+class ConvertVariableAssignmentToExpressionIntention : SelfTargetingIntention(
+ KtBinaryExpression::class.java,
+ KotlinBundle.lazyMessage("convert.to.assignment.expression"),
+) {
+ override fun isApplicableTo(element: KtBinaryExpression, caretOffset: Int): Boolean {
+ if (element.operationToken == KtTokens.EQ) return true
+ return false
+ }
+
+ override fun applyTo(element: KtBinaryExpression, editor: Editor?) {
+ val left = element.left ?: return
+ val right = element.right ?: return
+ val newElement = KtPsiFactory(element.project).createExpressionByPattern("$0.also { $1 = it }", right, left)
+ element.replace(newElement)
+ }
+}
diff --git a/idea/testData/intentions/convertVariableAssignmentToExpression/.intention b/idea/testData/intentions/convertVariableAssignmentToExpression/.intention
new file mode 100644
index 00000000000..0ba914724b3
--- /dev/null
+++ b/idea/testData/intentions/convertVariableAssignmentToExpression/.intention
@@ -0,0 +1 @@
+org.jetbrains.kotlin.idea.intentions.ConvertVariableAssignmentToExpressionIntention
diff --git a/idea/testData/intentions/convertVariableAssignmentToExpression/complexLhs.kt b/idea/testData/intentions/convertVariableAssignmentToExpression/complexLhs.kt
new file mode 100644
index 00000000000..45c75431291
--- /dev/null
+++ b/idea/testData/intentions/convertVariableAssignmentToExpression/complexLhs.kt
@@ -0,0 +1,8 @@
+// WITH_RUNTIME
+object X {
+ var string = "foo"
+}
+
+fun main() {
+ X.string = "bar"
+}
diff --git a/idea/testData/intentions/convertVariableAssignmentToExpression/complexLhs.kt.after b/idea/testData/intentions/convertVariableAssignmentToExpression/complexLhs.kt.after
new file mode 100644
index 00000000000..722973e6757
--- /dev/null
+++ b/idea/testData/intentions/convertVariableAssignmentToExpression/complexLhs.kt.after
@@ -0,0 +1,8 @@
+// WITH_RUNTIME
+object X {
+ var string = "foo"
+}
+
+fun main() {
+ "bar".also { X.string = it }
+}
diff --git a/idea/testData/intentions/convertVariableAssignmentToExpression/complexRhs.kt b/idea/testData/intentions/convertVariableAssignmentToExpression/complexRhs.kt
new file mode 100644
index 00000000000..b994c7b589f
--- /dev/null
+++ b/idea/testData/intentions/convertVariableAssignmentToExpression/complexRhs.kt
@@ -0,0 +1,9 @@
+// WITH_RUNTIME
+object X {
+ var string = "foo"
+}
+
+var target = "baz"
+fun main() {
+ target = X.string
+}
diff --git a/idea/testData/intentions/convertVariableAssignmentToExpression/complexRhs.kt.after b/idea/testData/intentions/convertVariableAssignmentToExpression/complexRhs.kt.after
new file mode 100644
index 00000000000..28fe699fe13
--- /dev/null
+++ b/idea/testData/intentions/convertVariableAssignmentToExpression/complexRhs.kt.after
@@ -0,0 +1,9 @@
+// WITH_RUNTIME
+object X {
+ var string = "foo"
+}
+
+var target = "baz"
+fun main() {
+ X.string.also { target = it }
+}
diff --git a/idea/testData/intentions/convertVariableAssignmentToExpression/noAssignment.kt b/idea/testData/intentions/convertVariableAssignmentToExpression/noAssignment.kt
new file mode 100644
index 00000000000..eb5d48ec902
--- /dev/null
+++ b/idea/testData/intentions/convertVariableAssignmentToExpression/noAssignment.kt
@@ -0,0 +1,5 @@
+// IS_APPLICABLE: false
+var x = 0
+fun main() {
+ x == 10
+}
diff --git a/idea/testData/intentions/convertVariableAssignmentToExpression/simple.kt b/idea/testData/intentions/convertVariableAssignmentToExpression/simple.kt
new file mode 100644
index 00000000000..db406346a4d
--- /dev/null
+++ b/idea/testData/intentions/convertVariableAssignmentToExpression/simple.kt
@@ -0,0 +1,5 @@
+// WITH_RUNTIME
+var x = 5
+fun foo() {
+ x = 10
+}
diff --git a/idea/testData/intentions/convertVariableAssignmentToExpression/simple.kt.after b/idea/testData/intentions/convertVariableAssignmentToExpression/simple.kt.after
new file mode 100644
index 00000000000..55db9e815f7
--- /dev/null
+++ b/idea/testData/intentions/convertVariableAssignmentToExpression/simple.kt.after
@@ -0,0 +1,5 @@
+// WITH_RUNTIME
+var x = 5
+fun foo() {
+ 10.also { x = it }
+}
diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java
index 3f84b3a7029..f9800d73e3a 100644
--- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java
+++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java
@@ -8240,6 +8240,39 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
}
}
+ @TestMetadata("idea/testData/intentions/convertVariableAssignmentToExpression")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class ConvertVariableAssignmentToExpression extends AbstractIntentionTest {
+ private void runTest(String testDataFilePath) throws Exception {
+ KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
+ }
+
+ public void testAllFilesPresentInConvertVariableAssignmentToExpression() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/intentions/convertVariableAssignmentToExpression"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), null, true);
+ }
+
+ @TestMetadata("complexLhs.kt")
+ public void testComplexLhs() throws Exception {
+ runTest("idea/testData/intentions/convertVariableAssignmentToExpression/complexLhs.kt");
+ }
+
+ @TestMetadata("complexRhs.kt")
+ public void testComplexRhs() throws Exception {
+ runTest("idea/testData/intentions/convertVariableAssignmentToExpression/complexRhs.kt");
+ }
+
+ @TestMetadata("noAssignment.kt")
+ public void testNoAssignment() throws Exception {
+ runTest("idea/testData/intentions/convertVariableAssignmentToExpression/noAssignment.kt");
+ }
+
+ @TestMetadata("simple.kt")
+ public void testSimple() throws Exception {
+ runTest("idea/testData/intentions/convertVariableAssignmentToExpression/simple.kt");
+ }
+ }
+
@TestMetadata("idea/testData/intentions/copyConcatenatedStringToClipboard")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)