diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/JetBundle.properties b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/JetBundle.properties index ed6c88c72d2..38ab025ef01 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/JetBundle.properties +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/JetBundle.properties @@ -4,9 +4,6 @@ add.return.type=Add return type declaration change.accessor.type=Change accessor type change.getter.type=Change getter type to {0} change.setter.type=Change setter parameter type to {0} -make.variable.immutable=Make variable immutable -make.variable.mutable=Make variable mutable -change.variable.mutability.family=Change Variable Mutability remove.function.body=Remove function body make.element.modifier=Make {0} {1} add.modifier=Add ''{0}'' modifier diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableMutabilityFix.java b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableMutabilityFix.java deleted file mode 100644 index 5d3c02701fd..00000000000 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableMutabilityFix.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright 2010-2015 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.quickfix; - -import com.intellij.codeInsight.intention.IntentionAction; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.util.IncorrectOperationException; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.kotlin.descriptors.VariableDescriptor; -import org.jetbrains.kotlin.idea.JetBundle; -import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage; -import org.jetbrains.kotlin.psi.JetFile; -import org.jetbrains.kotlin.psi.JetProperty; -import org.jetbrains.kotlin.psi.JetSimpleNameExpression; -import org.jetbrains.kotlin.resolve.BindingContext; -import org.jetbrains.kotlin.resolve.BindingContextUtils; -import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils; - -import static org.jetbrains.kotlin.psi.PsiPackage.JetPsiFactory; - -public class ChangeVariableMutabilityFix implements IntentionAction { - private boolean isVar; - - public ChangeVariableMutabilityFix(boolean isVar) { - this.isVar = isVar; - } - - public ChangeVariableMutabilityFix() { - this(false); - } - - @NotNull - @Override - public String getText() { - return isVar ? JetBundle.message("make.variable.immutable") : JetBundle.message("make.variable.mutable"); - } - - @NotNull - @Override - public String getFamilyName() { - return JetBundle.message("change.variable.mutability.family"); - } - - @Override - public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { - if (!(file instanceof JetFile)) return false; - JetProperty property = getCorrespondingProperty(editor, (JetFile) file); - return property != null && !property.isVar(); - } - - private static JetProperty getCorrespondingProperty(Editor editor, JetFile file) { - PsiElement elementAtCaret = file.findElementAt(editor.getCaretModel().getOffset()); - JetProperty property = PsiTreeUtil.getParentOfType(elementAtCaret, JetProperty.class); - if (property != null) return property; - JetSimpleNameExpression simpleNameExpression = PsiTreeUtil.getParentOfType(elementAtCaret, JetSimpleNameExpression.class); - if (simpleNameExpression != null) { - BindingContext bindingContext = ResolvePackage.analyzeFully(file); - VariableDescriptor descriptor = BindingContextUtils.extractVariableDescriptorIfAny(bindingContext, simpleNameExpression, true); - if (descriptor != null) { - PsiElement declaration = DescriptorToSourceUtils.descriptorToDeclaration(descriptor); - if (declaration instanceof JetProperty) { - return (JetProperty) declaration; - } - } - } - return null; - } - - @Override - public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { - JetProperty property = getCorrespondingProperty(editor, (JetFile)file); - assert property != null; - property.getValOrVarNode().getPsi().replace(JetPsiFactory(property).createValOrVarNode(isVar ? "val" : "var").getPsi()); - } - - @Override - public boolean startInWriteAction() { - return true; - } -} diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableMutabilityFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableMutabilityFix.kt new file mode 100644 index 00000000000..1b2168c6161 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVariableMutabilityFix.kt @@ -0,0 +1,68 @@ +/* + * Copyright 2010-2015 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.quickfix + +import com.intellij.codeInsight.intention.IntentionAction +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiFile +import org.jetbrains.kotlin.diagnostics.Diagnostic +import org.jetbrains.kotlin.diagnostics.Errors +import org.jetbrains.kotlin.psi.JetFile +import org.jetbrains.kotlin.psi.JetProperty +import org.jetbrains.kotlin.psi.JetPropertyAccessor +import org.jetbrains.kotlin.psi.JetPsiFactory +import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils + +public class ChangeVariableMutabilityFix(element: JetProperty, private val makeVar: Boolean) : JetIntentionAction(element) { + + override fun getText() = if (makeVar) "Make variable mutable" else "Make variable immutable" + + override fun getFamilyName(): String = getText() + + override fun isAvailable(project: Project, editor: Editor?, file: PsiFile): Boolean { + return element.isVar() != makeVar + } + + override fun invoke(project: Project, editor: Editor?, file: JetFile) { + element.getValOrVarNode().getPsi().replace(JetPsiFactory(project).createValOrVarNode(if (makeVar) "var" else "val").getPsi()) + } + + companion object { + public val VAL_WITH_SETTER_FACTORY: JetSingleIntentionActionFactory = object: JetSingleIntentionActionFactory() { + override fun createAction(diagnostic: Diagnostic): IntentionAction? { + val accessor = diagnostic.getPsiElement() as JetPropertyAccessor + val property = accessor.getParent() as JetProperty + return ChangeVariableMutabilityFix(property, true) + } + } + + public val VAL_REASSIGNMENT_FACTORY: JetSingleIntentionActionFactory = object: JetSingleIntentionActionFactory() { + override fun createAction(diagnostic: Diagnostic): IntentionAction? { + val propertyDescriptor = Errors.VAL_REASSIGNMENT.cast(diagnostic).getA() + val declaration = DescriptorToSourceUtils.descriptorToDeclaration(propertyDescriptor) as? JetProperty ?: return null + return ChangeVariableMutabilityFix(declaration, true) + } + } + + public val VAR_OVERRIDDEN_BY_VAL_FACTORY: JetSingleIntentionActionFactory = object: JetSingleIntentionActionFactory() { + override fun createAction(diagnostic: Diagnostic): IntentionAction? { + return ChangeVariableMutabilityFix(diagnostic.getPsiElement() as JetProperty, true) + } + } + } +} diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.java b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.java index ea4a6242918..6faa887abdd 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.java +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.java @@ -158,10 +158,9 @@ public class QuickFixRegistrar { QuickFixes.actions.put(ABSTRACT_MEMBER_NOT_IMPLEMENTED, implementMethodsHandler); QuickFixes.actions.put(MANY_IMPL_MEMBER_NOT_IMPLEMENTED, implementMethodsHandler); - ChangeVariableMutabilityFix changeVariableMutabilityFix = new ChangeVariableMutabilityFix(); - QuickFixes.actions.put(VAL_WITH_SETTER, changeVariableMutabilityFix); - QuickFixes.actions.put(VAL_REASSIGNMENT, changeVariableMutabilityFix); - QuickFixes.actions.put(VAR_OVERRIDDEN_BY_VAL, changeVariableMutabilityFix); + QuickFixes.factories.put(VAL_WITH_SETTER, ChangeVariableMutabilityFix.VAL_WITH_SETTER_FACTORY); + QuickFixes.factories.put(VAL_REASSIGNMENT, ChangeVariableMutabilityFix.VAL_REASSIGNMENT_FACTORY); + QuickFixes.factories.put(VAR_OVERRIDDEN_BY_VAL, ChangeVariableMutabilityFix.VAR_OVERRIDDEN_BY_VAL_FACTORY); JetSingleIntentionActionFactory removeValVarFromParameterFixFactory = RemoveValVarFromParameterFix.createFactory(); QuickFixes.factories.put(VAL_OR_VAR_ON_FUN_PARAMETER, removeValVarFromParameterFixFactory); diff --git a/idea/testData/quickfix/variables/changeMutability/localInGetter.kt b/idea/testData/quickfix/variables/changeMutability/localInGetter.kt new file mode 100644 index 00000000000..05398045207 --- /dev/null +++ b/idea/testData/quickfix/variables/changeMutability/localInGetter.kt @@ -0,0 +1,8 @@ +// "Make variable mutable" "true" + +val String.prop: Int + get() { + val p = 1 + p = 2 + return p + } \ No newline at end of file diff --git a/idea/testData/quickfix/variables/changeMutability/localInGetter.kt.after b/idea/testData/quickfix/variables/changeMutability/localInGetter.kt.after new file mode 100644 index 00000000000..6a3a8d8765a --- /dev/null +++ b/idea/testData/quickfix/variables/changeMutability/localInGetter.kt.after @@ -0,0 +1,8 @@ +// "Make variable mutable" "true" + +val String.prop: Int + get() { + var p = 1 + p = 2 + return p + } \ 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 ef4e72166ef..37e7291115a 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -6350,6 +6350,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/variables/changeMutability"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), true); } + @TestMetadata("localInGetter.kt") + public void testLocalInGetter() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/variables/changeMutability/localInGetter.kt"); + doTest(fileName); + } + @TestMetadata("valOverrideVar.kt") public void testValOverrideVar() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/variables/changeMutability/valOverrideVar.kt");