From 4b7013730ee0095ff967f0c29b35079fbccffbc7 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Mon, 5 Dec 2016 16:25:58 +0100 Subject: [PATCH] regexp: parser test coverage and remove dead code --- .../intellij/lang/regexp/RegExpParser.java | 33 +++---------------- .../lang/regexp/RegExpParserDefinition.java | 4 +++ .../lang/regexp/RegExpParsingTest.java | 28 ++++++++++++++++ .../testData/psi/CategoryShorthand1.txt | 6 ++++ .../testData/psi/CategoryShorthand2.txt | 8 +++++ RegExpSupport/testData/psi/Namedchars14.txt | 11 +++++++ .../testData/psi/OmitNumberInQuantifier.txt | 11 +++++++ .../testData/psi/PosixBracketExpression1.txt | 10 ++++++ .../testData/psi/PosixBracketExpression2.txt | 11 +++++++ 9 files changed, 94 insertions(+), 28 deletions(-) create mode 100644 RegExpSupport/testData/psi/CategoryShorthand1.txt create mode 100644 RegExpSupport/testData/psi/CategoryShorthand2.txt create mode 100644 RegExpSupport/testData/psi/Namedchars14.txt create mode 100644 RegExpSupport/testData/psi/OmitNumberInQuantifier.txt create mode 100644 RegExpSupport/testData/psi/PosixBracketExpression1.txt create mode 100644 RegExpSupport/testData/psi/PosixBracketExpression2.txt diff --git a/RegExpSupport/src/org/intellij/lang/regexp/RegExpParser.java b/RegExpSupport/src/org/intellij/lang/regexp/RegExpParser.java index 9c16d5334237..9fbe8d74d75c 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/RegExpParser.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/RegExpParser.java @@ -30,10 +30,6 @@ public class RegExpParser implements PsiParser { private static final TokenSet PROPERTY_TOKENS = TokenSet.create(RegExpTT.NUMBER, RegExpTT.COMMA, RegExpTT.NAME, RegExpTT.RBRACE); private final EnumSet myCapabilities; - public RegExpParser() { - myCapabilities = EnumSet.noneOf(RegExpCapability.class); - } - public RegExpParser(EnumSet capabilities) { myCapabilities = capabilities; } @@ -82,7 +78,6 @@ public class RegExpParser implements PsiParser { /** * BRANCH ::= ATOM BRANCH | "" */ - @SuppressWarnings({"StatementWithEmptyBody"}) private boolean parseBranch(PsiBuilder builder) { final PsiBuilder.Marker marker = builder.mark(); @@ -97,7 +92,8 @@ public class RegExpParser implements PsiParser { return false; } - while (parseAtom(builder)) ; + //noinspection StatementWithEmptyBody + while (parseAtom(builder)) {} marker.done(RegExpElementTypes.BRANCH); return true; @@ -141,10 +137,6 @@ public class RegExpParser implements PsiParser { if (minOmitted) { builder.advanceLexer(); } - else if (builder.getTokenType() != RegExpTT.NUMBER && myCapabilities.contains(RegExpCapability.DANGLING_METACHARACTERS)) { - marker.done(RegExpTT.CHARACTER); - return true; - } else { checkMatches(builder, RegExpTT.NUMBER, "Number expected"); } @@ -214,37 +206,26 @@ public class RegExpParser implements PsiParser { if (builder.getTokenType() == RegExpTT.CARET) { builder.advanceLexer(); } - - // DEFLIST - if (parseClassIntersection(builder)) { - while (RegExpTT.CHARACTERS.contains(builder.getTokenType()) || - builder.getTokenType() == RegExpTT.CHAR_CLASS || - builder.getTokenType() == RegExpTT.CLASS_BEGIN || - builder.getTokenType() == RegExpTT.PROPERTY || - builder.getTokenType() == RegExpTT.BRACKET_EXPRESSION_BEGIN) { - parseClassIntersection(builder); - } - } + parseClassIntersection(builder); checkMatches(builder, RegExpTT.CLASS_END, "Unclosed character class"); marker.done(RegExpElementTypes.CLASS); return marker; } - private boolean parseClassIntersection(PsiBuilder builder) { + private void parseClassIntersection(PsiBuilder builder) { final PsiBuilder.Marker marker = builder.mark(); parseClassdef(builder); if (RegExpTT.ANDAND != builder.getTokenType()) { marker.drop(); - return true; + return; } while (RegExpTT.ANDAND == builder.getTokenType()) { builder.advanceLexer(); parseClassdef(builder); } marker.done(RegExpElementTypes.INTERSECTION); - return true; } private boolean parseClassdef(PsiBuilder builder) { @@ -463,10 +444,6 @@ public class RegExpParser implements PsiParser { marker.drop(); return parseClass(builder); } - else if (type == RegExpTT.LBRACE && myCapabilities.contains(RegExpCapability.DANGLING_METACHARACTERS)) { - builder.advanceLexer(); - marker.done(RegExpElementTypes.CHAR); - } else { marker.drop(); return null; diff --git a/RegExpSupport/src/org/intellij/lang/regexp/RegExpParserDefinition.java b/RegExpSupport/src/org/intellij/lang/regexp/RegExpParserDefinition.java index e8a134eb491d..1117a78d20bd 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/RegExpParserDefinition.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/RegExpParserDefinition.java @@ -49,6 +49,10 @@ public class RegExpParserDefinition implements ParserDefinition { CAPABILITIES.add(capability); Disposer.register(parentDisposable, () -> CAPABILITIES.remove(capability)); } + else { + CAPABILITIES.remove(capability); + Disposer.register(parentDisposable, () -> CAPABILITIES.add(capability)); + } } @NotNull diff --git a/RegExpSupport/test/org/intellij/lang/regexp/RegExpParsingTest.java b/RegExpSupport/test/org/intellij/lang/regexp/RegExpParsingTest.java index 1a9814174e23..95887f56a1b3 100644 --- a/RegExpSupport/test/org/intellij/lang/regexp/RegExpParsingTest.java +++ b/RegExpSupport/test/org/intellij/lang/regexp/RegExpParsingTest.java @@ -188,6 +188,7 @@ public class RegExpParsingTest extends ParsingTestCase { public void testGroups37() throws IOException { doCodeTest("(?P=name)"); } public void testGroups38() throws IOException { doCodeTest("\\g'name'"); } public void testGroups39() throws IOException { doCodeTest("(?(name)yes-pattern|no-pattern)"); } + public void testGroups40() throws IOException { doCodeTest("(?(name)yes-pattern|{"); } public void testEscapes1() throws IOException { doCodeTest("\\q"); } public void testEscapes2() throws IOException { doCodeTest("\\#"); } @@ -243,6 +244,7 @@ public class RegExpParsingTest extends ParsingTestCase { public void testNamedchars11() throws IOException { doCodeTest("[:^xdigit:]+"); } public void testNamedchars12() throws IOException { doCodeTest("\\p{InArabic Extended-A}"); } public void testNamedchars13() throws IOException { doCodeTest("\\N{Mahjong Tile Winter}"); } + public void testNamedchars14() throws IOException { doCodeTest("[\\N{Mahjong Tile Winter}]"); } public void testBackrefs1() throws IOException { doCodeTest("(ac*)c*d[ac]*\\1"); } public void testBackrefs2() throws IOException { doCodeTest("(.)=\\1"); } @@ -336,14 +338,40 @@ public class RegExpParsingTest extends ParsingTestCase { public void testParse2() throws IOException { doCodeTest("1**"); } public void testParse3() throws IOException { doCodeTest("(([hH][tT]{2}[pP]|[fF][tT][pP])://)?[a-zA-Z0-9\\-]+(\\.[a-zA-Z0-9\\-]+)*"); } + public void testPosixBracketExpression1() throws IOException { + RegExpParserDefinition.setTestCapability(RegExpCapability.POSIX_BRACKET_EXPRESSIONS, getTestRootDisposable()); + doCodeTest("[[:alpha:]]"); + } + + public void testPosixBracketExpression2() throws IOException { + RegExpParserDefinition.setTestCapability(RegExpCapability.POSIX_BRACKET_EXPRESSIONS, getTestRootDisposable()); + doCodeTest("[[:^alpha:]]"); + } + + public void testCategoryShorthand1() throws IOException { + doCodeTest("\\pL"); + } + + public void testCategoryShorthand2() throws IOException { + RegExpParserDefinition.setTestCapability(RegExpCapability.UNICODE_CATEGORY_SHORTHAND, getTestRootDisposable()); + doCodeTest("\\pL"); + } + + public void testOmitNumberInQuantifier() throws IOException { + RegExpParserDefinition.setTestCapability(RegExpCapability.OMIT_NUMBERS_IN_QUANTIFIERS, getTestRootDisposable()); + doCodeTest("a{,3}"); + } + public void testDanglingMetaCharacter1() throws IOException { RegExpParserDefinition.setTestCapability(RegExpCapability.DANGLING_METACHARACTERS, getTestRootDisposable()); doCodeTest("{"); } + public void testDanglingMetaCharacter2() throws IOException { RegExpParserDefinition.setTestCapability(RegExpCapability.DANGLING_METACHARACTERS, getTestRootDisposable()); doCodeTest("a{a"); } + public void testDanglingMetaCharacters3() throws IOException { RegExpParserDefinition.setTestCapability(RegExpCapability.DANGLING_METACHARACTERS, getTestRootDisposable()); doCodeTest("{{E1:\\s*(?P([^\\n]+\\+)?[0-9]+)( *\\|[^\\n]*)?}}"); diff --git a/RegExpSupport/testData/psi/CategoryShorthand1.txt b/RegExpSupport/testData/psi/CategoryShorthand1.txt new file mode 100644 index 000000000000..434b72be7435 --- /dev/null +++ b/RegExpSupport/testData/psi/CategoryShorthand1.txt @@ -0,0 +1,6 @@ +REGEXP_FILE + RegExpPatternImpl: <\pL> + RegExpBranchImpl: <\pL> + RegExpPropertyImpl: <\pL> + PsiElement(PROPERTY)('\p') + PsiElement(CATEGORY_SHORT_HAND)('L') \ No newline at end of file diff --git a/RegExpSupport/testData/psi/CategoryShorthand2.txt b/RegExpSupport/testData/psi/CategoryShorthand2.txt new file mode 100644 index 000000000000..0ed54e7ffe0f --- /dev/null +++ b/RegExpSupport/testData/psi/CategoryShorthand2.txt @@ -0,0 +1,8 @@ +REGEXP_FILE + RegExpPatternImpl: <\pL> + RegExpBranchImpl: <\pL> + RegExpPropertyImpl: <\pL> + PsiElement(PROPERTY)('\p') + PsiErrorElement:Category shorthand not allowed in this regular expression dialect + + PsiElement(CATEGORY_SHORT_HAND)('L') \ No newline at end of file diff --git a/RegExpSupport/testData/psi/Namedchars14.txt b/RegExpSupport/testData/psi/Namedchars14.txt new file mode 100644 index 000000000000..32f06116addb --- /dev/null +++ b/RegExpSupport/testData/psi/Namedchars14.txt @@ -0,0 +1,11 @@ +REGEXP_FILE + RegExpPatternImpl: <[\N{Mahjong Tile Winter}]> + RegExpBranchImpl: <[\N{Mahjong Tile Winter}]> + RegExpClassImpl: <[\N{Mahjong Tile Winter}]> + PsiElement(CLASS_BEGIN)('[') + RegExpNamedCharacterImpl: <\N{Mahjong Tile Winter}> + PsiElement(NAMED_CHARACTER)('\N') + PsiElement(LBRACE)('{') + PsiElement(NAME)('Mahjong Tile Winter') + PsiElement(RBRACE)('}') + PsiElement(CLASS_END)(']') \ No newline at end of file diff --git a/RegExpSupport/testData/psi/OmitNumberInQuantifier.txt b/RegExpSupport/testData/psi/OmitNumberInQuantifier.txt new file mode 100644 index 000000000000..461b9d456518 --- /dev/null +++ b/RegExpSupport/testData/psi/OmitNumberInQuantifier.txt @@ -0,0 +1,11 @@ +REGEXP_FILE + RegExpPatternImpl: + RegExpBranchImpl: + RegExpClosureImpl: + RegExpCharImpl: + PsiElement(CHARACTER)('a') + RegExpQuantifierImpl: <{,3}> + PsiElement(LBRACE)('{') + PsiElement(COMMA)(',') + PsiElement(NUMBER)('3') + PsiElement(RBRACE)('}') \ No newline at end of file diff --git a/RegExpSupport/testData/psi/PosixBracketExpression1.txt b/RegExpSupport/testData/psi/PosixBracketExpression1.txt new file mode 100644 index 000000000000..4a983b5060fe --- /dev/null +++ b/RegExpSupport/testData/psi/PosixBracketExpression1.txt @@ -0,0 +1,10 @@ +REGEXP_FILE + RegExpPatternImpl: <[[:alpha:]]> + RegExpBranchImpl: <[[:alpha:]]> + RegExpClassImpl: <[[:alpha:]]> + PsiElement(CLASS_BEGIN)('[') + RegExpPosixBracketExpressionImpl: <[:alpha:]> + PsiElement(BRACKET_EXPRESSION_BEGIN)('[:') + PsiElement(NAME)('alpha') + PsiElement(BRACKET_EXPRESSION_END)(':]') + PsiElement(CLASS_END)(']') \ No newline at end of file diff --git a/RegExpSupport/testData/psi/PosixBracketExpression2.txt b/RegExpSupport/testData/psi/PosixBracketExpression2.txt new file mode 100644 index 000000000000..b4f40d64f753 --- /dev/null +++ b/RegExpSupport/testData/psi/PosixBracketExpression2.txt @@ -0,0 +1,11 @@ +REGEXP_FILE + RegExpPatternImpl: <[[:^alpha:]]> + RegExpBranchImpl: <[[:^alpha:]]> + RegExpClassImpl: <[[:^alpha:]]> + PsiElement(CLASS_BEGIN)('[') + RegExpPosixBracketExpressionImpl: <[:^alpha:]> + PsiElement(BRACKET_EXPRESSION_BEGIN)('[:') + PsiElement(CARET)('^') + PsiElement(NAME)('alpha') + PsiElement(BRACKET_EXPRESSION_END)(':]') + PsiElement(CLASS_END)(']') \ No newline at end of file