diff --git a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeConversionDescriptorBase.java b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeConversionDescriptorBase.java
index 34b87a6d6747..b2eb1d9df9bf 100644
--- a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeConversionDescriptorBase.java
+++ b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeConversionDescriptorBase.java
@@ -16,7 +16,11 @@
package com.intellij.refactoring.typeMigration;
import com.intellij.psi.PsiExpression;
+import com.intellij.psi.PsiSubstitutor;
+import com.intellij.psi.PsiType;
import com.intellij.refactoring.typeMigration.usageInfo.TypeMigrationUsageInfo;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.Nullable;
public class TypeConversionDescriptorBase {
@@ -33,7 +37,26 @@ public class TypeConversionDescriptorBase {
myRoot = root;
}
- public void replace(PsiExpression expression){}
+ /**
+ * @return converted expression type or null if not known
+ */
+ @Nullable
+ public PsiType conversionType() {
+ return null;
+ }
+
+ /**
+ * @return substitutor of converted method parameters
+ * or null if expression is not method call expression
+ */
+ @Nullable
+ public PsiSubstitutor getConvertedMethodParameters() {
+ return null;
+ }
+
+ public PsiExpression replace(PsiExpression expression) throws IncorrectOperationException {
+ return expression;
+ }
@Override
public String toString() {
diff --git a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationLabeler.java b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationLabeler.java
index 10adac418525..eaa2123506b7 100644
--- a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationLabeler.java
+++ b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationLabeler.java
@@ -331,6 +331,10 @@ public class TypeMigrationLabeler {
}
}
+ else if (expr instanceof PsiLambdaExpression) {
+ //TODO conversion of lambda expression now works incorrectly [Dmitry Batkovich]
+ return;
+ }
convertExpression(expr, migrationType, originalType, isCovariant);
}
diff --git a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationReplacementUtil.java b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationReplacementUtil.java
index 0004ff456cb6..873f6230f09b 100644
--- a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationReplacementUtil.java
+++ b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationReplacementUtil.java
@@ -40,7 +40,11 @@ public class TypeMigrationReplacementUtil {
public static void replaceExpression(PsiExpression expression, final Project project, Object conversion) {
if (conversion instanceof TypeConversionDescriptorBase) {
- ((TypeConversionDescriptorBase)conversion).replace(expression);
+ try {
+ ((TypeConversionDescriptorBase)conversion).replace(expression);
+ } catch (IncorrectOperationException e) {
+ LOG.error(e);
+ }
} else if (conversion instanceof String) {
String replacement = (String)conversion;
try {
diff --git a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationStatementProcessor.java b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationStatementProcessor.java
index 505fc9f35696..3431b403a8b5 100644
--- a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationStatementProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationStatementProcessor.java
@@ -219,12 +219,13 @@ class TypeMigrationStatementProcessor extends JavaRecursiveElementVisitor {
myLabeler.markFailedConversion(typePair, qualifierExpression);
} else {
final PsiElement parent = Util.getEssentialParent(expression);
+ final PsiType type = conversion.conversionType();
if (parent instanceof PsiMethodCallExpression) {
myLabeler.setConversionMapping((PsiMethodCallExpression)parent, conversion);
- myTypeEvaluator.setType(new TypeMigrationUsageInfo(parent), myTypeEvaluator.evaluateType((PsiExpression)parent));
+ myTypeEvaluator.setType(new TypeMigrationUsageInfo(parent), type != null ? type: myTypeEvaluator.evaluateType((PsiExpression)parent));
} else {
myLabeler.setConversionMapping(expression, conversion);
- myTypeEvaluator.setType(new TypeMigrationUsageInfo(expression), myTypeEvaluator.evaluateType(expression));
+ myTypeEvaluator.setType(new TypeMigrationUsageInfo(expression), type != null ? type: myTypeEvaluator.evaluateType(expression));
}
}
}
diff --git a/java/typeMigration/src/META-INF/TypeMigration.xml b/java/typeMigration/src/META-INF/TypeMigration.xml
index 8ab2163d80d3..9a0c0e187dfa 100644
--- a/java/typeMigration/src/META-INF/TypeMigration.xml
+++ b/java/typeMigration/src/META-INF/TypeMigration.xml
@@ -7,6 +7,11 @@
+
+
+
+
+
com.intellij.refactoring.typeMigration.intentions.ConvertFieldToAtomicIntention
Java/Concurrency
@@ -19,5 +24,11 @@
com.intellij.refactoring.typeMigration.intentions.ChangeClassParametersIntention
Java/Declaration
+
+
diff --git a/java/typeMigration/src/com/intellij/refactoring/typeMigration/TypeConversionDescriptor.java b/java/typeMigration/src/com/intellij/refactoring/typeMigration/TypeConversionDescriptor.java
index 0861f1ec9e5c..e1a2bd8b5ff3 100644
--- a/java/typeMigration/src/com/intellij/refactoring/typeMigration/TypeConversionDescriptor.java
+++ b/java/typeMigration/src/com/intellij/refactoring/typeMigration/TypeConversionDescriptor.java
@@ -5,12 +5,14 @@ import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiExpression;
+import com.intellij.psi.PsiType;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.structuralsearch.MatchOptions;
import com.intellij.structuralsearch.plugin.replace.ReplaceOptions;
import com.intellij.structuralsearch.plugin.replace.impl.Replacer;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
/**
* Created by IntelliJ IDEA.
@@ -25,10 +27,10 @@ public class TypeConversionDescriptor extends TypeConversionDescriptorBase {
private String myStringToReplace = null;
private String myReplaceByString = "$";
private PsiExpression myExpression;
+ private PsiType myConversionType;
public TypeConversionDescriptor(@NonNls final String stringToReplace, @NonNls final String replaceByString) {
- myStringToReplace = stringToReplace;
- myReplaceByString = replaceByString;
+ this(stringToReplace, replaceByString, (PsiExpression)null);
}
public TypeConversionDescriptor(@NonNls final String stringToReplace, @NonNls final String replaceByString, final PsiExpression expression) {
@@ -37,6 +39,16 @@ public class TypeConversionDescriptor extends TypeConversionDescriptorBase {
myExpression = expression;
}
+ public TypeConversionDescriptor(String stringToReplace, String replaceByString, PsiType conversionType) {
+ this(stringToReplace, replaceByString);
+ myConversionType = conversionType;
+ }
+
+ public TypeConversionDescriptor withConversionType(PsiType conversionType) {
+ myConversionType = conversionType;
+ return this;
+ }
+
public void setStringToReplace(String stringToReplace) {
myStringToReplace = stringToReplace;
}
@@ -61,8 +73,14 @@ public class TypeConversionDescriptor extends TypeConversionDescriptorBase {
myExpression = expression;
}
+ @Nullable
@Override
- public void replace(PsiExpression expression) {
+ public PsiType conversionType() {
+ return myConversionType;
+ }
+
+ @Override
+ public PsiExpression replace(PsiExpression expression) {
if (getExpression() != null) expression = getExpression();
final Project project = expression.getProject();
final ReplaceOptions options = new ReplaceOptions();
@@ -70,19 +88,9 @@ public class TypeConversionDescriptor extends TypeConversionDescriptorBase {
matchOptions.setFileType(StdFileTypes.JAVA);
options.setMatchOptions(matchOptions);
final Replacer replacer = new Replacer(project, null);
- try {
- final String replacement = replacer.testReplace(expression.getText(), getStringToReplace(), getReplaceByString(), options);
- try {
- JavaCodeStyleManager.getInstance(project).shortenClassReferences(expression.replace(
+ final String replacement = replacer.testReplace(expression.getText(), getStringToReplace(), getReplaceByString(), options);
+ return (PsiExpression)JavaCodeStyleManager.getInstance(project).shortenClassReferences(expression.replace(
JavaPsiFacade.getInstance(project).getElementFactory().createExpressionFromText(replacement, expression)));
- }
- catch (IncorrectOperationException e) {
- LOG.error(e);
- }
- }
- catch (IncorrectOperationException e) {
- LOG.error(e);
- }
}
@Override
diff --git a/java/typeMigration/src/com/intellij/refactoring/typeMigration/TypeMigrationVariableTypeFixProvider.java b/java/typeMigration/src/com/intellij/refactoring/typeMigration/TypeMigrationVariableTypeFixProvider.java
index fe8872b35840..bcebf17cef20 100644
--- a/java/typeMigration/src/com/intellij/refactoring/typeMigration/TypeMigrationVariableTypeFixProvider.java
+++ b/java/typeMigration/src/com/intellij/refactoring/typeMigration/TypeMigrationVariableTypeFixProvider.java
@@ -27,7 +27,12 @@ public class TypeMigrationVariableTypeFixProvider implements ChangeVariableTypeQ
@NotNull
public IntentionAction[] getFixes(@NotNull PsiVariable variable, @NotNull PsiType toReturn) {
- return new IntentionAction[]{new VariableTypeFix(variable, toReturn) {
+ return new IntentionAction[]{createTypeMigrationFix(variable, toReturn)};
+ }
+
+ @NotNull
+ public static VariableTypeFix createTypeMigrationFix(@NotNull final PsiVariable variable, @NotNull final PsiType toReturn) {
+ return new VariableTypeFix(variable, toReturn) {
@NotNull
@Override
public String getText() {
@@ -61,6 +66,6 @@ public class TypeMigrationVariableTypeFixProvider implements ChangeVariableTypeQ
public boolean startInWriteAction() {
return true;
}
- }};
+ };
}
}
diff --git a/java/typeMigration/src/com/intellij/refactoring/typeMigration/inspections/GuavaInspection.java b/java/typeMigration/src/com/intellij/refactoring/typeMigration/inspections/GuavaInspection.java
new file mode 100644
index 000000000000..60be8f9f462c
--- /dev/null
+++ b/java/typeMigration/src/com/intellij/refactoring/typeMigration/inspections/GuavaInspection.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2000-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 com.intellij.refactoring.typeMigration.inspections;
+
+import com.intellij.codeInsight.daemon.impl.quickfix.VariableTypeFix;
+import com.intellij.codeInspection.*;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.AtomicNotNullLazyValue;
+import com.intellij.psi.*;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.refactoring.typeMigration.TypeMigrationVariableTypeFixProvider;
+import com.intellij.refactoring.typeMigration.rules.TypeConversionRule;
+import com.intellij.refactoring.typeMigration.rules.guava.BaseGuavaTypeConversionRule;
+import com.intellij.util.containers.hash.HashMap;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.*;
+
+/**
+ * @author Dmitry Batkovich
+ */
+@SuppressWarnings("DialogTitleCapitalization")
+public class GuavaInspection extends BaseJavaLocalInspectionTool {
+ private final static String PROBLEM_DESCRIPTION = "Guava's functional primitives can be replaced by Java API";
+
+ @NotNull
+ @Override
+ public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
+ if (!PsiUtil.isLanguageLevel8OrHigher(holder.getFile())) {
+ return PsiElementVisitor.EMPTY_VISITOR;
+ }
+ return new JavaElementVisitor() {
+ private final AtomicNotNullLazyValue