diff --git a/RegExpSupport/resources/messages/RegExpBundle.properties b/RegExpSupport/resources/messages/RegExpBundle.properties index 790599d4cbcc..2613f5e83cee 100644 --- a/RegExpSupport/resources/messages/RegExpBundle.properties +++ b/RegExpSupport/resources/messages/RegExpBundle.properties @@ -27,6 +27,7 @@ error.back.reference.is.nested.into.the.capturing.group.it.refers.to=Back refere error.conditional.group.reference.not.allowed.inside.lookbehind=Conditional group reference not allowed inside lookbehind error.conditionals.are.not.supported.in.this.regex.dialect=Conditionals are not supported in this regex dialect error.dangling.metacharacter=Dangling quantifier ''{0}'' +error.dangling.opening.bracket=Unexpected start of quantifier '{' error.embedded.comments.are.not.supported.in.this.regex.dialect=Embedded comments are not supported in this regex dialect error.empty.group=Empty group error.group.reference.is.nested.into.the.named.group.it.refers.to=Group reference is nested into the named group it refers to diff --git a/RegExpSupport/src/org/intellij/lang/regexp/RegExpParser.java b/RegExpSupport/src/org/intellij/lang/regexp/RegExpParser.java index 28c8623f2b36..05be7fea1706 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/RegExpParser.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/RegExpParser.java @@ -192,7 +192,7 @@ public class RegExpParser implements PsiParser, LightPsiParser { } else { if (RegExpTT.QUANTIFIERS.contains(builder.getTokenType())) { - builder.error(RegExpBundle.message("error.dangling.metacharacter")); + builder.error(RegExpBundle.message("error.dangling.metacharacter", builder.getTokenText())); } } } @@ -600,11 +600,22 @@ public class RegExpParser implements PsiParser, LightPsiParser { private static void patternExpected(PsiBuilder builder) { final IElementType token = builder.getTokenType(); - if (token == RegExpTT.GROUP_END) { - builder.error(RegExpBundle.message("parse.error.unmatched.closing.parenthesis")); + if (token == RegExpTT.GROUP_END || token == RegExpTT.RBRACE || token == RegExpTT.CLASS_END) { + builder.error(RegExpBundle.message("parse.error.unmatched.closing.bracket", builder.getTokenText())); } - else if (RegExpTT.QUANTIFIERS.contains(token) || token == RegExpTT.RBRACE || token == RegExpTT.CLASS_END) { - builder.error(RegExpBundle.message("error.dangling.metacharacter")); + else if (token == RegExpTT.LBRACE) { + builder.error(RegExpBundle.message("error.dangling.opening.bracket")); + // try to recover + builder.advanceLexer(); + while (builder.getTokenType() == RegExpTT.NUMBER || builder.getTokenType() == RegExpTT.COMMA) { + builder.advanceLexer(); + } + if (builder.getTokenType() == RegExpTT.RBRACE) { + builder.advanceLexer(); + } + } + else if (RegExpTT.QUANTIFIERS.contains(token)) { + builder.error(RegExpBundle.message("error.dangling.metacharacter", builder.getTokenText())); } else { builder.error(RegExpBundle.message("parse.error.pattern.expected")); diff --git a/RegExpSupport/src/org/intellij/lang/regexp/validation/RegExpAnnotator.java b/RegExpSupport/src/org/intellij/lang/regexp/validation/RegExpAnnotator.java index 8ef91734fe0c..f022e15f81b6 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/validation/RegExpAnnotator.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/validation/RegExpAnnotator.java @@ -357,8 +357,9 @@ public final class RegExpAnnotator extends RegExpElementVisitor implements Annot @Override public void visitRegExpClosure(RegExpClosure closure) { if (closure.getAtom() instanceof RegExpSetOptions) { - myHolder.newAnnotation(HighlightSeverity.ERROR, RegExpBundle.message("error.dangling.metacharacter")) - .range(closure.getQuantifier()) + final RegExpQuantifier quantifier = closure.getQuantifier(); + myHolder.newAnnotation(HighlightSeverity.ERROR, RegExpBundle.message("error.dangling.metacharacter", quantifier.getUnescapedText())) + .range(quantifier) .create(); } } diff --git a/RegExpSupport/testData/ecmascript_psi/DanglingMetaCharacter1.txt b/RegExpSupport/testData/ecmascript_psi/DanglingMetaCharacter1.txt index 3b7c3bb2e58a..524efef06433 100644 --- a/RegExpSupport/testData/ecmascript_psi/DanglingMetaCharacter1.txt +++ b/RegExpSupport/testData/ecmascript_psi/DanglingMetaCharacter1.txt @@ -1,6 +1,6 @@ JS_UNICODE_REGEXP_FILE RegExpPatternImpl: <{> RegExpBranchImpl: <{> - PsiErrorElement:Dangling metacharacter + PsiErrorElement:Unexpected start of quantifier '{' PsiElement(LBRACE)('{') \ No newline at end of file diff --git a/RegExpSupport/testData/ecmascript_psi/DanglingMetaCharacter2.txt b/RegExpSupport/testData/ecmascript_psi/DanglingMetaCharacter2.txt index 706acf3175ca..ae06e98c04a0 100644 --- a/RegExpSupport/testData/ecmascript_psi/DanglingMetaCharacter2.txt +++ b/RegExpSupport/testData/ecmascript_psi/DanglingMetaCharacter2.txt @@ -1,6 +1,6 @@ JS_UNICODE_REGEXP_FILE RegExpPatternImpl: <}> RegExpBranchImpl: <}> - PsiErrorElement:Dangling metacharacter + PsiErrorElement:Unmatched closing '}' PsiElement(RBRACE)('}') \ No newline at end of file diff --git a/RegExpSupport/testData/ecmascript_psi/DanglingMetaCharacter3.txt b/RegExpSupport/testData/ecmascript_psi/DanglingMetaCharacter3.txt index 7a7954e44788..4816bdc9c8d4 100644 --- a/RegExpSupport/testData/ecmascript_psi/DanglingMetaCharacter3.txt +++ b/RegExpSupport/testData/ecmascript_psi/DanglingMetaCharacter3.txt @@ -1,6 +1,6 @@ JS_UNICODE_REGEXP_FILE RegExpPatternImpl: <]> RegExpBranchImpl: <]> - PsiErrorElement:Dangling metacharacter + PsiErrorElement:Unmatched closing ']' PsiElement(CLASS_END)(']') \ No newline at end of file diff --git a/RegExpSupport/testData/psi/Bug4.txt b/RegExpSupport/testData/psi/Bug4.txt index 444785445d51..202f7d04b94b 100644 --- a/RegExpSupport/testData/psi/Bug4.txt +++ b/RegExpSupport/testData/psi/Bug4.txt @@ -1,6 +1,6 @@ REGEXP_FILE RegExpPatternImpl: <{> RegExpBranchImpl: <{> - PsiErrorElement:Dangling metacharacter + PsiErrorElement:Unexpected start of quantifier '{' PsiElement(LBRACE)('{') \ No newline at end of file diff --git a/RegExpSupport/testData/psi/Groups32.txt b/RegExpSupport/testData/psi/Groups32.txt index a032c68f183b..26c081a1a63b 100644 --- a/RegExpSupport/testData/psi/Groups32.txt +++ b/RegExpSupport/testData/psi/Groups32.txt @@ -8,7 +8,7 @@ REGEXP_FILE PsiElement(COLON)(':') RegExpPatternImpl: <*> RegExpBranchImpl: <*> - PsiErrorElement:Dangling metacharacter + PsiErrorElement:Dangling quantifier '*' PsiElement(STAR)('*') PsiElement(GROUP_END)(')') \ No newline at end of file diff --git a/RegExpSupport/testData/psi/Groups36.txt b/RegExpSupport/testData/psi/Groups36.txt index b41bc2f5a63a..24553ae820a5 100644 --- a/RegExpSupport/testData/psi/Groups36.txt +++ b/RegExpSupport/testData/psi/Groups36.txt @@ -7,7 +7,7 @@ REGEXP_FILE PsiElement(GT)('>') RegExpPatternImpl: <{> RegExpBranchImpl: <{> - PsiErrorElement:Dangling metacharacter + PsiErrorElement:Unexpected start of quantifier '{' PsiElement(LBRACE)('{') PsiErrorElement:')' expected diff --git a/RegExpSupport/testData/psi/Groups40.txt b/RegExpSupport/testData/psi/Groups40.txt index 1b61d74d8f65..543c1ad538fd 100644 --- a/RegExpSupport/testData/psi/Groups40.txt +++ b/RegExpSupport/testData/psi/Groups40.txt @@ -32,7 +32,7 @@ REGEXP_FILE PsiElement(CHARACTER)('n') PsiElement(UNION)('|') RegExpBranchImpl: <{> - PsiErrorElement:Dangling metacharacter + PsiErrorElement:Unexpected start of quantifier '{' PsiElement(LBRACE)('{') PsiErrorElement:')' expected diff --git a/RegExpSupport/testData/psi/Groups5.txt b/RegExpSupport/testData/psi/Groups5.txt index 6a9dcccbf971..6b4dee5b8cb0 100644 --- a/RegExpSupport/testData/psi/Groups5.txt +++ b/RegExpSupport/testData/psi/Groups5.txt @@ -5,7 +5,7 @@ REGEXP_FILE PsiElement(GROUP_BEGIN)('(') RegExpPatternImpl: <*> RegExpBranchImpl: <*> - PsiErrorElement:Dangling metacharacter + PsiErrorElement:Dangling quantifier '*' PsiElement(STAR)('*') PsiElement(GROUP_END)(')') diff --git a/RegExpSupport/testData/psi/Incomplete13.txt b/RegExpSupport/testData/psi/Incomplete13.txt index ef8cb93394d3..f694104c7973 100644 --- a/RegExpSupport/testData/psi/Incomplete13.txt +++ b/RegExpSupport/testData/psi/Incomplete13.txt @@ -5,6 +5,6 @@ REGEXP_FILE PsiElement(CHARACTER)('a') PsiElement(UNION)('|') RegExpBranchImpl: <*> - PsiErrorElement:Dangling metacharacter + PsiErrorElement:Dangling quantifier '*' PsiElement(STAR)('*') \ No newline at end of file diff --git a/RegExpSupport/testData/psi/Parse2.txt b/RegExpSupport/testData/psi/Parse2.txt index 7143305b062b..62434c803267 100644 --- a/RegExpSupport/testData/psi/Parse2.txt +++ b/RegExpSupport/testData/psi/Parse2.txt @@ -6,6 +6,6 @@ REGEXP_FILE PsiElement(CHARACTER)('1') RegExpQuantifierImpl: <*> PsiElement(STAR)('*') - PsiErrorElement:Dangling metacharacter + PsiErrorElement:Dangling quantifier '*' PsiElement(STAR)('*') \ No newline at end of file diff --git a/RegExpSupport/testData/psi/Quantifiers10.txt b/RegExpSupport/testData/psi/Quantifiers10.txt index 2b19e572a2fc..abffbdb4510d 100644 --- a/RegExpSupport/testData/psi/Quantifiers10.txt +++ b/RegExpSupport/testData/psi/Quantifiers10.txt @@ -6,6 +6,6 @@ REGEXP_FILE PsiElement(CHARACTER)('a') RegExpQuantifierImpl: <*> PsiElement(STAR)('*') - PsiErrorElement:Dangling metacharacter + PsiErrorElement:Dangling quantifier '*' PsiElement(STAR)('*') \ No newline at end of file diff --git a/RegExpSupport/testData/psi/Quantifiers22.txt b/RegExpSupport/testData/psi/Quantifiers22.txt index 664f19b248d2..ed2205077229 100644 --- a/RegExpSupport/testData/psi/Quantifiers22.txt +++ b/RegExpSupport/testData/psi/Quantifiers22.txt @@ -1,15 +1,10 @@ REGEXP_FILE - RegExpPatternImpl: <{1,2> - RegExpBranchImpl: <{1,2> - PsiErrorElement:Dangling metacharacter + RegExpPatternImpl: <{1,2}> + RegExpBranchImpl: <{1,2}> + PsiErrorElement:Unexpected start of quantifier '{' PsiElement(LBRACE)('{') - RegExpCharImpl: <1> - PsiElement(CHARACTER)('1') - RegExpCharImpl: <,> - PsiElement(CHARACTER)(',') - RegExpCharImpl: <2> - PsiElement(CHARACTER)('2') - PsiErrorElement:Dangling metacharacter - - PsiElement(RBRACE)('}') \ No newline at end of file + PsiElement(NUMBER)('1') + PsiElement(COMMA)(',') + PsiElement(NUMBER)('2') + PsiElement(RBRACE)('}') \ No newline at end of file diff --git a/RegExpSupport/testData/psi/Simple14.txt b/RegExpSupport/testData/psi/Simple14.txt index d446f1d59515..5ac5c5d97313 100644 --- a/RegExpSupport/testData/psi/Simple14.txt +++ b/RegExpSupport/testData/psi/Simple14.txt @@ -1,7 +1,7 @@ REGEXP_FILE RegExpPatternImpl: <*a> RegExpBranchImpl: <*a> - PsiErrorElement:Dangling metacharacter + PsiErrorElement:Dangling quantifier '*' PsiElement(STAR)('*') RegExpCharImpl: diff --git a/RegExpSupport/testData/psi/Tests4.txt b/RegExpSupport/testData/psi/Tests4.txt index 2b19e572a2fc..abffbdb4510d 100644 --- a/RegExpSupport/testData/psi/Tests4.txt +++ b/RegExpSupport/testData/psi/Tests4.txt @@ -6,6 +6,6 @@ REGEXP_FILE PsiElement(CHARACTER)('a') RegExpQuantifierImpl: <*> PsiElement(STAR)('*') - PsiErrorElement:Dangling metacharacter + PsiErrorElement:Dangling quantifier '*' PsiElement(STAR)('*') \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/RegExpHighlightingTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/RegExpHighlightingTest.java index 6096dd182b35..7fbc421b6c74 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/RegExpHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/RegExpHighlightingTest.java @@ -1,4 +1,4 @@ -// 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-2021 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; @@ -214,9 +214,9 @@ public class RegExpHighlightingTest extends LightJavaCodeInsightFixtureTestCase } public void testOptions() { - doTest("(?i)+"); - doTest("(?i)*"); - doTest("(?i){5,6}"); + doTest("(?i)+"); + doTest("(?i)*"); + doTest("(?i){5,6}"); } public void testLookbehind() { diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/replace_all_dot/SuspiciousRegexExpressionArgument.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/replace_all_dot/SuspiciousRegexExpressionArgument.java index 6dd0166fb672..1c7a5599289d 100644 --- a/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/replace_all_dot/SuspiciousRegexExpressionArgument.java +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/bugs/replace_all_dot/SuspiciousRegexExpressionArgument.java @@ -2,7 +2,7 @@ class SuspicousRegexExpressionArgument {{ "a.s.d.f".split("."); "vb|amna".replaceAll("|", "-"); - "1+2+3".split("+"); + "1+2+3".split("+"); "one two".split(" "); "[][][]".split("]"); "{}{}{}".split("}"); diff --git a/xml/tests/testData/xml/WrongRegExpInSchema.xsd b/xml/tests/testData/xml/WrongRegExpInSchema.xsd index 20d5e7b5d258..c8cb02de69f9 100644 --- a/xml/tests/testData/xml/WrongRegExpInSchema.xsd +++ b/xml/tests/testData/xml/WrongRegExpInSchema.xsd @@ -1,7 +1,7 @@ -*)"/> +*)"/>