mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-16 14:23:28 +07:00
[java-intentions] More ModCommands (IDEA-322693)
GitOrigin-RevId: ac544ca3f30695ccf6f8c389444d6ab6bb182ade
This commit is contained in:
committed by
intellij-monorepo-bot
parent
555d12b0d2
commit
5ad96f7b38
@@ -119,7 +119,7 @@ final class ModuleHighlightUtil {
|
||||
.descriptionAndTooltip(message);
|
||||
rootModuleInfos.stream().map(f -> PsiManager.getInstance(project).findFile(f)).filter(f -> f != file).findFirst().ifPresent(
|
||||
duplicate -> {
|
||||
IntentionAction action = new GoToSymbolFix(duplicate, JavaErrorBundle
|
||||
var action = new GoToSymbolFix(duplicate, JavaErrorBundle
|
||||
.message("module.open.duplicate.text"));
|
||||
info.registerFix(action, null, null, null, null);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import com.intellij.codeInsight.daemon.QuickFixBundle;
|
||||
import com.intellij.codeInsight.intention.impl.BaseIntentionAction;
|
||||
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
|
||||
import com.intellij.codeInspection.util.IntentionName;
|
||||
import com.intellij.openapi.command.undo.UndoUtil;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -97,7 +96,6 @@ public class ExtendsListFix extends LocalQuickFixAndIntentionActionOnPsiElement
|
||||
@NotNull PsiElement endElement) {
|
||||
final PsiClass myClass = (PsiClass)startElement;
|
||||
invokeImpl(myClass);
|
||||
UndoUtil.markPsiFileForUndo(file);
|
||||
}
|
||||
|
||||
protected void invokeImpl(PsiClass myClass) {
|
||||
|
||||
@@ -1,62 +1,36 @@
|
||||
// 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.intention.IntentionAction;
|
||||
import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo;
|
||||
import com.intellij.codeInspection.util.IntentionName;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.modcommand.ModCommand;
|
||||
import com.intellij.modcommand.ModNavigate;
|
||||
import com.intellij.modcommand.PsiBasedModCommandAction;
|
||||
import com.intellij.psi.NavigatablePsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.SmartPointerManager;
|
||||
import com.intellij.psi.SmartPsiElementPointer;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class GoToSymbolFix implements IntentionAction {
|
||||
private final SmartPsiElementPointer<NavigatablePsiElement> myPointer;
|
||||
public class GoToSymbolFix extends PsiBasedModCommandAction<NavigatablePsiElement> {
|
||||
private final @IntentionName String myMessage;
|
||||
|
||||
public GoToSymbolFix(@NotNull NavigatablePsiElement symbol, @NotNull @Nls String message) {
|
||||
myPointer = SmartPointerManager.getInstance(symbol.getProject()).createSmartPsiElementPointer(symbol);
|
||||
super(symbol);
|
||||
myMessage = message;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
public String getFamilyName() {
|
||||
return myMessage;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return getText();
|
||||
protected @NotNull ModCommand perform(@NotNull ActionContext context, @NotNull NavigatablePsiElement element) {
|
||||
return new ModNavigate(element.getContainingFile().getVirtualFile(), 0, 0, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
return myPointer.getElement() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
NavigatablePsiElement e = myPointer.getElement();
|
||||
if (e != null && e.isValid()) {
|
||||
e.navigate(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull IntentionPreviewInfo generatePreview(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
|
||||
NavigatablePsiElement element = myPointer.getElement();
|
||||
if (element == null) return IntentionPreviewInfo.EMPTY;
|
||||
protected @NotNull IntentionPreviewInfo generatePreview(ActionContext context, NavigatablePsiElement element) {
|
||||
return IntentionPreviewInfo.navigate(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,74 +1,51 @@
|
||||
// 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.intellij.codeInsight.daemon.impl.quickfix;
|
||||
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.codeInsight.intention.FileModifier;
|
||||
import com.intellij.codeInsight.intention.HighPriorityAction;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInsight.intention.impl.BaseIntentionAction;
|
||||
import com.intellij.codeInsight.intention.PriorityAction;
|
||||
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.modcommand.ModPsiUpdater;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.siyeh.ig.psiutils.CommentTracker;
|
||||
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
|
||||
import it.unimi.dsi.fastutil.ints.IntSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public final class MoveParenthesisFix implements IntentionAction, HighPriorityAction {
|
||||
private final PsiCallExpression myCall;
|
||||
public final class MoveParenthesisFix extends PsiUpdateModCommandAction<PsiCallExpression> {
|
||||
private final int myPos;
|
||||
private final int myShiftSize;
|
||||
|
||||
public MoveParenthesisFix(PsiCallExpression call, int pos, int shiftSize) {
|
||||
myCall = call;
|
||||
super(call);
|
||||
myPos = pos;
|
||||
myShiftSize = shiftSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @IntentionName @NotNull String getText() {
|
||||
public @NotNull @IntentionFamilyName String getFamilyName() {
|
||||
return QuickFixBundle.message("intention.move.parenthesis.name");
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull @IntentionFamilyName String getFamilyName() {
|
||||
return getText();
|
||||
protected @NotNull Presentation getPresentation(@NotNull ActionContext context, @NotNull PsiCallExpression element) {
|
||||
return Presentation.of(getFamilyName()).withPriority(PriorityAction.Priority.HIGH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
return !project.isDisposed() && myCall.isValid() && BaseIntentionAction.canModify(myCall);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
PsiCallExpression copy = copyWithShift(myCall, myPos, myShiftSize);
|
||||
protected void invoke(@NotNull ActionContext context, @NotNull PsiCallExpression call, @NotNull ModPsiUpdater updater) {
|
||||
PsiCallExpression copy = copyWithShift(call, myPos, myShiftSize);
|
||||
if (copy != null) {
|
||||
new CommentTracker().replaceAndRestoreComments(myCall, copy);
|
||||
new CommentTracker().replaceAndRestoreComments(call, copy);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull FileModifier getFileModifierForPreview(@NotNull PsiFile target) {
|
||||
return new MoveParenthesisFix(PsiTreeUtil.findSameElementInCopy(myCall, target), myPos, myShiftSize);
|
||||
}
|
||||
|
||||
private static PsiCallExpression copyWithShift(PsiCallExpression parentCall, int pos, int shift) {
|
||||
PsiCallExpression parentCopy = (PsiCallExpression)parentCall.copy();
|
||||
|
||||
@@ -100,7 +100,7 @@ public abstract class DeprecationInspectionBase extends LocalInspectionTool {
|
||||
if (deprecatedElement instanceof PsiMethod method && methodCall != null) {
|
||||
PsiMethod replacement = findReplacementInJavaDoc(method, methodCall);
|
||||
if (replacement != null) {
|
||||
return new ReplaceMethodCallFix((PsiMethodCallExpression)elementToHighlight.getParent().getParent(), replacement);
|
||||
return new ReplaceMethodCallFix((PsiMethodCallExpression)elementToHighlight.getParent().getParent(), replacement).asQuickFix();
|
||||
}
|
||||
}
|
||||
if (deprecatedElement instanceof PsiField field) {
|
||||
@@ -108,7 +108,7 @@ public abstract class DeprecationInspectionBase extends LocalInspectionTool {
|
||||
if (referenceExpression != null) {
|
||||
PsiMember replacement = findReplacementInJavaDoc(field, referenceExpression);
|
||||
if (replacement != null) {
|
||||
return new ReplaceFieldReferenceFix(referenceExpression, replacement);
|
||||
return new ReplaceFieldReferenceFix(referenceExpression, replacement).asQuickFix();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +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.deprecation
|
||||
|
||||
import com.intellij.codeInsight.intention.FileModifier.SafeFieldForPreview
|
||||
import com.intellij.codeInspection.LocalQuickFixOnPsiElement
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.codeInspection.PsiUpdateModCommandAction
|
||||
import com.intellij.modcommand.ModCommandAction
|
||||
import com.intellij.modcommand.ModCommandAction.Presentation
|
||||
import com.intellij.modcommand.ModPsiUpdater
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager
|
||||
import com.intellij.psi.util.PsiFormatUtil
|
||||
@@ -40,15 +27,15 @@ private fun generateQualifierText(expr: PsiReferenceExpression,
|
||||
}
|
||||
}
|
||||
|
||||
internal class ReplaceMethodCallFix(expr: PsiMethodCallExpression, replacementMethod: PsiMethod) : LocalQuickFixOnPsiElement(expr) {
|
||||
@SafeFieldForPreview
|
||||
internal class ReplaceMethodCallFix(expr: PsiMethodCallExpression, replacementMethod: PsiMethod) :
|
||||
PsiUpdateModCommandAction<PsiMethodCallExpression>(expr) {
|
||||
private val myReplacementMethodPointer =
|
||||
SmartPointerManager.getInstance(replacementMethod.project).createSmartPsiElementPointer(replacementMethod)
|
||||
private val myReplacementText =
|
||||
PsiFormatUtil.formatMethod(replacementMethod, PsiSubstitutor.EMPTY, PsiFormatUtilBase.SHOW_CONTAINING_CLASS or PsiFormatUtilBase.SHOW_NAME, 0)
|
||||
|
||||
override fun getText(): String {
|
||||
return InspectionGadgetsBundle.message("replace.method.call.fix.text", myReplacementText)
|
||||
override fun getPresentation(context: ModCommandAction.ActionContext, element: PsiMethodCallExpression): Presentation {
|
||||
return Presentation.of(InspectionGadgetsBundle.message("replace.method.call.fix.text", myReplacementText))
|
||||
}
|
||||
|
||||
@Nls
|
||||
@@ -56,12 +43,12 @@ internal class ReplaceMethodCallFix(expr: PsiMethodCallExpression, replacementMe
|
||||
return InspectionGadgetsBundle.message("replace.method.call.fix.family.name")
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, file: PsiFile, startElement: PsiElement, endElement: PsiElement) {
|
||||
val expr = (startElement as? PsiMethodCallExpression) ?: return
|
||||
override fun invoke(context: ModCommandAction.ActionContext, expr: PsiMethodCallExpression, updater: ModPsiUpdater) {
|
||||
val replacementMethod = myReplacementMethodPointer.element ?: return
|
||||
|
||||
val qualifierText = generateQualifierText(expr.methodExpression, replacementMethod)
|
||||
|
||||
val project = context.project
|
||||
val elementFactory = JavaPsiFacade.getElementFactory(project)
|
||||
val newMethodCall = elementFactory.createExpressionFromText(qualifierText + replacementMethod.name + expr.argumentList.text, expr)
|
||||
val replaced = expr.replace(newMethodCall) as PsiMethodCallExpression
|
||||
@@ -69,8 +56,8 @@ internal class ReplaceMethodCallFix(expr: PsiMethodCallExpression, replacementMe
|
||||
}
|
||||
}
|
||||
|
||||
internal class ReplaceFieldReferenceFix(expr: PsiReferenceExpression, replacementMember: PsiMember) : LocalQuickFixOnPsiElement(expr) {
|
||||
@SafeFieldForPreview
|
||||
internal class ReplaceFieldReferenceFix(expr: PsiReferenceExpression, replacementMember: PsiMember) :
|
||||
PsiUpdateModCommandAction<PsiReferenceExpression>(expr) {
|
||||
private val myReplacementMemberPointer =
|
||||
SmartPointerManager.getInstance(replacementMember.project).createSmartPsiElementPointer(replacementMember)
|
||||
private val myReplacementText =
|
||||
@@ -87,16 +74,16 @@ internal class ReplaceFieldReferenceFix(expr: PsiReferenceExpression, replacemen
|
||||
return InspectionGadgetsBundle.message("replace.field.reference.fix.family.name")
|
||||
}
|
||||
|
||||
override fun getText(): String {
|
||||
return InspectionGadgetsBundle.message("replace.field.reference.fix.text", myReplacementText)
|
||||
override fun getPresentation(context: ModCommandAction.ActionContext, element: PsiReferenceExpression): Presentation {
|
||||
return Presentation.of(InspectionGadgetsBundle.message("replace.field.reference.fix.text", myReplacementText))
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, file: PsiFile, startElement: PsiElement, endElement: PsiElement) {
|
||||
val expr = (startElement as? PsiReferenceExpression) ?: return
|
||||
override fun invoke(context: ModCommandAction.ActionContext, expr: PsiReferenceExpression, updater: ModPsiUpdater) {
|
||||
val replacementMember = myReplacementMemberPointer.element ?: return
|
||||
|
||||
val qualifierText = generateQualifierText(expr, replacementMember)
|
||||
|
||||
val project = context.project
|
||||
val replaced = expr.replace(JavaPsiFacade.getElementFactory(project).createExpressionFromText(
|
||||
qualifierText + replacementMember.name + (if (replacementMember is PsiMethod) "()" else ""), expr))
|
||||
JavaCodeStyleManager.getInstance(project).shortenClassReferences(replaced)
|
||||
|
||||
@@ -187,7 +187,7 @@ move.class.to.package.family=Move Class to Package
|
||||
move.class.to.package.text=Move to package ''{0}''
|
||||
|
||||
# change if (!a == b) ... => if (!(a == b)) ...
|
||||
negation.broader.scope.family=Negation Broader Scope
|
||||
negation.broader.scope.family=Negation broader scope
|
||||
negation.broader.scope.text=Change to ''!({0})''
|
||||
|
||||
optimize.imports.fix=Optimize imports
|
||||
|
||||
@@ -2,56 +2,51 @@
|
||||
package com.intellij.codeInsight.daemon.impl.quickfix;
|
||||
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle;
|
||||
import com.intellij.codeInsight.intention.FileModifier;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
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.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* if (!a == b) ... => if (!(a == b)) ...
|
||||
*/
|
||||
public class NegationBroadScopeFix implements IntentionAction {
|
||||
private final PsiPrefixExpression myPrefixExpression;
|
||||
|
||||
public class NegationBroadScopeFix extends PsiUpdateModCommandAction<PsiPrefixExpression> {
|
||||
public NegationBroadScopeFix(@NotNull PsiPrefixExpression prefixExpression) {
|
||||
myPrefixExpression = prefixExpression;
|
||||
super(prefixExpression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable FileModifier getFileModifierForPreview(@NotNull PsiFile target) {
|
||||
return new NegationBroadScopeFix(PsiTreeUtil.findSameElementInCopy(myPrefixExpression, target));
|
||||
}
|
||||
protected @Nullable Presentation getPresentation(@NotNull ActionContext context, @NotNull PsiPrefixExpression expression) {
|
||||
PsiExpression operand = expression.getOperand();
|
||||
if (operand == null) return null;
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getText() {
|
||||
PsiExpression operand = myPrefixExpression.getOperand();
|
||||
String text = operand == null ? "" : operand.getText() + " ";
|
||||
PsiElement parent = myPrefixExpression.getParent();
|
||||
PsiElement parent = expression.getParent();
|
||||
String text = operand.getText() + " ";
|
||||
|
||||
String rop;
|
||||
if (parent instanceof PsiInstanceOfExpression) {
|
||||
if (parent instanceof PsiInstanceOfExpression instanceOf) {
|
||||
if (instanceOf.getOperand() != expression) return null;
|
||||
text += PsiKeyword.INSTANCEOF + " ";
|
||||
final PsiTypeElement typeElement = ((PsiInstanceOfExpression)parent).getCheckType();
|
||||
final PsiTypeElement typeElement = instanceOf.getCheckType();
|
||||
rop = typeElement == null ? "" : typeElement.getText();
|
||||
}
|
||||
else if (parent instanceof PsiBinaryExpression) {
|
||||
text += ((PsiBinaryExpression)parent).getOperationSign().getText() + " ";
|
||||
final PsiExpression rOperand = ((PsiBinaryExpression)parent).getROperand();
|
||||
else if (parent instanceof PsiBinaryExpression binaryExpression) {
|
||||
if (binaryExpression.getLOperand() != expression) return null;
|
||||
if (!TypeConversionUtil.isBooleanType(binaryExpression.getType())) return null;
|
||||
text += binaryExpression.getOperationSign().getText() + " ";
|
||||
final PsiExpression rOperand = binaryExpression.getROperand();
|
||||
rop = rOperand == null ? "" : rOperand.getText();
|
||||
}
|
||||
else {
|
||||
rop = "<expr>";
|
||||
return null;
|
||||
}
|
||||
|
||||
text += rop;
|
||||
return QuickFixBundle.message("negation.broader.scope.text", text);
|
||||
return Presentation.of(QuickFixBundle.message("negation.broader.scope.text", text));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -61,40 +56,15 @@ public class NegationBroadScopeFix implements IntentionAction {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
if (!myPrefixExpression.isValid() || myPrefixExpression.getOperand() == null) return false;
|
||||
|
||||
PsiElement parent = myPrefixExpression.getParent();
|
||||
if (parent instanceof PsiInstanceOfExpression && ((PsiInstanceOfExpression)parent).getOperand() == myPrefixExpression) {
|
||||
return true;
|
||||
}
|
||||
return parent instanceof PsiBinaryExpression binaryExpression &&
|
||||
binaryExpression.getLOperand() == myPrefixExpression &&
|
||||
TypeConversionUtil.isBooleanType(binaryExpression.getType());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiElement getElementToMakeWritable(@NotNull PsiFile file) {
|
||||
return myPrefixExpression.getContainingFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
if (!isAvailable(project, editor, file)) return;
|
||||
PsiExpression operand = myPrefixExpression.getOperand();
|
||||
protected void invoke(@NotNull ActionContext context, @NotNull PsiPrefixExpression myPrefixExpression, @NotNull ModPsiUpdater updater) {
|
||||
PsiExpression operand = Objects.requireNonNull(myPrefixExpression.getOperand());
|
||||
PsiElement unnegated = myPrefixExpression.replace(operand);
|
||||
PsiElement parent = unnegated.getParent();
|
||||
PsiElementFactory factory = JavaPsiFacade.getElementFactory(file.getProject());
|
||||
PsiElementFactory factory = JavaPsiFacade.getElementFactory(context.project());
|
||||
|
||||
PsiPrefixExpression negated = (PsiPrefixExpression)factory.createExpressionFromText("!(xxx)", parent);
|
||||
PsiParenthesizedExpression parentheses = (PsiParenthesizedExpression)negated.getOperand();
|
||||
parentheses.getExpression().replace(parent.copy());
|
||||
PsiParenthesizedExpression parentheses = (PsiParenthesizedExpression)Objects.requireNonNull(negated.getOperand());
|
||||
Objects.requireNonNull(parentheses.getExpression()).replace(parent.copy());
|
||||
parent.replace(negated);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
// 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.intention.PsiElementBaseIntentionAction;
|
||||
import com.intellij.codeInsight.intention.preview.IntentionPreviewUtils;
|
||||
import com.intellij.codeInspection.PsiUpdateModCommandAction;
|
||||
import com.intellij.java.JavaBundle;
|
||||
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 com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
import com.intellij.psi.impl.source.DummyHolder;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.refactoring.util.LambdaRefactoringUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.siyeh.ig.psiutils.CommentTracker;
|
||||
import com.siyeh.ig.psiutils.ExpressionUtils;
|
||||
import com.siyeh.ig.psiutils.ParenthesesUtils;
|
||||
@@ -25,7 +23,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class InlineStreamMapAction extends PsiElementBaseIntentionAction {
|
||||
public class InlineStreamMapAction extends PsiUpdateModCommandAction<PsiIdentifier> {
|
||||
private static final Logger LOG = Logger.getInstance(InlineStreamMapAction.class.getName());
|
||||
public static final class Holder {
|
||||
private static final Set<String> MAP_METHODS =
|
||||
@@ -35,21 +33,23 @@ public class InlineStreamMapAction extends PsiElementBaseIntentionAction {
|
||||
.of("flatMap", "flatMapToInt", "flatMapToLong", "flatMapToDouble", "forEach", "forEachOrdered", "anyMatch", "noneMatch", "allMatch")
|
||||
.append(MAP_METHODS).toSet();
|
||||
}
|
||||
|
||||
public InlineStreamMapAction() {
|
||||
super(PsiIdentifier.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull final PsiElement element) {
|
||||
if (!(element instanceof PsiIdentifier)) return false;
|
||||
protected @Nullable Presentation getPresentation(@NotNull ActionContext context, @NotNull PsiIdentifier element) {
|
||||
final PsiElement parent = element.getParent();
|
||||
if (!(parent instanceof PsiReferenceExpression)) return false;
|
||||
if (!(parent instanceof PsiReferenceExpression)) return null;
|
||||
final PsiElement gParent = parent.getParent();
|
||||
if (!(gParent instanceof PsiMethodCallExpression curCall)) return false;
|
||||
if (!isMapCall(curCall)) return false;
|
||||
if (!(gParent instanceof PsiMethodCallExpression curCall)) return null;
|
||||
if (!isMapCall(curCall)) return null;
|
||||
PsiMethodCallExpression nextCall = getNextExpressionToMerge(curCall);
|
||||
if(nextCall == null) return false;
|
||||
if(nextCall == null) return null;
|
||||
String key = curCall.getArgumentList().isEmpty() || nextCall.getArgumentList().isEmpty() ?
|
||||
"intention.inline.map.merge.text" : "intention.inline.map.inline.text";
|
||||
setText(JavaBundle.message(key, element.getText(), nextCall.getMethodExpression().getReferenceName()));
|
||||
return true;
|
||||
return Presentation.of(JavaBundle.message(key, element.getText(), nextCall.getMethodExpression().getReferenceName()));
|
||||
}
|
||||
|
||||
private static boolean isMapCall(@NotNull PsiMethodCallExpression methodCallExpression) {
|
||||
@@ -165,7 +165,7 @@ public class InlineStreamMapAction extends PsiElementBaseIntentionAction {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
|
||||
protected void invoke(@NotNull ActionContext context, @NotNull PsiIdentifier element, @NotNull ModPsiUpdater updater) {
|
||||
PsiMethodCallExpression mapCall = PsiTreeUtil.getParentOfType(element, PsiMethodCallExpression.class);
|
||||
if(mapCall == null) return;
|
||||
|
||||
@@ -190,7 +190,7 @@ public class InlineStreamMapAction extends PsiElementBaseIntentionAction {
|
||||
|
||||
CommentTracker ct = new CommentTracker();
|
||||
|
||||
if (!lambda.isPhysical() && !IntentionPreviewUtils.isPreviewElement(lambda)) {
|
||||
if (lambda.getContainingFile() instanceof DummyHolder) {
|
||||
lambda = (PsiLambdaExpression)nextCall.getArgumentList().add(lambda);
|
||||
}
|
||||
PsiElement body = lambda.getBody();
|
||||
@@ -201,7 +201,7 @@ public class InlineStreamMapAction extends PsiElementBaseIntentionAction {
|
||||
LOG.assertTrue(nextParameters.length == 1);
|
||||
PsiParameter[] prevParameters = previousLambda.getParameterList().getParameters();
|
||||
LOG.assertTrue(prevParameters.length == 1);
|
||||
PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
|
||||
PsiElementFactory factory = JavaPsiFacade.getElementFactory(context.project());
|
||||
for(PsiReferenceExpression ref : VariableAccessUtils.getVariableReferences(nextParameters[0], body)) {
|
||||
PsiExpression replacement = ct.markUnchanged(previousBody);
|
||||
if (ref.getParent() instanceof PsiExpression &&
|
||||
@@ -221,7 +221,7 @@ public class InlineStreamMapAction extends PsiElementBaseIntentionAction {
|
||||
} else {
|
||||
ct.replaceAndRestoreComments(nextQualifier, prevQualifier);
|
||||
}
|
||||
CodeStyleManager.getInstance(project).reformat(lambda);
|
||||
CodeStyleManager.getInstance(context.project()).reformat(lambda);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -295,7 +295,7 @@ public final class QuickFixFactoryImpl extends QuickFixFactory {
|
||||
@NotNull
|
||||
@Override
|
||||
public IntentionAction createNegationBroadScopeFix(@NotNull PsiPrefixExpression expr) {
|
||||
return new NegationBroadScopeFix(expr);
|
||||
return new NegationBroadScopeFix(expr).asIntention();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// "Change to '!(1 == 1)'" "true-preview"
|
||||
public class Foo {
|
||||
void task() {
|
||||
if (<caret>!(1 == 1)) {}
|
||||
if (!<caret>(1 == 1)) {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,45 +1,31 @@
|
||||
/*
|
||||
* 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.siyeh.ig.inheritance;
|
||||
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInsight.intention.QuickFixFactory;
|
||||
import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo;
|
||||
import com.intellij.codeInspection.ModCommands;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.java.analysis.JavaAnalysisBundle;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.progress.Task;
|
||||
import com.intellij.modcommand.ModCommand;
|
||||
import com.intellij.modcommand.ModCommandAction;
|
||||
import com.intellij.modcommand.ModCommandQuickFix;
|
||||
import com.intellij.modcommand.ModPsiUpdater;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.DebugUtil;
|
||||
import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.search.SearchScope;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.Query;
|
||||
import com.siyeh.InspectionGadgetsBundle;
|
||||
import com.siyeh.ig.InspectionGadgetsFix;
|
||||
import com.siyeh.ig.psiutils.ClassUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
class StaticInheritanceFix extends InspectionGadgetsFix {
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
class StaticInheritanceFix extends ModCommandQuickFix {
|
||||
private final boolean myReplaceInWholeProject;
|
||||
|
||||
StaticInheritanceFix(boolean replaceInWholeProject) {
|
||||
@@ -61,17 +47,8 @@ class StaticInheritanceFix extends InspectionGadgetsFix {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFix(final @NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
doFix(project, descriptor, false);
|
||||
}
|
||||
|
||||
private void doFix(final Project project, ProblemDescriptor descriptor, boolean inPreview) {
|
||||
final PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement)descriptor.getPsiElement();
|
||||
public @NotNull ModCommand perform(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
final PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement)descriptor.getStartElement();
|
||||
final PsiClass iface = (PsiClass)referenceElement.resolve();
|
||||
assert iface != null;
|
||||
final PsiField[] allFields = iface.getAllFields();
|
||||
@@ -80,83 +57,58 @@ class StaticInheritanceFix extends InspectionGadgetsFix {
|
||||
assert implementingClass != null;
|
||||
final PsiFile file = implementingClass.getContainingFile();
|
||||
|
||||
if (inPreview) {
|
||||
processUsages(allFields, implementingClass, project, true, iface, file);
|
||||
} else {
|
||||
ProgressManager.getInstance().run(new Task.Modal(project,
|
||||
JavaAnalysisBundle.message("static.inheritrance.fix.replace.progress", iface.getName()), false) {
|
||||
|
||||
@Override
|
||||
public void run(@NotNull ProgressIndicator indicator) {
|
||||
processUsages(allFields, implementingClass, project, false, iface, file);
|
||||
}
|
||||
});
|
||||
}
|
||||
return ModCommands.psiUpdate(ModCommandAction.ActionContext.from(descriptor), updater ->
|
||||
processUsages(allFields, implementingClass, project, iface, file, updater));
|
||||
}
|
||||
|
||||
private void processUsages(PsiField[] allFields,
|
||||
PsiClass implementingClass,
|
||||
Project project,
|
||||
boolean inPreview,
|
||||
PsiClass iface,
|
||||
PsiFile file) {
|
||||
private void processUsages(@NotNull PsiField @NotNull [] allFields,
|
||||
PsiClass implementingClass,
|
||||
Project project,
|
||||
PsiClass iface,
|
||||
PsiFile file,
|
||||
@NotNull ModPsiUpdater updater) {
|
||||
Map<PsiReferenceExpression, PsiClass> replacements = findReplacements(allFields, implementingClass, updater);
|
||||
PsiClassType classType = JavaPsiFacade.getInstance(project).getElementFactory().createType(iface);
|
||||
IntentionAction fix = QuickFixFactory.getInstance().createExtendsListFix(updater.getWritable(implementingClass), classType, false);
|
||||
fix.invoke(project, null, file);
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
|
||||
replacements.forEach((referenceExpression, containingClass) -> {
|
||||
final PsiReferenceExpression qualified = (PsiReferenceExpression)
|
||||
elementFactory.createExpressionFromText("xxx." + referenceExpression.getText(), referenceExpression);
|
||||
final PsiReferenceExpression newReference = (PsiReferenceExpression)referenceExpression.replace(qualified);
|
||||
final PsiReferenceExpression qualifier = (PsiReferenceExpression)newReference.getQualifierExpression();
|
||||
assert qualifier != null : DebugUtil.psiToString(newReference, true);
|
||||
qualifier.bindToElement(containingClass);
|
||||
});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Map<PsiReferenceExpression, PsiClass> findReplacements(@NotNull PsiField @NotNull [] allFields,
|
||||
@NotNull PsiClass implementingClass,
|
||||
@NotNull ModPsiUpdater updater) {
|
||||
Map<PsiReferenceExpression, PsiClass> replacements = new LinkedHashMap<>();
|
||||
for (final PsiField field : allFields) {
|
||||
SearchScope scope = ReadAction.compute(() -> implementingClass.getUseScope());
|
||||
if (inPreview) {
|
||||
scope = scope.intersectWith(new LocalSearchScope(file));
|
||||
}
|
||||
SearchScope scope = implementingClass.getUseScope();
|
||||
final Query<PsiReference> search = ReferencesSearch.search(field, scope, false);
|
||||
for (PsiReference reference : search) {
|
||||
if (!(reference instanceof PsiReferenceExpression referenceExpression)) {
|
||||
continue;
|
||||
}
|
||||
if (!myReplaceInWholeProject) {
|
||||
boolean isInheritor =
|
||||
ReadAction.compute(() -> {
|
||||
boolean isInheritor1 = false;
|
||||
PsiClass aClass = PsiTreeUtil.getParentOfType(referenceExpression, PsiClass.class);
|
||||
while (aClass != null) {
|
||||
isInheritor1 = InheritanceUtil.isInheritorOrSelf(aClass, implementingClass, true);
|
||||
if (isInheritor1) break;
|
||||
aClass = PsiTreeUtil.getParentOfType(aClass, PsiClass.class);
|
||||
}
|
||||
return isInheritor1;
|
||||
});
|
||||
boolean isInheritor = false;
|
||||
PsiClass aClass = PsiTreeUtil.getParentOfType(referenceExpression, PsiClass.class);
|
||||
while (aClass != null) {
|
||||
isInheritor = InheritanceUtil.isInheritorOrSelf(aClass, implementingClass, true);
|
||||
if (isInheritor) break;
|
||||
aClass = PsiTreeUtil.getParentOfType(aClass, PsiClass.class);
|
||||
}
|
||||
if (!isInheritor) continue;
|
||||
}
|
||||
final Runnable runnable = () -> {
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
|
||||
final PsiReferenceExpression qualified = (PsiReferenceExpression)
|
||||
elementFactory.createExpressionFromText("xxx." + referenceExpression.getText(), referenceExpression);
|
||||
final PsiReferenceExpression newReference = (PsiReferenceExpression)referenceExpression.replace(qualified);
|
||||
final PsiReferenceExpression qualifier = (PsiReferenceExpression)newReference.getQualifierExpression();
|
||||
assert qualifier != null : DebugUtil.psiToString(newReference, true);
|
||||
final PsiClass containingClass = field.getContainingClass();
|
||||
qualifier.bindToElement(containingClass);
|
||||
};
|
||||
if (inPreview) {
|
||||
runnable.run();
|
||||
} else {
|
||||
WriteCommandAction.runWriteCommandAction(project, null, null, runnable,
|
||||
ReadAction.compute(() -> referenceExpression.getContainingFile()));
|
||||
}
|
||||
|
||||
final PsiClass containingClass = Objects.requireNonNull(field.getContainingClass());
|
||||
replacements.put(updater.getWritable(referenceExpression), containingClass);
|
||||
}
|
||||
}
|
||||
final Runnable runnable = () -> {
|
||||
PsiClassType classType = JavaPsiFacade.getInstance(project).getElementFactory().createType(iface);
|
||||
IntentionAction fix = QuickFixFactory.getInstance().createExtendsListFix(implementingClass, classType, false);
|
||||
fix.invoke(project, null, file);
|
||||
};
|
||||
if (inPreview) {
|
||||
runnable.run();
|
||||
} else {
|
||||
WriteCommandAction.runWriteCommandAction(project, null, null, runnable, file);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull IntentionPreviewInfo generatePreview(@NotNull Project project, @NotNull ProblemDescriptor previewDescriptor) {
|
||||
doFix(project, previewDescriptor, true);
|
||||
return IntentionPreviewInfo.DIFF;
|
||||
return replacements;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.siyeh.ig.inheritance;
|
||||
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiJavaCodeReferenceElement;
|
||||
@@ -22,7 +23,6 @@ import com.intellij.psi.PsiReferenceList;
|
||||
import com.siyeh.InspectionGadgetsBundle;
|
||||
import com.siyeh.ig.BaseInspection;
|
||||
import com.siyeh.ig.BaseInspectionVisitor;
|
||||
import com.siyeh.ig.InspectionGadgetsFix;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashSet;
|
||||
@@ -38,8 +38,8 @@ public class StaticInheritanceInspection extends BaseInspection {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InspectionGadgetsFix @NotNull [] buildFixes(Object... infos) {
|
||||
return new InspectionGadgetsFix[]{new StaticInheritanceFix(false), new StaticInheritanceFix(true)};
|
||||
protected LocalQuickFix @NotNull [] buildFixes(Object... infos) {
|
||||
return new LocalQuickFix[]{new StaticInheritanceFix(false), new StaticInheritanceFix(true)};
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,19 +1,18 @@
|
||||
// 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.ipp.datetime;
|
||||
|
||||
import com.intellij.codeInsight.hint.HintManager;
|
||||
import com.intellij.codeInsight.intention.HighPriorityAction;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.codeInsight.intention.PriorityAction;
|
||||
import com.intellij.codeInspection.ModCommands;
|
||||
import com.intellij.modcommand.ModCommand;
|
||||
import com.intellij.modcommand.PsiBasedModCommandAction;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.siyeh.IntentionPowerPackBundle;
|
||||
import com.siyeh.ig.callMatcher.CallMatcher;
|
||||
import com.siyeh.ig.psiutils.ExpressionUtils;
|
||||
import com.siyeh.ig.psiutils.TypeUtils;
|
||||
import com.siyeh.ipp.base.Intention;
|
||||
import com.siyeh.ipp.base.PsiElementPredicate;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDateTime;
|
||||
@@ -25,7 +24,11 @@ import static com.siyeh.ig.callMatcher.CallMatcher.*;
|
||||
/**
|
||||
* @author Bas Leijdekkers
|
||||
*/
|
||||
public class ShowDateTimeExampleOutputIntention extends Intention implements HighPriorityAction {
|
||||
public class ShowDateTimeExampleOutputIntention extends PsiBasedModCommandAction<PsiExpression> {
|
||||
|
||||
public ShowDateTimeExampleOutputIntention() {
|
||||
super(PsiExpression.class);
|
||||
}
|
||||
|
||||
private static final CallMatcher DATE_TIME_FORMATTER_METHODS = anyOf(
|
||||
staticCall("java.time.format.DateTimeFormatter", "ofPattern"),
|
||||
@@ -33,107 +36,87 @@ public class ShowDateTimeExampleOutputIntention extends Intention implements Hig
|
||||
);
|
||||
private static final CallMatcher SIMPLE_DATE_FORMAT_METHODS =
|
||||
instanceCall("java.text.SimpleDateFormat", "applyPattern", "applyLocalizedPattern").parameterTypes(CommonClassNames.JAVA_LANG_STRING);
|
||||
Boolean dateTimeFormatter = null;
|
||||
|
||||
@Override
|
||||
public @NotNull String getFamilyName() {
|
||||
return IntentionPowerPackBundle.message("show.example.date.time.output.intention.family.name");
|
||||
}
|
||||
|
||||
enum Formatter {
|
||||
NONE, DATE_TIME_FORMATTER, SIMPLE_DATE_FORMAT
|
||||
}
|
||||
|
||||
private static @NotNull Formatter getFormatter(@NotNull PsiExpression expression) {
|
||||
if (!(expression.getParent() instanceof PsiExpressionList parent)) return Formatter.NONE;
|
||||
final PsiType type = expression.getType();
|
||||
if (!TypeUtils.isJavaLangString(type)) return Formatter.NONE;
|
||||
final PsiElement grandParent = parent.getParent();
|
||||
if (grandParent instanceof PsiMethodCallExpression call) {
|
||||
if (SIMPLE_DATE_FORMAT_METHODS.test(call)) {
|
||||
return Formatter.SIMPLE_DATE_FORMAT;
|
||||
}
|
||||
if (DATE_TIME_FORMATTER_METHODS.test(call)) {
|
||||
return Formatter.DATE_TIME_FORMATTER;
|
||||
}
|
||||
return Formatter.NONE;
|
||||
}
|
||||
if (grandParent instanceof PsiNewExpression newExpression) {
|
||||
final PsiJavaCodeReferenceElement classReference = newExpression.getClassReference();
|
||||
if (classReference == null || !"SimpleDateFormat".equals(classReference.getReferenceName())) {
|
||||
return Formatter.NONE;
|
||||
}
|
||||
final PsiElement target = classReference.resolve();
|
||||
if (!(target instanceof PsiClass aClass)) {
|
||||
return Formatter.NONE;
|
||||
}
|
||||
if (!InheritanceUtil.isInheritor(aClass, "java.text.SimpleDateFormat")) {
|
||||
return Formatter.NONE;
|
||||
}
|
||||
return Formatter.SIMPLE_DATE_FORMAT;
|
||||
}
|
||||
return Formatter.NONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getText() {
|
||||
return getFamilyName();
|
||||
protected @Nullable Presentation getPresentation(@NotNull ActionContext context, @NotNull PsiExpression expression) {
|
||||
while (expression.getParent() instanceof PsiExpression parent) {
|
||||
expression = parent;
|
||||
}
|
||||
Formatter formatter = getFormatter(expression);
|
||||
if (formatter == Formatter.NONE) return null;
|
||||
final Object value = ExpressionUtils.computeConstantExpression(expression);
|
||||
return value instanceof String ? Presentation.of(getFamilyName()).withPriority(PriorityAction.Priority.HIGH) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull PsiElementPredicate getElementPredicate() {
|
||||
return new PsiElementPredicate() {
|
||||
@Override
|
||||
public boolean satisfiedBy(PsiElement element) {
|
||||
if (!(element instanceof PsiExpression expression)) {
|
||||
return false;
|
||||
protected @NotNull ModCommand perform(@NotNull ActionContext context, @NotNull PsiExpression expression) {
|
||||
while (expression.getParent() instanceof PsiExpression parent) {
|
||||
expression = parent;
|
||||
}
|
||||
Formatter formatter = getFormatter(expression);
|
||||
final Object value = ExpressionUtils.computeConstantExpression(expression);
|
||||
if (!(value instanceof String)) return ModCommands.nop();
|
||||
return switch (formatter) {
|
||||
case NONE -> ModCommands.nop();
|
||||
case DATE_TIME_FORMATTER -> {
|
||||
try {
|
||||
final DateTimeFormatter fmt = DateTimeFormatter.ofPattern((String)value);
|
||||
//noinspection HardCodedStringLiteral
|
||||
yield ModCommands.info(LocalDateTime.now().format(fmt));
|
||||
}
|
||||
final PsiType type = expression.getType();
|
||||
if (!TypeUtils.isJavaLangString(type)) {
|
||||
return false;
|
||||
catch (IllegalArgumentException e) {
|
||||
yield ModCommands.error(IntentionPowerPackBundle.message("invalid.pattern.hint.text"));
|
||||
}
|
||||
PsiElement parent = PsiUtil.skipParenthesizedExprUp(expression).getParent();
|
||||
if (parent == null) return false;
|
||||
final PsiElement grandParent = parent.getParent();
|
||||
if (grandParent instanceof PsiMethodCallExpression) {
|
||||
if (SIMPLE_DATE_FORMAT_METHODS.test((PsiMethodCallExpression)grandParent)) {
|
||||
dateTimeFormatter = false;
|
||||
}
|
||||
else if (DATE_TIME_FORMATTER_METHODS.test((PsiMethodCallExpression)grandParent)) {
|
||||
dateTimeFormatter = true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
case SIMPLE_DATE_FORMAT -> {
|
||||
try {
|
||||
final SimpleDateFormat format = new SimpleDateFormat((String)value);
|
||||
yield ModCommands.info(format.format(new Date()));
|
||||
}
|
||||
else if (grandParent instanceof PsiNewExpression newExpression) {
|
||||
final PsiJavaCodeReferenceElement classReference = newExpression.getClassReference();
|
||||
if (classReference == null || !"SimpleDateFormat".equals(classReference.getReferenceName())) {
|
||||
return false;
|
||||
}
|
||||
final PsiElement target = classReference.resolve();
|
||||
if (!(target instanceof PsiClass aClass)) {
|
||||
return false;
|
||||
}
|
||||
if (!InheritanceUtil.isInheritor(aClass, "java.text.SimpleDateFormat")) {
|
||||
return false;
|
||||
}
|
||||
dateTimeFormatter = false;
|
||||
return true;
|
||||
catch (IllegalArgumentException e) {
|
||||
yield ModCommands.error(IntentionPowerPackBundle.message("invalid.pattern.hint.text"));
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
final Object value = ExpressionUtils.computeConstantExpression(expression);
|
||||
return value instanceof String;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processIntention(Editor editor, @NotNull PsiElement element) {
|
||||
if (!(element instanceof PsiExpression expression) || dateTimeFormatter == null) {
|
||||
return;
|
||||
}
|
||||
final Object value = ExpressionUtils.computeConstantExpression(expression);
|
||||
if (!(value instanceof String)) {
|
||||
return;
|
||||
}
|
||||
String example;
|
||||
if (dateTimeFormatter) {
|
||||
try {
|
||||
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern((String)value);
|
||||
//noinspection HardCodedStringLiteral
|
||||
example = LocalDateTime.now().format(formatter);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
example = IntentionPowerPackBundle.message("invalid.pattern.hint.text");
|
||||
}
|
||||
}
|
||||
else {
|
||||
try {
|
||||
final SimpleDateFormat format = new SimpleDateFormat((String)value);
|
||||
example = format.format(new Date());
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
example = IntentionPowerPackBundle.message("invalid.pattern.hint.text");
|
||||
}
|
||||
}
|
||||
HintManager.getInstance().showInformationHint(editor, example);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void processIntention(@NotNull PsiElement element) {
|
||||
assert false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
// 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.uiDesigner.binding;
|
||||
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.DeleteElementFix;
|
||||
import com.intellij.lang.annotation.AnnotationHolder;
|
||||
import com.intellij.lang.annotation.Annotator;
|
||||
import com.intellij.lang.annotation.HighlightSeverity;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.ui.UIBundle;
|
||||
import com.intellij.uiDesigner.UIDesignerBundle;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
|
||||
public class FormClassAnnotator implements Annotator {
|
||||
@@ -30,7 +28,7 @@ public class FormClassAnnotator implements Annotator {
|
||||
}
|
||||
else if (psiElement instanceof PsiClass aClass) {
|
||||
final List<PsiFile> formsBoundToClass = FormClassIndex.findFormsBoundToClass(aClass.getProject(), aClass);
|
||||
if (formsBoundToClass.size() > 0) {
|
||||
if (!formsBoundToClass.isEmpty()) {
|
||||
holder.newSilentAnnotation(HighlightSeverity.INFORMATION).range(aClass.getNameIdentifier()).gutterIconRenderer(new BoundIconRenderer(aClass)).create();
|
||||
}
|
||||
}
|
||||
@@ -54,37 +52,9 @@ public class FormClassAnnotator implements Annotator {
|
||||
|
||||
if (field.hasInitializer()) {
|
||||
final String message = UIDesignerBundle.message("field.is.overwritten.by.generated.code", field.getName());
|
||||
holder.newAnnotation(HighlightSeverity.WARNING, message).range(field.getInitializer())
|
||||
.withFix(new IntentionAction() {
|
||||
@Override
|
||||
@NotNull
|
||||
public String getText() {
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return UIBundle.message("remove.field.initializer.quick.fix");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
return field.getInitializer() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
final PsiExpression initializer = field.getInitializer();
|
||||
LOG.assertTrue(initializer != null);
|
||||
initializer.delete();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return true;
|
||||
}
|
||||
}).create();
|
||||
PsiExpression initializer = Objects.requireNonNull(field.getInitializer());
|
||||
holder.newAnnotation(HighlightSeverity.WARNING, message).range(initializer)
|
||||
.withFix(new DeleteElementFix(initializer, UIBundle.message("remove.field.initializer.quick.fix"))).create();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user