diff --git a/plugins/IntentionPowerPak/src/META-INF/plugin.xml b/plugins/IntentionPowerPak/src/META-INF/plugin.xml index e050f7b14371..82734880f59b 100644 --- a/plugins/IntentionPowerPak/src/META-INF/plugin.xml +++ b/plugins/IntentionPowerPak/src/META-INF/plugin.xml @@ -211,6 +211,11 @@ intention.category.declaration + + com.siyeh.ipp.decls.ChangeVariableTypeToRhsTypeIntention + intention.category.declaration + + diff --git a/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties b/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties index 8c489ff40f09..1045947e4d68 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties +++ b/plugins/IntentionPowerPak/src/com/siyeh/IntentionPowerPackBundle.properties @@ -169,6 +169,7 @@ make.protected.intention.name=Make 'protected' make.protected.intention.family.name=Make Protected make.private.intention.name=Make 'private' make.private.intention.family.name=Make Private +change.variable.type.to.rhs.type.intention.family.name=Change Variable Type to Type of Initializer #hand made demorgans.intention.name1=Replace '\\&\\&' with '||' @@ -202,6 +203,7 @@ flip.setter.call.intention.name=Flip Setter Call adapter.to.listener.intention.name=Replace extension of ''{0}'' with ''Listener'' implementation obscure.thrown.exceptions.intention.name=Replace with ''throws {0}'' add.array.creation.expression.intention.name=Add ''new {0}'' +change.variable.type.to.rhs.type.intention.name=Declare ''{0}'' with type ''{1}'' #categories diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/decls/ChangeVariableTypeToRhsTypeIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/decls/ChangeVariableTypeToRhsTypeIntention.java new file mode 100644 index 000000000000..729e5c21df82 --- /dev/null +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/decls/ChangeVariableTypeToRhsTypeIntention.java @@ -0,0 +1,75 @@ +/* + * Copyright 2000-2012 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. + */ + +/* + * (c) 2012 Desert Island BV + * created: 14 08 2012 + */ +package com.siyeh.ipp.decls; + +import com.intellij.psi.*; +import com.intellij.util.IncorrectOperationException; +import com.siyeh.IntentionPowerPackBundle; +import com.siyeh.ipp.base.MutablyNamedIntention; +import com.siyeh.ipp.base.PsiElementPredicate; +import org.jetbrains.annotations.NotNull; + +/** + * @author Bas Leijdekkers + */ +public class ChangeVariableTypeToRhsTypeIntention extends MutablyNamedIntention { + + @NotNull + @Override + protected PsiElementPredicate getElementPredicate() { + return new ChangeVariableTypeToRhsTypePredicate(); + } + + @Override + protected String getTextForElement(PsiElement element) { + final PsiVariable variable = (PsiVariable)element.getParent(); + final PsiExpression initializer = variable.getInitializer(); + assert initializer != null; + final PsiType type = initializer.getType(); + assert type != null; + return IntentionPowerPackBundle.message("change.variable.type.to.rhs.type.intention.name", + variable.getName(), type.getPresentableText()); + } + + @Override + protected void processIntention(@NotNull PsiElement element) throws IncorrectOperationException { + final PsiElement parent = element.getParent(); + if (!(parent instanceof PsiVariable)) { + return; + } + final PsiVariable variable = (PsiVariable)parent; + final PsiExpression initializer = variable.getInitializer(); + if (initializer == null) { + return; + } + final PsiType type = initializer.getType(); + if (type == null) { + return; + } + final PsiElementFactory factory = JavaPsiFacade.getElementFactory(element.getProject()); + final PsiTypeElement typeElement = factory.createTypeElement(type); + final PsiTypeElement variableTypeElement = variable.getTypeElement(); + if (variableTypeElement == null) { + return; + } + variableTypeElement.replace(typeElement); + } +} diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/decls/ChangeVariableTypeToRhsTypePredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/decls/ChangeVariableTypeToRhsTypePredicate.java new file mode 100644 index 000000000000..c639541d1c38 --- /dev/null +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/decls/ChangeVariableTypeToRhsTypePredicate.java @@ -0,0 +1,60 @@ +/* + * Copyright 2000-2012 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 com.siyeh.ipp.decls; + +import com.intellij.psi.*; +import com.siyeh.ipp.base.PsiElementPredicate; + +/** + * @author Bas Leijdekkers + */ +class ChangeVariableTypeToRhsTypePredicate implements PsiElementPredicate { + + @Override + public boolean satisfiedBy(PsiElement element) { + if (!(element instanceof PsiTypeElement)) { + return false; + } + final PsiElement parent = element.getParent(); + if (!(parent instanceof PsiVariable)) { + return false; + } + final PsiVariable variable = (PsiVariable)parent; + final PsiExpression initializer = variable.getInitializer(); + if (!(initializer instanceof PsiNewExpression)) { + return false; + } + final PsiType type = variable.getType(); + if (!(type instanceof PsiClassType)) { + return false; + } + final PsiType initializerType = initializer.getType(); + if (!(initializerType instanceof PsiClassType)) { + return false; + } + final PsiClassType initializerClassType = (PsiClassType)initializerType; + final PsiClass initializerClass = initializerClassType.resolve(); + if (initializerClass == null) { + return false; + } + final PsiClassType classType = (PsiClassType)type; + final PsiClass variableClass = classType.resolve(); + if (variableClass == null) { + return false; + } + return initializerClass.isInheritor(variableClass, true); + } +} diff --git a/plugins/IntentionPowerPak/src/intentionDescriptions/ChangeVariableTypeToRhsTypeIntention/after.java.template b/plugins/IntentionPowerPak/src/intentionDescriptions/ChangeVariableTypeToRhsTypeIntention/after.java.template new file mode 100644 index 000000000000..0d1b270a7e14 --- /dev/null +++ b/plugins/IntentionPowerPak/src/intentionDescriptions/ChangeVariableTypeToRhsTypeIntention/after.java.template @@ -0,0 +1,3 @@ +public class X { + private ArrayList ss = new ArrayList<>(); +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/intentionDescriptions/ChangeVariableTypeToRhsTypeIntention/before.java.template b/plugins/IntentionPowerPak/src/intentionDescriptions/ChangeVariableTypeToRhsTypeIntention/before.java.template new file mode 100644 index 000000000000..2a8cd46280d0 --- /dev/null +++ b/plugins/IntentionPowerPak/src/intentionDescriptions/ChangeVariableTypeToRhsTypeIntention/before.java.template @@ -0,0 +1,3 @@ +public class X { + private List ss = new ArrayList<>(); +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/intentionDescriptions/ChangeVariableTypeToRhsTypeIntention/description.html b/plugins/IntentionPowerPak/src/intentionDescriptions/ChangeVariableTypeToRhsTypeIntention/description.html new file mode 100644 index 000000000000..95b25c98770a --- /dev/null +++ b/plugins/IntentionPowerPak/src/intentionDescriptions/ChangeVariableTypeToRhsTypeIntention/description.html @@ -0,0 +1,5 @@ + + +This intention changes the type of a variable to the type of its initializer if that is more specific. + + \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/decls/change_variable_type_to_rhs_type/SameType.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/decls/change_variable_type_to_rhs_type/SameType.java new file mode 100644 index 000000000000..bd678bba0737 --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/decls/change_variable_type_to_rhs_type/SameType.java @@ -0,0 +1,5 @@ +import java.util.ArrayList; + +class X { + private ArrayList ss = new ArrayList(); +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/decls/change_variable_type_to_rhs_type/Simple.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/decls/change_variable_type_to_rhs_type/Simple.java new file mode 100644 index 000000000000..5f03f385f582 --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/decls/change_variable_type_to_rhs_type/Simple.java @@ -0,0 +1,6 @@ +import java.util.ArrayList; +import java.util.List; + +class X { + private List ss = new ArrayList<>(); +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/decls/change_variable_type_to_rhs_type/Simple_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/decls/change_variable_type_to_rhs_type/Simple_after.java new file mode 100644 index 000000000000..d3887514b72b --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/decls/change_variable_type_to_rhs_type/Simple_after.java @@ -0,0 +1,6 @@ +import java.util.ArrayList; +import java.util.List; + +class X { + private ArrayList ss = new ArrayList<>(); +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/decls/ChangeVariableTypeToRhsTypeIntentionTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/decls/ChangeVariableTypeToRhsTypeIntentionTest.java new file mode 100644 index 000000000000..60d2c90251b0 --- /dev/null +++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/decls/ChangeVariableTypeToRhsTypeIntentionTest.java @@ -0,0 +1,24 @@ +package com.siyeh.ipp.decls; + +import com.siyeh.IntentionPowerPackBundle; +import com.siyeh.ipp.IPPTestCase; + +/** + * @author Bas Leijdekkers + */ +public class ChangeVariableTypeToRhsTypeIntentionTest extends IPPTestCase { + + public void testSimple() { doTest("Declare 'ss' with type 'ArrayList'"); } + + public void testSameType() { assertIntentionNotAvailable(); } + + @Override + protected String getIntentionName() { + return IntentionPowerPackBundle.message("change.variable.type.to.rhs.type.intention.name", "ss", "ArrayList"); + } + + @Override + protected String getRelativePath() { + return "decls/change_variable_type_to_rhs_type"; + } +}