mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-21 05:51:25 +07:00
WrapWithAdapterMethodCallFix replaces individual cases
WrapArrayToArraysAsListFix, WrapLongWithMathToIntExactFix, WrapStringWithFileFix are united into WrapWithAdapterMethodCallFix. Also Paths.get(), Collections.singleton(), Collections.singletonList(), Arrays.stream() wrappers added Fixes IDEA-175129 Suggest to wrap a value with `Collections.singleton*()`
This commit is contained in:
@@ -282,9 +282,6 @@ public abstract class QuickFixFactory {
|
||||
@NotNull
|
||||
public abstract IntentionAction addMethodQualifierFix(@NotNull PsiMethodCallExpression methodCall);
|
||||
|
||||
@NotNull
|
||||
public abstract IntentionAction createWrapLongWithMathToIntExactFix(@Nullable PsiType type, @NotNull PsiExpression expression);
|
||||
|
||||
@NotNull
|
||||
public abstract IntentionAction createWrapWithOptionalFix(@Nullable PsiType type, @NotNull PsiExpression expression);
|
||||
|
||||
@@ -304,5 +301,5 @@ public abstract class QuickFixFactory {
|
||||
public abstract LocalQuickFixAndIntentionActionOnPsiElement createAccessStaticViaInstanceFix(PsiReferenceExpression methodRef, JavaResolveResult result);
|
||||
|
||||
@NotNull
|
||||
public abstract IntentionAction createWrapStringWithFileFix(@Nullable PsiType type, @NotNull PsiExpression expression);
|
||||
public abstract IntentionAction createWrapWithAdapterFix(@Nullable PsiType type, @NotNull PsiExpression expression);
|
||||
}
|
||||
@@ -710,10 +710,8 @@ public class HighlightMethodUtil {
|
||||
|
||||
TextRange fixRange = getFixRange(elementToHighlight);
|
||||
CastMethodArgumentFix.REGISTRAR.registerCastActions(candidates, methodCall, info, fixRange);
|
||||
WrapArrayToArraysAsListFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange);
|
||||
WrapLongWithMathToIntExactFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange);
|
||||
WrapObjectWithOptionalOfNullableFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange);
|
||||
WrapLongWithMathToIntExactFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange);
|
||||
WrapWithAdapterMethodCallFix.registerCastActions(candidates, methodCall, info, fixRange);
|
||||
PermuteArgumentsFix.registerFix(info, methodCall, candidates, fixRange);
|
||||
WrapExpressionFix.registerWrapAction(candidates, list.getExpressions(), info);
|
||||
registerChangeParameterClassFix(methodCall, list, info);
|
||||
@@ -790,10 +788,8 @@ public class HighlightMethodUtil {
|
||||
|
||||
TextRange fixRange = getFixRange(elementToHighlight);
|
||||
CastMethodArgumentFix.REGISTRAR.registerCastActions(candidates, methodCall, info, fixRange);
|
||||
WrapArrayToArraysAsListFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange);
|
||||
WrapLongWithMathToIntExactFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange);
|
||||
WrapObjectWithOptionalOfNullableFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange);
|
||||
WrapStringWithFileFix.REGISTAR.registerCastActions(candidates, methodCall, info, fixRange);
|
||||
WrapWithAdapterMethodCallFix.registerCastActions(candidates, methodCall, info, fixRange);
|
||||
PermuteArgumentsFix.registerFix(info, methodCall, candidates, fixRange);
|
||||
WrapExpressionFix.registerWrapAction(candidates, list.getExpressions(), info);
|
||||
registerChangeParameterClassFix(methodCall, list, info);
|
||||
@@ -858,10 +854,8 @@ public class HighlightMethodUtil {
|
||||
CastMethodArgumentFix.REGISTRAR.registerCastActions(methodCandidates, methodCall, highlightInfo, fixRange);
|
||||
PermuteArgumentsFix.registerFix(highlightInfo, methodCall, methodCandidates, fixRange);
|
||||
AddTypeArgumentsFix.REGISTRAR.registerCastActions(methodCandidates, methodCall, highlightInfo, fixRange);
|
||||
WrapArrayToArraysAsListFix.REGISTAR.registerCastActions(methodCandidates, methodCall, highlightInfo, fixRange);
|
||||
WrapLongWithMathToIntExactFix.REGISTAR.registerCastActions(methodCandidates, methodCall, highlightInfo, fixRange);
|
||||
WrapObjectWithOptionalOfNullableFix.REGISTAR.registerCastActions(methodCandidates, methodCall, highlightInfo, fixRange);
|
||||
WrapStringWithFileFix.REGISTAR.registerCastActions(methodCandidates, methodCall, highlightInfo, fixRange);
|
||||
WrapWithAdapterMethodCallFix.registerCastActions(methodCandidates, methodCall, highlightInfo, fixRange);
|
||||
registerMethodAccessLevelIntentions(methodCandidates, methodCall, list, highlightInfo);
|
||||
registerChangeMethodSignatureFromUsageIntentions(methodCandidates, list, highlightInfo, fixRange);
|
||||
RemoveRedundantArgumentsFix.registerIntentions(methodCandidates, list, highlightInfo, fixRange);
|
||||
|
||||
@@ -576,10 +576,9 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, QUICK_FIX_FACTORY.createAddTypeCastFix(lType, expression));
|
||||
}
|
||||
if (expression != null) {
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, QUICK_FIX_FACTORY.createWrapLongWithMathToIntExactFix(lType, expression));
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, QUICK_FIX_FACTORY.createWrapWithOptionalFix(lType, expression));
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, QUICK_FIX_FACTORY.createWrapExpressionFix(lType, expression));
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, QUICK_FIX_FACTORY.createWrapStringWithFileFix(lType, expression));
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, QUICK_FIX_FACTORY.createWrapWithAdapterFix(lType, expression));
|
||||
AddTypeArgumentsConditionalFix.register(highlightInfo, expression, lType);
|
||||
registerCollectionToArrayFixAction(highlightInfo, rType, lType, expression);
|
||||
}
|
||||
@@ -1462,7 +1461,7 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
QuickFixAction.registerQuickFixAction(info, QUICK_FIX_FACTORY.createConvertSwitchToIfIntention(statement));
|
||||
if (PsiType.LONG.equals(type) || PsiType.FLOAT.equals(type) || PsiType.DOUBLE.equals(type)) {
|
||||
QuickFixAction.registerQuickFixAction(info, QUICK_FIX_FACTORY.createAddTypeCastFix(PsiType.INT, expression));
|
||||
QuickFixAction.registerQuickFixAction(info, QUICK_FIX_FACTORY.createWrapLongWithMathToIntExactFix(PsiType.INT, expression));
|
||||
QuickFixAction.registerQuickFixAction(info, QUICK_FIX_FACTORY.createWrapWithAdapterFix(PsiType.INT, expression));
|
||||
}
|
||||
if (requiredLevel != null) {
|
||||
QuickFixAction.registerQuickFixAction(info, QUICK_FIX_FACTORY.createIncreaseLanguageLevelFix(requiredLevel));
|
||||
|
||||
@@ -43,9 +43,7 @@ public class ConstructorParametersFixer {
|
||||
}
|
||||
CastMethodArgumentFix.REGISTRAR.registerCastActions(candidates, constructorCall, highlightInfo, fixRange);
|
||||
AddTypeArgumentsFix.REGISTRAR.registerCastActions(candidates, constructorCall, highlightInfo, fixRange);
|
||||
WrapArrayToArraysAsListFix.REGISTAR.registerCastActions(candidates, constructorCall, highlightInfo, fixRange);
|
||||
WrapLongWithMathToIntExactFix.REGISTAR.registerCastActions(candidates, constructorCall, highlightInfo, fixRange);
|
||||
WrapObjectWithOptionalOfNullableFix.REGISTAR.registerCastActions(candidates, constructorCall, highlightInfo, fixRange);
|
||||
WrapStringWithFileFix.REGISTAR.registerCastActions(candidates, constructorCall, highlightInfo, fixRange);
|
||||
WrapWithAdapterMethodCallFix.registerCastActions(candidates, constructorCall, highlightInfo, fixRange);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public abstract class MethodArgumentFix implements IntentionAction {
|
||||
|
||||
protected final PsiExpressionList myArgList;
|
||||
protected final int myIndex;
|
||||
private final ArgumentFixerActionFactory myArgumentFixerActionFactory;
|
||||
protected final ArgumentFixerActionFactory myArgumentFixerActionFactory;
|
||||
protected final PsiType myToType;
|
||||
|
||||
protected MethodArgumentFix(@NotNull PsiExpressionList list, int i, @NotNull PsiType toType, @NotNull ArgumentFixerActionFactory fixerActionFactory) {
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.codeInsight.daemon.impl.quickfix;
|
||||
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author Dmitry Batkovich
|
||||
*/
|
||||
public class WrapArrayToArraysAsListFix extends MethodArgumentFix {
|
||||
public static final ArgumentFixerActionFactory REGISTAR = new MyFixerActionFactory();
|
||||
|
||||
protected WrapArrayToArraysAsListFix(final @NotNull PsiExpressionList list,
|
||||
final int i,
|
||||
final @NotNull PsiType toType,
|
||||
final @NotNull ArgumentFixerActionFactory fixerActionFactory) {
|
||||
super(list, i, toType, fixerActionFactory);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
if (myArgList.getExpressions().length == 1) {
|
||||
return QuickFixBundle.message("wrap.array.to.arrays.as.list.single.parameter.text");
|
||||
} else {
|
||||
return QuickFixBundle.message("wrap.array.to.arrays.as.list.parameter.text", myIndex + 1);
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyFixerActionFactory extends ArgumentFixerActionFactory {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected PsiExpression getModifiedArgument(final PsiExpression expression, final PsiType toType) throws IncorrectOperationException {
|
||||
final PsiType exprType = expression.getType();
|
||||
if (!(exprType instanceof PsiArrayType && toType instanceof PsiClassType)) {
|
||||
return null;
|
||||
}
|
||||
final PsiClass resolvedToType = ((PsiClassType)toType).resolve();
|
||||
if (resolvedToType == null) {
|
||||
return null;
|
||||
}
|
||||
final PsiClass javaUtilList = getJavaUtilList(expression);
|
||||
if (javaUtilList == null || !InheritanceUtil.isInheritorOrSelf(javaUtilList, resolvedToType, true)) {
|
||||
return null;
|
||||
}
|
||||
final PsiType[] parameters = ((PsiClassType)toType).getParameters();
|
||||
final PsiType arrayComponentType = ((PsiArrayType)exprType).getComponentType();
|
||||
if (!(parameters.length == 1 && parameters[0].equals(arrayComponentType))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final String rawNewExpression = String.format("java.util.Arrays.asList(%s)", expression.getText());
|
||||
final Project project = expression.getProject();
|
||||
final PsiExpression newExpression = JavaPsiFacade.getInstance(project).getElementFactory().createExpressionFromText(rawNewExpression, null);
|
||||
return (PsiExpression)JavaCodeStyleManager.getInstance(project).shortenClassReferences(newExpression);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiClass getJavaUtilList(final PsiElement context) {
|
||||
return JavaPsiFacade.getInstance(context.getProject()).findClass(CommonClassNames.JAVA_UTIL_LIST, context.getResolveScope());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areTypesConvertible(@NotNull final PsiType exprType, @NotNull final PsiType parameterType, @NotNull final PsiElement context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodArgumentFix createFix(final PsiExpressionList list, final int i, final PsiType toType) {
|
||||
return new WrapArrayToArraysAsListFix(list, i, toType, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,128 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-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 com.intellij.codeInsight.daemon.impl.quickfix;
|
||||
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle;
|
||||
import com.intellij.codeInsight.intention.HighPriorityAction;
|
||||
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author Dmitry Batkovich
|
||||
*/
|
||||
public class WrapLongWithMathToIntExactFix extends LocalQuickFixAndIntentionActionOnPsiElement implements HighPriorityAction {
|
||||
public final static MyMethodArgumentFixerFactory REGISTAR = new MyMethodArgumentFixerFactory();
|
||||
|
||||
private final PsiType myType;
|
||||
|
||||
public WrapLongWithMathToIntExactFix(final PsiType type, final @NotNull PsiExpression expression) {
|
||||
super(expression);
|
||||
myType = type;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return getFamilyName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project,
|
||||
@NotNull PsiFile file,
|
||||
@Nullable("is null when called from inspection") Editor editor,
|
||||
@NotNull PsiElement startElement,
|
||||
@NotNull PsiElement endElement) {
|
||||
startElement.replace(getModifiedExpression(startElement));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project,
|
||||
@NotNull PsiFile file,
|
||||
@NotNull PsiElement startElement,
|
||||
@NotNull PsiElement endElement) {
|
||||
return startElement.isValid() &&
|
||||
startElement.getManager().isInProject(startElement) &&
|
||||
PsiUtil.isLanguageLevel8OrHigher(startElement) &&
|
||||
areSameTypes(myType, PsiType.INT) &&
|
||||
areSameTypes(((PsiExpression) startElement).getType(), PsiType.LONG);
|
||||
}
|
||||
|
||||
private static boolean areSameTypes(@Nullable PsiType type, @NotNull PsiPrimitiveType expected) {
|
||||
return !(type == null ||
|
||||
!type.isValid() ||
|
||||
(!type.equals(expected) && !expected.getBoxedTypeName().equals(type.getCanonicalText(false))));
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return QuickFixBundle.message("wrap.long.with.math.to.int.text");
|
||||
}
|
||||
|
||||
private static PsiElement getModifiedExpression(PsiElement expression) {
|
||||
return JavaPsiFacade.getElementFactory(expression.getProject()).createExpressionFromText("java.lang.Math.toIntExact(" + expression.getText() + ")", expression);
|
||||
}
|
||||
|
||||
private static class MyMethodArgumentFix extends MethodArgumentFix implements HighPriorityAction {
|
||||
|
||||
protected MyMethodArgumentFix(@NotNull PsiExpressionList list,
|
||||
int i,
|
||||
@NotNull PsiType toType,
|
||||
@NotNull ArgumentFixerActionFactory fixerActionFactory) {
|
||||
super(list, i, toType, fixerActionFactory);
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return myArgList.getExpressions().length == 1
|
||||
? QuickFixBundle.message("wrap.long.with.math.to.int.parameter.single.text")
|
||||
: QuickFixBundle.message("wrap.long.with.math.to.int.parameter.multiple.text", myIndex + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
return PsiUtil.isLanguageLevel8OrHigher(file) && super.isAvailable(project, editor, file);
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyMethodArgumentFixerFactory extends ArgumentFixerActionFactory {
|
||||
@Nullable
|
||||
@Override
|
||||
protected PsiExpression getModifiedArgument(final PsiExpression expression, final PsiType toType) throws IncorrectOperationException {
|
||||
return areSameTypes(expression.getType(), PsiType.LONG) && areSameTypes(toType, PsiType.INT) ? (PsiExpression)getModifiedExpression(expression) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areTypesConvertible(@NotNull final PsiType exprType, @NotNull final PsiType parameterType, @NotNull final PsiElement context) {
|
||||
return parameterType.isConvertibleFrom(exprType) || (areSameTypes(parameterType, PsiType.INT) && areSameTypes(exprType, PsiType.LONG));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodArgumentFix createFix(final PsiExpressionList list, final int i, final PsiType toType) {
|
||||
return new MyMethodArgumentFix(list, i, toType, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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.codeInsight.daemon.impl.quickfix;
|
||||
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle;
|
||||
import com.intellij.codeInsight.intention.HighPriorityAction;
|
||||
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class WrapStringWithFileFix extends LocalQuickFixAndIntentionActionOnPsiElement implements HighPriorityAction {
|
||||
public final static MyMethodArgumentFixerFactory REGISTAR = new MyMethodArgumentFixerFactory();
|
||||
|
||||
@Nullable private final PsiType myType;
|
||||
|
||||
public WrapStringWithFileFix(@Nullable PsiType type, @NotNull PsiExpression expression) {
|
||||
super(expression);
|
||||
myType = type;
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return getFamilyName();
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return QuickFixBundle.message("wrap.with.java.io.file.text");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project,
|
||||
@NotNull PsiFile file,
|
||||
@NotNull PsiElement startElement,
|
||||
@NotNull PsiElement endElement) {
|
||||
return myType != null &&
|
||||
myType.isValid() &&
|
||||
myType.equalsToText(CommonClassNames.JAVA_IO_FILE) &&
|
||||
startElement.isValid() &&
|
||||
startElement.getManager().isInProject(startElement) &&
|
||||
isStringType(startElement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project,
|
||||
@NotNull PsiFile file,
|
||||
@Nullable Editor editor,
|
||||
@NotNull PsiElement startElement,
|
||||
@NotNull PsiElement endElement) {
|
||||
startElement.replace(getModifiedExpression(startElement));
|
||||
}
|
||||
|
||||
private static boolean isStringType(@NotNull PsiElement expression) {
|
||||
if (!(expression instanceof PsiExpression)) return false;
|
||||
final PsiType type = ((PsiExpression) expression).getType();
|
||||
if (type == null) return false;
|
||||
return type.equalsToText(CommonClassNames.JAVA_LANG_STRING);
|
||||
}
|
||||
|
||||
private static PsiElement getModifiedExpression(@NotNull PsiElement expression) {
|
||||
return JavaPsiFacade.getElementFactory(expression.getProject()).createExpressionFromText(PsiKeyword.NEW + " " + CommonClassNames.JAVA_IO_FILE + "(" + expression.getText() + ")", expression);
|
||||
}
|
||||
|
||||
private static class MyMethodArgumentFix extends MethodArgumentFix implements HighPriorityAction {
|
||||
|
||||
protected MyMethodArgumentFix(@NotNull PsiExpressionList list,
|
||||
int i,
|
||||
@NotNull PsiType toType,
|
||||
@NotNull ArgumentFixerActionFactory fixerActionFactory) {
|
||||
super(list, i, toType, fixerActionFactory);
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return myArgList.getExpressions().length == 1
|
||||
? QuickFixBundle.message("wrap.with.java.io.file.parameter.single.text")
|
||||
: QuickFixBundle.message("wrap.with.java.io.file.parameter.multiple.text", myIndex + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
return PsiUtil.isLanguageLevel8OrHigher(file) && super.isAvailable(project, editor, file);
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyMethodArgumentFixerFactory extends ArgumentFixerActionFactory {
|
||||
@Nullable
|
||||
@Override
|
||||
protected PsiExpression getModifiedArgument(final PsiExpression expression, final PsiType toType) throws IncorrectOperationException {
|
||||
return isStringType(expression) && toType.equalsToText(CommonClassNames.JAVA_IO_FILE) ? (PsiExpression)getModifiedExpression(expression) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areTypesConvertible(@NotNull final PsiType exprType, @NotNull final PsiType parameterType, @NotNull final PsiElement context) {
|
||||
return parameterType.isConvertibleFrom(exprType) || (parameterType.equalsToText(CommonClassNames.JAVA_IO_FILE) && exprType.equalsToText(CommonClassNames.JAVA_LANG_STRING));
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodArgumentFix createFix(final PsiExpressionList list, final int i, final PsiType toType) {
|
||||
return new MyMethodArgumentFix(list, i, toType, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* Copyright 2000-2017 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.codeInsight.daemon.impl.quickfix;
|
||||
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.codeInsight.intention.HighPriorityAction;
|
||||
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import one.util.streamex.StreamEx;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class WrapWithAdapterMethodCallFix extends LocalQuickFixAndIntentionActionOnPsiElement implements HighPriorityAction {
|
||||
static class Wrapper extends ArgumentFixerActionFactory {
|
||||
final Predicate<PsiType> myInTypeFilter;
|
||||
final Predicate<PsiType> myOutTypeFilter;
|
||||
final String myTemplate;
|
||||
|
||||
/**
|
||||
* @param template template for replacement (original expression is referenced as {@code {0}})
|
||||
* @param inTypeFilter filter for input type (must return true if supplied type is acceptable as input type for this wrapper)
|
||||
* @param outTypeFilter quick filter for output type (must return true if supplied output type is acceptable for this wrapper).
|
||||
* It's allowed to check imprecisely (return true even if output type is not acceptable) as more
|
||||
* expensive type check will be performed automatically.
|
||||
*/
|
||||
Wrapper(String template, Predicate<PsiType> inTypeFilter, Predicate<PsiType> outTypeFilter) {
|
||||
myInTypeFilter = inTypeFilter;
|
||||
myOutTypeFilter = outTypeFilter;
|
||||
myTemplate = template;
|
||||
}
|
||||
|
||||
boolean isApplicable(PsiElement context, PsiType inType, PsiType outType) {
|
||||
if (inType == null ||
|
||||
outType == null ||
|
||||
inType.equals(PsiType.NULL) ||
|
||||
!myInTypeFilter.test(inType) ||
|
||||
!myOutTypeFilter.test(outType)) {
|
||||
return false;
|
||||
}
|
||||
PsiType resultType = createReplacement(context, "((" + inType.getCanonicalText() + ")null)").getType();
|
||||
return resultType != null && outType.isAssignableFrom(resultType);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private PsiExpression createReplacement(PsiElement context, String replacement) {
|
||||
return JavaPsiFacade.getElementFactory(context.getProject()).createExpressionFromText(
|
||||
myTemplate.replace("{0}", replacement), context);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected PsiExpression getModifiedArgument(final PsiExpression expression, final PsiType toType) throws IncorrectOperationException {
|
||||
if (isApplicable(expression, expression.getType(), toType)) {
|
||||
return (PsiExpression)JavaCodeStyleManager.getInstance(expression.getProject())
|
||||
.shortenClassReferences(createReplacement(expression, expression.getText()));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean areTypesConvertible(@NotNull final PsiType exprType,
|
||||
@NotNull final PsiType parameterType,
|
||||
@NotNull final PsiElement context) {
|
||||
return parameterType.isConvertibleFrom(exprType) || isApplicable(context, exprType, parameterType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodArgumentFix createFix(final PsiExpressionList list, final int i, final PsiType toType) {
|
||||
return new MyMethodArgumentFix(list, i, toType, this);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return myTemplate.replace("{0}", "").replaceAll("\\b[a-z.]+\\.", "");
|
||||
}
|
||||
}
|
||||
|
||||
private static final Wrapper[] WRAPPERS = {
|
||||
new Wrapper("new java.io.File({0})",
|
||||
inType -> inType.equalsToText(CommonClassNames.JAVA_LANG_STRING),
|
||||
outType -> outType.equalsToText(CommonClassNames.JAVA_IO_FILE)),
|
||||
new Wrapper("java.nio.file.Paths.get({0})",
|
||||
inType -> inType.equalsToText(CommonClassNames.JAVA_LANG_STRING),
|
||||
outType -> outType.equalsToText("java.nio.file.Path")),
|
||||
new Wrapper("java.util.Arrays.asList({0})",
|
||||
inType -> inType instanceof PsiArrayType && ((PsiArrayType)inType).getComponentType() instanceof PsiClassType,
|
||||
outType -> InheritanceUtil.isInheritor(outType, CommonClassNames.JAVA_LANG_ITERABLE)),
|
||||
new Wrapper("java.lang.Math.toIntExact({0})",
|
||||
inType -> PsiType.LONG.equals(inType) || inType.equalsToText(CommonClassNames.JAVA_LANG_LONG),
|
||||
outType -> PsiType.INT.equals(outType) || outType.equalsToText(CommonClassNames.JAVA_LANG_INTEGER)),
|
||||
new Wrapper("java.util.Collections.singleton({0})",
|
||||
inType -> true,
|
||||
outType -> InheritanceUtil.isInheritor(outType, CommonClassNames.JAVA_LANG_ITERABLE)),
|
||||
new Wrapper("java.util.Collections.singletonList({0})",
|
||||
inType -> true,
|
||||
outType -> outType instanceof PsiClassType &&
|
||||
((PsiClassType)outType).rawType().equalsToText(CommonClassNames.JAVA_UTIL_LIST)),
|
||||
new Wrapper("java.util.Arrays.stream({0})",
|
||||
inType -> inType instanceof PsiArrayType,
|
||||
outType -> InheritanceUtil.isInheritor(outType, CommonClassNames.JAVA_UTIL_STREAM_BASE_STREAM))
|
||||
};
|
||||
|
||||
@Nullable private final PsiType myType;
|
||||
@Nullable private final Wrapper myWrapper;
|
||||
|
||||
public WrapWithAdapterMethodCallFix(@Nullable PsiType type, @NotNull PsiExpression expression) {
|
||||
super(expression);
|
||||
myType = type;
|
||||
myWrapper = StreamEx.of(WRAPPERS).findFirst(w -> w.isApplicable(expression, expression.getType(), type)).orElse(null);
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return QuickFixBundle.message("wrap.with.adapter.text", myWrapper);
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return QuickFixBundle.message("wrap.with.adapter.call.family.name");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project,
|
||||
@NotNull PsiFile file,
|
||||
@NotNull PsiElement startElement,
|
||||
@NotNull PsiElement endElement) {
|
||||
return myType != null &&
|
||||
myWrapper != null &&
|
||||
myType.isValid() &&
|
||||
startElement.isValid() &&
|
||||
startElement.getManager().isInProject(startElement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project,
|
||||
@NotNull PsiFile file,
|
||||
@Nullable Editor editor,
|
||||
@NotNull PsiElement startElement,
|
||||
@NotNull PsiElement endElement) {
|
||||
JavaCodeStyleManager.getInstance(project).shortenClassReferences(startElement.replace(getModifiedExpression(startElement)));
|
||||
}
|
||||
|
||||
private PsiExpression getModifiedExpression(@NotNull PsiElement expression) {
|
||||
assert myWrapper != null;
|
||||
return myWrapper.createReplacement(expression, expression.getText());
|
||||
}
|
||||
|
||||
private static class MyMethodArgumentFix extends MethodArgumentFix implements HighPriorityAction {
|
||||
|
||||
protected MyMethodArgumentFix(@NotNull PsiExpressionList list,
|
||||
int i,
|
||||
@NotNull PsiType toType,
|
||||
@NotNull Wrapper fixerActionFactory) {
|
||||
super(list, i, toType, fixerActionFactory);
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return myArgList.getExpressions().length == 1
|
||||
? QuickFixBundle.message("wrap.with.adapter.parameter.single.text", myArgumentFixerActionFactory)
|
||||
: QuickFixBundle.message("wrap.with.adapter.parameter.multiple.text", myIndex + 1, myArgumentFixerActionFactory);
|
||||
}
|
||||
}
|
||||
|
||||
public static void registerCastActions(@NotNull CandidateInfo[] candidates,
|
||||
@NotNull PsiCall call,
|
||||
HighlightInfo highlightInfo,
|
||||
final TextRange fixRange) {
|
||||
for (Wrapper wrapper : WRAPPERS) {
|
||||
wrapper.registerCastActions(candidates, call, highlightInfo, fixRange);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -657,12 +657,6 @@ public class EmptyQuickFixFactory extends QuickFixFactory {
|
||||
return QuickFixes.EMPTY_FIX;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public IntentionAction createWrapLongWithMathToIntExactFix(@Nullable PsiType type, @NotNull PsiExpression expression) {
|
||||
return QuickFixes.EMPTY_FIX;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public IntentionAction createWrapWithOptionalFix(@Nullable PsiType type, @NotNull PsiExpression expression) {
|
||||
@@ -702,7 +696,7 @@ public class EmptyQuickFixFactory extends QuickFixFactory {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public IntentionAction createWrapStringWithFileFix(@Nullable PsiType type, @NotNull PsiExpression expression) {
|
||||
public IntentionAction createWrapWithAdapterFix(@Nullable PsiType type, @NotNull PsiExpression expression) {
|
||||
return QuickFixes.EMPTY_FIX;
|
||||
}
|
||||
|
||||
|
||||
@@ -803,12 +803,6 @@ public class QuickFixFactoryImpl extends QuickFixFactory {
|
||||
return new AddMethodQualifierFix(methodCall);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public IntentionAction createWrapLongWithMathToIntExactFix(@Nullable PsiType type, @NotNull PsiExpression expression) {
|
||||
return new WrapLongWithMathToIntExactFix(type, expression);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public IntentionAction createWrapWithOptionalFix(@Nullable PsiType type, @NotNull PsiExpression expression) {
|
||||
@@ -885,8 +879,8 @@ public class QuickFixFactoryImpl extends QuickFixFactory {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public IntentionAction createWrapStringWithFileFix(@Nullable PsiType type, @NotNull PsiExpression expression) {
|
||||
return new WrapStringWithFileFix(type, expression);
|
||||
public IntentionAction createWrapWithAdapterFix(@Nullable PsiType type, @NotNull PsiExpression expression) {
|
||||
return new WrapWithAdapterMethodCallFix(type, expression);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
// "Wrap using 'Collections.singletonList()'" "true"
|
||||
import java.util.*;
|
||||
|
||||
class Test {
|
||||
|
||||
void m(long l) {
|
||||
List<Long> list = Collections.singletonList(l);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// "Wrap using 'Paths.get()'" "true"
|
||||
import java.nio.file.*;
|
||||
|
||||
class Test {
|
||||
|
||||
Path m() {
|
||||
return Paths.get("/etc/passwd");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// "Wrap 1st parameter using 'Collections.singleton()'" "true"
|
||||
import java.util.*;
|
||||
|
||||
class Test {
|
||||
|
||||
void method(Set<Long> set, double val) {
|
||||
|
||||
}
|
||||
|
||||
void m(long l) {
|
||||
method(Collections.singleton(l), l);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// "Wrap using 'Arrays.stream()'" "true"
|
||||
import java.util.*;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class Test {
|
||||
Stream<String> testStream(List<String[]> list) {
|
||||
return Arrays.stream(list.get(0));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// "Wrap using 'Collections.singletonList()'" "true"
|
||||
import java.util.*;
|
||||
|
||||
class Test {
|
||||
|
||||
void m(long l) {
|
||||
List<Long> list = <caret>l;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// "Wrap using 'Collections.singletonList()'" "false"
|
||||
import java.util.*;
|
||||
|
||||
class Test {
|
||||
|
||||
void m(long l) {
|
||||
List<Integer> list = <caret>l;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// "Wrap using 'Paths.get()'" "true"
|
||||
import java.nio.file.*;
|
||||
|
||||
class Test {
|
||||
|
||||
Path m() {
|
||||
return "/<caret>etc/passwd";
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// "Wrap 1st parameter using 'Collections.singleton()'" "true"
|
||||
import java.util.*;
|
||||
|
||||
class Test {
|
||||
|
||||
void method(Set<Long> set, double val) {
|
||||
|
||||
}
|
||||
|
||||
void m(long l) {
|
||||
method(<caret>l, l);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// "Wrap using 'Arrays.stream()'" "true"
|
||||
import java.util.*;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class Test {
|
||||
Stream<String> testStream(List<String[]> list) {
|
||||
return list.<caret>get(0);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Wrap using 'Arrays.asList()'" "true"
|
||||
// "Wrap parameter using 'Arrays.asList()'" "true"
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Wrap using 'Arrays.asList()'" "false"
|
||||
// "Wrap parameter using 'Arrays.asList()'" "false"
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class Test {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Wrap using 'Arrays.asList()'" "false"
|
||||
// "Wrap parameter using 'Arrays.asList()'" "false"
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class Test {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// "Wrap using 'Arrays.asList()'" "true"
|
||||
// "Wrap parameter using 'Arrays.asList()'" "true"
|
||||
import java.util.List;
|
||||
|
||||
public class Test {
|
||||
|
||||
@@ -16,14 +16,24 @@
|
||||
package com.intellij.java.codeInsight.daemon.quickFix;
|
||||
|
||||
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase;
|
||||
import com.intellij.testFramework.LightProjectDescriptor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class WrapStringWithFileFixTest extends LightQuickFixParameterizedTestCase {
|
||||
import static com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase.JAVA_9;
|
||||
|
||||
public class WrapWithAdapterMethodCallFixTest extends LightQuickFixParameterizedTestCase {
|
||||
public void test() {
|
||||
doAllTests();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected LightProjectDescriptor getProjectDescriptor() {
|
||||
return JAVA_9; // java.nio.file is mocked since Java 9 only
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return "/codeInsight/daemonCodeAnalyzer/quickFix/wrapStringWithFile";
|
||||
return "/codeInsight/daemonCodeAnalyzer/quickFix/wrapAdapterCall";
|
||||
}
|
||||
}
|
||||
@@ -265,9 +265,6 @@ replace.with.list.access.text=Replace with list access
|
||||
add.qualifier=Add qualifier
|
||||
add.qualifier.original.class.chooser.title=Original class
|
||||
|
||||
wrap.array.to.arrays.as.list.parameter.text=Wrap {0, choice, 1#1st|2#2nd|3#3rd|4#{0,number}th} parameter using ''Arrays.asList()''
|
||||
wrap.array.to.arrays.as.list.single.parameter.text=Wrap using 'Arrays.asList()'
|
||||
|
||||
annotations.fix=Annotations
|
||||
add.missing.annotation.parameters.fix=Add missing annotation parameters - {0}
|
||||
add.missing.annotation.single.parameter.fix=Add missing annotation parameter ''{0}''
|
||||
@@ -279,10 +276,6 @@ collection.addall.can.be.replaced.with.constructor.fix.options.title=Classes to
|
||||
collection.addall.can.be.replaced.with.constructor.fix.description=''{0}()'' method can be replaced with parametrized constructor
|
||||
collection.addall.can.be.replaced.with.constructor.fix.title=Replace 'addAll/putAll' method with parametrized constructor call
|
||||
|
||||
wrap.long.with.math.to.int.text=Wrap using 'Math.toIntExact()'
|
||||
wrap.long.with.math.to.int.parameter.single.text=Wrap parameter using 'Math.toIntExact()'
|
||||
wrap.long.with.math.to.int.parameter.multiple.text=Wrap {0, choice, 1#1st|2#2nd|3#3rd|4#{0,number}th} parameter using ''Math.toIntExact()''
|
||||
|
||||
add.exception.from.field.initializer.to.constructor.throws.text=Add exception to class {0, choice, 0#default constructor|1#constructor|2#constructors} signature
|
||||
add.exception.from.field.initializer.to.constructor.throws.family.text=Add exception to class constructors signature
|
||||
java.8.map.api.inspection.fix.text=Replace with ''{0}'' method call
|
||||
@@ -315,9 +308,10 @@ collection.to.array.family.name=Apply conversion '.toArray()'
|
||||
insert.sam.method.call.fix.name=Insert ''.{0}'' to call functional interface method
|
||||
insert.sam.method.call.fix.family.name=Insert single abstract method call
|
||||
|
||||
wrap.with.java.io.file.text=Wrap using 'new File()'
|
||||
wrap.with.java.io.file.parameter.single.text=Wrap parameter using 'new File()'
|
||||
wrap.with.java.io.file.parameter.multiple.text=Wrap {0, choice, 1#1st|2#2nd|3#3rd|4#{0,number}th} parameter using ''new File()''
|
||||
wrap.with.adapter.call.family.name=Wrap using adapter call or object
|
||||
wrap.with.adapter.text=Wrap using ''{0}''
|
||||
wrap.with.adapter.parameter.single.text=Wrap parameter using ''{0}''
|
||||
wrap.with.adapter.parameter.multiple.text=Wrap {0, choice, 1#1st|2#2nd|3#3rd|4#{0,number}th} parameter using ''{1}''
|
||||
|
||||
java.9.merge.module.statements.fix.family.name=Merge with other ''{0}'' directive
|
||||
java.9.merge.module.statements.fix.name=Merge with other ''{0} {1}'' directive
|
||||
|
||||
Reference in New Issue
Block a user