[java-inspections] More quickfixes to ModCommand

GitOrigin-RevId: ccc6093d680712cb81c1325d997fb2771b61a0be
This commit is contained in:
Tagir Valeev
2023-06-25 19:05:51 +00:00
committed by intellij-monorepo-bot
parent 80fe6724fe
commit ad40c945e2
90 changed files with 755 additions and 1129 deletions
@@ -615,7 +615,6 @@ text.shebang.mechanism.in.java.files.not.permitted=Shebang mechanism in .java fi
inspection.redundant.tostring.option.notnull.qualifier=Report only when qualifier is known to be not-null
highlighting.try.blocks=Highlighting try blocks...
intention.family.name.remove.new.family.name=Remove 'new'
intention.name.remove.new.display.name=Remove 'new'
inspection.unsatisfied.range.display.name=Return value is outside of declared range
inspection.unsatisfied.range.message=Return value range ''{0}'' is outside of declared range ''{1}''
inspection.unsatisfied.range.message.value=Return value ''{0}'' is outside of declared range ''{1}''
@@ -215,7 +215,7 @@ public abstract class QuickFixFactory {
public abstract IntentionAction createChangeParameterClassFix(@NotNull PsiClass aClass, @NotNull PsiClassType type);
@NotNull
public abstract IntentionAction createReplaceInaccessibleFieldWithGetterSetterFix(@NotNull PsiElement element,
public abstract IntentionAction createReplaceInaccessibleFieldWithGetterSetterFix(@NotNull PsiReferenceExpression element,
@NotNull PsiMethod getter,
boolean isSetter);
@@ -22,7 +22,7 @@
<extensionPoint qualifiedName="com.intellij.visibility" interface="com.intellij.codeInspection.visibility.VisibilityExtension" dynamic="true"/>
<extensionPoint qualifiedName="com.intellij.java.error.fix" beanClass="com.intellij.codeInsight.daemon.impl.analysis.ErrorFixExtensionPoint" dynamic="true">
<with attribute="implementationClass" implements="com.intellij.codeInsight.intention.IntentionAction"/>
<with attribute="implementationClass" implements="com.intellij.codeInsight.intention.CommonIntentionAction"/>
</extensionPoint>
<extensionPoint qualifiedName="com.intellij.lang.jvm.actions.jvmElementActionsFactory" interface="com.intellij.lang.jvm.actions.JvmElementActionsFactory" dynamic="true"/>
@@ -81,10 +81,10 @@ final class AdaptExpressionTypeFixUtil {
if (parameterType instanceof PsiClassType &&
((PsiClassType)parameterType).rawType().equalsToText(CommonClassNames.JAVA_LANG_CLASS) &&
typeParameter == getSoleTypeParameter(parameterType)) {
if (expectedTypeValue instanceof PsiClassType && JavaGenericsUtil.isReifiableType(expectedTypeValue)) {
if (expectedTypeValue instanceof PsiClassType classType && JavaGenericsUtil.isReifiableType(expectedTypeValue)) {
ReplaceExpressionAction fix = new ReplaceExpressionAction(
arg, ((PsiClassType)expectedTypeValue).rawType().getCanonicalText() + ".class",
((PsiClassType)expectedTypeValue).rawType().getPresentableText() + ".class");
arg, classType.rawType().getCanonicalText() + ".class",
classType.rawType().getPresentableText() + ".class");
info.registerFix(fix, null, null, null, null);
}
}
@@ -1,8 +1,9 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.daemon.impl.analysis;
import com.intellij.codeInsight.daemon.JavaErrorBundle;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.intention.CommonIntentionAction;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.diagnostic.PluginException;
import com.intellij.openapi.application.ApplicationManager;
@@ -32,10 +33,10 @@ public final class ErrorFixExtensionPoint implements PluginAware {
private transient PluginDescriptor pluginDescriptor;
private IntentionAction instantiate(PsiElement context) {
private CommonIntentionAction instantiate(PsiElement context) {
try {
return ApplicationManager.getApplication().loadClass(implementationClass, pluginDescriptor)
.asSubclass(IntentionAction.class).getConstructor(PsiElement.class).newInstance(context);
.asSubclass(CommonIntentionAction.class).getConstructor(PsiElement.class).newInstance(context);
}
catch (InvocationTargetException e) {
if(e.getCause() instanceof ProcessCanceledException) {
@@ -73,7 +74,7 @@ public final class ErrorFixExtensionPoint implements PluginAware {
@NotNull @PropertyKey(resourceBundle = JavaErrorBundle.BUNDLE) String code) {
List<ErrorFixExtensionPoint> fixes = getCodeToFixMap().get(code);
for (ErrorFixExtensionPoint fix : fixes) {
IntentionAction action = fix.instantiate(context);
IntentionAction action = fix.instantiate(context).asIntention();
info.registerFix(action, null, null, null, null);
}
}
@@ -324,7 +324,7 @@ public final class HighlightFixUtil {
if (setter != null && PsiUtil.isAccessible(setter, ref, accessObjectClass)) {
PsiElement element = PsiTreeUtil.skipParentsOfType(ref, PsiParenthesizedExpression.class);
if (element instanceof PsiAssignmentExpression && ((PsiAssignmentExpression)element).getOperationTokenType() == JavaTokenType.EQ) {
IntentionAction action = QUICK_FIX_FACTORY.createReplaceInaccessibleFieldWithGetterSetterFix(place, setter, true);
IntentionAction action = QUICK_FIX_FACTORY.createReplaceInaccessibleFieldWithGetterSetterFix(ref, setter, true);
builder.registerFix(action, null, null, parentFixRange, null);
}
}
@@ -333,7 +333,7 @@ public final class HighlightFixUtil {
PsiMethod getterPrototype = PropertyUtilBase.generateGetterPrototype(psiField);
PsiMethod getter = containingClass.findMethodBySignature(getterPrototype, true);
if (getter != null && PsiUtil.isAccessible(getter, ref, accessObjectClass)) {
IntentionAction action = QUICK_FIX_FACTORY.createReplaceInaccessibleFieldWithGetterSetterFix(place, getter, false);
IntentionAction action = QUICK_FIX_FACTORY.createReplaceInaccessibleFieldWithGetterSetterFix(ref, getter, false);
builder.registerFix(action, null, null, parentFixRange, null);
}
}
@@ -499,7 +499,7 @@ public final class HighlightFixUtil {
if (methodCandidate.isAccessible() && PsiUtil.isApplicable(method, methodCandidate.getSubstitutor(), exprList)) {
PsiExpression qualifier = ExpressionUtils.getEffectiveQualifier(methodCall.getMethodExpression(), method);
if (qualifier == null) continue;
IntentionAction fix = new QualifyMethodCallFix(methodCall, qualifier.getText());
var fix = new QualifyMethodCallFix(methodCall, qualifier.getText());
TextRange fixRange = HighlightMethodUtil.getFixRange(methodCall);
if (highlightInfo != null) {
highlightInfo.registerFix(fix, null, null, fixRange, null);
@@ -902,7 +902,7 @@ public final class HighlightMethodUtil {
WrapObjectWithOptionalOfNullableFix.REGISTAR.registerCastActions(candidates, methodCall, builder, fixRange);
WrapExpressionFix.registerWrapAction(candidates, list.getExpressions(), builder, fixRange);
PermuteArgumentsFix.registerFix(builder, methodCall, candidates, fixRange);
IntentionAction action = RemoveRepeatingCallFix.createFix(methodCall);
var action = RemoveRepeatingCallFix.createFix(methodCall);
if (action != null) {
builder.registerFix(action, null, null, fixRange, null);
}
@@ -584,7 +584,7 @@ public final class HighlightUtil {
String message = JavaErrorBundle.message("return.outside.switch.expr");
HighlightInfo.Builder info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(statement).descriptionAndTooltip(message);
if (statement.getReturnValue() != null) {
IntentionAction action = new ReplaceWithYieldFix(statement);
var action = new ReplaceWithYieldFix(statement);
info.registerFix(action, null, null, null, null);
}
return info;
@@ -1857,7 +1857,7 @@ public final class HighlightUtil {
HighlightInfo.Builder info =
HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(typeElement).descriptionAndTooltip(description);
if (!VariableAccessUtils.variableIsUsed(variable, variable.getDeclarationScope())) {
IntentionAction action = new RedundantInstanceofFix(expression);
var action = new RedundantInstanceofFix(expression);
info.registerFix(action, null, null, null, null);
}
return info;
@@ -3278,8 +3278,8 @@ public final class HighlightUtil {
HighlightInfo.Builder info =
HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF).range(refName).descriptionAndTooltip(description);
if (isCallToStaticMember(outerParent)) {
IntentionAction action = new RemoveNewKeywordFix(outerParent);
if (outerParent instanceof PsiNewExpression newExpression && isCallToStaticMember(newExpression)) {
var action = new RemoveNewKeywordFix(newExpression);
info.registerFix(action, null, null, null, null);
}
UnresolvedReferenceQuickFixUpdater.getInstance(containingFile.getProject()).registerQuickFixesLater(ref, info);
@@ -1197,14 +1197,14 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
if (!myHolder.hasErrorResults()) add(GenericsHighlightUtil.checkGenericCannotExtendException((PsiAnonymousClass)parent));
}
if (parent instanceof PsiNewExpression &&
if (parent instanceof PsiNewExpression newExpression &&
!(resolved instanceof PsiClass) &&
resolved instanceof PsiNamedElement &&
((PsiNewExpression)parent).getClassOrAnonymousClassReference() == ref) {
newExpression.getClassOrAnonymousClassReference() == ref) {
String text = JavaErrorBundle.message("cannot.resolve.symbol", ((PsiNamedElement)resolved).getName());
HighlightInfo.Builder info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(ref).descriptionAndTooltip(text);
if (HighlightUtil.isCallToStaticMember(parent)) {
IntentionAction action = new RemoveNewKeywordFix(parent);
if (HighlightUtil.isCallToStaticMember(newExpression)) {
var action = new RemoveNewKeywordFix(newExpression);
info.registerFix(action, null, null, null, null);
}
add(info);
@@ -1,21 +1,20 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.daemon.impl.analysis;
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
import com.intellij.codeInspection.PsiUpdateModCommandAction;
import com.intellij.java.analysis.JavaAnalysisBundle;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiJavaCodeReferenceElement;
import com.intellij.psi.PsiNewExpression;
import com.intellij.psi.PsiReferenceParameterList;
import com.siyeh.ig.psiutils.CommentTracker;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
import static com.intellij.util.ObjectUtils.tryCast;
final class RemoveNewKeywordFix extends LocalQuickFixAndIntentionActionOnPsiElement {
RemoveNewKeywordFix(PsiElement outerParent) {super(outerParent);}
final class RemoveNewKeywordFix extends PsiUpdateModCommandAction<PsiNewExpression> {
RemoveNewKeywordFix(@NotNull PsiNewExpression outerParent) {super(outerParent);}
@Override
public @NotNull String getFamilyName() {
@@ -23,19 +22,7 @@ final class RemoveNewKeywordFix extends LocalQuickFixAndIntentionActionOnPsiElem
}
@Override
public @NotNull String getText() {
return JavaAnalysisBundle.message("intention.name.remove.new.display.name");
}
@Override
public void invoke(@NotNull Project project,
@NotNull PsiFile file,
@Nullable Editor editor,
@NotNull PsiElement startElement,
@NotNull PsiElement endElement) {
PsiNewExpression newDeclaration = tryCast(startElement, PsiNewExpression.class);
if (newDeclaration == null) return;
protected void invoke(@NotNull ActionContext context, @NotNull PsiNewExpression newDeclaration, @NotNull ModPsiUpdater updater) {
PsiJavaCodeReferenceElement reference = newDeclaration.getClassOrAnonymousClassReference();
if (reference == null) return;
PsiElement qualifier = reference.getQualifier();
@@ -1,27 +1,26 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.codeInspection.PsiUpdateModCommandAction;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiMethodCallExpression;
import com.intellij.psi.PsiReferenceExpression;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class QualifyMethodCallFix extends LocalQuickFixAndIntentionActionOnPsiElement {
public class QualifyMethodCallFix extends PsiUpdateModCommandAction<PsiMethodCallExpression> {
private final String myQualifierText;
public QualifyMethodCallFix(@NotNull PsiMethodCallExpression call,
@NotNull String qualifierText) {
public QualifyMethodCallFix(@NotNull PsiMethodCallExpression call, @NotNull String qualifierText) {
super(call);
myQualifierText = qualifierText;
}
@Override
@NotNull
public String getText() {
return QuickFixBundle.message("qualify.method.call.fix", myQualifierText);
protected @Nullable Presentation getPresentation(@NotNull ActionContext context, @NotNull PsiMethodCallExpression element) {
return Presentation.of(QuickFixBundle.message("qualify.method.call.fix", myQualifierText)).withFixAllOption(this);
}
@NotNull
@@ -31,12 +30,8 @@ public class QualifyMethodCallFix extends LocalQuickFixAndIntentionActionOnPsiEl
}
@Override
public void invoke(@NotNull Project project,
@NotNull PsiFile file,
@Nullable Editor editor,
@NotNull PsiElement startElement,
@NotNull PsiElement endElement) {
PsiReferenceExpression expression = ((PsiMethodCallExpression)startElement).getMethodExpression();
expression.setQualifierExpression(JavaPsiFacade.getElementFactory(project).createExpressionFromText(myQualifierText, null));
protected void invoke(@NotNull ActionContext context, @NotNull PsiMethodCallExpression call, @NotNull ModPsiUpdater updater) {
PsiReferenceExpression expression = call.getMethodExpression();
expression.setQualifierExpression(JavaPsiFacade.getElementFactory(context.project()).createExpressionFromText(myQualifierText, null));
}
}
@@ -1,21 +1,17 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.PsiEquivalenceUtil;
import com.intellij.codeInsight.daemon.impl.actions.IntentionActionWithFixAllOption;
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
import com.intellij.codeInspection.PsiUpdateModCommandAction;
import com.intellij.java.analysis.JavaAnalysisBundle;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiMethodCallExpression;
import com.siyeh.ig.psiutils.MethodCallUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class RemoveRepeatingCallFix extends LocalQuickFixAndIntentionActionOnPsiElement implements IntentionActionWithFixAllOption {
public class RemoveRepeatingCallFix extends PsiUpdateModCommandAction<PsiMethodCallExpression> {
private final String myMethodName;
private RemoveRepeatingCallFix(PsiMethodCallExpression call, String methodName) {
@@ -24,12 +20,7 @@ public class RemoveRepeatingCallFix extends LocalQuickFixAndIntentionActionOnPsi
}
@Override
public void invoke(@NotNull Project project,
@NotNull PsiFile file,
@Nullable Editor editor,
@NotNull PsiElement startElement,
@NotNull PsiElement endElement) {
PsiMethodCallExpression call = (PsiMethodCallExpression)startElement;
protected void invoke(@NotNull ActionContext context, @NotNull PsiMethodCallExpression call, @NotNull ModPsiUpdater updater) {
PsiExpression qualifier = call.getMethodExpression().getQualifierExpression();
if (qualifier == null) {
return;
@@ -38,8 +29,8 @@ public class RemoveRepeatingCallFix extends LocalQuickFixAndIntentionActionOnPsi
}
@Override
public @NotNull String getText() {
return JavaAnalysisBundle.message("intention.name.remove.repeating.call", myMethodName);
protected @Nullable Presentation getPresentation(@NotNull ActionContext context, @NotNull PsiMethodCallExpression element) {
return Presentation.of(JavaAnalysisBundle.message("intention.name.remove.repeating.call", myMethodName)).withFixAllOption(this);
}
@Override
@@ -1,19 +1,16 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInspection.CommonQuickFixBundle;
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
import com.intellij.codeInspection.PsiUpdateModCommandAction;
import com.intellij.java.analysis.JavaAnalysisBundle;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiFile;
import com.siyeh.ig.psiutils.CommentTracker;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class ReplaceExpressionAction extends LocalQuickFixAndIntentionActionOnPsiElement {
public class ReplaceExpressionAction extends PsiUpdateModCommandAction<PsiExpression> {
private final String myReplacement;
private final String myPresentation;
private final String myOrigText;
@@ -26,17 +23,13 @@ public class ReplaceExpressionAction extends LocalQuickFixAndIntentionActionOnPs
}
@Override
public void invoke(@NotNull Project project,
@NotNull PsiFile file,
@Nullable Editor editor,
@NotNull PsiElement startElement,
@NotNull PsiElement endElement) {
new CommentTracker().replaceAndRestoreComments(startElement, myReplacement);
protected void invoke(@NotNull ActionContext context, @NotNull PsiExpression element, @NotNull ModPsiUpdater updater) {
new CommentTracker().replaceAndRestoreComments(element, myReplacement);
}
@Override
public @NotNull String getText() {
return CommonQuickFixBundle.message("fix.replace.x.with.y", myOrigText, myPresentation);
protected @Nullable Presentation getPresentation(@NotNull ActionContext context, @NotNull PsiExpression element) {
return Presentation.of(CommonQuickFixBundle.message("fix.replace.x.with.y", myOrigText, myPresentation));
}
@Override
@@ -1,17 +1,12 @@
/*
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
*/
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.intention.HighPriorityAction;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInsight.intention.PriorityAction;
import com.intellij.codeInspection.CommonQuickFixBundle;
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
import com.intellij.codeInspection.util.IntentionName;
import com.intellij.codeInspection.PsiUpdateModCommandAction;
import com.intellij.java.analysis.JavaAnalysisBundle;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiTypesUtil;
@@ -20,44 +15,27 @@ import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
public class ReplaceGetClassWithClassLiteralFix extends LocalQuickFixAndIntentionActionOnPsiElement implements HighPriorityAction {
private @IntentionName String myText;
public class ReplaceGetClassWithClassLiteralFix extends PsiUpdateModCommandAction<PsiMethodCallExpression> {
public ReplaceGetClassWithClassLiteralFix(PsiMethodCallExpression expression) {
super(expression);
}
@Override
public void invoke(@NotNull Project project,
@NotNull PsiFile file,
@Nullable Editor editor,
@NotNull PsiElement startElement,
@NotNull PsiElement endElement) {
PsiClass aClass = PsiTreeUtil.getParentOfType(startElement, PsiClass.class);
protected void invoke(@NotNull ActionContext context, @NotNull PsiMethodCallExpression call, @NotNull ModPsiUpdater updater) {
PsiClass aClass = PsiTreeUtil.getParentOfType(call, PsiClass.class);
assert aClass != null;
PsiExpression classLiteral = JavaPsiFacade.getElementFactory(project).createExpressionFromText(aClass.getName() + ".class", startElement);
new CommentTracker().replaceAndRestoreComments(startElement, classLiteral);
PsiExpression classLiteral = JavaPsiFacade.getElementFactory(context.project()).createExpressionFromText(aClass.getName() + ".class", call);
new CommentTracker().replaceAndRestoreComments(call, classLiteral);
}
@Override
public boolean isAvailable(@NotNull Project project,
@NotNull PsiFile file,
@NotNull PsiElement startElement,
@NotNull PsiElement endElement) {
PsiClass aClass = PsiTreeUtil.getParentOfType(startElement, PsiClass.class);
if (aClass == null) return false;
protected @Nullable Presentation getPresentation(@NotNull ActionContext context, @NotNull PsiMethodCallExpression call) {
PsiClass aClass = PsiTreeUtil.getParentOfType(call, PsiClass.class);
if (aClass == null) return null;
String className = aClass.getName();
if (className == null) return false;
myText = CommonQuickFixBundle.message("fix.replace.with.x", className + "." + PsiKeyword.CLASS);
return super.isAvailable(project, file, startElement, endElement);
}
@NotNull
@Override
public String getText() {
return myText;
if (className == null) return null;
return Presentation.of(CommonQuickFixBundle.message("fix.replace.with.x", className + "." + PsiKeyword.CLASS)).withPriority(
PriorityAction.Priority.HIGH);
}
@Nls
@@ -71,7 +49,7 @@ public class ReplaceGetClassWithClassLiteralFix extends LocalQuickFixAndIntentio
if (callExpression.getMethodExpression().getQualifierExpression() == null) {
PsiMethod method = callExpression.resolveMethod();
if (method != null && PsiTypesUtil.isGetClass(method)) {
IntentionAction action = new ReplaceGetClassWithClassLiteralFix(callExpression);
var action = new ReplaceGetClassWithClassLiteralFix(callExpression);
if (errorResult != null) {
errorResult.registerFix(action, null, null, null, null);
}
@@ -1,46 +1,41 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.daemon.impl.actions.IntentionActionWithFixAllOption;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInspection.CommonQuickFixBundle;
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.codeInspection.PsiUpdateModCommandAction;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.siyeh.ig.psiutils.CommentTracker;
import com.intellij.psi.PsiExpression;
import com.intellij.psi.PsiKeyword;
import com.intellij.psi.PsiReturnStatement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class ReplaceWithYieldFix extends LocalQuickFixAndIntentionActionOnPsiElement implements IntentionActionWithFixAllOption {
public class ReplaceWithYieldFix extends PsiUpdateModCommandAction<PsiReturnStatement> {
public ReplaceWithYieldFix(@NotNull PsiReturnStatement statement) {
super(statement);
}
@Override
public void invoke(@NotNull Project project,
@NotNull PsiFile file,
@Nullable Editor editor,
@NotNull PsiElement startElement,
@NotNull PsiElement endElement) {
PsiReturnStatement returnStatement = (PsiReturnStatement)startElement;
protected void invoke(@NotNull ActionContext context, @NotNull PsiReturnStatement returnStatement, @NotNull ModPsiUpdater updater) {
PsiExpression returnValue = returnStatement.getReturnValue();
if (returnValue == null) {
return;
}
TextRange range = returnStatement.getFirstChild().getTextRange();
// Work on document level to preserve formatting
file.getViewProvider().getDocument().replaceString(range.getStartOffset(), range.getEndOffset(), PsiKeyword.YIELD);
Document document = returnStatement.getContainingFile().getViewProvider().getDocument();
document.replaceString(range.getStartOffset(), range.getEndOffset(), PsiKeyword.YIELD);
}
@Override
public @NotNull String getText() {
return CommonQuickFixBundle.message("fix.replace.with.x", PsiKeyword.YIELD);
protected @Nullable Presentation getPresentation(@NotNull ActionContext context, @NotNull PsiReturnStatement element) {
return Presentation.of(getFamilyName()).withFixAllOption(this);
}
@Override
public @NotNull String getFamilyName() {
return getText();
return CommonQuickFixBundle.message("fix.replace.with.x", PsiKeyword.YIELD);
}
}
@@ -1,8 +1,9 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection;
import com.intellij.codeInsight.intention.HighPriorityAction;
import com.intellij.java.analysis.JavaAnalysisBundle;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
@@ -96,7 +97,7 @@ public class RedundantLambdaCodeBlockInspection extends AbstractBaseJavaLocalIns
return false;
}
private static class ReplaceWithExprFix implements LocalQuickFix, HighPriorityAction {
private static class ReplaceWithExprFix extends PsiUpdateModCommandQuickFix implements HighPriorityAction {
@NotNull
@Override
public String getFamilyName() {
@@ -104,17 +105,14 @@ public class RedundantLambdaCodeBlockInspection extends AbstractBaseJavaLocalIns
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiElement element = descriptor.getPsiElement();
if (element != null) {
final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(element, PsiLambdaExpression.class);
if (lambdaExpression != null) {
final PsiElement body = lambdaExpression.getBody();
if (body != null) {
PsiExpression expression = LambdaUtil.extractSingleExpressionFromBody(body);
if (expression != null) {
body.replace(expression);
}
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
final PsiLambdaExpression lambdaExpression = PsiTreeUtil.getParentOfType(element, PsiLambdaExpression.class);
if (lambdaExpression != null) {
final PsiElement body = lambdaExpression.getBody();
if (body != null) {
PsiExpression expression = LambdaUtil.extractSingleExpressionFromBody(body);
if (expression != null) {
body.replace(expression);
}
}
}
@@ -1,8 +1,9 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection;
import com.intellij.codeInsight.ExternalAnnotationsManager;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
@@ -21,7 +22,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Set;
class RemoveSuppressWarningAction implements LocalQuickFix {
class RemoveSuppressWarningAction extends PsiUpdateModCommandQuickFix {
private static final Logger LOG = Logger.getInstance(RemoveSuppressWarningAction.class);
@NotNull
@@ -44,42 +45,39 @@ class RemoveSuppressWarningAction implements LocalQuickFix {
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiElement element = descriptor.getPsiElement();
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
try {
if (element != null) {
if (element instanceof PsiComment) {
removeFromComment((PsiComment)element);
}
else {
PsiModifierListOwner commentOwner = PsiTreeUtil.getParentOfType(element, PsiModifierListOwner.class, false);
if (commentOwner != null) {
PsiElement psiElement = JavaSuppressionUtil.getElementMemberSuppressedIn(commentOwner, myID);
if (psiElement instanceof PsiAnnotation) {
removeFromAnnotation((PsiAnnotation)psiElement, commentOwner);
}
else if (psiElement instanceof PsiDocComment) {
removeFromJavaDoc((PsiDocComment)psiElement);
}
else { //try to remove from all comments
Set<PsiComment> comments = new HashSet<>();
commentOwner.accept(new PsiRecursiveElementWalkingVisitor() {
@Override
public void visitComment(@NotNull PsiComment comment) {
super.visitComment(comment);
if (comment.getText().contains(myID)) {
comments.add(comment);
}
}
});
for (PsiComment comment : comments) {
try {
removeFromComment(comment);
}
catch (IncorrectOperationException e) {
LOG.error(e);
if (element instanceof PsiComment comment) {
removeFromComment(comment);
}
else {
PsiModifierListOwner commentOwner = PsiTreeUtil.getParentOfType(element, PsiModifierListOwner.class, false);
if (commentOwner != null) {
PsiElement psiElement = JavaSuppressionUtil.getElementMemberSuppressedIn(commentOwner, myID);
if (psiElement instanceof PsiAnnotation annotation) {
removeFromAnnotation(annotation, commentOwner);
}
else if (psiElement instanceof PsiDocComment docComment) {
removeFromJavaDoc(docComment);
}
else { //try to remove from all comments
Set<PsiComment> comments = new HashSet<>();
commentOwner.accept(new PsiRecursiveElementWalkingVisitor() {
@Override
public void visitComment(@NotNull PsiComment comment) {
super.visitComment(comment);
if (comment.getText().contains(myID)) {
comments.add(comment);
}
}
});
for (PsiComment comment : comments) {
try {
removeFromComment(comment);
}
catch (IncorrectOperationException e) {
LOG.error(e);
}
}
}
}
@@ -156,10 +154,11 @@ class RemoveSuppressWarningAction implements LocalQuickFix {
@Nullable
private String removeFromElementText(PsiElement @NotNull ... elements) {
String text = "";
StringBuilder textBuilder = new StringBuilder();
for (PsiElement element : elements) {
text += StringUtil.trimStart(element.getText(), "//").trim();
textBuilder.append(StringUtil.trimStart(element.getText(), "//").trim());
}
String text = textBuilder.toString();
text = StringUtil.trimStart(text, "@").trim();
int secondCommentIdx = text.indexOf("//");
if (secondCommentIdx > 0) {
@@ -2,7 +2,7 @@
package com.intellij.codeInspection;
import com.intellij.java.analysis.JavaAnalysisBundle;
import com.intellij.openapi.project.Project;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import org.jetbrains.annotations.NonNls;
@@ -55,25 +55,19 @@ public final class StringTokenizerDelimiterInspection extends AbstractBaseJavaLo
final Set<Character> chars = new HashSet<>();
for (char c : delimiters.toCharArray()) {
if (!chars.add(c)) {
holder.registerProblem(delimiterArgument, JavaAnalysisBundle.message("delimiters.argument.contains.duplicated.characters"),
new ReplaceDelimitersWithUnique(delimiterArgument));
holder.problem(delimiterArgument, JavaAnalysisBundle.message("delimiters.argument.contains.duplicated.characters"))
.fix(new ReplaceDelimitersWithUnique(literal)).register();
return;
}
}
}
}
private final static class ReplaceDelimitersWithUnique extends LocalQuickFixOnPsiElement {
ReplaceDelimitersWithUnique(@NotNull PsiElement element) {
private final static class ReplaceDelimitersWithUnique extends PsiUpdateModCommandAction<PsiLiteralExpression> {
ReplaceDelimitersWithUnique(@NotNull PsiLiteralExpression element) {
super(element);
}
@NotNull
@Override
public String getText() {
return getFamilyName();
}
@NotNull
@Override
public String getFamilyName() {
@@ -81,16 +75,14 @@ public final class StringTokenizerDelimiterInspection extends AbstractBaseJavaLo
}
@Override
public void invoke(@NotNull Project project, @NotNull PsiFile file, @NotNull PsiElement startElement, @NotNull PsiElement endElement) {
protected void invoke(@NotNull ActionContext context, @NotNull PsiLiteralExpression delimiterArgument, @NotNull ModPsiUpdater updater) {
final Set<Character> uniqueChars = new LinkedHashSet<>();
final PsiLiteralExpression delimiterArgument = (PsiLiteralExpression)startElement;
final Object literal = delimiterArgument.getValue();
if(!(literal instanceof String)) return;
for (char c : ((String)literal).toCharArray()) {
if(!(delimiterArgument.getValue() instanceof String value)) return;
for (char c : value.toCharArray()) {
uniqueChars.add(c);
}
final String newDelimiters = StringUtil.join(uniqueChars, "");
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(context.project());
delimiterArgument.replace(elementFactory.createExpressionFromText('"' + StringUtil.escapeStringCharacters(newDelimiters) + '"', null));
}
}
@@ -2,6 +2,7 @@
package com.intellij.codeInspection;
import com.intellij.java.JavaBundle;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
@@ -46,7 +47,7 @@ public class SuspiciousReturnByteInputStreamInspection extends AbstractBaseJavaL
};
}
private static class ConvertToUnsignedByteFix implements LocalQuickFix {
private static class ConvertToUnsignedByteFix extends PsiUpdateModCommandQuickFix {
@Override
public @NotNull String getFamilyName() {
@@ -54,8 +55,8 @@ public class SuspiciousReturnByteInputStreamInspection extends AbstractBaseJavaL
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
if (!(descriptor.getPsiElement() instanceof PsiExpression expression)) {
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
if (!(element instanceof PsiExpression expression)) {
return;
}
CommentTracker tracker = new CommentTracker();
@@ -279,7 +279,7 @@ public abstract class DataFlowInspectionBase extends AbstractBaseJavaLocalInspec
}
reporter.registerProblem(expression,
JavaAnalysisBundle.message("dataflow.message.redundant.instanceof"),
new RedundantInstanceofFix(expression));
new RedundantInstanceofFix(expression).asQuickFix());
});
}
@@ -1,24 +1,9 @@
/*
* 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.
*/
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection.dataFlow.fix;
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
import com.intellij.codeInspection.PsiUpdateModCommandAction;
import com.intellij.java.analysis.JavaAnalysisBundle;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.util.PsiUtil;
@@ -26,10 +11,9 @@ import com.intellij.util.ArrayUtil;
import com.siyeh.ig.psiutils.BoolUtils;
import com.siyeh.ig.psiutils.CommentTracker;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class RedundantInstanceofFix extends LocalQuickFixAndIntentionActionOnPsiElement {
public RedundantInstanceofFix(@Nullable PsiElement element) {
public class RedundantInstanceofFix extends PsiUpdateModCommandAction<PsiElement> {
public RedundantInstanceofFix(@NotNull PsiElement element) {
super(element);
}
@@ -40,40 +24,33 @@ public class RedundantInstanceofFix extends LocalQuickFixAndIntentionActionOnPsi
}
@Override
public @NotNull String getText() {
return getFamilyName();
}
@Override
public void invoke(@NotNull Project project,
@NotNull PsiFile file,
@Nullable Editor editor,
@NotNull PsiElement startElement, @NotNull PsiElement endElement) {
PsiElement psiElement = startElement;
protected void invoke(@NotNull ActionContext context, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
PsiElement psiElement = element;
CommentTracker ct = new CommentTracker();
JavaCodeStyleManager javaCodeStyleManager = JavaCodeStyleManager.getInstance(context.project());
if (psiElement instanceof PsiMethodReferenceExpression) {
String replacement = CommonClassNames.JAVA_UTIL_OBJECTS + "::nonNull";
JavaCodeStyleManager.getInstance(project).shortenClassReferences(ct.replaceAndRestoreComments(psiElement, replacement));
javaCodeStyleManager.shortenClassReferences(ct.replaceAndRestoreComments(psiElement, replacement));
return;
}
String nonNullExpression = null;
if (psiElement instanceof PsiInstanceOfExpression) {
nonNullExpression = ct.text(((PsiInstanceOfExpression)psiElement).getOperand());
if (psiElement instanceof PsiInstanceOfExpression instanceOf) {
nonNullExpression = ct.text(instanceOf.getOperand());
}
else if (psiElement instanceof PsiMethodCallExpression) {
PsiExpression arg = ArrayUtil.getFirstElement(((PsiMethodCallExpression)psiElement).getArgumentList().getExpressions());
else if (psiElement instanceof PsiMethodCallExpression call) {
PsiExpression arg = ArrayUtil.getFirstElement(call.getArgumentList().getExpressions());
if (arg == null) return;
nonNullExpression = ct.text(arg);
}
if (nonNullExpression == null) return;
PsiElement parent = PsiUtil.skipParenthesizedExprUp(psiElement.getParent());
String replacement;
if (parent instanceof PsiExpression && BoolUtils.isNegation((PsiExpression)parent)) {
if (parent instanceof PsiExpression expression && BoolUtils.isNegation(expression)) {
replacement = nonNullExpression + "==null";
psiElement = parent;
} else {
replacement = nonNullExpression + "!=null";
}
JavaCodeStyleManager.getInstance(project).shortenClassReferences(ct.replaceAndRestoreComments(psiElement, replacement));
javaCodeStyleManager.shortenClassReferences(ct.replaceAndRestoreComments(psiElement, replacement));
}
}
@@ -1,10 +1,10 @@
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection.dataFlow.fix;
import com.intellij.codeInspection.CommonQuickFixBundle;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.PsiUpdateModCommandQuickFix;
import com.intellij.java.analysis.JavaAnalysisBundle;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.psi.JavaTokenType;
import com.intellij.psi.PsiElement;
@@ -16,7 +16,7 @@ import com.siyeh.ig.PsiReplacementUtil;
import com.siyeh.ig.psiutils.CommentTracker;
import org.jetbrains.annotations.NotNull;
public class ReplaceWithBooleanEqualsFix implements LocalQuickFix {
public class ReplaceWithBooleanEqualsFix extends PsiUpdateModCommandQuickFix {
private final String myOldExprText;
private final boolean myFalseIsAcceptable;
@@ -37,8 +37,8 @@ public class ReplaceWithBooleanEqualsFix implements LocalQuickFix {
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiElement qualifier = ObjectUtils.tryCast(descriptor.getPsiElement(), PsiExpression.class);
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
PsiElement qualifier = ObjectUtils.tryCast(element, PsiExpression.class);
if (qualifier == null) return;
if (myFalseIsAcceptable) {
qualifier = qualifier.getParent();
@@ -1,24 +1,10 @@
/*
* 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.
*/
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection.dataFlow.fix;
import com.intellij.codeInspection.CommonQuickFixBundle;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.PsiUpdateModCommandQuickFix;
import com.intellij.java.analysis.JavaAnalysisBundle;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.refactoring.extractMethod.ExtractMethodUtil;
@@ -26,7 +12,7 @@ import com.intellij.util.ObjectUtils;
import com.siyeh.ig.psiutils.CommentTracker;
import org.jetbrains.annotations.NotNull;
public class ReplaceWithConstantValueFix implements LocalQuickFix {
public class ReplaceWithConstantValueFix extends PsiUpdateModCommandQuickFix {
private final String myPresentableName;
private final String myReplacementText;
@@ -48,10 +34,7 @@ public class ReplaceWithConstantValueFix implements LocalQuickFix {
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiElement problemElement = descriptor.getPsiElement();
if (problemElement == null) return;
protected void applyFix(@NotNull Project project, @NotNull PsiElement problemElement, @NotNull ModPsiUpdater updater) {
PsiMethodCallExpression call = problemElement.getParent() instanceof PsiExpressionList &&
problemElement.getParent().getParent() instanceof PsiMethodCallExpression ?
(PsiMethodCallExpression)problemElement.getParent().getParent() :
@@ -1,9 +1,9 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection.dataFlow.fix;
import com.intellij.codeInspection.CommonQuickFixBundle;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.PsiUpdateModCommandQuickFix;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
@@ -16,7 +16,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.Objects;
public final class ReplaceWithObjectsEqualsFix implements LocalQuickFix {
public final class ReplaceWithObjectsEqualsFix extends PsiUpdateModCommandQuickFix {
private final String myQualifierText;
private final String myReplacementText;
@@ -40,8 +40,8 @@ public final class ReplaceWithObjectsEqualsFix implements LocalQuickFix {
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiMethodCallExpression call = PsiTreeUtil.getParentOfType(descriptor.getPsiElement(), PsiMethodCallExpression.class);
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
PsiMethodCallExpression call = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class);
if (call == null) return;
PsiExpression[] args = call.getArgumentList().getExpressions();
@@ -1,29 +1,15 @@
/*
* 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.
*/
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection.dataFlow.fix;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.PsiUpdateModCommandQuickFix;
import com.intellij.java.analysis.JavaAnalysisBundle;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
public class SimplifyToAssignmentFix implements LocalQuickFix {
public class SimplifyToAssignmentFix extends PsiUpdateModCommandQuickFix {
@NotNull
@Override
public String getFamilyName() {
@@ -31,10 +17,7 @@ public class SimplifyToAssignmentFix implements LocalQuickFix {
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiElement psiElement = descriptor.getPsiElement();
if (psiElement == null) return;
protected void applyFix(@NotNull Project project, @NotNull PsiElement psiElement, @NotNull ModPsiUpdater updater) {
final PsiAssignmentExpression assignmentExpression = PsiTreeUtil.getParentOfType(psiElement, PsiAssignmentExpression.class);
if (assignmentExpression == null) {
return;
@@ -1,33 +1,16 @@
/*
* 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.
*/
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection.dataFlow.fix;
import com.intellij.codeInsight.intention.FileModifier;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.PsiUpdateModCommandQuickFix;
import com.intellij.java.analysis.JavaAnalysisBundle;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class SurroundWithRequireNonNullFix implements LocalQuickFix {
public class SurroundWithRequireNonNullFix extends PsiUpdateModCommandQuickFix {
private final String myText;
private final SmartPsiElementPointer<PsiExpression> myQualifierPointer;
@@ -52,18 +35,11 @@ public class SurroundWithRequireNonNullFix implements LocalQuickFix {
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiExpression qualifier = myQualifierPointer.getElement();
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
PsiExpression qualifier = updater.getWritable(myQualifierPointer.getElement());
if (qualifier == null) return;
PsiExpression replacement = JavaPsiFacade.getElementFactory(project)
.createExpressionFromText("java.util.Objects.requireNonNull(" + qualifier.getText() + ")", qualifier);
JavaCodeStyleManager.getInstance(project).shortenClassReferences(qualifier.replace(replacement));
}
@Override
public @Nullable FileModifier getFileModifierForPreview(@NotNull PsiFile target) {
PsiExpression expression = myQualifierPointer.getElement();
if (expression == null) return null;
return new SurroundWithRequireNonNullFix(PsiTreeUtil.findSameElementInCopy(expression, target));
}
}
@@ -4,6 +4,7 @@ package com.intellij.codeInspection.miscGenerics;
import com.intellij.codeInspection.*;
import com.intellij.codeInspection.compiler.JavacQuirksInspectionVisitor;
import com.intellij.java.analysis.JavaAnalysisBundle;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
@@ -161,7 +162,7 @@ public class RedundantTypeArgsInspection extends GenericsInspectionToolBase {
}
}
private static class MyQuickFixAction implements LocalQuickFix {
private static class MyQuickFixAction extends PsiUpdateModCommandQuickFix {
@Override
@NotNull
public String getFamilyName() {
@@ -169,8 +170,7 @@ public class RedundantTypeArgsInspection extends GenericsInspectionToolBase {
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiElement element = descriptor.getPsiElement();
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
if (!(element instanceof PsiReferenceParameterList typeArgumentList)) return;
try {
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
@@ -6,12 +6,16 @@ import com.intellij.codeInsight.daemon.JavaErrorBundle;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
import com.intellij.codeInsight.javadoc.JavaDocUtil;
import com.intellij.codeInspection.*;
import com.intellij.codeInspection.AbstractBaseJavaLocalInspectionTool;
import com.intellij.codeInspection.ProblemHighlightType;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.codeInspection.PsiUpdateModCommandQuickFix;
import com.intellij.codeInspection.deadCode.UnusedDeclarationInspectionBase;
import com.intellij.codeInspection.util.IntentionFamilyName;
import com.intellij.codeInspection.util.IntentionName;
import com.intellij.java.analysis.JavaAnalysisBundle;
import com.intellij.lang.jvm.JvmModifier;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.diagnostic.Attachment;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
@@ -133,7 +137,7 @@ public final class RedundantThrowsDeclarationLocalInspection extends AbstractBas
});
}
static final class RedundantThrowsQuickFix implements LocalQuickFix {
static final class RedundantThrowsQuickFix extends PsiUpdateModCommandQuickFix {
@NotNull private final String myMethodName;
@NotNull private final String myExceptionName;
@@ -154,8 +158,7 @@ public final class RedundantThrowsDeclarationLocalInspection extends AbstractBas
}
@Override
public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) {
final PsiElement elem = descriptor.getPsiElement();
protected void applyFix(@NotNull Project project, @NotNull PsiElement elem, @NotNull ModPsiUpdater updater) {
if (!(elem instanceof PsiJavaCodeReferenceElement)) return;
final PsiElement maybeMethod = PsiTreeUtil.skipParentsOfType(elem, PsiReferenceList.class);
@@ -3,9 +3,9 @@ package com.intellij.codeInspection.enhancedSwitch;
import com.intellij.codeInsight.daemon.impl.analysis.HighlightingFeature;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.codeInspection.PsiUpdateModCommandQuickFix;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
@@ -65,7 +65,7 @@ public class RedundantLabeledSwitchRuleCodeBlockInspection extends LocalInspecti
return null;
}
private static class UnwrapCodeBlockFix implements LocalQuickFix {
private static class UnwrapCodeBlockFix extends PsiUpdateModCommandQuickFix {
@Nls(capitalization = Nls.Capitalization.Sentence)
@NotNull
@Override
@@ -74,8 +74,8 @@ public class RedundantLabeledSwitchRuleCodeBlockInspection extends LocalInspecti
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiBlockStatement body = PsiTreeUtil.getParentOfType(descriptor.getStartElement(), PsiBlockStatement.class);
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
PsiBlockStatement body = PsiTreeUtil.getParentOfType(element, PsiBlockStatement.class);
if (body != null && body.getParent() instanceof PsiSwitchLabeledRuleStatement) {
PsiStatement bodyStatement = getSingleStatement(body.getCodeBlock());
if (bodyStatement instanceof PsiYieldStatement) {
@@ -3,9 +3,9 @@ package com.intellij.codeInspection.enhancedSwitch;
import com.intellij.codeInsight.daemon.impl.analysis.HighlightingFeature;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.codeInspection.PsiUpdateModCommandQuickFix;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
@@ -62,7 +62,7 @@ public class SwitchLabeledRuleCanBeCodeBlockInspection extends LocalInspectionTo
};
}
private static class WrapWithCodeBlockFix implements LocalQuickFix {
private static class WrapWithCodeBlockFix extends PsiUpdateModCommandQuickFix {
private final @Nls String myMessage;
WrapWithCodeBlockFix(boolean isResultExpression) {
@@ -78,8 +78,7 @@ public class SwitchLabeledRuleCanBeCodeBlockInspection extends LocalInspectionTo
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiElement element = descriptor.getStartElement();
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
if (element instanceof PsiKeyword) {
element = element.getParent();
}
@@ -87,8 +86,8 @@ public class SwitchLabeledRuleCanBeCodeBlockInspection extends LocalInspectionTo
PsiSwitchBlock switchBlock = rule.getEnclosingSwitchBlock();
PsiStatement body = rule.getBody();
if (switchBlock instanceof PsiSwitchExpression && body instanceof PsiExpressionStatement) {
wrapExpression((PsiExpressionStatement)body);
if (switchBlock instanceof PsiSwitchExpression && body instanceof PsiExpressionStatement statement) {
wrapExpression(statement);
}
else if (body != null) {
wrapStatement(body);
@@ -3,10 +3,10 @@ package com.intellij.codeInspection.intermediaryVariable;
import com.intellij.codeInsight.daemon.impl.analysis.HighlightControlFlowUtil;
import com.intellij.codeInspection.AbstractBaseJavaLocalInspectionTool;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.codeInspection.PsiUpdateModCommandQuickFix;
import com.intellij.java.JavaBundle;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
@@ -17,8 +17,10 @@ import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.util.CommonJavaInlineUtil;
import com.intellij.util.CommonJavaRefactoringUtil;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
import com.siyeh.ig.psiutils.*;
import com.siyeh.ig.psiutils.CommentTracker;
import com.siyeh.ig.psiutils.ExpressionUtils;
import com.siyeh.ig.psiutils.SwitchUtils;
import com.siyeh.ig.psiutils.VariableAccessUtils;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
@@ -38,7 +40,7 @@ public final class ReturnSeparatedFromComputationInspection extends AbstractBase
super.visitReturnStatement(returnStatement);
final ReturnContext context = createReturnContext(returnStatement);
if (context != null && isApplicable(context)) {
registerProblem(holder, returnStatement, context.returnedVariable, isOnTheFly);
registerProblem(holder, returnStatement, context.returnedVariable);
}
}
};
@@ -165,7 +167,7 @@ public final class ReturnSeparatedFromComputationInspection extends AbstractBase
return !mover.isEmpty();
}
private static void doApply(PsiReturnStatement returnStatement, boolean isOnTheFly) {
private static void doApply(PsiReturnStatement returnStatement, @NotNull ModPsiUpdater updater) {
ReturnContext context = createReturnContext(returnStatement);
if (context != null) {
ControlFlow flow = createControlFlow(context);
@@ -173,20 +175,14 @@ public final class ReturnSeparatedFromComputationInspection extends AbstractBase
Mover mover = new Mover(flow, context.refactoredStatement, context.returnedVariable, context.returnType, false);
boolean removeReturn = mover.moveTo(context.refactoredStatement, true);
if (!mover.isEmpty()) {
Highlighter highlighter = new Highlighter();
applyChanges(mover, context, removeReturn, highlighter);
deleteRedundantVariable(context, highlighter);
if (isOnTheFly) {
highlighter.highlight();
}
applyChanges(mover, context, removeReturn, updater);
deleteRedundantVariable(context, updater);
}
}
}
}
private static void deleteRedundantVariable(@NotNull ReturnContext context, Highlighter highlighter) {
private static void deleteRedundantVariable(@NotNull ReturnContext context, @NotNull ModPsiUpdater updater) {
PsiExpression value = PsiUtil.skipParenthesizedExprDown(context.returnedVariable.getInitializer());
boolean isConstant = value instanceof PsiLiteralExpression || value instanceof PsiThisExpression || PsiUtil.isConstantExpression(value);
@@ -209,7 +205,7 @@ public final class ReturnSeparatedFromComputationInspection extends AbstractBase
for (PsiJavaCodeReferenceElement usage : usages) {
PsiExpression inlined = CommonJavaInlineUtil.getInstance().inlineVariable(context.returnedVariable, value, usage, null);
if (firstInlined == null) firstInlined = inlined;
highlighter.add(inlined);
updater.highlight(inlined);
}
}
if (isSimple || isSingleUsage || usages.isEmpty()) {
@@ -239,17 +235,20 @@ public final class ReturnSeparatedFromComputationInspection extends AbstractBase
expression instanceof PsiClassObjectAccessExpression;
}
private static void applyChanges(@NotNull Mover mover, @NotNull ReturnContext context, boolean removeReturn, Highlighter highlighter) {
private static void applyChanges(@NotNull Mover mover,
@NotNull ReturnContext context,
boolean removeReturn,
@NotNull ModPsiUpdater updater) {
for (PsiElement anchor : mover.insertBefore) {
PsiElement added = anchor.getParent().addBefore(context.returnStatement, anchor);
highlighter.add(added);
updater.highlight(added);
}
mover.replaceInline.forEach(e -> {
if (e instanceof PsiBreakStatement) {
replaceStatementKeepComments((PsiBreakStatement)e, context.returnStatement, highlighter);
if (e instanceof PsiBreakStatement breakStatement) {
replaceStatementKeepComments(breakStatement, context.returnStatement, updater);
}
else if (e instanceof PsiAssignmentExpression) {
inlineAssignment((PsiAssignmentExpression)e, context.returnStatement, highlighter);
else if (e instanceof PsiAssignmentExpression assignment) {
inlineAssignment(assignment, context.returnStatement, updater);
}
});
mover.removeCompletely.forEach(e -> removeElementKeepComments(e));
@@ -267,7 +266,7 @@ public final class ReturnSeparatedFromComputationInspection extends AbstractBase
private static void inlineAssignment(PsiAssignmentExpression assignmentExpression,
PsiReturnStatement returnStatement,
Highlighter highlighter) {
@NotNull ModPsiUpdater updater) {
PsiElement assignmentParent = assignmentExpression.getParent();
LOG.assertTrue(assignmentParent instanceof PsiExpressionStatement, "PsiExpressionStatement");
PsiReturnStatement returnStatementCopy = (PsiReturnStatement)returnStatement.copy();
@@ -275,14 +274,14 @@ public final class ReturnSeparatedFromComputationInspection extends AbstractBase
PsiExpression returnValue = returnStatementCopy.getReturnValue();
if (rExpression != null && returnValue != null) {
returnValue.replace(rExpression);
replaceStatementKeepComments((PsiExpressionStatement)assignmentParent, returnStatementCopy, highlighter);
replaceStatementKeepComments((PsiExpressionStatement)assignmentParent, returnStatementCopy, updater);
}
}
private static void replaceStatementKeepComments(PsiStatement replacedStatement,
PsiReturnStatement returnStatement,
Highlighter highlighter) {
highlighter.add(new CommentTracker().replaceAndRestoreComments(replacedStatement, returnStatement));
@NotNull ModPsiUpdater updater) {
updater.highlight(new CommentTracker().replaceAndRestoreComments(replacedStatement, returnStatement));
}
private static void removeElementKeepComments(PsiElement removedElement) {
@@ -324,29 +323,29 @@ public final class ReturnSeparatedFromComputationInspection extends AbstractBase
if (checkingApplicability && !isEmpty()) {
return false; // optimization
}
if (targetStatement instanceof PsiBlockStatement) {
return moveToBlock((PsiBlockStatement)targetStatement, returnAtTheEnd);
if (targetStatement instanceof PsiBlockStatement blockStatement) {
return moveToBlock(blockStatement, returnAtTheEnd);
}
if (targetStatement instanceof PsiIfStatement) {
return moveToIf((PsiIfStatement)targetStatement);
if (targetStatement instanceof PsiIfStatement ifStatement) {
return moveToIf(ifStatement);
}
if (targetStatement instanceof PsiConditionalLoopStatement) {
return moveToConditionalLoop((PsiConditionalLoopStatement)targetStatement);
if (targetStatement instanceof PsiConditionalLoopStatement loop) {
return moveToConditionalLoop(loop);
}
if (targetStatement instanceof PsiForeachStatement) {
return moveToForeach((PsiForeachStatement)targetStatement);
if (targetStatement instanceof PsiForeachStatement foreachStatement) {
return moveToForeach(foreachStatement);
}
if (targetStatement instanceof PsiSwitchStatement) {
return moveToSwitch((PsiSwitchStatement)targetStatement);
if (targetStatement instanceof PsiSwitchStatement switchStatement) {
return moveToSwitch(switchStatement);
}
if (targetStatement instanceof PsiTryStatement) {
return moveToTry((PsiTryStatement)targetStatement, returnAtTheEnd);
if (targetStatement instanceof PsiTryStatement tryStatement) {
return moveToTry(tryStatement, returnAtTheEnd);
}
if (targetStatement instanceof PsiLabeledStatement) {
return moveToLabeled((PsiLabeledStatement)targetStatement, returnAtTheEnd);
if (targetStatement instanceof PsiLabeledStatement labeledStatement) {
return moveToLabeled(labeledStatement, returnAtTheEnd);
}
if (targetStatement instanceof PsiExpressionStatement) {
return inlineExpression((PsiExpressionStatement)targetStatement);
if (targetStatement instanceof PsiExpressionStatement expressionStatement) {
return inlineExpression(expressionStatement);
}
if (targetStatement instanceof PsiThrowStatement ||
targetStatement instanceof PsiReturnStatement ||
@@ -389,17 +388,17 @@ public final class ReturnSeparatedFromComputationInspection extends AbstractBase
}
private boolean moveToConditionalLoop(@NotNull PsiConditionalLoopStatement loop) {
moveToBreaks(loop, false);
moveToBreaks(loop);
return isAlwaysTrue(loop.getCondition(), loop instanceof PsiForStatement);
}
private boolean moveToForeach(@NotNull PsiForeachStatement targetStatement) {
moveToBreaks(targetStatement, false);
moveToBreaks(targetStatement);
return false;
}
private boolean moveToSwitch(@NotNull PsiSwitchStatement targetStatement) {
moveToBreaks(targetStatement, false);
moveToBreaks(targetStatement);
PsiCodeBlock body = targetStatement.getBody();
return body != null && moveToBlockBody(body, false) && hasTotalSwitchLabel(body);
}
@@ -429,7 +428,7 @@ public final class ReturnSeparatedFromComputationInspection extends AbstractBase
if (statement == null) {
return false;
}
moveToBreaks(statement, false);
moveToBreaks(statement);
return moveTo(statement, returnAtTheEnd);
}
@@ -451,11 +450,11 @@ public final class ReturnSeparatedFromComputationInspection extends AbstractBase
return false;
}
private void moveToBreaks(@NotNull PsiStatement targetStatement, boolean returnAtTheEnd) {
private void moveToBreaks(@NotNull PsiStatement targetStatement) {
Set<PsiBreakStatement> breaks = getBreaks(targetStatement);
for (PsiBreakStatement breakStatement : breaks) {
PsiStatement prevNonEmptyStatement = getPrevNonEmptyStatement(breakStatement, removeCompletely);
if (prevNonEmptyStatement == null || !moveTo(prevNonEmptyStatement, returnAtTheEnd)) {
if (prevNonEmptyStatement == null || !moveTo(prevNonEmptyStatement, false)) {
replaceInline.add(breakStatement);
}
else {
@@ -527,20 +526,18 @@ public final class ReturnSeparatedFromComputationInspection extends AbstractBase
private static void registerProblem(@NotNull ProblemsHolder holder,
@NotNull PsiReturnStatement returnStatement,
@NotNull PsiVariable variable, boolean isOnTheFly) {
@NotNull PsiVariable variable) {
String name = variable.getName();
holder.registerProblem(returnStatement,
JavaBundle.message("inspection.return.separated.from.computation.descriptor", name),
new VariableFix(name, isOnTheFly));
new VariableFix(name));
}
private static class VariableFix implements LocalQuickFix {
private static class VariableFix extends PsiUpdateModCommandQuickFix {
private final String myName;
private final boolean myIsOnTheFly;
VariableFix(String name, boolean isOnTheFly) {
VariableFix(String name) {
myName = name;
myIsOnTheFly = isOnTheFly;
}
@Nls
@@ -558,10 +555,9 @@ public final class ReturnSeparatedFromComputationInspection extends AbstractBase
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiElement element = descriptor.getPsiElement();
if (element instanceof PsiReturnStatement) {
doApply((PsiReturnStatement)element, myIsOnTheFly);
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
if (element instanceof PsiReturnStatement returnStatement) {
doApply(returnStatement, updater);
}
}
}
@@ -573,24 +569,4 @@ public final class ReturnSeparatedFromComputationInspection extends AbstractBase
@NotNull PsiVariable returnedVariable,
@NotNull PsiCodeBlock variableScope) {
}
private static class Highlighter {
private final List<PsiElement> myElements = new ArrayList<>();
public void add(@NotNull PsiElement element) {
if (element instanceof PsiReturnStatement) {
PsiExpression value = ((PsiReturnStatement)element).getReturnValue();
if (value != null) {
myElements.add(value);
return;
}
}
myElements.add(element);
}
public void highlight() {
List<PsiElement> validElements = ContainerUtil.filter(myElements, PsiElement::isValid);
HighlightUtils.highlightElements(validElements);
}
}
}
@@ -3,9 +3,10 @@ package com.intellij.codeInspection.sillyAssignment;
import com.intellij.codeInspection.AbstractBaseJavaLocalInspectionTool;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.codeInspection.PsiUpdateModCommandQuickFix;
import com.intellij.java.JavaBundle;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
@@ -132,7 +133,7 @@ public class SillyAssignmentInspection extends AbstractBaseJavaLocalInspectionTo
return rExpression;
}
private static class RemoveSillyAssignmentFix implements LocalQuickFix {
private static class RemoveSillyAssignmentFix extends PsiUpdateModCommandQuickFix {
@Nls
@NotNull
@@ -142,8 +143,8 @@ public class SillyAssignmentInspection extends AbstractBaseJavaLocalInspectionTo
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiExpression expression = ObjectUtils.tryCast(descriptor.getPsiElement(), PsiExpression.class);
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
final PsiExpression expression = ObjectUtils.tryCast(element, PsiExpression.class);
if (!(getArrayExpressionOrItself(expression) instanceof PsiReferenceExpression)) {
return;
}
@@ -1,13 +1,11 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection.streamMigration;
import com.intellij.codeInsight.intention.FileModifier;
import com.intellij.codeInsight.intention.HighPriorityAction;
import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
import com.intellij.codeInsight.intention.PriorityAction;
import com.intellij.codeInspection.*;
import com.intellij.java.JavaBundle;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.editor.Editor;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.FileIndexFacade;
import com.intellij.openapi.util.TextRange;
@@ -18,7 +16,6 @@ import com.intellij.psi.impl.light.LightElement;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.IncorrectOperationException;
import com.siyeh.ig.callMatcher.CallMatcher;
import com.siyeh.ig.psiutils.CommentTracker;
import org.jetbrains.annotations.Nls;
@@ -199,7 +196,7 @@ public class SimplifyForEachInspection extends AbstractBaseJavaLocalInspectionTo
}
}
public static class SimplifyForEachFix implements LocalQuickFix {
public static class SimplifyForEachFix extends PsiUpdateModCommandQuickFix {
@NotNull private final @Nls String myCustomName;
protected SimplifyForEachFix(@NotNull @Nls String customName) {
@@ -220,8 +217,8 @@ public class SimplifyForEachInspection extends AbstractBaseJavaLocalInspectionTo
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiExpressionStatement statement = tryCast(descriptor.getPsiElement(), PsiExpressionStatement.class);
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
PsiExpressionStatement statement = tryCast(element, PsiExpressionStatement.class);
if (statement == null) return;
PsiMethodCallExpression call = tryCast(statement.getExpression(), PsiMethodCallExpression.class);
if (call == null) return;
@@ -233,23 +230,28 @@ public class SimplifyForEachInspection extends AbstractBaseJavaLocalInspectionTo
}
}
public static class ForEachNonFinalFix extends PsiElementBaseIntentionAction implements HighPriorityAction {
public static class ForEachNonFinalFix extends PsiUpdateModCommandAction<PsiElement> {
private final @Nullable PsiElement myContext;
private final @Nls String myMessage;
public ForEachNonFinalFix(@Nullable PsiElement context) {
super(PsiElement.class);
SimplifyForEachContext simplifyContext = findMigration(context);
if (simplifyContext == null) {
myContext = null;
myMessage = null;
}
else {
myContext = context;
setText(JavaBundle.message("quickfix.text.avoid.mutation.using.stream.api.0.operation", simplifyContext.myMigration.getReplacement()));
myMessage =
JavaBundle.message("quickfix.text.avoid.mutation.using.stream.api.0.operation", simplifyContext.myMigration.getReplacement());
}
}
@Override
public @Nullable FileModifier getFileModifierForPreview(@NotNull PsiFile target) {
return new ForEachNonFinalFix(PsiTreeUtil.findSameElementInCopy(myContext, target));
protected @Nullable Presentation getPresentation(@NotNull ActionContext context, @NotNull PsiElement element) {
return myContext == null || !myContext.isValid() ? null :
Presentation.of(myMessage).withPriority(PriorityAction.Priority.HIGH);
}
private static SimplifyForEachContext findMigration(@Nullable PsiElement context) {
@@ -267,23 +269,18 @@ public class SimplifyForEachInspection extends AbstractBaseJavaLocalInspectionTo
}
@Override
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
protected void invoke(@NotNull ActionContext context, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
PsiMethodCallExpression call =
PsiTreeUtil.getParentOfType(PsiTreeUtil.getParentOfType(element, PsiLambdaExpression.class), PsiMethodCallExpression.class);
SimplifyForEachContext simplifyForEachContext = SimplifyForEachContext.from(call);
if (simplifyForEachContext != null) {
PsiElement result = simplifyForEachContext.migrate();
if (result != null) {
MigrateToStreamFix.simplify(project, result);
MigrateToStreamFix.simplify(context.project(), result);
}
}
}
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
return myContext != null && myContext.isValid();
}
@Nls
@NotNull
@Override
@@ -7,6 +7,7 @@ import com.intellij.codeInspection.redundantCast.RemoveRedundantCastUtil;
import com.intellij.codeInspection.util.InspectionMessage;
import com.intellij.codeInspection.util.IntentionName;
import com.intellij.java.JavaBundle;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.diagnostic.Attachment;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
@@ -243,7 +244,7 @@ public class StreamToLoopInspection extends AbstractBaseJavaLocalInspectionTool
return null;
}
static class ReplaceStreamWithLoopFix implements LocalQuickFix {
static class ReplaceStreamWithLoopFix extends PsiUpdateModCommandQuickFix {
private final @IntentionName String myMessage;
ReplaceStreamWithLoopFix(@IntentionName String message) {
@@ -263,8 +264,7 @@ public class StreamToLoopInspection extends AbstractBaseJavaLocalInspectionTool
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiElement element = descriptor.getStartElement();
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
if(!(element instanceof PsiMethodCallExpression terminalCall)) return;
CodeBlockSurrounder surrounder = CodeBlockSurrounder.forExpression(terminalCall);
if (surrounder == null) return;
@@ -1,19 +1,16 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.codeInspection.CommonQuickFixBundle;
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
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.codeInspection.PsiUpdateModCommandAction;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.psi.PsiReceiverParameter;
import com.siyeh.ig.psiutils.CommentTracker;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class ReceiverParameterNameFix extends LocalQuickFixAndIntentionActionOnPsiElement {
public class ReceiverParameterNameFix extends PsiUpdateModCommandAction<PsiReceiverParameter> {
private final String myNewName;
public ReceiverParameterNameFix(@NotNull PsiReceiverParameter parameter, @NotNull String newName) {
@@ -22,9 +19,8 @@ public class ReceiverParameterNameFix extends LocalQuickFixAndIntentionActionOnP
}
@Override
@NotNull
public String getText() {
return CommonQuickFixBundle.message("fix.replace.with.x", myNewName);
protected @Nullable Presentation getPresentation(@NotNull ActionContext context, @NotNull PsiReceiverParameter element) {
return Presentation.of(CommonQuickFixBundle.message("fix.replace.with.x", myNewName));
}
@NotNull
@@ -34,12 +30,8 @@ public class ReceiverParameterNameFix extends LocalQuickFixAndIntentionActionOnP
}
@Override
public void invoke(@NotNull Project project,
@NotNull PsiFile file,
@Nullable Editor editor,
@NotNull PsiElement startElement,
@NotNull PsiElement endElement) {
protected void invoke(@NotNull ActionContext context, @NotNull PsiReceiverParameter receiver, @NotNull ModPsiUpdater updater) {
CommentTracker ct = new CommentTracker();
ct.replaceExpressionAndRestoreComments(((PsiReceiverParameter)startElement).getIdentifier(), myNewName);
ct.replaceExpressionAndRestoreComments(receiver.getIdentifier(), myNewName);
}
}
@@ -1,24 +1,9 @@
/*
* Copyright 2000-2011 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.
*/
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.codeInsight.daemon.impl.actions.IntentionActionWithFixAllOption;
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
import com.intellij.openapi.editor.Editor;
import com.intellij.codeInspection.PsiUpdateModCommandAction;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
@@ -26,29 +11,24 @@ import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class ReplaceInaccessibleFieldWithGetterSetterFix extends LocalQuickFixAndIntentionActionOnPsiElement
implements IntentionActionWithFixAllOption {
public class ReplaceInaccessibleFieldWithGetterSetterFix extends PsiUpdateModCommandAction<PsiReferenceExpression> {
private final String myMethodName;
private final boolean myIsSetter;
public ReplaceInaccessibleFieldWithGetterSetterFix(@NotNull PsiElement element, @NotNull PsiMethod getter, boolean isSetter) {
public ReplaceInaccessibleFieldWithGetterSetterFix(@NotNull PsiReferenceExpression element, @NotNull PsiMethod getter, boolean isSetter) {
super(element);
myMethodName = getter.getName();
myIsSetter = isSetter;
}
@Override
public void invoke(@NotNull Project project,
@NotNull PsiFile file,
@Nullable Editor editor,
@NotNull PsiElement startElement,
@NotNull PsiElement endElement) {
PsiReferenceExpression place = (PsiReferenceExpression)startElement;
protected void invoke(@NotNull ActionContext context, @NotNull PsiReferenceExpression place, @NotNull ModPsiUpdater updater) {
String qualifier = null;
final PsiExpression qualifierExpression = place.getQualifierExpression();
if (qualifierExpression != null) {
qualifier = qualifierExpression.getText();
}
Project project = context.project();
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
PsiMethodCallExpression callExpression;
final String call = (qualifier != null ? qualifier + "." : "") + myMethodName;
@@ -68,10 +48,10 @@ public class ReplaceInaccessibleFieldWithGetterSetterFix extends LocalQuickFixAn
}
}
@NotNull
@Override
public String getText() {
return myIsSetter ? QuickFixBundle.message("replace.with.setter") : QuickFixBundle.message("replace.with.getter");
protected @Nullable Presentation getPresentation(@NotNull ActionContext context, @NotNull PsiReferenceExpression element) {
String message = myIsSetter ? QuickFixBundle.message("replace.with.setter") : QuickFixBundle.message("replace.with.getter");
return Presentation.of(message).withFixAllOption(this);
}
@NotNull
@@ -1,31 +1,16 @@
/*
* 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.
*/
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.codeInspection.CommonQuickFixBundle;
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
import com.intellij.codeInspection.PsiUpdateModCommandAction;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class ReplacePrimitiveWithBoxedTypeAction extends LocalQuickFixAndIntentionActionOnPsiElement {
public class ReplacePrimitiveWithBoxedTypeAction extends PsiUpdateModCommandAction<PsiTypeElement> {
private final String myPrimitiveName;
private final String myBoxedTypeName;
private static final Logger LOG = Logger.getInstance(ReplacePrimitiveWithBoxedTypeAction.class);
@@ -36,12 +21,6 @@ public class ReplacePrimitiveWithBoxedTypeAction extends LocalQuickFixAndIntenti
myBoxedTypeName = boxedTypeName;
}
@NotNull
@Override
public String getText() {
return CommonQuickFixBundle.message("fix.replace.x.with.y", myPrimitiveName, myBoxedTypeName);
}
@NotNull
@Override
public String getFamilyName() {
@@ -49,41 +28,30 @@ public class ReplacePrimitiveWithBoxedTypeAction extends LocalQuickFixAndIntenti
}
@Override
public boolean isAvailable(@NotNull Project project,
@NotNull PsiFile file,
@NotNull PsiElement startElement,
@NotNull PsiElement endElement) {
if (startElement instanceof PsiTypeElement) {
PsiType type = ((PsiTypeElement)startElement).getType();
if (type instanceof PsiWildcardType) {
type = ((PsiWildcardType)type).getBound();
}
if (type instanceof PsiPrimitiveType) {
return ((PsiPrimitiveType)type).getBoxedType(startElement) != null;
}
protected @Nullable Presentation getPresentation(@NotNull ActionContext context, @NotNull PsiTypeElement typeElement) {
PsiType type = typeElement.getType();
if (type instanceof PsiWildcardType wildcardType) {
type = wildcardType.getBound();
}
return false;
if (!(type instanceof PsiPrimitiveType primitiveType) || primitiveType.getBoxedType(typeElement) == null) return null;
return Presentation.of(CommonQuickFixBundle.message("fix.replace.x.with.y", myPrimitiveName, myBoxedTypeName));
}
@Override
public void invoke(@NotNull Project project,
@NotNull PsiFile file,
@Nullable Editor editor,
@NotNull PsiElement startElement,
@NotNull PsiElement endElement) {
final PsiType type = ((PsiTypeElement)startElement).getType();
protected void invoke(@NotNull ActionContext context, @NotNull PsiTypeElement typeElement, @NotNull ModPsiUpdater updater) {
final PsiType type = typeElement.getType();
PsiType boxedType;
if (type instanceof PsiPrimitiveType) {
boxedType = ((PsiPrimitiveType)type).getBoxedType(startElement);
if (type instanceof PsiPrimitiveType primitiveType) {
boxedType = primitiveType.getBoxedType(typeElement);
} else {
LOG.assertTrue(type instanceof PsiWildcardType);
final PsiWildcardType wildcardType = (PsiWildcardType)type;
final PsiClassType boxedBound = ((PsiPrimitiveType)wildcardType.getBound()).getBoxedType(startElement);
final PsiClassType boxedBound = ((PsiPrimitiveType)wildcardType.getBound()).getBoxedType(typeElement);
LOG.assertTrue(boxedBound != null);
boxedType = wildcardType.isExtends() ? PsiWildcardType.createExtends(startElement.getManager(), boxedBound)
: PsiWildcardType.createSuper(startElement.getManager(), boxedBound);
boxedType = wildcardType.isExtends() ? PsiWildcardType.createExtends(typeElement.getManager(), boxedBound)
: PsiWildcardType.createSuper(typeElement.getManager(), boxedBound);
}
LOG.assertTrue(boxedType != null);
startElement.replace(JavaPsiFacade.getElementFactory(project).createTypeElement(boxedType));
typeElement.replace(JavaPsiFacade.getElementFactory(context.project()).createTypeElement(boxedType));
}
}
@@ -1,18 +1,17 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
import com.intellij.codeInspection.PsiUpdateModCommandAction;
import com.intellij.java.JavaBundle;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.util.NlsSafe;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.tree.JavaSharedImplUtil;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class SetVariableTypeFix extends LocalQuickFixAndIntentionActionOnPsiElement {
@SafeFieldForPreview
public class SetVariableTypeFix extends PsiUpdateModCommandAction<PsiVariable> {
private final @NotNull SmartTypePointer myTypePointer;
private final @NotNull @NlsSafe String myTypeText;
@@ -23,30 +22,25 @@ public class SetVariableTypeFix extends LocalQuickFixAndIntentionActionOnPsiElem
}
@Override
public void invoke(@NotNull Project project,
@NotNull PsiFile file,
@Nullable Editor editor,
@NotNull PsiElement startElement,
@NotNull PsiElement endElement) {
protected void invoke(@NotNull ActionContext context, @NotNull PsiVariable variable, @NotNull ModPsiUpdater updater) {
PsiType type = myTypePointer.getType();
if (type == null) return;
PsiVariable variable = (PsiVariable)startElement;
if (!(variable instanceof PsiReceiverParameter)) {
JavaSharedImplUtil.normalizeBrackets(variable);
}
PsiTypeElement typeElement = variable.getTypeElement();
if (typeElement == null) return;
PsiTypeElement typeElementByExplicitType = JavaPsiFacade.getElementFactory(project).createTypeElement(type);
PsiTypeElement typeElementByExplicitType = JavaPsiFacade.getElementFactory(context.project()).createTypeElement(type);
typeElement.replace(typeElementByExplicitType);
}
@Override
protected boolean isAvailable() {
return super.isAvailable() && myTypePointer.getType() != null;
protected @Nullable Presentation getPresentation(@NotNull ActionContext context, @NotNull PsiVariable element) {
return myTypePointer.getType() == null ? null : Presentation.of(getText());
}
@Override
public @NotNull String getText() {
@NotNull
protected @Nls String getText() {
return JavaBundle.message("intention.name.set.variable.type", myTypeText);
}
@@ -1,38 +1,33 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.intention.impl;
import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInsight.daemon.impl.analysis.HighlightingFeature;
import com.intellij.codeInsight.daemon.impl.analysis.JavaModuleGraphUtil;
import com.intellij.codeInsight.intention.BaseElementAtCaretIntentionAction;
import com.intellij.codeInspection.util.IntentionName;
import com.intellij.codeInspection.PsiUpdateModCommandAction;
import com.intellij.java.JavaBundle;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.NlsContexts;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.search.searches.ClassInheritorsSearch;
import com.intellij.psi.search.searches.FunctionalExpressionSearch;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.util.CommonRefactoringUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.SequentialModalProgressTask;
import com.intellij.util.SequentialTask;
import com.intellij.util.containers.ContainerUtil;
import com.siyeh.ig.psiutils.SealedUtils;
import one.util.streamex.StreamEx;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.PropertyKey;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public class SealClassAction extends BaseElementAtCaretIntentionAction {
public class SealClassAction extends PsiUpdateModCommandAction<PsiClass> {
public SealClassAction() {
super(PsiClass.class);
}
@Override
@NotNull
public String getFamilyName() {
@@ -40,20 +35,13 @@ public class SealClassAction extends BaseElementAtCaretIntentionAction {
}
@Override
public @IntentionName @NotNull String getText() {
return getFamilyName();
protected @Nullable Presentation getPresentation(@NotNull ActionContext context, @NotNull PsiClass element) {
return isAvailable(context, element) ? super.getPresentation(context, element) : null;
}
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
PsiClass aClass = PsiTreeUtil.getParentOfType(element, PsiClass.class);
if (aClass == null) return false;
return isAvailable(aClass, editor);
}
private static boolean isAvailable(@NotNull PsiClass aClass, Editor editor) {
private static boolean isAvailable(@NotNull ActionContext context, @NotNull PsiClass aClass) {
if (!HighlightingFeature.SEALED_CLASSES.isAvailable(aClass)) return false;
int offset = editor.getCaretModel().getOffset();
int offset = context.offset();
PsiElement lBrace = aClass.getLBrace();
if (lBrace == null) return false;
if (offset >= lBrace.getTextRange().getStartOffset()) return false;
@@ -67,18 +55,15 @@ public class SealClassAction extends BaseElementAtCaretIntentionAction {
}
@Override
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
PsiClass aClass = PsiTreeUtil.getParentOfType(element, PsiClass.class);
if (aClass == null) return;
if (!isAvailable(aClass, editor)) return;
sealClass(project, editor, aClass);
protected void invoke(@NotNull ActionContext context, @NotNull PsiClass aClass, @NotNull ModPsiUpdater updater) {
sealClass(context.project(), updater, aClass);
}
static void sealClass(@NotNull Project project, Editor editor, PsiClass psiClass) {
static void sealClass(@NotNull Project project, ModPsiUpdater updater, PsiClass psiClass) {
PsiJavaFile parentFile = (PsiJavaFile)psiClass.getContainingFile();
if (psiClass.isInterface()) {
if (FunctionalExpressionSearch.search(psiClass).findFirst() != null) {
showError(project, editor, "intention.error.make.sealed.class.is.used.in.functional.expression");
updater.cancel(JavaBundle.message("intention.error.make.sealed.class.is.used.in.functional.expression"));
return;
}
}
@@ -94,19 +79,13 @@ public class SealClassAction extends BaseElementAtCaretIntentionAction {
return false;
}
inheritors.add(inheritor);
inheritors.add(updater.getWritable(inheritor));
return true;
});
if (!message.isNull()) {
showError(project, editor, message.get());
updater.cancel(JavaBundle.message(message.get()));
return;
}
Set<VirtualFile> filesWithInheritors = new HashSet<>();
filesWithInheritors.add(parentFile.getVirtualFile());
for (PsiClass inheritor : inheritors) {
filesWithInheritors.add(inheritor.getContainingFile().getVirtualFile());
}
FileModificationService.getInstance().prepareVirtualFilesForWrite(project, filesWithInheritors);
List<String> names = ContainerUtil.map(inheritors, PsiClass::getQualifiedName);
@PsiModifier.ModifierConstant String modifier;
if (!names.isEmpty()) {
@@ -114,81 +93,43 @@ public class SealClassAction extends BaseElementAtCaretIntentionAction {
if (shouldCreatePermitsList(inheritors, parentFile)) {
addPermitsClause(project, psiClass, names);
}
setInheritorsModifiers(project, inheritors);
setInheritorsModifiers(inheritors);
}
else {
if (psiClass.isInterface()) {
showError(project, editor, "intention.error.make.sealed.class.interface.has.no.inheritors");
updater.cancel(JavaBundle.message("intention.error.make.sealed.class.interface.has.no.inheritors"));
return;
}
else {
modifier = PsiModifier.FINAL;
}
}
ApplicationManager.getApplication().runWriteAction(() -> {
PsiModifierList modifierList = Objects.requireNonNull(psiClass.getModifierList());
modifierList.setModifierProperty(modifier, true);
});
}
private static void showError(@NotNull Project project, Editor editor, @PropertyKey(resourceBundle = JavaBundle.BUNDLE) String message) {
CommonRefactoringUtil.showErrorHint(project, editor, JavaBundle.message(message), getErrorTitle(), null);
PsiModifierList modifierList = Objects.requireNonNull(psiClass.getModifierList());
modifierList.setModifierProperty(modifier, true);
}
private static boolean shouldCreatePermitsList(List<PsiClass> inheritors, PsiFile parentFile) {
return !inheritors.stream().allMatch(psiClass -> psiClass.getContainingFile() == parentFile);
return !ContainerUtil.and(inheritors, psiClass -> psiClass.getContainingFile() == parentFile);
}
public void setParentModifier(PsiClass aClass) {
ApplicationManager.getApplication().runWriteAction(() -> {
PsiModifierList modifierList = Objects.requireNonNull(aClass.getModifierList());
if (modifierList.hasModifierProperty(PsiModifier.NON_SEALED)) {
modifierList.setModifierProperty(PsiModifier.NON_SEALED, false);
private static void setInheritorsModifiers(List<PsiClass> inheritors) {
for (PsiClass inheritor : inheritors) {
PsiModifierList modifierList = inheritor.getModifierList();
assert modifierList != null; // ensured by absence of anonymous classes
if (modifierList.hasModifierProperty(PsiModifier.SEALED) ||
modifierList.hasModifierProperty(PsiModifier.NON_SEALED) ||
modifierList.hasModifierProperty(PsiModifier.FINAL)) {
continue;
}
modifierList.setModifierProperty(PsiModifier.SEALED, true);
});
}
private static void setInheritorsModifiers(@NotNull Project project, List<PsiClass> inheritors) {
String title = JavaBundle.message("intention.make.sealed.class.task.title.set.inheritors.modifiers");
SequentialModalProgressTask task = new SequentialModalProgressTask(project, title, true);
task.setTask(new SequentialTask() {
private int current = 0;
private final int size = inheritors.size();
@Override
public boolean isDone() {
return current >= size;
}
@Override
public boolean iteration() {
task.getIndicator().setFraction(((double)current) / size);
PsiClass inheritor = inheritors.get(current);
current++;
PsiModifierList modifierList = inheritor.getModifierList();
assert modifierList != null; // ensured by absence of anonymous classes
if (modifierList.hasModifierProperty(PsiModifier.SEALED) ||
modifierList.hasModifierProperty(PsiModifier.NON_SEALED) ||
modifierList.hasModifierProperty(PsiModifier.FINAL)) {
return isDone();
}
ApplicationManager.getApplication().runWriteAction(() -> {
modifierList.setModifierProperty(PsiModifier.NON_SEALED, true);
});
return isDone();
}
});
ProgressManager.getInstance().run(task);
modifierList.setModifierProperty(PsiModifier.NON_SEALED, true);
}
}
private static void addPermitsClause(@NotNull Project project, PsiClass aClass, List<String> nonNullNames) {
String permitsClause = StreamEx.of(nonNullNames).sorted().joining(",", "permits ", "");
PsiReferenceList permitsList = createPermitsClause(project, permitsClause);
PsiReferenceList implementsList = Objects.requireNonNull(aClass.getImplementsList());
ApplicationManager.getApplication().runWriteAction(() -> {
aClass.addAfter(permitsList, implementsList);
});
aClass.addAfter(permitsList, implementsList);
}
@NotNull
@@ -198,13 +139,4 @@ public class SealClassAction extends BaseElementAtCaretIntentionAction {
PsiClass newClass = javaFile.getClasses()[0];
return Objects.requireNonNull(newClass.getPermitsList());
}
@Override
public boolean startInWriteAction() {
return false;
}
private static @NlsContexts.DialogTitle String getErrorTitle() {
return JavaBundle.message("intention.make.sealed.class.hint.title");
}
}
@@ -1,47 +1,33 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.intention.impl;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
import com.intellij.codeInspection.PsiUpdateModCommandAction;
import com.intellij.codeInspection.util.IntentionFamilyName;
import com.intellij.codeInspection.util.IntentionName;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.search.searches.DirectClassInheritorsSearch;
import com.intellij.util.ObjectUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class SealClassFromPermitsListAction extends LocalQuickFixAndIntentionActionOnPsiElement {
public class SealClassFromPermitsListAction extends PsiUpdateModCommandAction<PsiClass> {
public SealClassFromPermitsListAction(@Nullable PsiElement element) {
public SealClassFromPermitsListAction(@NotNull PsiClass element) {
super(element);
}
@Override
public boolean isAvailable(@NotNull Project project,
@NotNull PsiFile file,
@NotNull PsiElement startElement, @NotNull PsiElement endElement) {
PsiClass psiClass = ObjectUtils.tryCast(getStartElement(), PsiClass.class);
return psiClass != null && DirectClassInheritorsSearch.search(psiClass).findFirst() != null;
protected @Nullable Presentation getPresentation(@NotNull ActionContext context, @NotNull PsiClass psiClass) {
return DirectClassInheritorsSearch.search(psiClass).findFirst() != null ?
Presentation.of(getFamilyName()) : null;
}
@Override
public void invoke(@NotNull Project project,
@NotNull PsiFile file,
@Nullable Editor editor,
@NotNull PsiElement startElement,
@NotNull PsiElement endElement) {
PsiClass psiClass = ObjectUtils.tryCast(startElement, PsiClass.class);
if (psiClass == null || psiClass.hasModifierProperty(PsiModifier.SEALED)) return;
SealClassAction.sealClass(project, editor, psiClass);
}
@Override
public @IntentionName @NotNull String getText() {
return getFamilyName();
protected void invoke(@NotNull ActionContext context, @NotNull PsiClass psiClass, @NotNull ModPsiUpdater updater) {
if (psiClass.hasModifierProperty(PsiModifier.SEALED)) return;
SealClassAction.sealClass(context.project(), updater, psiClass);
}
@Override
@@ -372,10 +372,10 @@ public final class QuickFixFactoryImpl extends QuickFixFactory {
@NotNull
@Override
public IntentionAction createReplaceInaccessibleFieldWithGetterSetterFix(@NotNull PsiElement element,
public IntentionAction createReplaceInaccessibleFieldWithGetterSetterFix(@NotNull PsiReferenceExpression element,
@NotNull PsiMethod getter,
boolean isSetter) {
return new ReplaceInaccessibleFieldWithGetterSetterFix(element, getter, isSetter);
return new ReplaceInaccessibleFieldWithGetterSetterFix(element, getter, isSetter).asIntention();
}
@NotNull
@@ -620,7 +620,7 @@ public final class QuickFixFactoryImpl extends QuickFixFactory {
public IntentionAction createReplacePrimitiveWithBoxedTypeAction(@NotNull PsiTypeElement element,
@NotNull String typeName,
@NotNull String boxedTypeName) {
return new ReplacePrimitiveWithBoxedTypeAction(element, typeName, boxedTypeName);
return new ReplacePrimitiveWithBoxedTypeAction(element, typeName, boxedTypeName).asIntention();
}
@Nullable
@@ -1051,7 +1051,7 @@ public final class QuickFixFactoryImpl extends QuickFixFactory {
@Override
public @NotNull IntentionAction createSealClassFromPermitsListFix(@NotNull PsiClass classFromPermitsList) {
return new SealClassFromPermitsListAction(classFromPermitsList);
return new SealClassFromPermitsListAction(classFromPermitsList).asIntention();
}
@Override
@@ -1066,7 +1066,7 @@ public final class QuickFixFactoryImpl extends QuickFixFactory {
@Override
public @NotNull IntentionAction createReceiverParameterTypeFix(@NotNull PsiReceiverParameter parameter, @NotNull PsiType newType) {
return new ReceiverParameterTypeFix(parameter, newType);
return new ReceiverParameterTypeFix(parameter, newType).asIntention();
}
private final static class ReceiverParameterTypeFix extends SetVariableTypeFix {
@@ -1075,7 +1075,7 @@ public final class QuickFixFactoryImpl extends QuickFixFactory {
}
@Override
public @NotNull String getText() {
protected @NotNull String getText() {
return QuickFixBundle.message("fix.receiver.parameter.type.text");
}
@@ -1156,12 +1156,12 @@ public final class QuickFixFactoryImpl extends QuickFixFactory {
@Override
public @NotNull IntentionAction createSetVariableTypeFix(@NotNull PsiVariable variable, @NotNull PsiType type) {
return new SetVariableTypeFix(variable, type);
return new SetVariableTypeFix(variable, type).asIntention();
}
@Override
public @NotNull IntentionAction createReceiverParameterNameFix(@NotNull PsiReceiverParameter parameter, @NotNull String newName) {
return new ReceiverParameterNameFix(parameter, newName);
return new ReceiverParameterNameFix(parameter, newName).asIntention();
}
@Override
@@ -1,8 +1,9 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection;
import com.intellij.codeInsight.intention.HighPriorityAction;
import com.intellij.java.JavaBundle;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
@@ -13,7 +14,7 @@ import org.jetbrains.annotations.NotNull;
import static com.intellij.util.ObjectUtils.tryCast;
public class ReplaceComputeWithComputeIfPresentFix implements LocalQuickFix, HighPriorityAction {
public class ReplaceComputeWithComputeIfPresentFix extends PsiUpdateModCommandQuickFix implements HighPriorityAction {
private static final CallMatcher MAP_COMPUTE = CallMatcher.instanceCall(CommonClassNames.JAVA_UTIL_MAP, "compute").
parameterTypes("K", CommonClassNames.JAVA_UTIL_FUNCTION_BI_FUNCTION);
@@ -24,8 +25,8 @@ public class ReplaceComputeWithComputeIfPresentFix implements LocalQuickFix, Hig
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiLambdaExpression lambda = PsiTreeUtil.getParentOfType(descriptor.getStartElement(), PsiLambdaExpression.class);
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
PsiLambdaExpression lambda = PsiTreeUtil.getParentOfType(element, PsiLambdaExpression.class);
if (lambda == null) return;
PsiMethodCallExpression call = PsiTreeUtil.getParentOfType(lambda, PsiMethodCallExpression.class);
if (call == null || !"compute".equals(call.getMethodExpression().getReferenceName())) return;
@@ -1,17 +1,15 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection;
import com.intellij.java.JavaBundle;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiElementFactory;
import com.intellij.psi.PsiType;
import com.intellij.psi.PsiTypeElement;
import com.intellij.psi.*;
import com.intellij.util.ObjectUtils;
import com.siyeh.InspectionGadgetsBundle;
import org.jetbrains.annotations.NotNull;
public class ReplaceTypeInCastFix implements LocalQuickFix {
public class ReplaceTypeInCastFix extends PsiUpdateModCommandQuickFix {
private final String myExistingTypeText;
private final String myWantedTypeText;
private final String myWantedTypeCanonicalText;
@@ -35,8 +33,8 @@ public class ReplaceTypeInCastFix implements LocalQuickFix {
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiTypeElement typeElement = ObjectUtils.tryCast(descriptor.getStartElement(), PsiTypeElement.class);
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
PsiTypeElement typeElement = ObjectUtils.tryCast(element, PsiTypeElement.class);
if (typeElement == null) return;
PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
PsiTypeElement replacement = factory.createTypeElement(factory.createTypeFromText(myWantedTypeCanonicalText, typeElement));
@@ -1,21 +1,8 @@
/*
* 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.
*/
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection;
import com.intellij.java.JavaBundle;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiElement;
@@ -26,7 +13,7 @@ import com.intellij.util.ObjectUtils;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
public class ReplaceWithTrivialLambdaFix implements LocalQuickFix {
public class ReplaceWithTrivialLambdaFix extends PsiUpdateModCommandQuickFix {
private final String myValue;
public ReplaceWithTrivialLambdaFix(Object value) {
@@ -48,8 +35,8 @@ public class ReplaceWithTrivialLambdaFix implements LocalQuickFix {
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiMethodReferenceExpression methodRef = ObjectUtils.tryCast(descriptor.getStartElement(), PsiMethodReferenceExpression.class);
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
PsiMethodReferenceExpression methodRef = ObjectUtils.tryCast(element, PsiMethodReferenceExpression.class);
if (methodRef == null) return;
PsiLambdaExpression lambdaExpression = LambdaRefactoringUtil.convertMethodReferenceToLambda(methodRef, true, true);
if (lambdaExpression == null) return;
@@ -1,22 +1,9 @@
/*
* 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.
*/
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection;
import com.intellij.codeInsight.intention.HighPriorityAction;
import com.intellij.java.JavaBundle;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.VariableKind;
@@ -31,7 +18,7 @@ import org.jetbrains.annotations.Nullable;
import static com.intellij.util.ObjectUtils.tryCast;
public class StreamFilterNotNullFix implements LocalQuickFix, HighPriorityAction {
public class StreamFilterNotNullFix extends PsiUpdateModCommandQuickFix implements HighPriorityAction {
@Override
@NotNull
public String getFamilyName() {
@@ -39,8 +26,8 @@ public class StreamFilterNotNullFix implements LocalQuickFix, HighPriorityAction
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiFunctionalExpression function = findFunction(descriptor.getStartElement());
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
PsiFunctionalExpression function = findFunction(element);
if (function == null) return;
PsiMethodCallExpression call = PsiTreeUtil.getParentOfType(function, PsiMethodCallExpression.class);
if (call == null) return;
@@ -1,8 +1,9 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection;
import com.intellij.codeInsight.generation.surroundWith.JavaWithIfSurrounder;
import com.intellij.java.JavaBundle;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
@@ -12,7 +13,7 @@ import com.siyeh.ig.psiutils.ParenthesesUtils;
import com.siyeh.ipp.trivialif.MergeIfAndIntention;
import org.jetbrains.annotations.NotNull;
public class SurroundWithIfFix implements LocalQuickFix {
public class SurroundWithIfFix extends PsiUpdateModCommandQuickFix {
private static final Logger LOG = Logger.getInstance(SurroundWithIfFix.class);
private final String myText;
private final String mySuffix;
@@ -29,8 +30,7 @@ public class SurroundWithIfFix implements LocalQuickFix {
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiElement element = descriptor.getPsiElement();
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
PsiElement anchorStatement = CommonJavaRefactoringUtil.getParentStatement(element, false);
LOG.assertTrue(anchorStatement != null);
if (anchorStatement.getParent() instanceof PsiLambdaExpression) {
@@ -2,24 +2,19 @@
package com.intellij.codeInspection.java18StreamApi;
import com.intellij.codeInspection.AbstractBaseJavaLocalInspectionTool;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.codeInspection.ui.InspectionOptionsPanel;
import com.intellij.codeInspection.PsiUpdateModCommandQuickFix;
import com.intellij.java.JavaBundle;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.JavaFeature;
import com.intellij.psi.*;
import com.intellij.util.ui.UI;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.Collection;
/**
@@ -86,8 +81,7 @@ public class StaticPseudoFunctionalStyleMethodInspection extends AbstractBaseJav
};
}
public static final class ReplacePseudoLambdaWithLambda implements LocalQuickFix {
@SafeFieldForPreview
public static final class ReplacePseudoLambdaWithLambda extends PsiUpdateModCommandQuickFix {
private final StaticPseudoFunctionalStyleMethodOptions.PipelineElement myHandler;
private ReplacePseudoLambdaWithLambda(StaticPseudoFunctionalStyleMethodOptions.PipelineElement handler) {
@@ -101,8 +95,7 @@ public class StaticPseudoFunctionalStyleMethodInspection extends AbstractBaseJav
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiElement psiElement = descriptor.getPsiElement();
protected void applyFix(@NotNull Project project, @NotNull PsiElement psiElement, @NotNull ModPsiUpdater updater) {
if (psiElement instanceof PsiReferenceExpression && psiElement.getParent() instanceof PsiMethodCallExpression call) {
myHandler.template().convertToStream(call, null, false);
}
@@ -1,15 +1,16 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection.javaDoc;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.PsiUpdateModCommandQuickFix;
import com.intellij.java.JavaBundle;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.javadoc.PsiDocTag;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
class RemoveTagFix implements LocalQuickFix {
class RemoveTagFix extends PsiUpdateModCommandQuickFix {
private final String myTagName;
RemoveTagFix(String tagName) {
@@ -29,8 +30,8 @@ class RemoveTagFix implements LocalQuickFix {
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiDocTag tag = PsiTreeUtil.getParentOfType(descriptor.getPsiElement(), PsiDocTag.class);
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
PsiDocTag tag = PsiTreeUtil.getParentOfType(element, PsiDocTag.class);
if (tag != null) {
tag.delete();
}
@@ -8,7 +8,7 @@ class A {
* @since 2020.3
* @author me
*/
void f() /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 */
void f() /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ /* 6 */
// seven
/* 8 */ /* 9 */ { }
@@ -14,15 +14,15 @@ public class Main {
}
}
if(list.size() > 2) {
for (String x : list) {
if (x != null) {
if (x.startsWith("x")) {
System.out.println("Ok!");
break;
}
}
}
}
for (String x : list) {
if (x != null) {
if (x.startsWith("x")) {
System.out.println("Ok!");
break;
}
}
}
}
if(list.size() > 2) {
boolean b = false;
for (String x : list) {
@@ -2,7 +2,7 @@
class A {
void foo(int x){
String i = x > 0 ? "" : null;
<caret>if (i != null) {
if (i<caret> != null) {
i.hashCode();
}
}
@@ -2,8 +2,8 @@
class A {
void foo(){
String s = null;
<caret>if (s != null) {
for (int i=0; i!=s.hashCode();i++){}
if (s != null) {
<caret> for (int i=0; i!=s.hashCode();i++){}
}
}
}
@@ -1,11 +1,12 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.java.codeInsight.intention;
import com.intellij.JavaTestUtil;
import com.intellij.codeInsight.intention.impl.SealClassAction;
import com.intellij.codeInspection.ModCommands;
import com.intellij.java.JavaBundle;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.refactoring.util.CommonRefactoringUtil;
import com.intellij.modcommand.ModCommand;
import com.intellij.modcommand.ModCommandAction.ActionContext;
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
import org.jetbrains.annotations.NotNull;
@@ -34,15 +35,11 @@ public class SealClassActionFailingTest extends LightJavaCodeInsightFixtureTestC
private void checkErrorMessage(@NotNull String message) {
myFixture.configureByFile(getTestName(false) + ".java");
ActionContext ac = ActionContext.from(getEditor(), getFile());
SealClassAction action = new SealClassAction();
assertTrue(action.isAvailable(getProject(), getEditor(), getFile()));
try {
ApplicationManager.getApplication().runWriteAction(() -> action.invoke(getProject(), getEditor(), getFile()));
} catch (CommonRefactoringUtil.RefactoringErrorHintException e) {
assertEquals(message, e.getMessage());
return;
}
fail("Test must fail with error message");
assertNotNull(action.getPresentation(ac));
ModCommand command = action.perform(ac);
assertEquals(ModCommands.error(message), command);
}
@Override
@@ -1,7 +1,9 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.java.codeInsight.intention;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInsight.intention.impl.SealClassAction;
import com.intellij.openapi.application.impl.NonBlockingReadActionImpl;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiFile;
@@ -14,11 +16,12 @@ public class SealClassActionMultiFileTest extends LightJavaCodeInsightFixtureTes
PsiClass direct2 = myFixture.addClass("class Direct2 extends Main {}");
PsiClass indirect = myFixture.addClass("class Indirect extends Direct1 {}");
SealClassAction action = new SealClassAction();
IntentionAction action = new SealClassAction().asIntention();
assertTrue(action.isAvailable(getProject(), getEditor(), getFile()));
WriteCommandAction.runWriteCommandAction(getProject(), () -> {
action.invoke(getProject(), getEditor(), getFile());
});
NonBlockingReadActionImpl.waitForAsyncTaskCompletion();
assertEquals("sealed class Main permits Direct1, Direct2 {}", main.getText());
assertEquals("non-sealed class Direct1 extends Main {}", direct1.getText());
assertEquals("non-sealed class Direct2 extends Main {}", direct2.getText());
@@ -1,8 +1,11 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.java.codeInsight.intention;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInsight.intention.impl.SealClassFromPermitsListAction;
import com.intellij.openapi.application.impl.NonBlockingReadActionImpl;
import com.intellij.psi.PsiClass;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
public class SealClassFromPermitsListActionTest extends LightJavaCodeInsightFixtureTestCase {
@@ -29,10 +32,12 @@ public class SealClassFromPermitsListActionTest extends LightJavaCodeInsightFixt
}
private void doTest(boolean isAvailable) {
SealClassFromPermitsListAction action = new SealClassFromPermitsListAction(myFixture.getElementAtCaret());
IntentionAction action = new SealClassFromPermitsListAction(
PsiTreeUtil.getNonStrictParentOfType(myFixture.getElementAtCaret(), PsiClass.class)).asIntention();
if (isAvailable) {
assertTrue(action.isAvailable(getProject(), getEditor(), getFile()));
myFixture.launchAction(action);
NonBlockingReadActionImpl.waitForAsyncTaskCompletion();
}
else {
assertFalse(action.isAvailable(getProject(), getEditor(), getFile()));
@@ -1,10 +1,11 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.java.codeInspection;
import com.intellij.JavaTestUtil;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInspection.sillyAssignment.SillyAssignmentInspection;
import com.intellij.java.JavaBundle;
import com.intellij.openapi.application.impl.NonBlockingReadActionImpl;
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
/**
@@ -29,6 +30,7 @@ public class RemoveSillyAssignmentFixTest extends LightJavaCodeInsightFixtureTes
final IntentionAction intention = myFixture.findSingleIntention(JavaBundle.message("assignment.to.itself.quickfix.name"));
assertNotNull(intention);
myFixture.launchAction(intention);
NonBlockingReadActionImpl.waitForAsyncTaskCompletion();
myFixture.checkResultByFile(getTestName(false) + ".after.java");
}
@@ -1,10 +1,12 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.java.propertyBased;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInsight.intention.impl.SealClassAction;
import com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.application.impl.NonBlockingReadActionImpl;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
@@ -49,7 +51,7 @@ public class MakeClassSealedPropertyTest extends BaseUnivocityTest {
Generator<PsiJavaFile> javaFiles = psiJavaFiles();
PsiJavaFile psiFile = env.generateValue(javaFiles, "Open %s in editor");
SealClassAction makeSealedAction = new SealClassAction();
IntentionAction makeSealedAction = new SealClassAction().asIntention();
FileEditorManager editorManager = FileEditorManager.getInstance(myProject);
Editor editor = editorManager.openTextEditor(new OpenFileDescriptor(myProject, psiFile.getVirtualFile()), true);
@@ -90,11 +92,12 @@ public class MakeClassSealedPropertyTest extends BaseUnivocityTest {
}
private static boolean convertToSealedClass(@NotNull Editor editor,
@NotNull SealClassAction makeSealedAction,
@NotNull IntentionAction makeSealedAction,
@NotNull PsiIdentifier classIdentifier) {
try {
PsiFile containingFile = classIdentifier.getContainingFile();
ShowIntentionActionsHandler.chooseActionAndInvoke(containingFile, editor, makeSealedAction, makeSealedAction.getText());
NonBlockingReadActionImpl.waitForAsyncTaskCompletion();
return true;
}
catch (CommonRefactoringUtil.RefactoringErrorHintException e) {
@@ -103,11 +106,11 @@ public class MakeClassSealedPropertyTest extends BaseUnivocityTest {
}
private static boolean canConvertToSealedClass(@NotNull Editor editor,
@NotNull SealClassAction makeSealedAction,
@NotNull IntentionAction makeSealedAction,
@NotNull PsiClass psiClass) {
PsiIdentifier nameIdentifier = psiClass.getNameIdentifier();
if (nameIdentifier == null) return false;
editor.getCaretModel().moveToOffset(nameIdentifier.getTextOffset());
return makeSealedAction.isAvailable(psiClass.getProject(), editor, nameIdentifier);
return makeSealedAction.isAvailable(psiClass.getProject(), editor, nameIdentifier.getContainingFile());
}
}
@@ -1396,13 +1396,12 @@ intention.name.move.into.if.branches=Move up into 'if' statement branches
intention.name.collapse.into.loop=Collapse into loop
intention.family.name.make.sealed=Seal class
intention.error.make.sealed.class.is.used.in.functional.expression=Class is used in functional expression
intention.make.sealed.class.hint.title=Make Sealed
intention.error.make.sealed.class.has.anonymous.or.local.inheritors=Some of the inheritors are anonymous or local
intention.error.make.sealed.class.different.packages=Module is unnamed and some of the inheritors are in the different package
intention.error.make.sealed.class.inheritors.not.in.java.file=Some of the inheritors are not in java files
intention.error.make.sealed.class.different.modules=Some of the inheritors are in different modules
intention.error.make.sealed.class.interface.has.no.inheritors=Interface has no inheritors
intention.make.sealed.class.task.title.set.inheritors.modifiers=Setting inheritors modifiers
intention.make.sealed.class.task.title.set.inheritors.modifiers=Computing Inheritors Modifiers
intention.family.name.move.member.into.class=Move member into class
inspection.fill.permits.list.no.missing.inheritors=Sealed class has no missing inheritors
inspection.fill.permits.list.display.name=Same file subclasses are missing from permits clause of a sealed class
@@ -29,4 +29,9 @@ public interface CommonIntentionAction {
@IntentionFamilyName
@Contract(pure = true)
String getFamilyName();
/**
* @return this action adapted to {@link IntentionAction} interface
*/
@NotNull IntentionAction asIntention();
}
@@ -111,4 +111,9 @@ public interface IntentionAction extends FileModifier, CommonIntentionAction {
copy.invoke(project, editor, file);
return IntentionPreviewInfo.DIFF;
}
@Override
default @NotNull IntentionAction asIntention() {
return this;
}
}
@@ -63,6 +63,7 @@ public interface ModCommandAction extends CommonIntentionAction {
/**
* @return this action adapted to {@link IntentionAction} interface
*/
@Override
@Contract(pure = true)
default @NotNull IntentionAction asIntention() {
return ModCommandService.getInstance().wrap(this);
@@ -372,7 +372,11 @@ final class PsiUpdateImpl {
if (myRenameSymbol != null) {
throw new IllegalStateException("One element is already registered for rename");
}
myRenameSymbol = new ModRenameSymbol(myNavigationFile, element.getTextRange(), suggestedNames);
TextRange range = getRange(element);
if (range == null) {
throw new IllegalArgumentException("Element disappeared after postponed operations: " + element);
}
myRenameSymbol = new ModRenameSymbol(myNavigationFile, range, suggestedNames);
}
@Override
@@ -1,9 +1,13 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.siyeh.ig.bugs;
import com.intellij.codeInspection.*;
import com.intellij.codeInspection.AbstractBaseJavaLocalInspectionTool;
import com.intellij.codeInspection.CommonQuickFixBundle;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.codeInspection.PsiUpdateModCommandQuickFix;
import com.intellij.codeInspection.util.ChronoUtil;
import com.intellij.codeInspection.util.InspectionMessage;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.NlsSafe;
import com.intellij.openapi.util.TextRange;
@@ -142,10 +146,8 @@ public class SuspiciousDateFormatInspection extends AbstractBaseJavaLocalInspect
}
}
private static class IncorrectDateFormatFix implements LocalQuickFix {
@SafeFieldForPreview
private static class IncorrectDateFormatFix extends PsiUpdateModCommandQuickFix {
private final Token myToken;
@SafeFieldForPreview
private final TextRange myRange;
IncorrectDateFormatFix(Token token, TextRange range) {
@@ -168,8 +170,8 @@ public class SuspiciousDateFormatInspection extends AbstractBaseJavaLocalInspect
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiLiteralExpression literal = ObjectUtils.tryCast(descriptor.getStartElement(), PsiLiteralExpression.class);
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
PsiLiteralExpression literal = ObjectUtils.tryCast(element, PsiLiteralExpression.class);
if (literal == null) return;
String text = literal.getText();
if (myRange.getEndOffset() >= text.length()) return;
@@ -1,11 +1,11 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.siyeh.ig.controlflow;
import com.intellij.codeInsight.daemon.impl.analysis.HighlightingFeature;
import com.intellij.codeInspection.AbstractBaseJavaLocalInspectionTool;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.codeInspection.PsiUpdateModCommandQuickFix;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
@@ -132,15 +132,15 @@ public class SwitchExpressionCanBePushedDownInspection extends AbstractBaseJavaL
return result;
}
private static class PushDownSwitchExpressionFix implements LocalQuickFix {
private static class PushDownSwitchExpressionFix extends PsiUpdateModCommandQuickFix {
@Override
public @NotNull String getFamilyName() {
return InspectionGadgetsBundle.message("inspection.common.subexpression.in.switch.fix.family.name");
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiSwitchBlock block = PsiTreeUtil.getParentOfType(descriptor.getStartElement(), PsiSwitchBlock.class);
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
PsiSwitchBlock block = PsiTreeUtil.getParentOfType(element, PsiSwitchBlock.class);
if (block == null) return;
List<PsiExpression> branches = extractBranches(block);
if (branches == null) return;
@@ -1,9 +1,10 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.siyeh.ig.performance;
import com.intellij.codeInsight.daemon.impl.analysis.HighlightingFeature;
import com.intellij.codeInspection.*;
import com.intellij.codeInspection.util.IntentionFamilyName;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
@@ -195,15 +196,15 @@ public final class RedundantStringFormatCallInspection extends LocalInspectionTo
return true;
}
private static final class ReplaceWithPrintFix implements LocalQuickFix {
private static final class ReplaceWithPrintFix extends PsiUpdateModCommandQuickFix {
@Override
public @IntentionFamilyName @NotNull String getFamilyName() {
return CommonQuickFixBundle.message("fix.replace.x.with.y", "printf()", "print()");
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiMethodCallExpression printStreamPrintfCall = getDirectParentMethod(descriptor.getPsiElement());
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
final PsiMethodCallExpression printStreamPrintfCall = getDirectParentMethod(element);
if (printStreamPrintfCall == null) return;
ExpressionUtils.bindCallTo(printStreamPrintfCall, "print");
@@ -216,24 +217,22 @@ public final class RedundantStringFormatCallInspection extends LocalInspectionTo
}
}
private static final class RemoveRedundantStringFormatFix implements LocalQuickFix {
private static final class RemoveRedundantStringFormatFix extends PsiUpdateModCommandQuickFix {
@Override
public @IntentionFamilyName @NotNull String getFamilyName() {
return InspectionGadgetsBundle.message("redundant.string.format.call.quickfix");
}
@Override
public void applyFix(@NotNull final Project project,
@NotNull final ProblemDescriptor descriptor) {
final PsiMethodCallExpression stringFormat = getDirectParentMethod(descriptor.getPsiElement());
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
final PsiMethodCallExpression stringFormat = getDirectParentMethod(element);
if (stringFormat != null) {
removeRedundantStringFormatCall(stringFormat);
}
}
}
private static final class ReplaceStringFormatWithPrintfFix implements LocalQuickFix {
private static final class ReplaceStringFormatWithPrintfFix extends PsiUpdateModCommandQuickFix {
private final boolean myIsPrintlnCall;
private ReplaceStringFormatWithPrintfFix(boolean isPrintlnCall) {
@@ -246,8 +245,8 @@ public final class RedundantStringFormatCallInspection extends LocalInspectionTo
}
@Override
public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) {
final PsiMethodCallExpression stringFormatCall = getDirectParentMethod(descriptor.getPsiElement());
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
final PsiMethodCallExpression stringFormatCall = getDirectParentMethod(element);
if (stringFormatCall == null) return;
final PsiMethodCallExpression printlnCall = getDirectParentMethod(stringFormatCall);
@@ -264,15 +263,15 @@ public final class RedundantStringFormatCallInspection extends LocalInspectionTo
}
}
private static final class RemoveRedundantStringFormattedFix implements LocalQuickFix {
private static final class RemoveRedundantStringFormattedFix extends PsiUpdateModCommandQuickFix {
@Override
public @IntentionFamilyName @NotNull String getFamilyName() {
return InspectionGadgetsBundle.message("redundant.string.formatted.call.quickfix");
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiMethodCallExpression stringFormattedCall = getDirectParentMethod(descriptor.getPsiElement());
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
final PsiMethodCallExpression stringFormattedCall = getDirectParentMethod(element);
if (stringFormattedCall == null) return;
final PsiExpression expression = stringFormattedCall.getMethodExpression().getQualifierExpression();
@@ -282,7 +281,7 @@ public final class RedundantStringFormatCallInspection extends LocalInspectionTo
}
}
private static final class ReplaceStringFormattedWithPrintfFix implements LocalQuickFix {
private static final class ReplaceStringFormattedWithPrintfFix extends PsiUpdateModCommandQuickFix {
private final boolean myIsPrintlnCall;
private ReplaceStringFormattedWithPrintfFix(boolean isPrintlnCall) {
@@ -295,8 +294,8 @@ public final class RedundantStringFormatCallInspection extends LocalInspectionTo
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiMethodCallExpression stringFormattedCall = getDirectParentMethod(descriptor.getPsiElement());
protected void applyFix(@NotNull Project project, @NotNull PsiElement startElement, @NotNull ModPsiUpdater updater) {
final PsiMethodCallExpression stringFormattedCall = getDirectParentMethod(startElement);
if (stringFormattedCall == null) return;
final PsiMethodCallExpression printlnCall = PsiTreeUtil.getParentOfType(stringFormattedCall, PsiMethodCallExpression.class);
@@ -1,4 +1,4 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.siyeh.ig.psiutils;
import com.intellij.codeInsight.daemon.impl.analysis.JavaModuleGraphUtil;
@@ -6,7 +6,6 @@ import com.intellij.java.JavaBundle;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.searches.DirectClassInheritorsSearch;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.ArrayUtil;
@@ -18,7 +17,6 @@ import org.jetbrains.annotations.PropertyKey;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static com.intellij.util.ObjectUtils.tryCast;
@@ -112,7 +110,8 @@ public final class SealedUtils {
modifiers.setModifierProperty(PsiModifier.SEALED, false);
}
public static @Nullable String checkInheritor(@NotNull PsiJavaFile parentFile, @Nullable PsiJavaModule module, @NotNull PsiClass inheritor) {
public static @Nullable @PropertyKey(resourceBundle = JavaBundle.BUNDLE) String checkInheritor(
@NotNull PsiJavaFile parentFile, @Nullable PsiJavaModule module, @NotNull PsiClass inheritor) {
@PropertyKey(resourceBundle = JavaBundle.BUNDLE)
String result = null;
if (PsiUtil.isLocalOrAnonymousClass(inheritor)) {
@@ -1,9 +1,9 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.siyeh.ig.style;
import com.intellij.codeInspection.*;
import com.intellij.codeInspection.options.OptPane;
import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
@@ -13,11 +13,9 @@ import com.siyeh.ig.psiutils.CommentTracker;
import com.siyeh.ig.psiutils.ControlFlowUtils;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import static com.intellij.codeInspection.options.OptPane.*;
import static com.intellij.codeInspection.options.OptPane.checkbox;
import static com.intellij.codeInspection.options.OptPane.pane;
import static com.intellij.util.ObjectUtils.tryCast;
public class SimplifiableIfStatementInspection extends AbstractBaseJavaLocalInspectionTool implements CleanupLocalInspectionTool {
@@ -81,7 +79,7 @@ public class SimplifiableIfStatementInspection extends AbstractBaseJavaLocalInsp
ct.deleteAndRestoreComments(result);
}
private static class SimplifiableIfStatementFix implements LocalQuickFix {
private static class SimplifiableIfStatementFix extends PsiUpdateModCommandQuickFix {
private final String myOperator;
SimplifiableIfStatementFix(String operator) {
@@ -99,8 +97,8 @@ public class SimplifiableIfStatementInspection extends AbstractBaseJavaLocalInsp
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiIfStatement ifStatement = PsiTreeUtil.getParentOfType(descriptor.getStartElement(), PsiIfStatement.class);
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
PsiIfStatement ifStatement = PsiTreeUtil.getParentOfType(element, PsiIfStatement.class);
if (ifStatement == null) return;
IfConditionalModel model = IfConditionalModel.from(ifStatement, false);
@@ -1,7 +1,8 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection;
import com.intellij.java.JavaBundle;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.NlsSafe;
import com.intellij.psi.*;
@@ -149,7 +150,7 @@ public class RedundantComparatorComparingInspection extends AbstractBaseJavaLoca
return null;
}
static class DeleteComparingCallFix implements LocalQuickFix {
static class DeleteComparingCallFix extends PsiUpdateModCommandQuickFix {
private final String mySourceMethod;
private final String myTargetMethod;
@@ -175,8 +176,8 @@ public class RedundantComparatorComparingInspection extends AbstractBaseJavaLoca
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiMethodCallExpression comparingCall = PsiTreeUtil.getParentOfType(descriptor.getStartElement(), PsiMethodCallExpression.class);
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
PsiMethodCallExpression comparingCall = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class);
if (comparingCall == null) return;
PsiMethodCallExpression thenComparingCall = PsiTreeUtil.getParentOfType(comparingCall, PsiMethodCallExpression.class);
if (thenComparingCall == null) return;
@@ -186,7 +187,7 @@ public class RedundantComparatorComparingInspection extends AbstractBaseJavaLoca
}
}
private static class ReplaceMaxMinFix implements LocalQuickFix {
private static class ReplaceMaxMinFix extends PsiUpdateModCommandQuickFix {
private final String myReplacement;
ReplaceMaxMinFix(String replacement) {
@@ -208,8 +209,8 @@ public class RedundantComparatorComparingInspection extends AbstractBaseJavaLoca
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiMethodCallExpression call = PsiTreeUtil.getParentOfType(descriptor.getStartElement(), PsiMethodCallExpression.class);
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
PsiMethodCallExpression call = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class);
if (call == null) return;
PsiExpression comparator = ArrayUtil.getLastElement(call.getArgumentList().getExpressions());
if (comparator == null) return;
@@ -221,7 +222,7 @@ public class RedundantComparatorComparingInspection extends AbstractBaseJavaLoca
}
}
private static class ReplaceWithEntryComparatorFix implements LocalQuickFix {
private static class ReplaceWithEntryComparatorFix extends PsiUpdateModCommandQuickFix {
private final String myReplacementMethod;
ReplaceWithEntryComparatorFix(String replacementMethod) {
@@ -243,8 +244,8 @@ public class RedundantComparatorComparingInspection extends AbstractBaseJavaLoca
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiMethodCallExpression call = PsiTreeUtil.getParentOfType(descriptor.getStartElement(), PsiMethodCallExpression.class);
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
PsiMethodCallExpression call = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class);
if (call == null) return;
String params = getGenericParameters(call);
PsiExpression[] args = call.getArgumentList().getExpressions();
@@ -1,8 +1,9 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection;
import com.intellij.codeInspection.dataFlow.DfaPsiUtil;
import com.intellij.codeInspection.dataFlow.value.RelationType;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
@@ -50,7 +51,7 @@ public class RedundantCompareCallInspection extends AbstractBaseJavaLocalInspect
};
}
private static class InlineCompareCallFix implements LocalQuickFix {
private static class InlineCompareCallFix extends PsiUpdateModCommandQuickFix {
private @NotNull final RelationType myRelationType;
InlineCompareCallFix(@NotNull RelationType relationType) {
@@ -65,8 +66,8 @@ public class RedundantCompareCallInspection extends AbstractBaseJavaLocalInspect
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiMethodCallExpression call = ObjectUtils.tryCast(descriptor.getStartElement(), PsiMethodCallExpression.class);
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
PsiMethodCallExpression call = ObjectUtils.tryCast(element, PsiMethodCallExpression.class);
if (call == null) return;
PsiExpression[] args = call.getArgumentList().getExpressions();
if(args.length != 2) return;
@@ -1,8 +1,9 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection;
import com.intellij.codeInspection.dataFlow.DfaPsiUtil;
import com.intellij.codeInspection.dataFlow.value.RelationType;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.NlsSafe;
import com.intellij.psi.*;
@@ -77,7 +78,7 @@ public class RedundantCompareToJavaTimeInspection extends AbstractBaseJavaLocalI
};
}
private static class InlineCompareToTimeCallFix implements LocalQuickFix {
private static class InlineCompareToTimeCallFix extends PsiUpdateModCommandQuickFix {
private @NotNull final RelationType myRelationType;
private @NotNull final String myArgumentType;
@@ -110,8 +111,8 @@ public class RedundantCompareToJavaTimeInspection extends AbstractBaseJavaLocalI
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiMethodCallExpression call = PsiTreeUtil.getParentOfType(descriptor.getStartElement(), PsiMethodCallExpression.class);
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
PsiMethodCallExpression call = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class);
if (call == null) return;
PsiExpression first = call.getMethodExpression().getQualifierExpression();
if (first == null) {
@@ -2,6 +2,7 @@
package com.intellij.codeInspection;
import com.intellij.codeInsight.AnnotationTargetUtil;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
@@ -102,7 +103,7 @@ public class RedundantExplicitVariableTypeInspection extends AbstractBaseJavaLoc
};
}
private static class ReplaceWithVarFix implements LocalQuickFix {
private static class ReplaceWithVarFix extends PsiUpdateModCommandQuickFix {
@Nls
@NotNull
@Override
@@ -111,11 +112,10 @@ public class RedundantExplicitVariableTypeInspection extends AbstractBaseJavaLoc
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiElement element = descriptor.getPsiElement();
if (element instanceof PsiTypeElement) {
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
if (element instanceof PsiTypeElement typeElement) {
CodeStyleManager.getInstance(project)
.reformat(IntroduceVariableUtil.expandDiamondsAndReplaceExplicitTypeWithVar((PsiTypeElement)element, element));
.reformat(IntroduceVariableUtil.expandDiamondsAndReplaceExplicitTypeWithVar(typeElement, element));
}
}
}
@@ -2,6 +2,7 @@
package com.intellij.codeInspection;
import com.intellij.codeInsight.BlockUtils;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
@@ -365,7 +366,7 @@ public class TrivialFunctionalExpressionUsageInspection extends AbstractBaseJava
}
}
private static abstract class ReplaceFix implements LocalQuickFix {
private static abstract class ReplaceFix extends PsiUpdateModCommandQuickFix {
@Nls
@NotNull
@Override
@@ -374,8 +375,8 @@ public class TrivialFunctionalExpressionUsageInspection extends AbstractBaseJava
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
apply(descriptor.getPsiElement());
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
apply(element);
}
void apply(@NotNull PsiElement psiElement) {
@@ -8,8 +8,10 @@ import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo;
import com.intellij.codeInsight.options.JavaClassValidator;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.PsiUpdateModCommandQuickFix;
import com.intellij.codeInspection.SetInspectionOptionFix;
import com.intellij.codeInspection.options.OptPane;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.command.undo.BasicUndoableAction;
@@ -282,7 +284,7 @@ public class TypeMayBeWeakenedInspection extends BaseInspection {
new JavaClassValidator().withTitle(InspectionGadgetsBundle.message("inspection.type.may.be.weakened.add.stop.class.selection.table"))));
}
private static class TypeMayBeWeakenedFix extends InspectionGadgetsFix {
private static class TypeMayBeWeakenedFix extends PsiUpdateModCommandQuickFix {
private final String fqClassName;
TypeMayBeWeakenedFix(@NotNull String fqClassName) {
@@ -302,8 +304,7 @@ public class TypeMayBeWeakenedInspection extends BaseInspection {
}
@Override
protected void doFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiElement element = descriptor.getPsiElement();
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
final PsiElement parent = element.getParent();
final PsiTypeElement typeElement;
if (parent instanceof PsiVariable variable) {
@@ -360,7 +361,6 @@ public class TypeMayBeWeakenedInspection extends BaseInspection {
}
final JavaCodeStyleManager javaCodeStyleManager = JavaCodeStyleManager.getInstance(project);
javaCodeStyleManager.shortenClassReferences(replacement);
}
}
@@ -16,11 +16,14 @@
package com.siyeh.ig.dataflow;
import com.intellij.codeInsight.BlockUtils;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.PsiUpdateModCommandQuickFix;
import com.intellij.modcommand.ModPsiUpdater;
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.codeStyle.VariableKind;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.SearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
@@ -31,20 +34,17 @@ import com.intellij.util.Query;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.psiutils.CommentTracker;
import com.siyeh.ig.psiutils.HighlightUtils;
import com.siyeh.ig.psiutils.VariableAccessUtils;
import com.siyeh.ig.psiutils.VariableNameGenerator;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public class ReuseOfLocalVariableInspection extends BaseInspection {
@Override
protected InspectionGadgetsFix buildFix(Object... infos) {
protected LocalQuickFix buildFix(Object... infos) {
return new ReuseOfLocalVariableFix();
}
@@ -65,7 +65,7 @@ public class ReuseOfLocalVariableInspection extends BaseInspection {
return new ReuseOfLocalVariableVisitor();
}
private static class ReuseOfLocalVariableFix extends InspectionGadgetsFix {
private static class ReuseOfLocalVariableFix extends PsiUpdateModCommandQuickFix {
@Override
@NotNull
@@ -74,8 +74,8 @@ public class ReuseOfLocalVariableInspection extends BaseInspection {
}
@Override
public void doFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)descriptor.getPsiElement();
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)element;
final PsiLocalVariable variable = (PsiLocalVariable)referenceExpression.resolve();
if (variable == null) return;
final PsiAssignmentExpression assignment = (PsiAssignmentExpression)PsiUtil.skipParenthesizedExprUp(referenceExpression.getParent());
@@ -92,7 +92,6 @@ public class ReuseOfLocalVariableInspection extends BaseInspection {
final Query<PsiReference> query = ReferencesSearch.search(variable, scope, false);
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
final PsiElementFactory factory = psiFacade.getElementFactory();
List<PsiReferenceExpression> collectedReferences = new ArrayList<>();
for (PsiReference reference : query) {
final PsiElement referenceElement = reference.getElement();
final TextRange textRange = assignmentStatement.getTextRange();
@@ -100,8 +99,7 @@ public class ReuseOfLocalVariableInspection extends BaseInspection {
continue;
}
final PsiExpression newExpression = factory.createExpressionFromText(newVariableName, referenceElement);
final PsiReferenceExpression replacementExpression = (PsiReferenceExpression)referenceElement.replace(newExpression);
collectedReferences.add(replacementExpression);
referenceElement.replace(newExpression);
}
CommentTracker commentTracker = new CommentTracker();
final PsiExpression rhs = assignment.getRExpression();
@@ -113,8 +111,8 @@ public class ReuseOfLocalVariableInspection extends BaseInspection {
commentTracker.deleteAndRestoreComments(Objects.requireNonNull(assignmentStatement));
final PsiElement[] elements = declarationStatement.getDeclaredElements();
final PsiLocalVariable newVariable = (PsiLocalVariable)elements[0];
final PsiElement context = declarationStatement.getParent();
HighlightUtils.showRenameTemplate(context, newVariable, collectedReferences.toArray(new PsiReferenceExpression[0]));
updater.rename(newVariable, new VariableNameGenerator(newVariable, VariableKind.LOCAL_VARIABLE)
.byExpression(newVariable.getInitializer()).byType(newVariable.getType()).generateAll(true));
}
}
@@ -17,9 +17,11 @@ package com.siyeh.ig.dataflow;
import com.intellij.codeInsight.daemon.impl.analysis.HighlightControlFlowUtil;
import com.intellij.codeInsight.generation.GenerateMembersUtil;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemHighlightType;
import com.intellij.codeInspection.PsiUpdateModCommandQuickFix;
import com.intellij.codeInspection.options.OptPane;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
@@ -33,7 +35,6 @@ import com.intellij.util.SmartList;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.psiutils.*;
import org.intellij.lang.annotations.Pattern;
import org.jetbrains.annotations.NonNls;
@@ -42,7 +43,8 @@ import org.jetbrains.annotations.Nullable;
import java.util.List;
import static com.intellij.codeInspection.options.OptPane.*;
import static com.intellij.codeInspection.options.OptPane.checkbox;
import static com.intellij.codeInspection.options.OptPane.pane;
public class TooBroadScopeInspection extends BaseInspection {
@@ -199,7 +201,7 @@ public class TooBroadScopeInspection extends BaseInspection {
}
@Override
public InspectionGadgetsFix buildFix(Object... infos) {
public LocalQuickFix buildFix(Object... infos) {
final PsiVariable variable = (PsiVariable)infos[0];
return new TooBroadScopeInspectionFix(variable.getName());
}
@@ -337,7 +339,7 @@ public class TooBroadScopeInspection extends BaseInspection {
registerVariableError(variable, variable);
}
private boolean isAssignmentToVariable(PsiElement element, PsiLocalVariable variable) {
private static boolean isAssignmentToVariable(PsiElement element, PsiLocalVariable variable) {
if (!(element instanceof PsiExpressionStatement expressionStatement)) {
return false;
}
@@ -358,7 +360,7 @@ public class TooBroadScopeInspection extends BaseInspection {
}
}
private class TooBroadScopeInspectionFix extends InspectionGadgetsFix {
private class TooBroadScopeInspectionFix extends PsiUpdateModCommandQuickFix {
private final String variableName;
@@ -379,8 +381,7 @@ public class TooBroadScopeInspection extends BaseInspection {
}
@Override
protected void doFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiElement variableIdentifier = descriptor.getPsiElement();
protected void applyFix(@NotNull Project project, @NotNull PsiElement variableIdentifier, @NotNull ModPsiUpdater updater) {
if (!(variableIdentifier instanceof PsiIdentifier)) {
return;
}
@@ -451,12 +452,10 @@ public class TooBroadScopeInspection extends BaseInspection {
newDeclaration = codeStyleManager.reformat(newDeclaration);
removeOldVariable(variable, tracker);
tracker.insertCommentsBefore(newDeclaration);
if (isOnTheFly()) {
HighlightUtils.highlightElement(newDeclaration);
}
updater.highlight(newDeclaration);
}
private void removeOldVariable(@NotNull PsiVariable variable, CommentTracker tracker) {
private static void removeOldVariable(@NotNull PsiVariable variable, CommentTracker tracker) {
final PsiDeclarationStatement declaration = (PsiDeclarationStatement)variable.getParent();
if (declaration == null) {
return;
@@ -470,9 +469,9 @@ public class TooBroadScopeInspection extends BaseInspection {
}
}
private PsiDeclarationStatement createNewDeclaration(@NotNull PsiVariable variable,
@Nullable PsiExpression initializer,
CommentTracker tracker) {
private static PsiDeclarationStatement createNewDeclaration(@NotNull PsiVariable variable,
@Nullable PsiExpression initializer,
CommentTracker tracker) {
final Project project = variable.getProject();
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
final PsiElementFactory factory = psiFacade.getElementFactory();
@@ -1,17 +1,16 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.siyeh.ig.encapsulation;
import com.intellij.codeInspection.CommonQuickFixBundle;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.PsiUpdateModCommandQuickFix;
import com.intellij.modcommand.ModPsiUpdater;
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.psi.util.PsiTreeUtil;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.PsiReplacementUtil;
import com.siyeh.ig.psiutils.HighlightUtils;
import com.siyeh.ig.psiutils.TypeUtils;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -20,7 +19,7 @@ import org.jetbrains.annotations.Nullable;
/**
* @author Bas Leijdekkers
*/
final class ReturnOfCollectionFieldFix extends InspectionGadgetsFix {
final class ReturnOfCollectionFieldFix extends PsiUpdateModCommandQuickFix {
private final String myReplacementText;
private final String myQualifiedClassName;
@@ -31,7 +30,7 @@ final class ReturnOfCollectionFieldFix extends InspectionGadgetsFix {
}
@Nullable
public static InspectionGadgetsFix build(PsiReferenceExpression referenceExpression) {
public static ReturnOfCollectionFieldFix build(PsiReferenceExpression referenceExpression) {
final String text = referenceExpression.getText();
if (TypeUtils.expressionHasTypeOrSubtype(referenceExpression, CommonClassNames.JAVA_UTIL_MAP)) {
if (TypeUtils.expressionHasTypeOrSubtype(referenceExpression, "java.util.SortedMap")) {
@@ -67,16 +66,15 @@ final class ReturnOfCollectionFieldFix extends InspectionGadgetsFix {
}
@Override
protected void doFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiElement element = descriptor.getPsiElement();
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
if (!(element instanceof PsiReferenceExpression referenceExpression)) {
return;
}
fixContainingMethodReturnType(referenceExpression);
fixContainingMethodReturnType(referenceExpression, updater);
PsiReplacementUtil.replaceExpressionAndShorten(referenceExpression, myReplacementText);
}
private void fixContainingMethodReturnType(PsiReferenceExpression referenceExpression) {
private void fixContainingMethodReturnType(PsiReferenceExpression referenceExpression, @NotNull ModPsiUpdater updater) {
final PsiMethod method = PsiTreeUtil.getParentOfType(referenceExpression, PsiMethod.class, true, PsiLambdaExpression.class);
if (method == null) {
return;
@@ -123,8 +121,6 @@ final class ReturnOfCollectionFieldFix extends InspectionGadgetsFix {
final PsiElement replacement = returnTypeElement.replace(newTypeElement);
final JavaCodeStyleManager javaCodeStyleManager = JavaCodeStyleManager.getInstance(project);
javaCodeStyleManager.shortenClassReferences(replacement);
if (isOnTheFly()) {
HighlightUtils.highlightElement(replacement);
}
updater.highlight(replacement);
}
}
@@ -1,8 +1,10 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.siyeh.ig.errorhandling;
import com.intellij.codeInspection.CleanupLocalInspectionTool;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.PsiUpdateModCommandQuickFix;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.*;
@@ -12,10 +14,8 @@ import com.intellij.psi.util.PsiUtil;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.psiutils.DeclarationSearchUtils;
import com.siyeh.ig.psiutils.ExpressionUtils;
import com.siyeh.ig.psiutils.HighlightUtils;
import com.siyeh.ig.psiutils.TypeUtils;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NonNls;
@@ -29,7 +29,7 @@ public class UnnecessaryInitCauseInspection extends BaseInspection implements Cl
@Nullable
@Override
protected InspectionGadgetsFix buildFix(Object... infos) {
protected LocalQuickFix buildFix(Object... infos) {
return new UnnecessaryInitCauseFix();
}
@@ -59,7 +59,7 @@ public class UnnecessaryInitCauseInspection extends BaseInspection implements Cl
return null;
}
private static class UnnecessaryInitCauseFix extends InspectionGadgetsFix {
private static class UnnecessaryInitCauseFix extends PsiUpdateModCommandQuickFix {
@Nls
@NotNull
@@ -69,8 +69,8 @@ public class UnnecessaryInitCauseInspection extends BaseInspection implements Cl
}
@Override
protected void doFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiElement element = descriptor.getPsiElement().getParent().getParent();
protected void applyFix(@NotNull Project project, @NotNull PsiElement startElement, @NotNull ModPsiUpdater updater) {
final PsiElement element = startElement.getParent().getParent();
if (!(element instanceof PsiMethodCallExpression methodCallExpression)) {
return;
}
@@ -93,9 +93,7 @@ public class UnnecessaryInitCauseInspection extends BaseInspection implements Cl
return;
}
final PsiElement newElement = argumentList1.add(argument);
if (isOnTheFly()) {
HighlightUtils.highlightElement(newElement);
}
updater.highlight(newElement);
final PsiElement parent = methodCallExpression.getParent();
if (parent instanceof PsiExpressionStatement) {
parent.delete();
@@ -3,8 +3,10 @@ package com.siyeh.ig.inheritance;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.options.JavaClassValidator;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.PsiUpdateModCommandQuickFix;
import com.intellij.codeInspection.options.OptPane;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.*;
@@ -15,7 +17,6 @@ import com.siyeh.HardcodedMethodConstants;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.psiutils.*;
import com.siyeh.ig.ui.ExternalizableStringSet;
import org.jdom.Element;
@@ -24,6 +25,8 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import static com.intellij.codeInspection.options.OptPane.*;
/**
@@ -50,7 +53,7 @@ public class RefusedBequestInspection extends BaseInspection {
@Nullable
@Override
protected InspectionGadgetsFix buildFix(Object... infos) {
protected LocalQuickFix buildFix(Object... infos) {
return new RefusedBequestFix();
}
@@ -85,7 +88,7 @@ public class RefusedBequestInspection extends BaseInspection {
return new RefusedBequestVisitor();
}
private static class RefusedBequestFix extends InspectionGadgetsFix {
private static class RefusedBequestFix extends PsiUpdateModCommandQuickFix {
@Nls
@NotNull
@@ -95,8 +98,7 @@ public class RefusedBequestInspection extends BaseInspection {
}
@Override
protected void doFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiElement methodName = descriptor.getPsiElement();
protected void applyFix(@NotNull Project project, @NotNull PsiElement methodName, @NotNull ModPsiUpdater updater) {
final PsiMethod method = (PsiMethod)methodName.getParent();
assert method != null;
final PsiCodeBlock body = method.getBody();
@@ -141,12 +143,15 @@ public class RefusedBequestInspection extends BaseInspection {
final PsiElement element = body.addAfter(newStatement, brace);
final PsiElement element1 = styleManager.reformat(element);
final PsiElement element2 = JavaCodeStyleManager.getInstance(project).shortenClassReferences(element1);
if (isOnTheFly() && element2.isPhysical()) {
HighlightUtils.highlightElement(element2);
if (element2 instanceof PsiDeclarationStatement declarationStatement) {
final PsiLocalVariable variable = (PsiLocalVariable)declarationStatement.getDeclaredElements()[0];
HighlightUtils.showRenameTemplate(body, variable);
}
updater.highlight(element2);
if (element2 instanceof PsiDeclarationStatement declarationStatement) {
final PsiLocalVariable variable = (PsiLocalVariable)declarationStatement.getDeclaredElements()[0];
List<String> nameSuggestions = new VariableNameGenerator(variable, VariableKind.LOCAL_VARIABLE)
.byExpression(variable.getInitializer())
.byType(variable.getType())
.byName("original", "superResult")
.generateAll(true);
updater.rename(variable, nameSuggestions);
}
}
}
@@ -1,21 +1,25 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.siyeh.ig.performance;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.PsiUpdateModCommandQuickFix;
import com.intellij.codeInspection.options.OptPane;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.ObjectUtils;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.callMatcher.CallMatcher;
import com.siyeh.ig.psiutils.*;
import org.jetbrains.annotations.*;
import java.util.List;
import static com.intellij.codeInspection.options.OptPane.dropdown;
import static com.intellij.codeInspection.options.OptPane.pane;
@@ -59,7 +63,7 @@ public class ToArrayCallWithZeroLengthArrayArgumentInspection extends BaseInspec
@Override
@Nullable
protected InspectionGadgetsFix buildFix(Object... infos) {
protected LocalQuickFix buildFix(Object... infos) {
final PsiExpression argument = (PsiExpression)infos[1];
return new ToArrayCallWithZeroLengthArrayArgumentFix(myMode.isEmptyPreferred(argument));
}
@@ -114,7 +118,7 @@ public class ToArrayCallWithZeroLengthArrayArgumentInspection extends BaseInspec
return CollectionUtils.isCollectionOrMapSize(dimensions[0], qualifier);
}
private static class ToArrayCallWithZeroLengthArrayArgumentFix extends InspectionGadgetsFix {
private static class ToArrayCallWithZeroLengthArrayArgumentFix extends PsiUpdateModCommandQuickFix {
private final boolean myEmptyPreferred;
ToArrayCallWithZeroLengthArrayArgumentFix(boolean emptyPreferred) {
@@ -137,8 +141,7 @@ public class ToArrayCallWithZeroLengthArrayArgumentInspection extends BaseInspec
}
@Override
protected void doFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiElement element = descriptor.getPsiElement();
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
final PsiElement parent = element.getParent();
final PsiElement grandParent = parent.getParent();
if (!(grandParent instanceof PsiMethodCallExpression methodCallExpression)) return;
@@ -170,31 +173,22 @@ public class ToArrayCallWithZeroLengthArrayArgumentInspection extends BaseInspec
if (statement == null) return;
final PsiType qualifierType = qualifier.getType();
if (qualifierType == null) return;
PsiDeclarationStatement declarationStatement = factory.createVariableDeclarationStatement("var", qualifierType, qualifier);
List<String> names = new VariableNameGenerator(statement, VariableKind.LOCAL_VARIABLE)
.byExpression(qualifier).byType(qualifierType).generateAll(true);
String name = names.get(0);
PsiDeclarationStatement declarationStatement = factory.createVariableDeclarationStatement(name, qualifierType, qualifier);
PsiElement statementParent = statement.getParent();
while (statementParent instanceof PsiLoopStatement || statementParent instanceof PsiIfStatement) {
statement = (PsiStatement)statementParent;
statementParent = statement.getParent();
}
final String toArrayText = "var.toArray(new " + typeText + "[var.size()])";
final String toArrayText = name + ".toArray(new " + typeText + "[" + name + ".size()])";
PsiMethodCallExpression newMethodCallExpression =
(PsiMethodCallExpression)factory.createExpressionFromText(toArrayText, methodCallExpression);
declarationStatement = (PsiDeclarationStatement)statementParent.addBefore(declarationStatement, statement);
newMethodCallExpression = (PsiMethodCallExpression)methodCallExpression.replace(newMethodCallExpression);
showRenameTemplate(declarationStatement, newMethodCallExpression, statementParent);
}
private void showRenameTemplate(PsiDeclarationStatement declarationStatement, PsiMethodCallExpression methodCallExpression,
PsiElement context) {
if (!isOnTheFly()) {
return;
}
methodCallExpression.replace(newMethodCallExpression);
final PsiVariable variable = (PsiVariable)declarationStatement.getDeclaredElements()[0];
final PsiReferenceExpression ref1 = (PsiReferenceExpression)methodCallExpression.getMethodExpression().getQualifierExpression();
final PsiNewExpression argument = (PsiNewExpression)methodCallExpression.getArgumentList().getExpressions()[0];
final PsiMethodCallExpression sizeExpression = (PsiMethodCallExpression)argument.getArrayDimensions()[0];
final PsiReferenceExpression ref2 = (PsiReferenceExpression)sizeExpression.getMethodExpression().getQualifierExpression();
HighlightUtils.showRenameTemplate(context, variable, ref1, ref2);
updater.rename(variable, names);
}
}
}
@@ -1,10 +1,11 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.siyeh.ig.redundancy;
import com.intellij.codeInsight.PsiEquivalenceUtil;
import com.intellij.codeInspection.*;
import com.intellij.codeInspection.util.InspectionMessage;
import com.intellij.codeInspection.util.IntentionName;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.NlsSafe;
import com.intellij.psi.*;
@@ -615,8 +616,7 @@ public class RedundantCollectionOperationInspection extends AbstractBaseJavaLoca
}
}
private static class RedundantCollectionOperationFix implements LocalQuickFix {
@SafeFieldForPreview
private static class RedundantCollectionOperationFix extends PsiUpdateModCommandQuickFix {
private final RedundantCollectionOperationHandler myHandler;
RedundantCollectionOperationFix(RedundantCollectionOperationHandler handler) {
@@ -636,8 +636,8 @@ public class RedundantCollectionOperationInspection extends AbstractBaseJavaLoca
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiMethodCallExpression call = PsiTreeUtil.getParentOfType(descriptor.getStartElement(), PsiMethodCallExpression.class);
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
PsiMethodCallExpression call = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class);
if (call == null) return;
myHandler.performFix(project, call);
}
@@ -3,6 +3,7 @@ package com.siyeh.ig.redundancy;
import com.intellij.codeInspection.*;
import com.intellij.codeInspection.util.ChronoUtil;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.NlsSafe;
import com.intellij.psi.*;
@@ -175,7 +176,7 @@ public class RedundantExplicitChronoFieldInspection extends AbstractBaseJavaLoca
};
}
private static class InlineChronoEnumCallFix implements LocalQuickFix {
private static class InlineChronoEnumCallFix extends PsiUpdateModCommandQuickFix {
private @NotNull final String myNewMethodName;
private final int myDeletedArgumentIndex;
@@ -197,8 +198,8 @@ public class RedundantExplicitChronoFieldInspection extends AbstractBaseJavaLoca
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiMethodCallExpression call = PsiTreeUtil.getParentOfType(descriptor.getStartElement(), PsiMethodCallExpression.class);
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
PsiMethodCallExpression call = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class);
if (call == null) return;
PsiExpression qualifierExpression = call.getMethodExpression().getQualifierExpression();
if (qualifierExpression == null) {
@@ -9,6 +9,7 @@ import com.intellij.codeInspection.options.OptPane;
import com.intellij.codeInspection.util.IntentionFamilyName;
import com.intellij.codeInspection.util.IntentionName;
import com.intellij.java.analysis.JavaAnalysisBundle;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
@@ -19,7 +20,6 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.siyeh.HardcodedMethodConstants;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.PsiReplacementUtil;
import com.siyeh.ig.callMatcher.CallMapper;
import com.siyeh.ig.callMatcher.CallMatcher;
@@ -649,7 +649,7 @@ public class RedundantStringOperationInspection extends AbstractBaseJavaLocalIns
* {@link String#substring(int, int)} with {@link String#charAt(int)} or
* {@code stringValue.substring(i, i + 1).equals("_")} with {@code stringValue.charAt(i) == '_'}
*/
private static class SubstringToCharAtQuickFix implements LocalQuickFix {
private static class SubstringToCharAtQuickFix extends PsiUpdateModCommandQuickFix {
@NotNull private final String myText;
@NotNull private final String myConverted;
private final boolean myEquality;
@@ -671,12 +671,12 @@ public class RedundantStringOperationInspection extends AbstractBaseJavaLocalIns
}
@Override
public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) {
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
if (myEquality) {
applyEqualityFix(descriptor);
applyEqualityFix(element);
}
else {
PsiMethodCallExpression call = tryCast(descriptor.getPsiElement().getParent().getParent(), PsiMethodCallExpression.class);
PsiMethodCallExpression call = tryCast(element.getParent().getParent(), PsiMethodCallExpression.class);
if (call == null) return;
PsiExpression[] args = call.getArgumentList().getExpressions();
if (args.length != 2) return;
@@ -685,8 +685,8 @@ public class RedundantStringOperationInspection extends AbstractBaseJavaLocalIns
}
}
private static void applyEqualityFix(@NotNull final ProblemDescriptor descriptor) {
final PsiElement element = descriptor.getPsiElement().getParent().getParent();
private static void applyEqualityFix(@NotNull PsiElement startElement) {
final PsiElement element = startElement.getParent().getParent();
final PsiMethodCallExpression call = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class);
if (call == null) return;
@@ -730,7 +730,7 @@ public class RedundantStringOperationInspection extends AbstractBaseJavaLocalIns
ExpressionUtils.bindCallTo(equalsCall, methodToUse);
}
private static class UseContentEqualsFix implements LocalQuickFix {
private static class UseContentEqualsFix extends PsiUpdateModCommandQuickFix {
@Override
public @NotNull String getFamilyName() {
@@ -745,14 +745,14 @@ public class RedundantStringOperationInspection extends AbstractBaseJavaLocalIns
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiMethodCallExpression changeCaseCall = PsiTreeUtil.getParentOfType(descriptor.getStartElement(), PsiMethodCallExpression.class);
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
PsiMethodCallExpression changeCaseCall = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class);
if (changeCaseCall == null) return;
useMethodInsteadOfRedundantCall(CONTENT_EQUALS, changeCaseCall);
}
}
private static class RemoveRedundantChangeCaseFix implements LocalQuickFix {
private static class RemoveRedundantChangeCaseFix extends PsiUpdateModCommandQuickFix {
private final @NotNull String caseRedundant;
private final @NotNull PlaceCaseEqualType myPlaceCaseEqualType;
@@ -780,9 +780,8 @@ public class RedundantStringOperationInspection extends AbstractBaseJavaLocalIns
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiMethodCallExpression changeCaseCall = PsiTreeUtil.getParentOfType(descriptor.getStartElement(), PsiMethodCallExpression.class);
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
PsiMethodCallExpression changeCaseCall = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class);
if (changeCaseCall == null) return;
if (myPlaceCaseEqualType == PlaceCaseEqualType.RIGHT) {
@@ -813,7 +812,7 @@ public class RedundantStringOperationInspection extends AbstractBaseJavaLocalIns
}
}
private static class RemoveRedundantSubstringFix implements LocalQuickFix {
private static class RemoveRedundantSubstringFix extends PsiUpdateModCommandQuickFix {
private final @NotNull String myBindCallName;
RemoveRedundantSubstringFix(@NotNull @NonNls String bindCallName) {
@@ -836,8 +835,8 @@ public class RedundantStringOperationInspection extends AbstractBaseJavaLocalIns
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiMethodCallExpression substringCall = PsiTreeUtil.getParentOfType(descriptor.getStartElement(), PsiMethodCallExpression.class);
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
PsiMethodCallExpression substringCall = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class);
if (substringCall == null) return;
PsiExpression stringExpr = substringCall.getMethodExpression().getQualifierExpression();
if (stringExpr == null) return;
@@ -854,7 +853,7 @@ public class RedundantStringOperationInspection extends AbstractBaseJavaLocalIns
}
}
private static class StripIsEmptyToIsBlankFix implements LocalQuickFix {
private static class StripIsEmptyToIsBlankFix extends PsiUpdateModCommandQuickFix {
@Nls
@NotNull
@Override
@@ -870,8 +869,8 @@ public class RedundantStringOperationInspection extends AbstractBaseJavaLocalIns
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiMethodCallExpression stripCall = PsiTreeUtil.getNonStrictParentOfType(descriptor.getStartElement(), PsiMethodCallExpression.class);
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
PsiMethodCallExpression stripCall = PsiTreeUtil.getNonStrictParentOfType(element, PsiMethodCallExpression.class);
if (stripCall == null) return;
PsiMethodCallExpression isEmptyCall = ExpressionUtils.getCallForQualifier(stripCall);
if (isEmptyCall == null) return;
@@ -882,7 +881,7 @@ public class RedundantStringOperationInspection extends AbstractBaseJavaLocalIns
}
}
private static class RemoveRedundantStringCallFix implements LocalQuickFix {
private static class RemoveRedundantStringCallFix extends PsiUpdateModCommandQuickFix {
private final FixType myFixType;
private final String myToRemove;
@@ -906,8 +905,8 @@ public class RedundantStringOperationInspection extends AbstractBaseJavaLocalIns
}
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
PsiMethodCallExpression call = PsiTreeUtil.getNonStrictParentOfType(descriptor.getStartElement(), PsiMethodCallExpression.class);
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
PsiMethodCallExpression call = PsiTreeUtil.getNonStrictParentOfType(element, PsiMethodCallExpression.class);
if (call == null) return;
PsiExpression qualifier = ExpressionUtils.getEffectiveQualifier(call.getMethodExpression());
if (qualifier == null) return;
@@ -943,7 +942,7 @@ public class RedundantStringOperationInspection extends AbstractBaseJavaLocalIns
}
}
private static final class StringConstructorFix extends InspectionGadgetsFix {
private static final class StringConstructorFix extends PsiUpdateModCommandQuickFix {
private final @IntentionName String myName;
private StringConstructorFix(boolean noArguments) {
@@ -965,8 +964,8 @@ public class RedundantStringOperationInspection extends AbstractBaseJavaLocalIns
}
@Override
public void doFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiNewExpression expression = tryCast(descriptor.getPsiElement().getParent(), PsiNewExpression.class);
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
final PsiNewExpression expression = tryCast(element.getParent(), PsiNewExpression.class);
if (expression == null) return;
final PsiExpressionList argList = expression.getArgumentList();
if (argList == null) return;
@@ -984,7 +983,7 @@ public class RedundantStringOperationInspection extends AbstractBaseJavaLocalIns
return tryCast(resolvedExpression, PsiMethodCallExpression.class);
}
private static final class ByteArrayOutputStreamToStringFix extends InspectionGadgetsFix {
private static final class ByteArrayOutputStreamToStringFix extends PsiUpdateModCommandQuickFix {
private final String myText;
private ByteArrayOutputStreamToStringFix(String text) {
@@ -1004,8 +1003,8 @@ public class RedundantStringOperationInspection extends AbstractBaseJavaLocalIns
}
@Override
public void doFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiNewExpression expression = tryCast(descriptor.getPsiElement().getParent(), PsiNewExpression.class);
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
final PsiNewExpression expression = tryCast(element.getParent(), PsiNewExpression.class);
if (expression == null) return;
final PsiExpressionList args = expression.getArgumentList();
@@ -1030,7 +1029,7 @@ public class RedundantStringOperationInspection extends AbstractBaseJavaLocalIns
}
}
private static final class SubstringToEmptyStringFix extends InspectionGadgetsFix {
private static final class SubstringToEmptyStringFix extends PsiUpdateModCommandQuickFix {
@Override
@NotNull
@@ -1045,14 +1044,14 @@ public class RedundantStringOperationInspection extends AbstractBaseJavaLocalIns
}
@Override
public void doFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiMethodCallExpression expression = tryCast(descriptor.getPsiElement().getParent().getParent(), PsiMethodCallExpression.class);
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
final PsiMethodCallExpression expression = tryCast(element.getParent().getParent(), PsiMethodCallExpression.class);
if (expression == null) return;
new CommentTracker().replaceAndRestoreComments(expression, "\"\"");
}
}
private static final class ReplaceWithValueOfFix extends InspectionGadgetsFix {
private static final class ReplaceWithValueOfFix extends PsiUpdateModCommandQuickFix {
@Override
@NotNull
@@ -1067,8 +1066,8 @@ public class RedundantStringOperationInspection extends AbstractBaseJavaLocalIns
}
@Override
public void doFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiNewExpression expression = tryCast(descriptor.getPsiElement().getParent(), PsiNewExpression.class);
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
final PsiNewExpression expression = tryCast(element.getParent(), PsiNewExpression.class);
if (expression == null) return;
final CharArrayCreationArgument charArrayCreationArgument = CharArrayCreationArgument.from(expression.getArgumentList());
if (charArrayCreationArgument == null) return;
@@ -1078,7 +1077,7 @@ public class RedundantStringOperationInspection extends AbstractBaseJavaLocalIns
}
}
private static final class UnwrapArrayInitializerFix extends InspectionGadgetsFix {
private static final class UnwrapArrayInitializerFix extends PsiUpdateModCommandQuickFix {
private final String myInitializerText;
private UnwrapArrayInitializerFix(String initializerText) {
@@ -1098,8 +1097,8 @@ public class RedundantStringOperationInspection extends AbstractBaseJavaLocalIns
}
@Override
public void doFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiNewExpression expression = tryCast(descriptor.getPsiElement(), PsiNewExpression.class);
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
final PsiNewExpression expression = tryCast(element, PsiNewExpression.class);
if (expression == null) return;
final PsiArrayInitializerExpression initializer = expression.getArrayInitializer();
if (initializer == null || initializer.getInitializers().length != 1) return;
@@ -1,7 +1,8 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.siyeh.ig.redundancy;
import com.intellij.codeInspection.*;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
@@ -91,16 +92,15 @@ public class ReplaceOnLiteralHasNoEffectInspection extends AbstractBaseJavaLocal
};
}
private static class ReplaceOnLiteralWithQualifierFix implements LocalQuickFix {
private static class ReplaceOnLiteralWithQualifierFix extends PsiUpdateModCommandQuickFix {
@Override
public @NotNull String getFamilyName() {
return InspectionGadgetsBundle.message("inspection.redundant.string.fix.family.name");
}
@Override
public void applyFix(@NotNull Project project,
@NotNull ProblemDescriptor descriptor) {
PsiMethodCallExpression call = tryCast(descriptor.getStartElement(), PsiMethodCallExpression.class);
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
PsiMethodCallExpression call = tryCast(element, PsiMethodCallExpression.class);
if (call == null) return;
PsiExpression qualifier = call.getMethodExpression().getQualifierExpression();
if (qualifier == null) return;
@@ -1,10 +1,11 @@
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.siyeh.ig.style;
import com.intellij.codeInspection.CleanupLocalInspectionTool;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.PsiUpdateModCommandQuickFix;
import com.intellij.codeInspection.options.OptPane;
import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
@@ -12,23 +13,21 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
import com.siyeh.ig.InspectionGadgetsFix;
import com.siyeh.ig.psiutils.ClassUtils;
import com.siyeh.ig.psiutils.HighlightUtils;
import com.siyeh.ig.psiutils.ImportUtils;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.*;
import static com.intellij.codeInspection.options.OptPane.*;
import static com.intellij.codeInspection.options.OptPane.checkbox;
import static com.intellij.codeInspection.options.OptPane.pane;
/**
* @author Bas Leijdekkers
*/
public class UnqualifiedInnerClassAccessInspection extends BaseInspection implements CleanupLocalInspectionTool{
@SuppressWarnings({"PublicField"})
@SuppressWarnings("PublicField")
public boolean ignoreReferencesToLocalInnerClasses = true;
@Override
@@ -38,7 +37,7 @@ public class UnqualifiedInnerClassAccessInspection extends BaseInspection implem
}
@Override
protected InspectionGadgetsFix buildFix(Object... infos) {
protected LocalQuickFix buildFix(Object... infos) {
return new UnqualifiedInnerClassAccessFix();
}
@@ -53,7 +52,7 @@ public class UnqualifiedInnerClassAccessInspection extends BaseInspection implem
return new UnqualifiedInnerClassAccessVisitor();
}
private static class UnqualifiedInnerClassAccessFix extends InspectionGadgetsFix {
private static class UnqualifiedInnerClassAccessFix extends PsiUpdateModCommandQuickFix {
@Override
@NotNull
@@ -63,8 +62,7 @@ public class UnqualifiedInnerClassAccessInspection extends BaseInspection implem
}
@Override
protected void doFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiElement element = descriptor.getPsiElement();
protected void applyFix(@NotNull Project project, @NotNull PsiElement element, @NotNull ModPsiUpdater updater) {
if (!(element instanceof PsiJavaCodeReferenceElement referenceElement)) {
return;
}
@@ -118,7 +116,7 @@ public class UnqualifiedInnerClassAccessInspection extends BaseInspection implem
final Collection<PsiJavaCodeReferenceElement> references = referenceCollector.getReferences();
final SmartPointerManager pointerManager = SmartPointerManager.getInstance(project);
final List<SmartPsiElementPointer> pointers = new ArrayList<>();
final List<SmartPsiElementPointer<PsiJavaCodeReferenceElement>> pointers = new ArrayList<>();
for (PsiJavaCodeReferenceElement reference : references) {
final SmartPsiElementPointer<PsiJavaCodeReferenceElement> pointer = pointerManager.createSmartPsiElementPointer(reference);
pointers.add(pointer);
@@ -138,16 +136,12 @@ public class UnqualifiedInnerClassAccessInspection extends BaseInspection implem
document.replaceString(0, document.getTextLength(), text);
documentManager.commitDocument(document);
if (pointers.size() > 1) {
final List<PsiElement> elements = new ArrayList<>();
for (SmartPsiElementPointer pointer : pointers) {
for (var pointer : pointers) {
PsiElement psiElement = pointer.getElement();
if (psiElement != null) {
elements.add(psiElement);
updater.highlight(element);
}
}
if (isOnTheFly()) {
HighlightUtils.highlightElements(elements);
}
}
}
@@ -156,7 +150,6 @@ public class UnqualifiedInnerClassAccessInspection extends BaseInspection implem
if (element == null) {
return out;
}
//noinspection SuspiciousMethodCalls
if (references.contains(element)) {
final String shortClassName = getShortClassName(aClass, new StringBuilder()).toString();
if (isReferenceToTargetClass(shortClassName, aClass, element)) {
@@ -2,7 +2,7 @@ class Test {
void test(int a, int b) {
int i = a + b;
System.out.println(i);
int i1 = a - b;
System.out.println(i1);
int j = a - b;
System.out.println(j);
}
}
@@ -2,7 +2,7 @@ class Test {
void test(int a, int b) {
int i = a + b;
System.out.println(i);
int i1 = a - b;
System.out.println(i1);
int j = a - b;
System.out.println(j);
}
}
@@ -3,7 +3,7 @@ package com.siyeh.igfixes.dataflow.too_broad_scope;
public class ForStatement {
void noCondition() {
<caret>for (var i = 1; ; i++) {
<caret> for (var i = 1; ; i++) {
if (i == 10){
break;
}
@@ -2,21 +2,17 @@
package com.intellij.codeInspection.i18n;
import com.ibm.icu.text.MessagePattern;
import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo;
import com.intellij.codeInspection.*;
import com.intellij.codeInspection.restriction.AnnotationContext;
import com.intellij.codeInspection.restriction.StringFlowUtil;
import com.intellij.ide.highlighter.JavaFileType;
import com.intellij.java.i18n.JavaI18nBundle;
import com.intellij.lang.properties.PropertiesFileType;
import com.intellij.lang.properties.psi.Property;
import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.util.PropertyUtilBase;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.ObjectUtils;
import com.intellij.util.ThreeState;
import one.util.streamex.IntStreamEx;
@@ -160,7 +156,7 @@ public class TitleCapitalizationInspection extends AbstractBaseJavaLocalInspecti
return null;
}
private static class TitleCapitalizationFix implements LocalQuickFix {
private static class TitleCapitalizationFix extends PsiUpdateModCommandQuickFix {
private final Value myTitleValue;
private final Nls.Capitalization myCapitalization;
@@ -176,10 +172,23 @@ public class TitleCapitalizationInspection extends AbstractBaseJavaLocalInspecti
}
@Override
public final void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiElement problemElement = descriptor.getPsiElement();
if (problemElement == null) return;
doFix(project, problemElement);
protected void applyFix(@NotNull Project project, @NotNull PsiElement problemElement, @NotNull ModPsiUpdater updater) {
PsiLiteralExpression literal = updater.getWritable(getTargetLiteral(problemElement));
if (literal != null) {
Value value = Value.of(literal);
if (value == null) return;
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
final PsiExpression newExpression =
factory.createExpressionFromText('"' + StringUtil.escapeStringCharacters(value.fixCapitalization(myCapitalization)) + '"',
problemElement);
literal.replace(newExpression);
}
if (problemElement instanceof PsiMethodCallExpression call) {
final Property property = updater.getWritable(getPropertyArgument(call));
Value value = Value.of(property, call.getArgumentList().getExpressionCount() > 1);
if (value == null) return;
property.setValue(value.fixCapitalization(myCapitalization));
}
}
private static @Nullable PsiLiteralExpression getTargetLiteral(@NotNull PsiElement element) {
@@ -203,57 +212,6 @@ public class TitleCapitalizationInspection extends AbstractBaseJavaLocalInspecti
return null;
}
protected void doFix(@NotNull Project project, @NotNull PsiElement element) throws IncorrectOperationException {
PsiLiteralExpression literal = getTargetLiteral(element);
if (literal != null) {
Value value = Value.of(literal);
if (value == null) return;
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
final PsiExpression newExpression =
factory.createExpressionFromText('"' + StringUtil.escapeStringCharacters(value.fixCapitalization(myCapitalization)) + '"',
element);
literal.replace(newExpression);
}
if (element instanceof PsiMethodCallExpression call) {
final Property property = getPropertyArgument(call);
Value value = Value.of(property, call.getArgumentList().getExpressionCount() > 1);
if (value == null) return;
property.setValue(value.fixCapitalization(myCapitalization));
}
}
@Override
public @NotNull IntentionPreviewInfo generatePreview(@NotNull Project project, @NotNull ProblemDescriptor previewDescriptor) {
PsiElement element = previewDescriptor.getStartElement();
PsiLiteralExpression literal = getTargetLiteral(element);
if (literal != null) {
PsiFile file = literal.getContainingFile();
if (file == element.getContainingFile()) {
doFix(project, element);
return IntentionPreviewInfo.DIFF;
}
PsiElement parent = literal.getParent();
Value value = Value.of(literal);
if (value == null) return IntentionPreviewInfo.EMPTY;
Object mark = PsiTreeUtil.mark(literal);
PsiElement copyParent = parent.copy();
PsiLiteralExpression copyLiteral = (PsiLiteralExpression)Objects.requireNonNull(PsiTreeUtil.releaseMark(copyParent, mark));
String newLiteral = '"' + StringUtil.escapeStringCharacters(value.fixCapitalization(myCapitalization)) + '"';
copyLiteral.replace(JavaPsiFacade.getElementFactory(project).createExpressionFromText(newLiteral, null));
return new IntentionPreviewInfo.CustomDiff(JavaFileType.INSTANCE, file.getName(), parent.getText(), copyParent.getText());
}
if (element instanceof PsiMethodCallExpression call) {
final Property property = getPropertyArgument(call);
Value value = Value.of(property, call.getArgumentList().getExpressionCount() > 1);
if (value == null) return IntentionPreviewInfo.EMPTY;
Property copy = (Property)property.copy();
copy.setValue(value.fixCapitalization(myCapitalization));
return new IntentionPreviewInfo.CustomDiff(PropertiesFileType.INSTANCE, property.getContainingFile().getName(), property.getText(),
copy.getText());
}
return IntentionPreviewInfo.EMPTY;
}
@Nullable
private static Property getPropertyArgument(PsiMethodCallExpression arg) {
PsiExpression[] args = arg.getArgumentList().getExpressions();
@@ -38,7 +38,7 @@ class X {
}
void main(int x) {
test(<warning descr="String 'hello world' is not properly capitalized. It should have title capitalization">message("property.lowercase")</warning>);
test(<warning descr="String 'hello world' is not properly capitalized. It should have title capitalization"><caret>message("property.lowercase")</warning>);
test(message("property.titlecase"));
test(message("property.unknown"));
test(message("property.parameterized", "World"));
@@ -1,10 +1,11 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInspection;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInspection.capitalization.AnnotateCapitalizationIntention;
import com.intellij.codeInspection.i18n.TitleCapitalizationInspection;
import com.intellij.openapi.application.PluginPathManager;
import com.intellij.openapi.application.impl.NonBlockingReadActionImpl;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.testFramework.LightProjectDescriptor;
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
@@ -94,6 +95,19 @@ public class CapitalizationInspectionTest extends LightJavaCodeInsightFixtureTes
property.icu4j.title=Generate Code with {0, plural, one {Foo} other {Bar}}""";
myFixture.addFileToProject("MyBundle.properties", props);
doTest(false);
IntentionAction action = myFixture.findSingleIntention("Properly capitalize");
assertEquals("""
property.lowercase=Hello World
property.titlecase=Hello World
property.titlecase.html=<html><b>Hello</b> World</html>
property.parameterized=Hello {0}
property.choice.title=Hello {0,choice,0#World|1#Universe}
property.choice.mixed=Hello {0,choice,0#World|1#universe}
property.choice.lower=Hello {0,choice,0#world|1#universe}
property.choice.sentence.start={0,choice,0#No|1#{0}} {0,choice,0#occurrences|1#occurrence|2#occurrences} found so far
property.sentence.with.quote='return' is not allowed here
property.with.underscore.mnemonic=Subm_it
property.icu4j.title=Generate Code with {0, plural, one {Foo} other {Bar}}""", myFixture.getIntentionPreviewText(action));
}
public void testRecursiveMethod() {
@@ -106,6 +120,7 @@ public class CapitalizationInspectionTest extends LightJavaCodeInsightFixtureTes
AnnotateCapitalizationIntention intention = new AnnotateCapitalizationIntention();
assertTrue(intention.isAvailable(getProject(), getEditor(), getFile()));
intention.invoke(getProject(), getEditor(), getFile());
NonBlockingReadActionImpl.waitForAsyncTaskCompletion();
myFixture.checkResultByFile("Intention_after.java");
assertFalse(intention.isAvailable(getProject(), getEditor(), getFile()));
}
@@ -116,6 +131,7 @@ public class CapitalizationInspectionTest extends LightJavaCodeInsightFixtureTes
final IntentionAction action = myFixture.filterAvailableIntentions("Properly capitalize").get(0);
WriteCommandAction.writeCommandAction(getProject()).run(() -> action.invoke(getProject(), myFixture.getEditor(), getFile()));
NonBlockingReadActionImpl.waitForAsyncTaskCompletion();
myFixture.checkResultByFile(getTestName(false) + "_after.java");
}