diff --git a/compiler/frontend/src/org/jetbrains/kotlin/psi/KtDestructuringDeclaration.java b/compiler/frontend/src/org/jetbrains/kotlin/psi/KtDestructuringDeclaration.java
index 9c8804c5cf5..c86d5420adc 100644
--- a/compiler/frontend/src/org/jetbrains/kotlin/psi/KtDestructuringDeclaration.java
+++ b/compiler/frontend/src/org/jetbrains/kotlin/psi/KtDestructuringDeclaration.java
@@ -53,6 +53,11 @@ public class KtDestructuringDeclaration extends KtDeclarationImpl implements KtV
return PsiTreeUtil.getNextSiblingOfType(eqNode.getPsi(), KtExpression.class);
}
+ public boolean isVar() {
+ return getNode().findChildByType(KtTokens.VAR_KEYWORD) != null;
+ }
+
+ @Override
@Nullable
public PsiElement getValOrVarKeyword() {
return findChildByType(TokenSet.create(VAL_KEYWORD, VAR_KEYWORD));
diff --git a/idea/resources/inspectionDescriptions/CanBeVal.html b/idea/resources/inspectionDescriptions/CanBeVal.html
new file mode 100644
index 00000000000..57a4e98079d
--- /dev/null
+++ b/idea/resources/inspectionDescriptions/CanBeVal.html
@@ -0,0 +1,5 @@
+
+
+This inspection reports mutable local variables (declared with 'var' keyword) that can be made immutable.
+
+
diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml
index a38a663433f..784324fb2c9 100644
--- a/idea/src/META-INF/plugin.xml
+++ b/idea/src/META-INF/plugin.xml
@@ -1391,6 +1391,13 @@
cleanupTool="false"
level="WEAK WARNING"/>
+
+
diff --git a/idea/src/org/jetbrains/kotlin/idea/inspections/CanBeValInspection.kt b/idea/src/org/jetbrains/kotlin/idea/inspections/CanBeValInspection.kt
new file mode 100644
index 00000000000..00e7c3478ea
--- /dev/null
+++ b/idea/src/org/jetbrains/kotlin/idea/inspections/CanBeValInspection.kt
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2010-2016 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.kotlin.idea.inspections
+
+import com.intellij.codeInspection.IntentionWrapper
+import com.intellij.codeInspection.ProblemHighlightType
+import com.intellij.codeInspection.ProblemsHolder
+import com.intellij.psi.PsiElementVisitor
+import com.intellij.psi.search.searches.ReferencesSearch
+import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode
+import org.jetbrains.kotlin.cfg.pseudocode.PseudocodeUtil
+import org.jetbrains.kotlin.cfg.pseudocode.containingDeclarationForPseudocode
+import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction
+import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionWithNext
+import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.AccessTarget
+import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.WriteValueInstruction
+import org.jetbrains.kotlin.idea.caches.resolve.analyze
+import org.jetbrains.kotlin.idea.quickfix.ChangeVariableMutabilityFix
+import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
+import org.jetbrains.kotlin.idea.references.readWriteAccess
+import org.jetbrains.kotlin.psi.*
+import org.jetbrains.kotlin.resolve.BindingContext
+import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
+import java.util.*
+
+class CanBeValInspection : AbstractKotlinInspection() {
+ override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
+ return object: KtVisitorVoid() {
+ private val pseudocodeCache = HashMap()
+
+ override fun visitDeclaration(declaration: KtDeclaration) {
+ super.visitDeclaration(declaration)
+
+ when (declaration) {
+ is KtProperty -> {
+ if (declaration.isVar && declaration.isLocal && canBeVal(declaration, declaration.hasInitializer(), listOf(declaration))) {
+ reportCanBeVal(declaration)
+ }
+ }
+
+ is KtDestructuringDeclaration -> {
+ val entries = declaration.entries
+ if (declaration.isVar && entries.all { canBeVal(it, true, entries) }) {
+ reportCanBeVal(declaration)
+ }
+ }
+ }
+ }
+
+ private fun canBeVal(declaration: KtVariableDeclaration, hasInitializer: Boolean, allDeclarations: Collection): Boolean {
+ if (allDeclarations.all { ReferencesSearch.search(it, it.useScope).none() }) {
+ // do not report for unused var's (otherwise we'll get it highlighted immediately after typing the declaration
+ return false
+ }
+
+ if (hasInitializer) {
+ val hasWriteUsages = ReferencesSearch.search(declaration, declaration.useScope).any {
+ (it as? KtSimpleNameReference)?.element?.readWriteAccess(useResolveForReadWrite = true)?.isWrite == true
+ }
+ return !hasWriteUsages
+ }
+ else {
+ val bindingContext = declaration.analyze(BodyResolveMode.FULL)
+ val pseudocode = pseudocode(declaration, bindingContext) ?: return false
+ val descriptor = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, declaration] ?: return false
+
+ val writeInstructions = pseudocode.instructionsIncludingDeadCode
+ .filterIsInstance()
+ .filter { (it.target as? AccessTarget.Call)?.resolvedCall?.resultingDescriptor == descriptor }
+ .toSet()
+ if (writeInstructions.isEmpty()) return false // incorrect code - do not report
+
+ return writeInstructions.none { canReach(it, writeInstructions) }
+ }
+ }
+
+ private fun pseudocode(element: KtElement, bindingContext: BindingContext): Pseudocode? {
+ val declaration = element.containingDeclarationForPseudocode ?: return null
+ return pseudocodeCache.getOrPut(declaration) { PseudocodeUtil.generatePseudocode(declaration, bindingContext) }
+ }
+
+ private fun canReach(from: Instruction, targets: Set, visited: HashSet = HashSet()): Boolean {
+ // special algorithm for linear code to avoid too deep recursion
+ var instruction = from
+ while (instruction is InstructionWithNext) {
+ val next = instruction.next ?: return false
+ if (next in visited) continue
+ if (next in targets) return true
+ visited.add(next)
+ instruction = next
+ }
+
+ for (next in instruction.nextInstructions) {
+ if (next in visited) continue
+ if (next in targets) return true
+ visited.add(next)
+ if (canReach(next, targets)) return true
+ }
+ return false
+ }
+
+ private fun reportCanBeVal(declaration: KtValVarKeywordOwner) {
+ val problemDescriptor = holder.manager.createProblemDescriptor(
+ declaration,
+ declaration.valOrVarKeyword!!,
+ "Can be declared as 'val'",
+ ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
+ isOnTheFly,
+ IntentionWrapper(ChangeVariableMutabilityFix(declaration, false), declaration.containingFile)
+ )
+ holder.registerProblem(problemDescriptor)
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableMutabilityFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableMutabilityFix.kt
index bf9ca7a7fec..a2029e3e3b8 100644
--- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableMutabilityFix.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableMutabilityFix.kt
@@ -24,32 +24,23 @@ import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
-import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
-class ChangeVariableMutabilityFix(element: KtNamedDeclaration, private val makeVar: Boolean) : KotlinQuickFixAction(element) {
+class ChangeVariableMutabilityFix(element: KtValVarKeywordOwner, private val makeVar: Boolean) : KotlinQuickFixAction(element) {
override fun getText() = if (makeVar) "Make variable mutable" else "Make variable immutable"
override fun getFamilyName(): String = text
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean {
- return when (element) {
- is KtProperty -> element.isVar != makeVar
- is KtParameter ->
- element.getStrictParentOfType()?.valueParameterList == element.parent
- && (element.valOrVarKeyword == KtTokens.VAR_KEYWORD) != makeVar
- else -> false
- }
+ val valOrVar = element.valOrVarKeyword?.node?.elementType ?: return false
+ return (valOrVar == KtTokens.VAR_KEYWORD) != makeVar
}
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
val factory = KtPsiFactory(project)
val newKeyword = if (makeVar) factory.createVarKeyword() else factory.createValKeyword()
- when (element) {
- is KtProperty -> element.valOrVarKeyword.replace(newKeyword)
- is KtParameter -> element.valOrVarKeyword!!.replace(newKeyword)
- }
+ element.valOrVarKeyword!!.replace(newKeyword)
}
companion object {
@@ -63,7 +54,7 @@ class ChangeVariableMutabilityFix(element: KtNamedDeclaration, private val makeV
val VAL_REASSIGNMENT_FACTORY: KotlinSingleIntentionActionFactory = object: KotlinSingleIntentionActionFactory() {
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
val propertyDescriptor = Errors.VAL_REASSIGNMENT.cast(diagnostic).a
- val declaration = DescriptorToSourceUtils.descriptorToDeclaration(propertyDescriptor) as? KtNamedDeclaration ?: return null
+ val declaration = DescriptorToSourceUtils.descriptorToDeclaration(propertyDescriptor) as? KtValVarKeywordOwner ?: return null
return ChangeVariableMutabilityFix(declaration, true)
}
}
@@ -72,7 +63,7 @@ class ChangeVariableMutabilityFix(element: KtNamedDeclaration, private val makeV
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
val element = diagnostic.psiElement
return when (element) {
- is KtProperty, is KtParameter -> ChangeVariableMutabilityFix(element as KtNamedDeclaration, true)
+ is KtProperty, is KtParameter -> ChangeVariableMutabilityFix(element as KtValVarKeywordOwner, true)
else -> null
}
}
diff --git a/idea/testData/inspections/canBeVal/alwaysAssigned.kt b/idea/testData/inspections/canBeVal/alwaysAssigned.kt
new file mode 100644
index 00000000000..34d45fc7a7c
--- /dev/null
+++ b/idea/testData/inspections/canBeVal/alwaysAssigned.kt
@@ -0,0 +1,6 @@
+fun foo(p: Int) {
+ var v1: Int
+ var v2: Int = 0
+ if (p > 0) v1 = 1 else v1 = 2
+ v2 = 1
+}
\ No newline at end of file
diff --git a/idea/testData/inspections/canBeVal/assignedInLoop.kt b/idea/testData/inspections/canBeVal/assignedInLoop.kt
new file mode 100644
index 00000000000..45225c85362
--- /dev/null
+++ b/idea/testData/inspections/canBeVal/assignedInLoop.kt
@@ -0,0 +1,6 @@
+fun foo(p: Int) {
+ var v: Int
+ for (i in 1..10) {
+ v = i
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspections/canBeVal/assignedTwice.kt b/idea/testData/inspections/canBeVal/assignedTwice.kt
new file mode 100644
index 00000000000..d43be3b4dbd
--- /dev/null
+++ b/idea/testData/inspections/canBeVal/assignedTwice.kt
@@ -0,0 +1,5 @@
+fun foo(p: Int) {
+ var v: Int
+ v = 0
+ if (p > 0) v = 1
+}
\ No newline at end of file
diff --git a/idea/testData/inspections/canBeVal/desctructuringDeclaration1.kt b/idea/testData/inspections/canBeVal/desctructuringDeclaration1.kt
new file mode 100644
index 00000000000..2adcc1edf05
--- /dev/null
+++ b/idea/testData/inspections/canBeVal/desctructuringDeclaration1.kt
@@ -0,0 +1,6 @@
+fun foo(p: Int) {
+ var (v1, v2) = getPair()
+ print(v1)
+}
+
+fun getPair(): Pair = 1 to ""
\ No newline at end of file
diff --git a/idea/testData/inspections/canBeVal/desctructuringDeclaration2.kt b/idea/testData/inspections/canBeVal/desctructuringDeclaration2.kt
new file mode 100644
index 00000000000..eb5155f4ac4
--- /dev/null
+++ b/idea/testData/inspections/canBeVal/desctructuringDeclaration2.kt
@@ -0,0 +1,7 @@
+fun foo(p: Int) {
+ var (v1, v2) = getPair()
+ print(v1)
+ v2 = ""
+}
+
+fun getPair(): Pair = 1 to ""
\ No newline at end of file
diff --git a/idea/testData/inspections/canBeVal/desctructuringDeclarationUnused.kt b/idea/testData/inspections/canBeVal/desctructuringDeclarationUnused.kt
new file mode 100644
index 00000000000..9300ab09a34
--- /dev/null
+++ b/idea/testData/inspections/canBeVal/desctructuringDeclarationUnused.kt
@@ -0,0 +1,5 @@
+fun foo(p: Int) {
+ var (v1, v2) = getPair()
+}
+
+fun getPair(): Pair = 1 to ""
\ No newline at end of file
diff --git a/idea/testData/inspections/canBeVal/inspectionData/expected.xml b/idea/testData/inspections/canBeVal/inspectionData/expected.xml
new file mode 100644
index 00000000000..124baef166b
--- /dev/null
+++ b/idea/testData/inspections/canBeVal/inspectionData/expected.xml
@@ -0,0 +1,55 @@
+
+
+ withInitializer.kt
+ 4
+ light_idea_test_case
+
+ Local 'var' can be declared as 'val'
+ Can be declared as 'val'
+
+
+
+ alwaysAssigned.kt
+ 2
+ light_idea_test_case
+
+ Local 'var' can be declared as 'val'
+ Can be declared as 'val'
+
+
+
+ notAssignedWhenNotUsed.kt
+ 2
+ light_idea_test_case
+
+ Local 'var' can be declared as 'val'
+ Can be declared as 'val'
+
+
+
+ twoVariables.kt
+ 2
+ light_idea_test_case
+
+ Local 'var' can be declared as 'val'
+ Can be declared as 'val'
+
+
+
+ twoVariables.kt
+ 3
+ light_idea_test_case
+
+ Local 'var' can be declared as 'val'
+ Can be declared as 'val'
+
+
+
+ desctructuringDeclaration1.kt
+ 2
+ light_idea_test_case
+
+ Local 'var' can be declared as 'val'
+ Can be declared as 'val'
+
+
diff --git a/idea/testData/inspections/canBeVal/inspectionData/inspections.test b/idea/testData/inspections/canBeVal/inspectionData/inspections.test
new file mode 100644
index 00000000000..81d05f0cc24
--- /dev/null
+++ b/idea/testData/inspections/canBeVal/inspectionData/inspections.test
@@ -0,0 +1 @@
+// INSPECTION_CLASS: org.jetbrains.kotlin.idea.inspections.CanBeValInspection
diff --git a/idea/testData/inspections/canBeVal/notAssignedWhenNotUsed.kt b/idea/testData/inspections/canBeVal/notAssignedWhenNotUsed.kt
new file mode 100644
index 00000000000..24cf5cbc099
--- /dev/null
+++ b/idea/testData/inspections/canBeVal/notAssignedWhenNotUsed.kt
@@ -0,0 +1,7 @@
+fun foo(p: Int) {
+ var v: Int
+ if (p > 0) {
+ v = 1
+ print(v)
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspections/canBeVal/onlyLocal.kt b/idea/testData/inspections/canBeVal/onlyLocal.kt
new file mode 100644
index 00000000000..df559ba9399
--- /dev/null
+++ b/idea/testData/inspections/canBeVal/onlyLocal.kt
@@ -0,0 +1,10 @@
+var global = 1
+
+class C {
+ var field = 2
+
+ fun foo() {
+ print(field)
+ print(global)
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/inspections/canBeVal/onlyVar.kt b/idea/testData/inspections/canBeVal/onlyVar.kt
new file mode 100644
index 00000000000..dbb60432d7c
--- /dev/null
+++ b/idea/testData/inspections/canBeVal/onlyVar.kt
@@ -0,0 +1,4 @@
+fun foo() {
+ val v = 1
+ print(v)
+}
\ No newline at end of file
diff --git a/idea/testData/inspections/canBeVal/twoVariables.kt b/idea/testData/inspections/canBeVal/twoVariables.kt
new file mode 100644
index 00000000000..06515d1b089
--- /dev/null
+++ b/idea/testData/inspections/canBeVal/twoVariables.kt
@@ -0,0 +1,6 @@
+fun foo(p: Int) {
+ var v1: Int
+ var v2: Int
+ if (p > 0) v1 = 1 else v1 = 2
+ v2 = 1
+}
\ No newline at end of file
diff --git a/idea/testData/inspections/canBeVal/unused.kt b/idea/testData/inspections/canBeVal/unused.kt
new file mode 100644
index 00000000000..08b5be627cf
--- /dev/null
+++ b/idea/testData/inspections/canBeVal/unused.kt
@@ -0,0 +1,3 @@
+fun foo() {
+ var v: Int
+}
\ No newline at end of file
diff --git a/idea/testData/inspections/canBeVal/unusedWithInitializer.kt b/idea/testData/inspections/canBeVal/unusedWithInitializer.kt
new file mode 100644
index 00000000000..aae64fd6b66
--- /dev/null
+++ b/idea/testData/inspections/canBeVal/unusedWithInitializer.kt
@@ -0,0 +1,3 @@
+fun foo() {
+ var v = 1
+}
\ No newline at end of file
diff --git a/idea/testData/inspections/canBeVal/withInitializer.kt b/idea/testData/inspections/canBeVal/withInitializer.kt
new file mode 100644
index 00000000000..043426599b8
--- /dev/null
+++ b/idea/testData/inspections/canBeVal/withInitializer.kt
@@ -0,0 +1,8 @@
+fun foo() {
+ var v1 = 1
+ var v2 = 2
+ var v3 = 3
+ v1 = 1
+ v2++
+ print(v3)
+}
\ No newline at end of file
diff --git a/idea/testData/quickfix/variables/changeMutability/canBeVal/.inspection b/idea/testData/quickfix/variables/changeMutability/canBeVal/.inspection
new file mode 100644
index 00000000000..cdd811ef674
--- /dev/null
+++ b/idea/testData/quickfix/variables/changeMutability/canBeVal/.inspection
@@ -0,0 +1 @@
+org.jetbrains.kotlin.idea.inspections.CanBeValInspection
\ No newline at end of file
diff --git a/idea/testData/quickfix/variables/changeMutability/canBeVal/multiVariable.kt b/idea/testData/quickfix/variables/changeMutability/canBeVal/multiVariable.kt
new file mode 100644
index 00000000000..952389e35c9
--- /dev/null
+++ b/idea/testData/quickfix/variables/changeMutability/canBeVal/multiVariable.kt
@@ -0,0 +1,9 @@
+// "Make variable immutable" "true"
+fun foo(p: Int) {
+ var (v1, v2) = getPair()!!
+ v1
+}
+
+fun getPair(): Pair? = null
+
+data class Pair(val a: T1, val b: T2)
\ No newline at end of file
diff --git a/idea/testData/quickfix/variables/changeMutability/canBeVal/multiVariable.kt.after b/idea/testData/quickfix/variables/changeMutability/canBeVal/multiVariable.kt.after
new file mode 100644
index 00000000000..f0eb7a7ec9e
--- /dev/null
+++ b/idea/testData/quickfix/variables/changeMutability/canBeVal/multiVariable.kt.after
@@ -0,0 +1,9 @@
+// "Make variable immutable" "true"
+fun foo(p: Int) {
+ val (v1, v2) = getPair()!!
+ v1
+}
+
+fun getPair(): Pair? = null
+
+data class Pair(val a: T1, val b: T2)
\ No newline at end of file
diff --git a/idea/testData/quickfix/variables/changeMutability/canBeVal/singleVariable.kt b/idea/testData/quickfix/variables/changeMutability/canBeVal/singleVariable.kt
new file mode 100644
index 00000000000..81a90c537f1
--- /dev/null
+++ b/idea/testData/quickfix/variables/changeMutability/canBeVal/singleVariable.kt
@@ -0,0 +1,5 @@
+// "Make variable immutable" "true"
+fun foo(p: Int) {
+ var v: Int
+ if (p > 0) v = 1 else v = 2
+}
\ No newline at end of file
diff --git a/idea/testData/quickfix/variables/changeMutability/canBeVal/singleVariable.kt.after b/idea/testData/quickfix/variables/changeMutability/canBeVal/singleVariable.kt.after
new file mode 100644
index 00000000000..22c16345e99
--- /dev/null
+++ b/idea/testData/quickfix/variables/changeMutability/canBeVal/singleVariable.kt.after
@@ -0,0 +1,5 @@
+// "Make variable immutable" "true"
+fun foo(p: Int) {
+ val v: Int
+ if (p > 0) v = 1 else v = 2
+}
\ No newline at end of file
diff --git a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/InspectionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/InspectionTestGenerated.java
index eb8c255a57c..1eb091d8af2 100644
--- a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/InspectionTestGenerated.java
+++ b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/InspectionTestGenerated.java
@@ -112,6 +112,12 @@ public class InspectionTestGenerated extends AbstractInspectionTest {
doTest(fileName);
}
+ @TestMetadata("canBeVal/inspectionData/inspections.test")
+ public void testCanBeVal_inspectionData_Inspections_test() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspections/canBeVal/inspectionData/inspections.test");
+ doTest(fileName);
+ }
+
@TestMetadata("conflictingExtensionProperty/inspectionData/inspections.test")
public void testConflictingExtensionProperty_inspectionData_Inspections_test() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspections/conflictingExtensionProperty/inspectionData/inspections.test");
diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java
index 4ea4adb6f42..817a1aec359 100644
--- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java
+++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java
@@ -1581,6 +1581,16 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/variables"), Pattern.compile("^(\\w+)\\.((before\\.Main\\.\\w+)|(test))$"), true);
}
+ @TestMetadata("idea/testData/quickfix/variables/changeMutability")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class ChangeMutability extends AbstractQuickFixMultiFileTest {
+ public void testAllFilesPresentInChangeMutability() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/variables/changeMutability"), Pattern.compile("^(\\w+)\\.((before\\.Main\\.\\w+)|(test))$"), true);
+ }
+
+ }
+
}
}
diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java
index 2d579f87e9b..3485aea4d04 100644
--- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java
+++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java
@@ -7781,6 +7781,27 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/variables/changeMutability/valWithSetter.kt");
doTest(fileName);
}
+
+ @TestMetadata("idea/testData/quickfix/variables/changeMutability/canBeVal")
+ @TestDataPath("$PROJECT_ROOT")
+ @RunWith(JUnit3RunnerWithInners.class)
+ public static class CanBeVal extends AbstractQuickFixTest {
+ public void testAllFilesPresentInCanBeVal() throws Exception {
+ KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/variables/changeMutability/canBeVal"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true);
+ }
+
+ @TestMetadata("multiVariable.kt")
+ public void testMultiVariable() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/variables/changeMutability/canBeVal/multiVariable.kt");
+ doTest(fileName);
+ }
+
+ @TestMetadata("singleVariable.kt")
+ public void testSingleVariable() throws Exception {
+ String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/variables/changeMutability/canBeVal/singleVariable.kt");
+ doTest(fileName);
+ }
+ }
}
@TestMetadata("idea/testData/quickfix/variables/changeToFunctionInvocation")