mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IJPL-223228 [regex]: use intention implementation as basis for quick-fixes for char ranges and repetition range
GitOrigin-RevId: 2ca234590cef988044c6781978f7b84954f965bd
This commit is contained in:
committed by
intellij-monorepo-bot
parent
777fa5cd08
commit
ff5fb1d005
@@ -170,6 +170,8 @@ parse.error.unclosed.posix.bracket.expression=Unclosed POSIX bracket expression
|
||||
parse.error.unclosed.property=Unclosed property
|
||||
parse.error.unicode.character.name.expected=Unicode character name expected
|
||||
parse.error.unmatched.closing.bracket=Unmatched closing ''{0}''
|
||||
quickfix.family.name.flip.bounds=Flip bounds
|
||||
|
||||
regexp.dialog.language=&Language:
|
||||
|
||||
# Flags for java.util.regex.Pattern
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.intellij.lang.regexp.validation;
|
||||
|
||||
import com.intellij.modcommand.ActionContext;
|
||||
import com.intellij.modcommand.ModPsiUpdater;
|
||||
import com.intellij.modcommand.Presentation;
|
||||
import com.intellij.modcommand.PsiUpdateModCommandAction;
|
||||
import org.intellij.lang.regexp.RegExpBundle;
|
||||
import org.intellij.lang.regexp.inspection.RegExpReplacementUtil;
|
||||
import org.intellij.lang.regexp.psi.RegExpChar;
|
||||
import org.intellij.lang.regexp.psi.RegExpCharRange;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author Bas Leijdekkers
|
||||
*/
|
||||
final class CharRangeFix extends PsiUpdateModCommandAction<RegExpCharRange> {
|
||||
|
||||
CharRangeFix(@NotNull RegExpCharRange charRange) {
|
||||
super(charRange);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getFamilyName() {
|
||||
return RegExpBundle.message("quickfix.family.name.flip.bounds");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable Presentation getPresentation(@NotNull ActionContext context, @NotNull RegExpCharRange charRange) {
|
||||
final RegExpChar from = charRange.getFrom();
|
||||
final RegExpChar to = charRange.getTo();
|
||||
if (to == null) return null;
|
||||
return Presentation.of(RegExpBundle.message("intention.name.flip.elements", from.getText(), to.getText()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void invoke(@NotNull ActionContext context, @NotNull RegExpCharRange charRange, @NotNull ModPsiUpdater updater) {
|
||||
RegExpReplacementUtil.flipLeftRight(charRange.getFrom(), charRange.getTo());
|
||||
}
|
||||
}
|
||||
@@ -100,11 +100,11 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot
|
||||
}
|
||||
final int fromCodePoint = from.getValue();
|
||||
final int toCodePoint = to.getValue();
|
||||
if (fromCodePoint == -1 || toCodePoint == -1) {
|
||||
return;
|
||||
}
|
||||
if (toCodePoint < fromCodePoint) {
|
||||
myHolder.newAnnotation(HighlightSeverity.ERROR, RegExpBundle.message("error.illegal.character.range.to.from")).range(range).create();
|
||||
if (fromCodePoint != -1 && toCodePoint != -1 && toCodePoint < fromCodePoint) {
|
||||
myHolder.newAnnotation(HighlightSeverity.ERROR, RegExpBundle.message("error.illegal.character.range.to.from"))
|
||||
.range(range)
|
||||
.withFix(new CharRangeFix(range))
|
||||
.create();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -399,7 +399,9 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot
|
||||
if (minValue != null && maxValue != null) {
|
||||
if (minValue.longValue() > maxValue.longValue() || minValue.doubleValue() > maxValue.doubleValue()) {
|
||||
final TextRange range = new TextRange(minElement.getTextOffset(), maxElement.getTextOffset() + maxElement.getTextLength());
|
||||
myHolder.newAnnotation(HighlightSeverity.ERROR, RegExpBundle.message("error.illegal.repetition.range.min.max")).range(range)
|
||||
myHolder.newAnnotation(HighlightSeverity.ERROR, RegExpBundle.message("error.illegal.repetition.range.min.max"))
|
||||
.range(range)
|
||||
.withFix(new RepetitionRangeFix(quantifier))
|
||||
.create();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.intellij.lang.regexp.validation;
|
||||
|
||||
import com.intellij.modcommand.ActionContext;
|
||||
import com.intellij.modcommand.ModPsiUpdater;
|
||||
import com.intellij.modcommand.Presentation;
|
||||
import com.intellij.modcommand.PsiUpdateModCommandAction;
|
||||
import org.intellij.lang.regexp.RegExpBundle;
|
||||
import org.intellij.lang.regexp.inspection.RegExpReplacementUtil;
|
||||
import org.intellij.lang.regexp.psi.RegExpNumber;
|
||||
import org.intellij.lang.regexp.psi.RegExpQuantifier;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author Bas Leijdekkers
|
||||
*/
|
||||
final class RepetitionRangeFix extends PsiUpdateModCommandAction<RegExpQuantifier> {
|
||||
|
||||
RepetitionRangeFix(@NotNull RegExpQuantifier quantifier) {
|
||||
super(quantifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getFamilyName() {
|
||||
return RegExpBundle.message("quickfix.family.name.flip.bounds");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @Nullable Presentation getPresentation(@NotNull ActionContext context, @NotNull RegExpQuantifier quantifier) {
|
||||
final RegExpNumber min = quantifier.getMin();
|
||||
final RegExpNumber max = quantifier.getMax();
|
||||
if (min == null || max == null) return null;
|
||||
return Presentation.of(RegExpBundle.message("intention.name.flip.elements", min.getText(), max.getText()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void invoke(@NotNull ActionContext context, @NotNull RegExpQuantifier quantifier, @NotNull ModPsiUpdater updater) {
|
||||
RegExpReplacementUtil.flipLeftRight(quantifier.getMin(), quantifier.getMax());
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2026 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.java.codeInsight;
|
||||
|
||||
import com.intellij.ide.highlighter.JavaFileType;
|
||||
@@ -31,7 +31,7 @@ public class RegExpHighlightingTest extends LightJavaCodeInsightFixtureTestCase
|
||||
// needs only partial escaping
|
||||
@NonNls String code = "<weak_warning descr=\"'\\\\P{IsBlank}' can be simplified to '[^ \\\\t]'\">\\\\P{IsBlank}</weak_warning>";
|
||||
myFixture.enableInspections(new RegExpSimplifiableInspection());
|
||||
myFixture.configureByText(JavaFileType.INSTANCE, "class X {{ java.util.regex.Pattern.compile(\"" + code + "\"); }}");
|
||||
myFixture.configureByText(JavaFileType.INSTANCE, wrap(code));
|
||||
myFixture.testHighlighting();
|
||||
}
|
||||
|
||||
@@ -108,7 +108,9 @@ public class RegExpHighlightingTest extends LightJavaCodeInsightFixtureTestCase
|
||||
}
|
||||
|
||||
public void testIllegalCharacterRange3() {
|
||||
doTest("[<error descr=\"Illegal character range (to < from)\">z-a</error>]");
|
||||
doTest("[<error descr=\"Illegal character range (to < from)\">z-a</error>]",
|
||||
"Swap ",
|
||||
"[a-z]");
|
||||
}
|
||||
|
||||
public void testIllegalCharacterRange4() {
|
||||
@@ -194,7 +196,9 @@ public class RegExpHighlightingTest extends LightJavaCodeInsightFixtureTestCase
|
||||
public void testCountedQuantifier() {
|
||||
doTest("a{2147483647}");
|
||||
doTest("a{<error descr=\"Repetition value too large\">2147483648</error>}");
|
||||
doTest("a{<error descr=\"Illegal repetition range (min > max)\">1,0</error>}");
|
||||
doTest("a{<error descr=\"Illegal repetition range (min > max)\">1,0</error>}",
|
||||
"Swap ",
|
||||
"a{0,1}");
|
||||
}
|
||||
|
||||
public void testOptions() {
|
||||
@@ -261,9 +265,20 @@ public class RegExpHighlightingTest extends LightJavaCodeInsightFixtureTestCase
|
||||
|
||||
private void doTest(@NonNls String code) {
|
||||
code = StringUtil.escapeBackSlashes(code);
|
||||
myFixture.configureByText(JavaFileType.INSTANCE, "class X {{ java.util.regex.Pattern.compile(\"" + code + "\"); }}");
|
||||
myFixture.configureByText(JavaFileType.INSTANCE, wrap(code));
|
||||
myFixture.testHighlighting();
|
||||
}
|
||||
|
||||
private void doTest(@NonNls String code, @NonNls String fixPrefix, @NonNls String result) {
|
||||
myFixture.configureByText(JavaFileType.INSTANCE, wrap(StringUtil.escapeBackSlashes(code)));
|
||||
myFixture.testHighlighting();
|
||||
myFixture.launchAction(myFixture.findSingleIntention(fixPrefix));
|
||||
myFixture.checkResult(wrap(result));
|
||||
}
|
||||
|
||||
private static @NonNls @NotNull String wrap(@NonNls String code) {
|
||||
return "class X {{ java.util.regex.Pattern.compile(\"" + code + "\"); }}";
|
||||
}
|
||||
|
||||
private void doTestUnexpectedAnchor(@NonNls String code) {
|
||||
myFixture.enableInspections(new UnexpectedAnchorInspection());
|
||||
|
||||
Reference in New Issue
Block a user