From 748a1e5eee550460acd5c67704c5ea9dcc179531 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Mon, 5 Dec 2016 11:41:14 +0100 Subject: [PATCH] PY-21575 (False positive: "Unclosed group reference" for backreference to a named group in regex) --- .../org/intellij/lang/regexp/_RegExLexer.java | 173 +++++++++--------- .../intellij/lang/regexp/regexp-lexer.flex | 9 +- .../lang/regexp/RegExpParsingTest.java | 4 + RegExpSupport/testData/psi/Groups36.txt | 14 ++ RegExpSupport/testData/psi/Groups37.txt | 7 + RegExpSupport/testData/psi/Groups38.txt | 7 + RegExpSupport/testData/psi/Groups39.txt | 53 ++++++ 7 files changed, 177 insertions(+), 90 deletions(-) create mode 100644 RegExpSupport/testData/psi/Groups36.txt create mode 100644 RegExpSupport/testData/psi/Groups37.txt create mode 100644 RegExpSupport/testData/psi/Groups38.txt create mode 100644 RegExpSupport/testData/psi/Groups39.txt diff --git a/RegExpSupport/gen/org/intellij/lang/regexp/_RegExLexer.java b/RegExpSupport/gen/org/intellij/lang/regexp/_RegExLexer.java index 24fa1e4c2829..9040c9d8e677 100644 --- a/RegExpSupport/gen/org/intellij/lang/regexp/_RegExLexer.java +++ b/RegExpSupport/gen/org/intellij/lang/regexp/_RegExLexer.java @@ -191,19 +191,19 @@ class _RegExLexer implements FlexLexer { "\1\17\1\20\1\21\1\22\1\2\1\23\1\24\1\25"+ "\1\26\1\27\1\30\1\31\1\30\1\32\1\33\1\34"+ "\1\10\1\35\1\2\1\36\1\37\1\23\1\40\1\41"+ - "\1\42\1\43\1\44\1\45\1\1\1\46\1\47\2\50"+ - "\1\51\1\52\1\0\1\53\1\54\1\55\1\56\1\57"+ - "\1\60\1\10\1\61\1\62\1\63\1\64\1\10\1\64"+ - "\1\65\2\66\1\67\1\70\1\71\1\72\1\73\1\74"+ - "\1\75\1\10\1\76\1\77\1\100\1\0\1\101\1\102"+ - "\1\103\1\104\1\0\1\105\1\106\1\107\1\110\1\111"+ - "\1\0\1\112\1\0\1\113\1\0\1\114\1\115\1\116"+ - "\2\72\1\117\1\120\1\121\1\122\1\123\1\124\1\125"+ - "\1\126\1\0\1\113\1\0\1\127\2\72\1\117\1\130"+ - "\1\113\1\72\1\117\1\72\1\131\4\72"; + "\1\42\1\43\1\44\1\45\1\1\1\26\1\46\1\47"+ + "\2\50\1\51\1\52\1\0\1\53\1\54\1\55\1\56"+ + "\1\57\1\60\1\10\1\61\1\62\1\63\1\64\1\10"+ + "\1\64\1\65\2\66\1\67\1\70\1\71\1\72\1\73"+ + "\1\74\1\75\1\10\1\76\1\77\1\100\1\0\1\101"+ + "\1\102\1\103\1\104\1\0\1\105\1\106\1\107\1\110"+ + "\1\111\1\0\1\112\1\0\1\113\1\0\1\114\1\115"+ + "\1\116\2\72\1\117\1\120\1\121\1\122\1\123\1\124"+ + "\1\125\1\126\1\0\1\113\1\0\1\127\2\72\1\117"+ + "\1\130\1\113\1\72\1\117\1\72\1\131\4\72"; private static int [] zzUnpackAction() { - int [] result = new int[138]; + int [] result = new int[139]; int offset = 0; offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); return result; @@ -235,20 +235,20 @@ class _RegExLexer implements FlexLexer { "\0\u03e0\0\u04d8\0\u03e0\0\u0516\0\u03e0\0\u0554\0\u03e0\0\u03e0"+ "\0\u03e0\0\u0592\0\u03e0\0\u05d0\0\u03e0\0\u060e\0\u03e0\0\u064c"+ "\0\u03e0\0\u03e0\0\u045c\0\u03e0\0\u03e0\0\u03e0\0\u068a\0\u06c8"+ - "\0\u03e0\0\u03e0\0\u03e0\0\u03e0\0\u03e0\0\u0706\0\u0744\0\u03e0"+ - "\0\u0782\0\u07c0\0\u03e0\0\u07fe\0\u083c\0\u03e0\0\u03e0\0\u03e0"+ - "\0\u03e0\0\u03e0\0\u03e0\0\u087a\0\u08b8\0\u03e0\0\u03e0\0\u08f6"+ - "\0\u03e0\0\u03e0\0\u03e0\0\u03e0\0\u0934\0\u0972\0\u03e0\0\u03e0"+ - "\0\u09b0\0\u03e0\0\u03e0\0\u03e0\0\u09ee\0\u03e0\0\u03e0\0\u03e0"+ - "\0\u03e0\0\u0a2c\0\u0a6a\0\u03e0\0\u03e0\0\u03e0\0\u03e0\0\u0aa8"+ - "\0\u03e0\0\u0ae6\0\u0b24\0\u0b62\0\u03e0\0\u03e0\0\u03e0\0\u0ba0"+ - "\0\u0bde\0\u0c1c\0\u03e0\0\u03e0\0\u03e0\0\u03e0\0\u03e0\0\u03e0"+ - "\0\u03e0\0\u0c5a\0\u0c98\0\u0cd6\0\u03e0\0\u0d14\0\u03e0\0\u0d52"+ - "\0\u03e0\0\u03e0\0\u0d90\0\u0dce\0\u0e0c\0\u03e0\0\u0e4a\0\u0e88"+ - "\0\u0ec6\0\u0f04"; + "\0\u03e0\0\u03e0\0\u0706\0\u03e0\0\u03e0\0\u03e0\0\u0744\0\u0782"+ + "\0\u03e0\0\u07c0\0\u07fe\0\u03e0\0\u083c\0\u087a\0\u03e0\0\u03e0"+ + "\0\u03e0\0\u03e0\0\u03e0\0\u03e0\0\u08b8\0\u08f6\0\u03e0\0\u03e0"+ + "\0\u0934\0\u03e0\0\u03e0\0\u03e0\0\u03e0\0\u0972\0\u09b0\0\u03e0"+ + "\0\u03e0\0\u09ee\0\u03e0\0\u03e0\0\u03e0\0\u0a2c\0\u03e0\0\u03e0"+ + "\0\u03e0\0\u03e0\0\u0a6a\0\u0aa8\0\u03e0\0\u03e0\0\u03e0\0\u03e0"+ + "\0\u0ae6\0\u03e0\0\u0b24\0\u0b62\0\u0ba0\0\u03e0\0\u03e0\0\u03e0"+ + "\0\u0bde\0\u0c1c\0\u0c5a\0\u03e0\0\u03e0\0\u03e0\0\u03e0\0\u03e0"+ + "\0\u03e0\0\u03e0\0\u0c98\0\u0cd6\0\u0d14\0\u03e0\0\u0d52\0\u03e0"+ + "\0\u0d90\0\u03e0\0\u03e0\0\u0dce\0\u0e0c\0\u0e4a\0\u03e0\0\u0e88"+ + "\0\u0ec6\0\u0f04\0\u0f42"; private static int [] zzUnpackRowMap() { - int [] result = new int[138]; + int [] result = new int[139]; int offset = 0; offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); return result; @@ -287,66 +287,67 @@ class _RegExLexer implements FlexLexer { "\1\64\7\43\1\64\4\43\1\64\20\43\1\62\1\43"+ "\1\63\1\43\1\27\63\43\5\65\1\66\5\65\1\67"+ "\1\65\1\70\10\65\26\67\1\65\3\67\3\65\1\67"+ - "\4\65\1\71\5\65\65\13\1\72\10\13\13\65\1\46"+ - "\12\65\26\46\1\65\3\46\3\65\1\46\6\65\1\73"+ - "\16\65\1\46\12\65\26\46\1\65\3\46\1\65\1\74"+ - "\1\65\1\46\17\65\1\66\5\65\1\46\12\65\26\46"+ - "\1\65\3\46\3\65\1\46\13\65\2\44\2\65\1\66"+ - "\5\65\1\46\3\65\1\44\6\65\26\46\1\44\3\46"+ - "\3\65\1\46\12\65\13\75\1\46\4\75\1\32\5\75"+ - "\26\46\1\75\3\46\3\75\1\46\4\75\1\76\5\75"+ - "\120\0\1\77\64\0\1\100\1\101\5\0\1\102\55\0"+ - "\1\103\1\104\1\105\4\106\1\103\1\107\1\103\1\107"+ - "\1\110\1\103\1\111\1\112\1\103\1\107\5\106\2\113"+ - "\1\114\1\115\3\116\3\117\1\120\2\121\2\122\3\123"+ - "\1\110\1\124\1\125\1\126\1\104\1\127\1\130\1\131"+ - "\2\103\1\112\1\110\1\103\1\112\1\103\1\112\6\103"+ - "\47\0\1\132\27\0\2\44\14\0\1\44\34\0\1\44"+ + "\4\65\1\71\5\65\65\13\1\72\10\13\13\65\1\73"+ + "\12\65\26\73\1\65\3\73\3\65\1\73\6\65\1\74"+ + "\16\65\1\73\12\65\26\73\1\65\3\73\1\65\1\75"+ + "\1\65\1\73\17\65\1\66\5\65\1\73\12\65\26\73"+ + "\1\65\3\73\3\65\1\73\13\65\2\44\2\65\1\66"+ + "\5\65\1\73\3\65\1\44\6\65\26\73\1\44\3\73"+ + "\3\65\1\73\12\65\13\76\1\46\4\76\1\32\5\76"+ + "\26\46\1\76\3\46\3\76\1\46\4\76\1\77\5\76"+ + "\120\0\1\100\64\0\1\101\1\102\5\0\1\103\55\0"+ + "\1\104\1\105\1\106\4\107\1\104\1\110\1\104\1\110"+ + "\1\111\1\104\1\112\1\113\1\104\1\110\5\107\2\114"+ + "\1\115\1\116\3\117\3\120\1\121\2\122\2\123\3\124"+ + "\1\111\1\125\1\126\1\127\1\105\1\130\1\131\1\132"+ + "\2\104\1\113\1\111\1\104\1\113\1\104\1\113\6\104"+ + "\47\0\1\133\27\0\2\44\14\0\1\44\34\0\1\44"+ "\22\0\2\46\1\0\2\46\5\0\5\46\6\0\32\46"+ - "\3\0\1\46\23\0\1\133\75\0\1\134\1\135\5\0"+ - "\1\102\47\0\1\136\5\0\1\103\1\104\1\105\4\106"+ - "\1\103\3\107\1\110\1\103\1\111\1\112\1\103\1\107"+ - "\5\106\2\113\1\114\1\115\3\116\3\117\1\120\2\121"+ - "\2\122\3\123\1\110\1\124\1\125\1\126\1\104\1\127"+ - "\1\130\1\131\2\103\1\112\1\110\1\103\1\112\1\103"+ - "\1\112\6\103\71\0\1\137\17\0\1\67\12\0\26\67"+ + "\3\0\1\46\23\0\1\134\75\0\1\135\1\136\5\0"+ + "\1\103\47\0\1\137\5\0\1\104\1\105\1\106\4\107"+ + "\1\104\3\110\1\111\1\104\1\112\1\113\1\104\1\110"+ + "\5\107\2\114\1\115\1\116\3\117\3\120\1\121\2\122"+ + "\2\123\3\124\1\111\1\125\1\126\1\127\1\105\1\130"+ + "\1\131\1\132\2\104\1\113\1\111\1\104\1\113\1\104"+ + "\1\113\6\104\71\0\1\140\17\0\1\67\12\0\26\67"+ "\1\0\3\67\3\0\1\67\25\0\1\70\12\0\26\70"+ - "\1\0\3\70\3\0\1\70\23\0\1\140\70\0\1\141"+ - "\37\0\1\142\13\0\1\143\1\144\6\0\1\145\1\0"+ - "\1\145\1\146\1\147\1\150\11\0\1\100\75\0\1\151"+ - "\1\152\64\0\2\104\51\0\1\104\23\0\1\153\51\0"+ - "\1\153\27\0\1\154\147\0\1\155\1\156\14\0\76\157"+ - "\1\0\2\160\3\0\1\161\20\0\2\160\1\0\1\160"+ - "\4\0\3\160\5\0\2\160\3\0\1\160\22\0\2\162"+ - "\24\0\2\162\1\0\1\162\4\0\3\162\5\0\2\162"+ - "\3\0\1\162\101\0\1\163\1\164\25\0\1\165\144\0"+ - "\1\166\12\0\1\167\75\0\1\170\1\171\1\0\5\172"+ - "\1\0\70\172\11\0\1\151\66\0\1\173\51\0\1\173"+ - "\52\0\1\174\45\0\2\175\24\0\2\175\1\0\1\175"+ - "\4\0\3\175\5\0\2\175\3\0\1\175\22\0\2\176"+ - "\4\0\1\177\17\0\2\176\1\0\1\176\4\0\3\176"+ - "\5\0\2\176\3\0\1\176\22\0\2\200\24\0\2\200"+ - "\1\0\1\200\4\0\3\200\5\0\2\200\3\0\1\200"+ - "\21\0\5\172\1\201\70\172\2\0\1\202\51\0\1\202"+ - "\30\0\1\116\67\0\2\203\4\0\1\175\17\0\2\203"+ - "\1\0\1\203\4\0\3\203\5\0\2\203\3\0\1\203"+ - "\22\0\2\204\24\0\2\204\1\0\1\204\4\0\3\204"+ - "\5\0\2\204\3\0\1\204\22\0\2\205\4\0\1\175"+ - "\17\0\2\205\1\0\1\205\4\0\3\205\5\0\2\205"+ - "\3\0\1\205\22\0\2\206\24\0\2\206\1\0\1\206"+ - "\4\0\3\206\5\0\2\206\3\0\1\206\22\0\2\207"+ - "\4\0\1\175\17\0\2\207\1\0\1\207\4\0\3\207"+ - "\5\0\2\207\3\0\1\207\22\0\2\210\4\0\1\175"+ - "\17\0\2\210\1\0\1\210\4\0\3\210\5\0\2\210"+ - "\3\0\1\210\22\0\2\211\4\0\1\175\17\0\2\211"+ - "\1\0\1\211\4\0\3\211\5\0\2\211\3\0\1\211"+ - "\22\0\2\212\4\0\1\175\17\0\2\212\1\0\1\212"+ - "\4\0\3\212\5\0\2\212\3\0\1\212\22\0\2\212"+ - "\4\0\1\177\17\0\2\212\1\0\1\212\4\0\3\212"+ - "\5\0\2\212\3\0\1\212\21\0"; + "\1\0\3\70\3\0\1\70\13\0\2\73\10\0\5\73"+ + "\6\0\32\73\3\0\1\73\23\0\1\141\70\0\1\142"+ + "\37\0\1\143\13\0\1\144\1\145\6\0\1\146\1\0"+ + "\1\146\1\147\1\150\1\151\11\0\1\101\75\0\1\152"+ + "\1\153\64\0\2\105\51\0\1\105\23\0\1\154\51\0"+ + "\1\154\27\0\1\155\147\0\1\156\1\157\14\0\76\160"+ + "\1\0\2\161\3\0\1\162\20\0\2\161\1\0\1\161"+ + "\4\0\3\161\5\0\2\161\3\0\1\161\22\0\2\163"+ + "\24\0\2\163\1\0\1\163\4\0\3\163\5\0\2\163"+ + "\3\0\1\163\101\0\1\164\1\165\25\0\1\166\144\0"+ + "\1\167\12\0\1\170\75\0\1\171\1\172\1\0\5\173"+ + "\1\0\70\173\11\0\1\152\66\0\1\174\51\0\1\174"+ + "\52\0\1\175\45\0\2\176\24\0\2\176\1\0\1\176"+ + "\4\0\3\176\5\0\2\176\3\0\1\176\22\0\2\177"+ + "\4\0\1\200\17\0\2\177\1\0\1\177\4\0\3\177"+ + "\5\0\2\177\3\0\1\177\22\0\2\201\24\0\2\201"+ + "\1\0\1\201\4\0\3\201\5\0\2\201\3\0\1\201"+ + "\21\0\5\173\1\202\70\173\2\0\1\203\51\0\1\203"+ + "\30\0\1\117\67\0\2\204\4\0\1\176\17\0\2\204"+ + "\1\0\1\204\4\0\3\204\5\0\2\204\3\0\1\204"+ + "\22\0\2\205\24\0\2\205\1\0\1\205\4\0\3\205"+ + "\5\0\2\205\3\0\1\205\22\0\2\206\4\0\1\176"+ + "\17\0\2\206\1\0\1\206\4\0\3\206\5\0\2\206"+ + "\3\0\1\206\22\0\2\207\24\0\2\207\1\0\1\207"+ + "\4\0\3\207\5\0\2\207\3\0\1\207\22\0\2\210"+ + "\4\0\1\176\17\0\2\210\1\0\1\210\4\0\3\210"+ + "\5\0\2\210\3\0\1\210\22\0\2\211\4\0\1\176"+ + "\17\0\2\211\1\0\1\211\4\0\3\211\5\0\2\211"+ + "\3\0\1\211\22\0\2\212\4\0\1\176\17\0\2\212"+ + "\1\0\1\212\4\0\3\212\5\0\2\212\3\0\1\212"+ + "\22\0\2\213\4\0\1\176\17\0\2\213\1\0\1\213"+ + "\4\0\3\213\5\0\2\213\3\0\1\213\22\0\2\213"+ + "\4\0\1\200\17\0\2\213\1\0\1\213\4\0\3\213"+ + "\5\0\2\213\3\0\1\213\21\0"; private static int [] zzUnpackTrans() { - int [] result = new int[3906]; + int [] result = new int[3968]; int offset = 0; offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); return result; @@ -387,15 +388,15 @@ class _RegExLexer implements FlexLexer { "\12\0\1\1\5\0\2\11\1\1\2\11\2\1\12\11"+ "\1\1\1\11\1\1\1\11\1\1\3\11\1\1\1\11"+ "\1\1\1\11\1\1\1\11\1\1\2\11\1\1\3\11"+ - "\2\1\5\11\2\1\1\11\1\0\1\1\1\11\2\1"+ - "\6\11\2\1\2\11\1\1\4\11\2\1\2\11\1\1"+ - "\3\11\1\0\4\11\1\0\1\1\4\11\1\0\1\11"+ - "\1\0\1\1\1\0\3\11\3\1\7\11\1\0\1\1"+ - "\1\0\1\11\1\1\1\11\1\1\2\11\3\1\1\11"+ - "\4\1"; + "\2\1\2\11\1\1\3\11\2\1\1\11\1\0\1\1"+ + "\1\11\2\1\6\11\2\1\2\11\1\1\4\11\2\1"+ + "\2\11\1\1\3\11\1\0\4\11\1\0\1\1\4\11"+ + "\1\0\1\11\1\0\1\1\1\0\3\11\3\1\7\11"+ + "\1\0\1\1\1\0\1\11\1\1\1\11\1\1\2\11"+ + "\3\1\1\11\4\1"; private static int [] zzUnpackAttribute() { - int [] result = new int[138]; + int [] result = new int[139]; int offset = 0; offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); return result; diff --git a/RegExpSupport/src/org/intellij/lang/regexp/regexp-lexer.flex b/RegExpSupport/src/org/intellij/lang/regexp/regexp-lexer.flex index 16ff07395dab..d90f4964e2b2 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/regexp-lexer.flex +++ b/RegExpSupport/src/org/intellij/lang/regexp/regexp-lexer.flex @@ -100,6 +100,7 @@ RBRACKET="]" ESCAPE="\\" NAME=[:letter:]([:letter:]|_|-|" "|"("|")"|[:digit:])* +GROUP_NAME=[:letter:]([:letter:]|_|-|" "|[:digit:])* ANY=[^] META1 = {ESCAPE} | {LBRACKET} | "^" @@ -340,25 +341,25 @@ HEX_CHAR=[0-9a-fA-F] } { - {NAME} { return RegExpTT.NAME; } + {GROUP_NAME} { return RegExpTT.NAME; } ">" { yybegin(YYINITIAL); return RegExpTT.GT; } {ANY} { yybegin(YYINITIAL); return RegExpTT.BAD_CHARACTER; } } { - {NAME} { return RegExpTT.NAME; } + {GROUP_NAME} { return RegExpTT.NAME; } "'" { yybegin(YYINITIAL); return RegExpTT.QUOTE; } {ANY} { yybegin(YYINITIAL); return RegExpTT.BAD_CHARACTER; } } { - {NAME} { return RegExpTT.NAME; } + {GROUP_NAME} { return RegExpTT.NAME; } ")" { yybegin(YYINITIAL); return RegExpTT.GROUP_END; } {ANY} { yybegin(YYINITIAL); return RegExpTT.BAD_CHARACTER; } } { - {NAME} { return RegExpTT.NAME; } + {GROUP_NAME} { return RegExpTT.NAME; } [:digit:]+ { return RegExpTT.NUMBER; } ")" { yybegin(YYINITIAL); return RegExpTT.GROUP_END; } {ANY} { yybegin(YYINITIAL); return RegExpTT.BAD_CHARACTER; } diff --git a/RegExpSupport/test/org/intellij/lang/regexp/RegExpParsingTest.java b/RegExpSupport/test/org/intellij/lang/regexp/RegExpParsingTest.java index f351c303a042..1d057c835fd0 100644 --- a/RegExpSupport/test/org/intellij/lang/regexp/RegExpParsingTest.java +++ b/RegExpSupport/test/org/intellij/lang/regexp/RegExpParsingTest.java @@ -184,6 +184,10 @@ public class RegExpParsingTest extends ParsingTestCase { public void testGroups33() throws IOException { doCodeTest("(?[a-c])\\1"); } public void testGroups34() throws IOException { doCodeTest("(?[a-c])\\k"); } public void testGroups35() throws IOException { doCodeTest("\\k"); } + public void testGroups36() throws IOException { doCodeTest("(?P{"); } + 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 testEscapes1() throws IOException { doCodeTest("\\q"); } public void testEscapes2() throws IOException { doCodeTest("\\#"); } diff --git a/RegExpSupport/testData/psi/Groups36.txt b/RegExpSupport/testData/psi/Groups36.txt new file mode 100644 index 000000000000..bb6cfb567a65 --- /dev/null +++ b/RegExpSupport/testData/psi/Groups36.txt @@ -0,0 +1,14 @@ +REGEXP_FILE + RegExpPatternImpl: <(?P{> + RegExpBranchImpl: <(?P{> + RegExpClosureImpl: <(?P{> + RegExpGroupImpl: <(?P> + PsiElement(PYTHON_NAMED_GROUP)('(?P<') + PsiElement(NAME)('name') + PsiElement(GT)('>') + PsiErrorElement:Dangling metacharacter + + RegExpQuantifierImpl: <{> + PsiElement(LBRACE)('{') + PsiErrorElement:Number expected + \ No newline at end of file diff --git a/RegExpSupport/testData/psi/Groups37.txt b/RegExpSupport/testData/psi/Groups37.txt new file mode 100644 index 000000000000..7944e6527490 --- /dev/null +++ b/RegExpSupport/testData/psi/Groups37.txt @@ -0,0 +1,7 @@ +REGEXP_FILE + RegExpPatternImpl: <(?P=name)> + RegExpBranchImpl: <(?P=name)> + RegExpNamedGroupRefImpl: <(?P=name)> + PsiElement(PYTHON_NAMED_GROUP_REF)('(?P=') + PsiElement(NAME)('name') + PsiElement(GROUP_END)(')') \ No newline at end of file diff --git a/RegExpSupport/testData/psi/Groups38.txt b/RegExpSupport/testData/psi/Groups38.txt new file mode 100644 index 000000000000..5603f065cdd4 --- /dev/null +++ b/RegExpSupport/testData/psi/Groups38.txt @@ -0,0 +1,7 @@ +REGEXP_FILE + RegExpPatternImpl: <\g'name'> + RegExpBranchImpl: <\g'name'> + RegExpNamedGroupRefImpl: <\g'name'> + PsiElement(RUBY_QUOTED_NAMED_GROUP_CALL)('\g'') + PsiElement(NAME)('name') + PsiElement(QUOTE)(''') \ No newline at end of file diff --git a/RegExpSupport/testData/psi/Groups39.txt b/RegExpSupport/testData/psi/Groups39.txt new file mode 100644 index 000000000000..60bd9b26a375 --- /dev/null +++ b/RegExpSupport/testData/psi/Groups39.txt @@ -0,0 +1,53 @@ +REGEXP_FILE + RegExpPatternImpl: <(?(name)yes-pattern|no-pattern)> + RegExpBranchImpl: <(?(name)yes-pattern|no-pattern)> + RegExpPyCondRefImpl: <(?(name)yes-pattern|no-pattern)> + PsiElement(PYTHON_COND_REF)('(?(') + PsiElement(NAME)('name') + PsiElement(GROUP_END)(')') + RegExpBranchImpl: + RegExpCharImpl: + PsiElement(CHARACTER)('y') + RegExpCharImpl: + PsiElement(CHARACTER)('e') + RegExpCharImpl: + PsiElement(CHARACTER)('s') + RegExpCharImpl: <-> + PsiElement(MINUS)('-') + RegExpCharImpl:

+ PsiElement(CHARACTER)('p') + RegExpCharImpl: + PsiElement(CHARACTER)('a') + RegExpCharImpl: + PsiElement(CHARACTER)('t') + RegExpCharImpl: + PsiElement(CHARACTER)('t') + RegExpCharImpl: + PsiElement(CHARACTER)('e') + RegExpCharImpl: + PsiElement(CHARACTER)('r') + RegExpCharImpl: + PsiElement(CHARACTER)('n') + PsiElement(UNION)('|') + RegExpBranchImpl: + RegExpCharImpl: + PsiElement(CHARACTER)('n') + RegExpCharImpl: + PsiElement(CHARACTER)('o') + RegExpCharImpl: <-> + PsiElement(MINUS)('-') + RegExpCharImpl:

+ PsiElement(CHARACTER)('p') + RegExpCharImpl: + PsiElement(CHARACTER)('a') + RegExpCharImpl: + PsiElement(CHARACTER)('t') + RegExpCharImpl: + PsiElement(CHARACTER)('t') + RegExpCharImpl: + PsiElement(CHARACTER)('e') + RegExpCharImpl: + PsiElement(CHARACTER)('r') + RegExpCharImpl: + PsiElement(CHARACTER)('n') + PsiElement(GROUP_END)(')') \ No newline at end of file