From c0056cf5235dbf021ba59379b6547cbcb0f1c024 Mon Sep 17 00:00:00 2001 From: "igor.petrenko" Date: Mon, 31 Aug 2026 10:38:47 +0300 Subject: [PATCH 1/2] CE-209 oap-plugin: supervision completion --- .../plugin/gen/parser/OapParser.java | 58 ++- .../plugin/gen/parser/_OapLexer.java | 481 ++++++++++-------- gradle.properties | 2 +- grammars/_OapLexer.flex | 7 + grammars/oap.bnf | 27 +- .../OapSupervisionCompletionContributor.kt | 55 ++ .../plugin/formatter/OapFormattingBlock.kt | 18 + src/main/resources/META-INF/plugin.xml | 1 + .../oap/application/plugin/FormatterTest.kt | 8 + .../OapSupervisionCompletionTest.kt | 123 +++++ .../plugin/parser/OapParserTest.kt | 2 +- testdata/formatter/array-after.oap | 1 + .../enterAfterEmptyServicesBlock-after.oap | 3 + .../enterAfterEmptyServicesBlock.oap | 2 + .../formatter/enterAfterModuleName-after.oap | 2 + testdata/formatter/enterAfterModuleName.oap | 1 + 16 files changed, 559 insertions(+), 232 deletions(-) create mode 100644 src/main/kotlin/oap/application/plugin/completion/OapSupervisionCompletionContributor.kt create mode 100644 src/test/kotlin/oap/application/plugin/completion/OapSupervisionCompletionTest.kt create mode 100644 testdata/formatter/enterAfterEmptyServicesBlock-after.oap create mode 100644 testdata/formatter/enterAfterEmptyServicesBlock.oap create mode 100644 testdata/formatter/enterAfterModuleName-after.oap create mode 100644 testdata/formatter/enterAfterModuleName.oap diff --git a/gen/oap/application/plugin/gen/parser/OapParser.java b/gen/oap/application/plugin/gen/parser/OapParser.java index ace38f8..473e40a 100644 --- a/gen/oap/application/plugin/gen/parser/OapParser.java +++ b/gen/oap/application/plugin/gen/parser/OapParser.java @@ -792,13 +792,12 @@ public static boolean dot_remote(PsiBuilder builder_, int level_) { // '.' module_services_service_supervision_entities static boolean dot_supervision(PsiBuilder builder_, int level_) { if (!recursion_guard_(builder_, level_, "dot_supervision")) return false; - if (!nextTokenIs(builder_, OAP_DOT)) return false; boolean result_, pinned_; Marker marker_ = enter_section_(builder_, level_, _NONE_); result_ = consumeToken(builder_, OAP_DOT); pinned_ = result_; // pin = 1 result_ = result_ && module_services_service_supervision_entities(builder_, level_ + 1); - exit_section_(builder_, level_, marker_, result_, pinned_, null); + exit_section_(builder_, level_, marker_, result_, pinned_, OapParser::recover_supervision); return result_ || pinned_; } @@ -3736,6 +3735,31 @@ private static boolean recover_remote_0(PsiBuilder builder_, int level_) { return result_; } + /* ********************************************************** */ + // !('supervise' | 'schedule' | 'thread' | 'delay' | 'cron' | '}' | dedent) + static boolean recover_supervision(PsiBuilder builder_, int level_) { + if (!recursion_guard_(builder_, level_, "recover_supervision")) return false; + boolean result_; + Marker marker_ = enter_section_(builder_, level_, _NOT_); + result_ = !recover_supervision_0(builder_, level_ + 1); + exit_section_(builder_, level_, marker_, result_, false, null); + return result_; + } + + // 'supervise' | 'schedule' | 'thread' | 'delay' | 'cron' | '}' | dedent + private static boolean recover_supervision_0(PsiBuilder builder_, int level_) { + if (!recursion_guard_(builder_, level_, "recover_supervision_0")) return false; + boolean result_; + result_ = consumeToken(builder_, OAP_ID_SUPERVISE); + if (!result_) result_ = consumeToken(builder_, OAP_ID_SCHEDULE); + if (!result_) result_ = consumeToken(builder_, OAP_ID_THREAD); + if (!result_) result_ = consumeToken(builder_, OAP_ID_DELAY); + if (!result_) result_ = consumeToken(builder_, OAP_ID_CRON); + if (!result_) result_ = consumeToken(builder_, OAP_RIGHTBRACE); + if (!result_) result_ = consumeToken(builder_, OAP_DEDENT); + return result_; + } + /* ********************************************************** */ // '<' reference_kernel_value_in '>' public static boolean reference_kernel_value(PsiBuilder builder_, int level_) { @@ -4206,13 +4230,36 @@ public static boolean service_name(PsiBuilder builder_, int level_) { } /* ********************************************************** */ - // supervision_object_brace | supervision_object_colon + // &'{' supervision_object_brace | supervision_object_colon static boolean supervision_object(PsiBuilder builder_, int level_) { if (!recursion_guard_(builder_, level_, "supervision_object")) return false; if (!nextTokenIs(builder_, "", OAP_COLON, OAP_LEFTBRACE)) return false; boolean result_; - result_ = supervision_object_brace(builder_, level_ + 1); + Marker marker_ = enter_section_(builder_); + result_ = supervision_object_0(builder_, level_ + 1); if (!result_) result_ = supervision_object_colon(builder_, level_ + 1); + exit_section_(builder_, marker_, null, result_); + return result_; + } + + // &'{' supervision_object_brace + private static boolean supervision_object_0(PsiBuilder builder_, int level_) { + if (!recursion_guard_(builder_, level_, "supervision_object_0")) return false; + boolean result_; + Marker marker_ = enter_section_(builder_); + result_ = supervision_object_0_0(builder_, level_ + 1); + result_ = result_ && supervision_object_brace(builder_, level_ + 1); + exit_section_(builder_, marker_, null, result_); + return result_; + } + + // &'{' + private static boolean supervision_object_0_0(PsiBuilder builder_, int level_) { + if (!recursion_guard_(builder_, level_, "supervision_object_0_0")) return false; + boolean result_; + Marker marker_ = enter_section_(builder_, level_, _AND_); + result_ = consumeToken(builder_, OAP_LEFTBRACE); + exit_section_(builder_, level_, marker_, result_, false, null); return result_; } @@ -4220,14 +4267,13 @@ static boolean supervision_object(PsiBuilder builder_, int level_) { // '{' module_services_service_supervision_entities* '}' static boolean supervision_object_brace(PsiBuilder builder_, int level_) { if (!recursion_guard_(builder_, level_, "supervision_object_brace")) return false; - if (!nextTokenIs(builder_, OAP_LEFTBRACE)) return false; boolean result_, pinned_; Marker marker_ = enter_section_(builder_, level_, _NONE_); result_ = consumeToken(builder_, OAP_LEFTBRACE); pinned_ = result_; // pin = 1 result_ = result_ && report_error_(builder_, supervision_object_brace_1(builder_, level_ + 1)); result_ = pinned_ && consumeToken(builder_, OAP_RIGHTBRACE) && result_; - exit_section_(builder_, level_, marker_, result_, pinned_, null); + exit_section_(builder_, level_, marker_, result_, pinned_, OapParser::recover_supervision); return result_ || pinned_; } diff --git a/gen/oap/application/plugin/gen/parser/_OapLexer.java b/gen/oap/application/plugin/gen/parser/_OapLexer.java index 92cd8fb..0159957 100644 --- a/gen/oap/application/plugin/gen/parser/_OapLexer.java +++ b/gen/oap/application/plugin/gen/parser/_OapLexer.java @@ -408,26 +408,26 @@ private static int zzUnpackcmap_blocks(String packed, int offset, int [] result) "\1\32\1\33\1\34\1\35\1\36\1\37\1\40\1\41"+ "\1\37\1\42\1\43\10\2\1\44\1\45\3\2\1\46"+ "\1\2\1\47\1\50\1\51\1\52\4\2\1\53\2\2"+ - "\1\54\4\2\1\55\1\56\1\57\1\60\1\2\1\61"+ + "\1\54\4\37\1\55\1\56\1\57\1\60\1\2\1\61"+ "\1\2\1\62\1\63\1\37\1\64\1\65\2\11\1\66"+ "\1\67\1\70\1\71\1\72\1\3\1\73\1\74\4\73"+ "\1\75\1\76\1\77\3\1\11\0\1\100\4\0\1\14"+ - "\1\17\3\0\1\37\31\0\1\11\2\0\1\37\1\0"+ - "\1\37\2\11\1\0\4\73\6\0\1\100\5\0\1\37"+ - "\13\0\1\101\15\0\1\11\2\37\2\11\5\73\4\0"+ - "\1\102\2\0\1\103\2\0\1\37\3\0\1\104\6\0"+ - "\1\105\1\0\1\106\1\0\1\107\1\110\1\0\1\111"+ - "\2\0\1\112\4\0\1\37\1\103\2\73\1\113\1\73"+ - "\1\114\10\0\1\37\16\0\1\115\3\0\1\37\3\73"+ - "\6\0\1\116\1\117\1\37\3\0\1\120\1\0\1\121"+ - "\12\0\1\122\1\37\1\123\2\73\2\0\1\124\3\0"+ - "\1\37\1\0\1\125\5\0\1\126\6\0\1\37\1\127"+ - "\1\73\3\0\1\130\1\131\1\37\1\132\7\0\1\133"+ - "\1\0\1\134\1\0\1\135\1\0\1\136\1\0\1\37"+ - "\10\0\1\137\2\0\1\37\1\0\1\140\1\0\1\141"+ - "\1\142\5\0\1\37\1\0\1\143\2\0\1\144\2\0"+ - "\1\37\1\0\1\145\1\146\2\0\1\37\1\0\1\147"+ - "\1\0\1\150\1\151\1\0\1\152"; + "\1\17\3\0\1\37\23\0\5\37\1\0\1\11\2\0"+ + "\1\37\1\0\1\37\2\11\1\0\4\73\6\0\1\100"+ + "\5\0\1\37\13\0\1\101\10\0\5\37\1\11\2\37"+ + "\2\11\5\73\4\0\1\102\2\0\1\103\2\0\1\37"+ + "\3\0\1\104\6\0\1\105\1\0\1\106\1\0\1\107"+ + "\1\110\1\0\1\111\2\0\1\112\5\37\1\103\2\73"+ + "\1\113\1\73\1\114\10\0\1\37\16\0\1\115\4\37"+ + "\3\73\6\0\1\116\1\117\1\37\3\0\1\120\1\0"+ + "\1\121\10\0\2\37\1\122\1\37\1\123\2\73\2\0"+ + "\1\124\3\0\1\37\1\0\1\125\5\0\1\126\4\0"+ + "\3\37\1\127\1\73\3\0\1\130\1\131\1\37\1\132"+ + "\7\0\1\133\1\0\1\134\1\37\1\135\1\0\1\136"+ + "\1\0\1\37\10\0\1\137\2\0\1\37\1\0\1\140"+ + "\1\0\1\141\1\142\5\0\1\37\1\0\1\143\2\0"+ + "\1\144\2\0\1\37\1\0\1\145\1\146\2\0\1\37"+ + "\1\0\1\147\1\0\1\150\1\151\1\0\1\152"; private static int [] zzUnpackAction() { int [] result = new int[454]; @@ -491,23 +491,23 @@ private static int zzUnpackAction(String packed, int offset, int [] result) { "\0\u299d\0\u29d2\0\u0813\0\u2a07\0\u2a3c\0\u2a71\0\u2aa6\0\u2adb"+ "\0\u2b10\0\u0813\0\u2b45\0\u2b7a\0\u2baf\0\u2be4\0\u2c19\0\u2c4e"+ "\0\u0813\0\u2c83\0\u0813\0\u2cb8\0\u0813\0\u0813\0\u2ced\0\u0813"+ - "\0\u2d22\0\u2d57\0\u0813\0\u2d8c\0\u2dc1\0\u2df6\0\u2e2b\0\u2e60"+ + "\0\u2d22\0\u2d57\0\u0d40\0\u2d8c\0\u2dc1\0\u2df6\0\u2e2b\0\u2e60"+ "\0\u0bcd\0\u2e95\0\u2eca\0\u1415\0\u2eff\0\u1415\0\u2f34\0\u2f69"+ "\0\u2f9e\0\u2fd3\0\u3008\0\u303d\0\u3072\0\u30a7\0\u30dc\0\u3111"+ "\0\u3146\0\u317b\0\u31b0\0\u31e5\0\u321a\0\u324f\0\u3284\0\u32b9"+ - "\0\u32ee\0\u3323\0\u3358\0\u338d\0\u33c2\0\u0813\0\u33f7\0\u342c"+ + "\0\u32ee\0\u3323\0\u3358\0\u338d\0\u33c2\0\u0d40\0\u33f7\0\u342c"+ "\0\u3461\0\u3496\0\u34cb\0\u3500\0\u3535\0\u356a\0\u359f\0\u35d4"+ "\0\u3609\0\u363e\0\u3673\0\u0813\0\u0813\0\u36a8\0\u36dd\0\u3712"+ "\0\u3747\0\u0813\0\u377c\0\u0813\0\u37b1\0\u37e6\0\u381b\0\u3850"+ - "\0\u3885\0\u38ba\0\u38ef\0\u3924\0\u3959\0\u398e\0\u0813\0\u39c3"+ + "\0\u3885\0\u38ba\0\u38ef\0\u3924\0\u3959\0\u398e\0\u0d40\0\u39c3"+ "\0\u1415\0\u39f8\0\u3a2d\0\u3a62\0\u3a97\0\u0813\0\u3acc\0\u3b01"+ "\0\u3b36\0\u3b6b\0\u3ba0\0\u0813\0\u3bd5\0\u3c0a\0\u3c3f\0\u3c74"+ "\0\u3ca9\0\u0813\0\u3cde\0\u3d13\0\u3d48\0\u3d7d\0\u3db2\0\u3de7"+ "\0\u3e1c\0\u1415\0\u3e51\0\u3e86\0\u3ebb\0\u3ef0\0\u0813\0\u0813"+ "\0\u3f25\0\u0813\0\u3f5a\0\u3f8f\0\u3fc4\0\u3ff9\0\u402e\0\u4063"+ - "\0\u4098\0\u0813\0\u40cd\0\u0813\0\u4102\0\u1415\0\u4137\0\u0813"+ + "\0\u4098\0\u0813\0\u40cd\0\u0d40\0\u4102\0\u1415\0\u4137\0\u0813"+ "\0\u416c\0\u41a1\0\u41d6\0\u420b\0\u4240\0\u4275\0\u42aa\0\u42df"+ - "\0\u4314\0\u4349\0\u0813\0\u437e\0\u43b3\0\u43e8\0\u441d\0\u0813"+ + "\0\u4314\0\u4349\0\u0d40\0\u437e\0\u43b3\0\u43e8\0\u441d\0\u0813"+ "\0\u4452\0\u0813\0\u0813\0\u4487\0\u44bc\0\u44f1\0\u4526\0\u455b"+ "\0\u4590\0\u45c5\0\u0813\0\u45fa\0\u462f\0\u0813\0\u4664\0\u4699"+ "\0\u46ce\0\u4703\0\u0813\0\u0813\0\u4738\0\u476d\0\u47a2\0\u47d7"+ @@ -588,109 +588,123 @@ private static int zzUnpackRowMap(String packed, int offset, int [] result) { "\1\54\6\50\1\162\1\55\1\144\12\50\1\163\1\164"+ "\1\50\1\60\11\50\1\157\10\50\1\150\1\50\1\132"+ "\1\50\1\51\1\52\1\51\1\53\1\50\1\51\1\50"+ - "\1\54\6\50\1\165\1\55\1\144\13\50\1\166\1\167"+ - "\15\50\1\170\1\171\4\50\1\150\1\50\1\132\1\50"+ - "\1\51\1\52\1\51\1\53\1\50\1\51\1\50\1\54"+ - "\1\172\5\50\1\126\1\55\1\173\3\50\3\172\3\50"+ - "\27\172\1\174\3\50\1\51\1\52\1\51\1\53\1\50"+ - "\1\51\1\50\1\54\1\175\6\50\1\55\4\50\3\175"+ - "\3\50\27\175\2\50\1\132\1\74\1\51\1\52\1\51"+ - "\1\53\1\50\1\51\1\176\1\54\1\74\1\67\1\70"+ - "\1\50\1\102\2\74\1\75\1\50\1\177\1\50\1\103"+ - "\3\74\2\50\1\104\27\74\1\121\1\103\2\50\1\51"+ - "\1\52\1\51\1\53\1\50\1\51\1\200\1\54\1\125"+ - "\3\50\1\102\1\50\1\126\1\55\1\201\1\50\1\202"+ - "\1\50\3\125\3\50\10\125\1\203\16\125\1\121\1\50"+ - "\1\132\1\74\1\51\1\64\1\51\1\65\1\50\1\51"+ - "\1\176\1\54\1\204\1\67\1\70\1\50\1\205\2\74"+ - "\1\75\1\50\1\177\1\50\1\100\3\74\1\120\2\50"+ - "\5\74\1\206\14\74\1\207\4\74\1\121\1\100\1\210"+ - "\1\50\1\51\1\52\1\51\1\53\1\50\1\51\1\50"+ - "\1\54\5\50\1\211\1\50\1\55\44\50\1\74\1\51"+ - "\1\64\1\51\1\65\1\50\1\51\1\176\1\54\1\74"+ - "\4\50\2\74\1\75\1\212\1\50\1\77\1\100\3\74"+ - "\1\213\2\50\27\74\1\50\1\100\1\50\1\74\1\51"+ - "\1\52\1\51\1\53\1\50\1\51\1\176\1\54\1\74"+ - "\3\50\1\102\2\74\1\75\3\50\1\103\3\74\2\50"+ - "\1\104\27\74\1\50\1\103\1\50\1\74\1\51\1\52"+ - "\1\51\1\53\1\50\1\51\1\176\1\54\1\74\4\50"+ - "\1\105\1\74\1\75\3\50\1\103\3\74\3\50\27\74"+ - "\1\50\1\103\1\50\1\74\1\51\1\64\1\51\1\65"+ - "\1\50\1\51\1\176\1\54\1\74\1\67\1\70\2\50"+ - "\2\74\1\75\1\116\1\177\1\77\1\100\3\74\3\50"+ - "\5\74\1\206\14\74\1\207\4\74\1\50\1\100\2\50"+ - "\1\51\1\64\1\51\1\65\1\50\1\51\1\50\1\54"+ - "\7\50\1\55\1\116\1\177\1\77\42\50\1\51\1\214"+ - "\1\51\1\215\1\50\1\51\1\50\1\54\1\216\5\50"+ - "\1\126\1\55\3\50\1\217\3\216\3\50\11\216\1\220"+ - "\1\216\1\221\5\216\1\222\1\223\4\216\4\50\1\51"+ - "\1\64\1\51\1\65\1\50\1\51\1\50\1\54\7\50"+ - "\1\55\1\224\1\225\1\77\4\50\1\226\35\50\1\51"+ - "\1\52\1\51\1\53\1\50\1\51\1\50\1\54\4\50"+ - "\1\102\2\50\1\55\1\50\1\225\7\50\1\104\33\50"+ - "\1\51\1\50\2\51\1\50\1\51\1\50\1\54\1\216"+ - "\5\50\1\126\1\55\3\50\1\217\3\216\3\50\13\216"+ - "\1\221\13\216\4\50\1\51\1\52\1\51\1\53\1\50"+ - "\1\51\1\50\1\54\5\50\1\105\1\50\1\55\1\50"+ - "\1\225\42\50\1\74\7\50\1\54\1\74\4\50\2\74"+ - "\1\75\4\50\3\74\3\50\27\74\1\150\1\50\1\132"+ - "\1\227\1\230\1\50\1\227\1\50\1\227\1\230\1\227"+ - "\1\54\7\227\1\231\44\227\66\0\1\51\1\0\2\51"+ - "\1\0\1\51\60\0\1\52\1\0\1\232\61\0\1\51"+ - "\1\52\2\51\1\0\1\51\56\0\2\54\1\0\62\54"+ - "\20\0\1\54\114\0\1\233\53\0\1\234\74\0\1\235"+ - "\64\0\1\236\50\0\1\237\70\0\1\240\27\0\1\64"+ - "\1\0\1\241\61\0\1\51\1\64\2\51\1\0\1\51"+ - "\56\0\7\242\1\243\21\242\1\244\33\242\33\0\1\245"+ - "\70\0\1\246\100\0\1\247\11\0\1\74\5\0\1\74"+ - "\2\0\1\74\4\0\3\74\4\0\3\74\3\0\27\74"+ - "\3\0\1\74\5\0\1\74\2\0\1\74\4\0\2\74"+ - "\1\54\4\0\3\74\3\0\27\74\17\0\1\250\1\0"+ - "\1\250\62\0\1\251\1\0\1\251\116\0\1\252\64\0"+ - "\1\253\14\0\1\115\10\0\1\115\5\0\1\254\5\0"+ - "\3\115\3\0\27\115\3\0\1\125\10\0\1\125\4\0"+ - "\1\125\1\0\1\125\4\0\3\125\3\0\27\125\3\0"+ + "\1\54\1\125\5\50\1\165\1\55\1\144\3\50\3\125"+ + "\3\50\2\125\1\166\1\167\15\125\1\170\1\171\4\125"+ + "\1\150\1\50\1\132\1\50\1\51\1\52\1\51\1\53"+ + "\1\50\1\51\1\50\1\54\1\172\5\50\1\126\1\55"+ + "\1\173\3\50\3\172\3\50\27\172\1\174\3\50\1\51"+ + "\1\52\1\51\1\53\1\50\1\51\1\50\1\54\1\175"+ + "\6\50\1\55\4\50\3\175\3\50\27\175\2\50\1\132"+ + "\1\74\1\51\1\52\1\51\1\53\1\50\1\51\1\176"+ + "\1\54\1\74\1\67\1\70\1\50\1\102\2\74\1\75"+ + "\1\50\1\177\1\50\1\103\3\74\2\50\1\104\27\74"+ + "\1\121\1\103\2\50\1\51\1\52\1\51\1\53\1\50"+ + "\1\51\1\200\1\54\1\125\3\50\1\102\1\50\1\126"+ + "\1\55\1\201\1\50\1\202\1\50\3\125\3\50\10\125"+ + "\1\203\16\125\1\121\1\50\1\132\1\74\1\51\1\64"+ + "\1\51\1\65\1\50\1\51\1\176\1\54\1\204\1\67"+ + "\1\70\1\50\1\205\2\74\1\75\1\50\1\177\1\50"+ + "\1\100\3\74\1\120\2\50\5\74\1\206\14\74\1\207"+ + "\4\74\1\121\1\100\1\210\1\50\1\51\1\52\1\51"+ + "\1\53\1\50\1\51\1\50\1\54\5\50\1\211\1\50"+ + "\1\55\44\50\1\74\1\51\1\64\1\51\1\65\1\50"+ + "\1\51\1\176\1\54\1\74\4\50\2\74\1\75\1\212"+ + "\1\50\1\77\1\100\3\74\1\213\2\50\27\74\1\50"+ + "\1\100\1\50\1\74\1\51\1\52\1\51\1\53\1\50"+ + "\1\51\1\176\1\54\1\74\3\50\1\102\2\74\1\75"+ + "\3\50\1\103\3\74\2\50\1\104\27\74\1\50\1\103"+ + "\1\50\1\74\1\51\1\52\1\51\1\53\1\50\1\51"+ + "\1\176\1\54\1\74\4\50\1\105\1\74\1\75\3\50"+ + "\1\103\3\74\3\50\27\74\1\50\1\103\1\50\1\74"+ + "\1\51\1\64\1\51\1\65\1\50\1\51\1\176\1\54"+ + "\1\74\1\67\1\70\2\50\2\74\1\75\1\116\1\177"+ + "\1\77\1\100\3\74\3\50\5\74\1\206\14\74\1\207"+ + "\4\74\1\50\1\100\2\50\1\51\1\64\1\51\1\65"+ + "\1\50\1\51\1\50\1\54\7\50\1\55\1\116\1\177"+ + "\1\77\42\50\1\51\1\214\1\51\1\215\1\50\1\51"+ + "\1\50\1\54\1\216\5\50\1\126\1\55\3\50\1\217"+ + "\3\216\3\50\11\216\1\220\1\216\1\221\5\216\1\222"+ + "\1\223\4\216\4\50\1\51\1\64\1\51\1\65\1\50"+ + "\1\51\1\50\1\54\7\50\1\55\1\224\1\225\1\77"+ + "\4\50\1\226\35\50\1\51\1\52\1\51\1\53\1\50"+ + "\1\51\1\50\1\54\4\50\1\102\2\50\1\55\1\50"+ + "\1\225\7\50\1\104\33\50\1\51\1\50\2\51\1\50"+ + "\1\51\1\50\1\54\1\216\5\50\1\126\1\55\3\50"+ + "\1\217\3\216\3\50\13\216\1\221\13\216\4\50\1\51"+ + "\1\52\1\51\1\53\1\50\1\51\1\50\1\54\5\50"+ + "\1\105\1\50\1\55\1\50\1\225\42\50\1\74\7\50"+ + "\1\54\1\74\4\50\2\74\1\75\4\50\3\74\3\50"+ + "\27\74\1\150\1\50\1\132\1\227\1\230\1\50\1\227"+ + "\1\50\1\227\1\230\1\227\1\54\7\227\1\231\44\227"+ + "\66\0\1\51\1\0\2\51\1\0\1\51\60\0\1\52"+ + "\1\0\1\232\61\0\1\51\1\52\2\51\1\0\1\51"+ + "\56\0\2\54\1\0\62\54\20\0\1\54\114\0\1\233"+ + "\53\0\1\234\74\0\1\235\64\0\1\236\50\0\1\237"+ + "\70\0\1\240\27\0\1\64\1\0\1\241\61\0\1\51"+ + "\1\64\2\51\1\0\1\51\56\0\7\242\1\243\21\242"+ + "\1\244\33\242\33\0\1\245\70\0\1\246\100\0\1\247"+ + "\11\0\1\74\5\0\1\74\2\0\1\74\4\0\3\74"+ + "\4\0\3\74\3\0\27\74\3\0\1\74\5\0\1\74"+ + "\2\0\1\74\4\0\2\74\1\54\4\0\3\74\3\0"+ + "\27\74\17\0\1\250\1\0\1\250\62\0\1\251\1\0"+ + "\1\251\116\0\1\252\64\0\1\253\14\0\1\115\10\0"+ + "\1\115\5\0\1\254\5\0\3\115\3\0\27\115\3\0"+ "\1\125\10\0\1\125\4\0\1\125\1\0\1\125\4\0"+ - "\3\125\3\0\13\125\1\255\13\125\37\0\1\256\67\0"+ - "\1\257\73\0\1\260\61\0\1\261\54\0\1\262\70\0"+ - "\1\263\103\0\1\264\62\0\1\265\43\0\1\266\74\0"+ - "\1\267\74\0\1\270\44\0\1\271\100\0\1\272\50\0"+ - "\1\273\14\0\1\274\53\0\1\275\60\0\1\276\76\0"+ - "\1\277\67\0\1\300\67\0\1\301\50\0\1\302\62\0"+ - "\1\303\20\0\1\304\50\0\1\305\22\0\1\172\10\0"+ - "\1\172\4\0\1\172\1\0\1\172\4\0\3\172\3\0"+ - "\27\172\3\0\1\175\10\0\1\175\4\0\1\175\1\0"+ - "\1\175\4\0\3\175\3\0\27\175\3\0\7\306\1\307"+ - "\21\306\1\310\33\306\7\311\1\312\21\311\1\313\33\311"+ + "\3\125\3\0\27\125\3\0\1\125\10\0\1\125\4\0"+ + "\1\125\1\0\1\125\4\0\3\125\3\0\13\125\1\255"+ + "\13\125\37\0\1\256\67\0\1\257\73\0\1\260\61\0"+ + "\1\261\54\0\1\262\70\0\1\263\103\0\1\264\62\0"+ + "\1\265\43\0\1\266\74\0\1\267\74\0\1\270\44\0"+ + "\1\271\100\0\1\272\50\0\1\273\14\0\1\274\53\0"+ + "\1\275\60\0\1\276\76\0\1\277\67\0\1\300\14\0"+ "\1\125\10\0\1\125\4\0\1\125\1\0\1\125\4\0"+ - "\3\125\3\0\14\125\1\314\12\125\3\0\1\74\5\0"+ - "\1\74\2\0\1\74\4\0\3\74\4\0\3\74\3\0"+ - "\1\315\26\74\3\0\1\74\5\0\1\74\2\0\1\74"+ - "\4\0\3\74\4\0\3\74\3\0\20\74\1\316\6\74"+ - "\5\0\1\214\1\0\1\317\61\0\1\51\1\214\2\51"+ - "\1\0\1\51\56\0\1\216\10\0\1\216\4\0\1\216"+ - "\1\0\1\216\4\0\3\216\3\0\27\216\3\0\1\216"+ + "\3\125\3\0\20\125\1\301\6\125\3\0\1\125\10\0"+ + "\1\125\4\0\1\125\1\0\1\125\4\0\3\125\3\0"+ + "\4\125\1\302\22\125\3\0\1\125\10\0\1\125\4\0"+ + "\1\125\1\0\1\125\4\0\3\125\3\0\2\125\1\303"+ + "\20\125\1\304\3\125\3\0\1\125\10\0\1\125\4\0"+ + "\1\125\1\0\1\125\4\0\3\125\3\0\7\125\1\305"+ + "\17\125\3\0\1\172\10\0\1\172\4\0\1\172\1\0"+ + "\1\172\4\0\3\172\3\0\27\172\3\0\1\175\10\0"+ + "\1\175\4\0\1\175\1\0\1\175\4\0\3\175\3\0"+ + "\27\175\3\0\7\306\1\307\21\306\1\310\33\306\7\311"+ + "\1\312\21\311\1\313\33\311\1\125\10\0\1\125\4\0"+ + "\1\125\1\0\1\125\4\0\3\125\3\0\14\125\1\314"+ + "\12\125\3\0\1\74\5\0\1\74\2\0\1\74\4\0"+ + "\3\74\4\0\3\74\3\0\1\315\26\74\3\0\1\74"+ + "\5\0\1\74\2\0\1\74\4\0\3\74\4\0\3\74"+ + "\3\0\20\74\1\316\6\74\5\0\1\214\1\0\1\317"+ + "\61\0\1\51\1\214\2\51\1\0\1\51\56\0\1\216"+ "\10\0\1\216\4\0\1\216\1\0\1\216\4\0\3\216"+ - "\3\0\4\216\1\320\22\216\3\0\1\216\10\0\1\216"+ - "\4\0\1\216\1\0\1\216\4\0\3\216\3\0\15\216"+ - "\1\321\11\216\3\0\1\216\10\0\1\216\4\0\1\216"+ - "\1\0\1\216\4\0\3\216\3\0\4\216\1\322\22\216"+ + "\3\0\27\216\3\0\1\216\10\0\1\216\4\0\1\216"+ + "\1\0\1\216\4\0\3\216\3\0\4\216\1\320\22\216"+ "\3\0\1\216\10\0\1\216\4\0\1\216\1\0\1\216"+ - "\4\0\3\216\3\0\7\216\1\323\17\216\3\0\1\227"+ - "\1\230\1\0\1\227\1\0\1\227\1\230\56\227\2\0"+ - "\1\52\131\0\1\324\66\0\1\325\46\0\1\326\66\0"+ - "\1\327\75\0\1\330\71\0\1\331\13\0\1\64\62\0"+ - "\7\242\1\332\21\242\1\244\33\242\45\0\1\333\71\0"+ - "\1\334\70\0\1\335\55\0\1\336\50\0\1\337\42\0"+ - "\1\115\13\0\3\115\3\0\27\115\3\0\1\125\10\0"+ + "\4\0\3\216\3\0\15\216\1\321\11\216\3\0\1\216"+ + "\10\0\1\216\4\0\1\216\1\0\1\216\4\0\3\216"+ + "\3\0\4\216\1\322\22\216\3\0\1\216\10\0\1\216"+ + "\4\0\1\216\1\0\1\216\4\0\3\216\3\0\7\216"+ + "\1\323\17\216\3\0\1\227\1\230\1\0\1\227\1\0"+ + "\1\227\1\230\56\227\2\0\1\52\131\0\1\324\66\0"+ + "\1\325\46\0\1\326\66\0\1\327\75\0\1\330\71\0"+ + "\1\331\13\0\1\64\62\0\7\242\1\332\21\242\1\244"+ + "\33\242\45\0\1\333\71\0\1\334\70\0\1\335\55\0"+ + "\1\336\50\0\1\337\42\0\1\115\13\0\3\115\3\0"+ + "\27\115\3\0\1\125\10\0\1\125\4\0\1\125\1\0"+ + "\1\125\4\0\3\125\3\0\16\125\1\340\10\125\57\0"+ + "\1\341\50\0\1\342\10\0\1\325\64\0\1\343\62\0"+ + "\1\344\4\0\1\345\63\0\1\346\57\0\1\347\67\0"+ + "\1\350\31\0\1\351\114\0\1\352\64\0\1\353\63\0"+ + "\1\354\65\0\1\355\73\0\1\356\64\0\1\357\62\0"+ + "\1\360\65\0\1\361\65\0\1\362\57\0\1\363\62\0"+ + "\1\364\16\0\1\125\10\0\1\125\4\0\1\125\1\0"+ + "\1\125\4\0\3\125\3\0\15\125\1\365\11\125\3\0"+ + "\1\125\10\0\1\125\4\0\1\125\1\0\1\125\4\0"+ + "\3\125\3\0\12\125\1\366\14\125\3\0\1\125\10\0"+ "\1\125\4\0\1\125\1\0\1\125\4\0\3\125\3\0"+ - "\16\125\1\340\10\125\57\0\1\341\50\0\1\342\10\0"+ - "\1\325\64\0\1\343\62\0\1\344\4\0\1\345\63\0"+ - "\1\346\57\0\1\347\67\0\1\350\31\0\1\351\114\0"+ - "\1\352\64\0\1\353\63\0\1\354\65\0\1\355\73\0"+ - "\1\356\64\0\1\357\62\0\1\360\65\0\1\361\65\0"+ - "\1\362\57\0\1\363\62\0\1\364\66\0\1\365\61\0"+ - "\1\366\61\0\1\367\73\0\1\370\66\0\1\371\11\0"+ + "\7\125\1\367\17\125\3\0\1\125\10\0\1\125\4\0"+ + "\1\125\1\0\1\125\4\0\3\125\3\0\16\125\1\370"+ + "\10\125\3\0\1\125\10\0\1\125\4\0\1\125\1\0"+ + "\1\125\4\0\3\125\3\0\20\125\1\371\6\125\3\0"+ "\7\306\1\372\21\306\1\310\33\306\7\311\1\373\21\311"+ "\1\313\33\311\1\125\10\0\1\125\4\0\1\125\1\0"+ "\1\125\4\0\3\125\3\0\2\125\1\374\24\125\3\0"+ @@ -714,96 +728,122 @@ private static int zzUnpackRowMap(String packed, int offset, int [] result) { "\1\u0115\53\0\1\u0116\67\0\1\u0117\11\0\1\u0118\47\0"+ "\1\u0119\64\0\1\u011a\64\0\1\u011b\64\0\1\u011c\67\0"+ "\1\u011d\77\0\1\u011e\63\0\1\u011f\52\0\1\u0120\57\0"+ - "\1\u0121\100\0\1\u0122\62\0\1\u0123\50\0\1\u0124\70\0"+ - "\1\u0125\64\0\1\u0126\64\0\1\u0127\25\0\1\125\10\0"+ - "\1\125\4\0\1\125\1\0\1\125\4\0\3\125\3\0"+ - "\12\125\1\u0128\14\125\3\0\1\74\5\0\1\74\2\0"+ - "\1\74\4\0\3\74\4\0\3\74\3\0\21\74\1\376"+ - "\5\74\3\0\1\74\5\0\1\74\2\0\1\74\4\0"+ - "\3\74\4\0\3\74\3\0\4\74\1\u0129\22\74\3\0"+ - "\1\216\10\0\1\216\4\0\1\216\1\0\1\216\4\0"+ - "\3\216\3\0\14\216\1\u012a\12\216\3\0\1\216\10\0"+ - "\1\216\4\0\1\216\1\0\1\216\4\0\3\216\3\0"+ - "\23\216\1\u012b\3\216\3\0\1\216\10\0\1\216\4\0"+ - "\1\216\1\0\1\216\4\0\3\216\3\0\5\216\1\u012c"+ - "\21\216\3\0\1\216\10\0\1\216\4\0\1\216\1\0"+ - "\1\216\4\0\3\216\3\0\24\216\1\u012d\2\216\3\0"+ - "\1\216\10\0\1\216\4\0\1\216\1\0\1\216\4\0"+ - "\3\216\3\0\21\216\1\u012e\5\216\46\0\1\u012f\70\0"+ - "\1\u0130\62\0\1\u0131\75\0\1\u0132\51\0\1\u0133\64\0"+ - "\1\u0134\64\0\1\u0135\60\0\1\u0136\25\0\1\125\10\0"+ - "\1\125\4\0\1\125\1\0\1\125\4\0\3\125\3\0"+ - "\4\125\1\u0137\22\125\56\0\1\u0138\67\0\1\u0139\45\0"+ - "\1\u013a\64\0\1\u013b\73\0\1\u013c\73\0\1\u013d\62\0"+ - "\1\u013e\44\0\1\u013f\70\0\1\u0140\75\0\1\u0141\67\0"+ - "\1\u0142\54\0\1\u0143\65\0\1\u0144\73\0\1\u0145\72\0"+ - "\1\u0146\41\0\1\u0147\101\0\1\u0148\44\0\1\u0149\31\0"+ - "\1\125\10\0\1\125\4\0\1\125\1\0\1\125\4\0"+ - "\3\125\3\0\23\125\1\u014a\3\125\3\0\1\216\10\0"+ - "\1\216\4\0\1\216\1\0\1\216\4\0\3\216\3\0"+ - "\4\216\1\u014b\22\216\3\0\1\216\10\0\1\216\4\0"+ - "\1\216\1\0\1\216\4\0\3\216\3\0\12\216\1\u014c"+ - "\14\216\3\0\1\216\10\0\1\216\4\0\1\216\1\0"+ - "\1\216\4\0\3\216\3\0\10\216\1\u014d\16\216\44\0"+ - "\1\u014e\61\0\1\u014f\65\0\1\u0150\63\0\1\u0151\63\0"+ - "\1\u0152\102\0\1\u0153\52\0\1\u0154\76\0\1\u0155\11\0"+ - "\1\125\10\0\1\125\4\0\1\125\1\0\1\125\4\0"+ - "\3\125\3\0\13\125\1\u0156\13\125\36\0\1\u0157\76\0"+ - "\1\u0158\65\0\1\u0159\65\0\1\u015a\54\0\1\u015b\64\0"+ - "\1\u015c\104\0\1\u015d\54\0\1\u015e\70\0\1\u015f\67\0"+ - "\1\u0160\43\0\1\u0161\77\0\1\u0162\57\0\1\u0163\60\0"+ - "\1\u0164\103\0\1\u0165\65\0\1\u0166\43\0\1\u0167\26\0"+ + "\1\u0121\100\0\1\u0122\13\0\1\125\10\0\1\125\4\0"+ + "\1\125\1\0\1\125\4\0\3\125\3\0\14\125\1\u0123"+ + "\12\125\3\0\1\125\10\0\1\125\4\0\1\125\1\0"+ + "\1\125\4\0\3\125\3\0\1\u0124\26\125\3\0\1\125"+ + "\10\0\1\125\4\0\1\125\1\0\1\125\4\0\3\125"+ + "\3\0\4\125\1\u0125\22\125\3\0\1\125\10\0\1\125"+ + "\4\0\1\125\1\0\1\125\4\0\3\125\3\0\4\125"+ + "\1\u0126\22\125\3\0\1\125\10\0\1\125\4\0\1\125"+ + "\1\0\1\125\4\0\3\125\3\0\4\125\1\u0127\22\125"+ + "\3\0\1\125\10\0\1\125\4\0\1\125\1\0\1\125"+ + "\4\0\3\125\3\0\12\125\1\u0128\14\125\3\0\1\74"+ + "\5\0\1\74\2\0\1\74\4\0\3\74\4\0\3\74"+ + "\3\0\21\74\1\376\5\74\3\0\1\74\5\0\1\74"+ + "\2\0\1\74\4\0\3\74\4\0\3\74\3\0\4\74"+ + "\1\u0129\22\74\3\0\1\216\10\0\1\216\4\0\1\216"+ + "\1\0\1\216\4\0\3\216\3\0\14\216\1\u012a\12\216"+ + "\3\0\1\216\10\0\1\216\4\0\1\216\1\0\1\216"+ + "\4\0\3\216\3\0\23\216\1\u012b\3\216\3\0\1\216"+ + "\10\0\1\216\4\0\1\216\1\0\1\216\4\0\3\216"+ + "\3\0\5\216\1\u012c\21\216\3\0\1\216\10\0\1\216"+ + "\4\0\1\216\1\0\1\216\4\0\3\216\3\0\24\216"+ + "\1\u012d\2\216\3\0\1\216\10\0\1\216\4\0\1\216"+ + "\1\0\1\216\4\0\3\216\3\0\21\216\1\u012e\5\216"+ + "\46\0\1\u012f\70\0\1\u0130\62\0\1\u0131\75\0\1\u0132"+ + "\51\0\1\u0133\64\0\1\u0134\64\0\1\u0135\60\0\1\u0136"+ + "\25\0\1\125\10\0\1\125\4\0\1\125\1\0\1\125"+ + "\4\0\3\125\3\0\4\125\1\u0137\22\125\56\0\1\u0138"+ + "\67\0\1\u0139\45\0\1\u013a\64\0\1\u013b\73\0\1\u013c"+ + "\73\0\1\u013d\62\0\1\u013e\44\0\1\u013f\70\0\1\u0140"+ + "\75\0\1\u0141\67\0\1\u0142\54\0\1\u0143\65\0\1\u0144"+ + "\73\0\1\u0145\11\0\1\125\10\0\1\125\4\0\1\125"+ + "\1\0\1\125\4\0\3\125\3\0\26\125\1\u0146\3\0"+ "\1\125\10\0\1\125\4\0\1\125\1\0\1\125\4\0"+ - "\3\125\3\0\3\125\1\u0168\23\125\3\0\1\216\10\0"+ - "\1\216\4\0\1\216\1\0\1\216\4\0\3\216\3\0"+ - "\12\216\1\u0169\14\216\3\0\1\216\10\0\1\216\4\0"+ - "\1\216\1\0\1\216\4\0\3\216\3\0\4\216\1\u016a"+ - "\22\216\3\0\1\216\10\0\1\216\4\0\1\216\1\0"+ - "\1\216\4\0\3\216\3\0\2\216\1\u016b\24\216\61\0"+ - "\1\u016c\62\0\1\u016d\46\0\1\u016e\65\0\1\u016f\64\0"+ - "\1\u0170\64\0\1\u0171\25\0\1\125\10\0\1\125\4\0"+ - "\1\125\1\0\1\125\4\0\3\125\3\0\4\125\1\u0172"+ - "\22\125\40\0\1\u0173\104\0\1\u0174\46\0\1\u0175\102\0"+ - "\1\u0176\52\0\1\u0177\57\0\1\u0178\105\0\1\u0179\62\0"+ - "\1\u017a\46\0\1\u017b\74\0\1\u017c\64\0\1\u017d\71\0"+ - "\1\u017e\55\0\1\u017f\62\0\1\u0180\21\0\1\125\10\0"+ + "\3\125\3\0\3\125\1\u0147\23\125\3\0\1\125\10\0"+ "\1\125\4\0\1\125\1\0\1\125\4\0\3\125\3\0"+ - "\4\125\1\u0181\22\125\3\0\1\216\10\0\1\216\4\0"+ - "\1\216\1\0\1\216\4\0\3\216\3\0\21\216\1\u0182"+ - "\5\216\3\0\1\216\10\0\1\216\4\0\1\216\1\0"+ - "\1\216\4\0\3\216\3\0\4\216\1\u0183\22\216\56\0"+ - "\1\u0184\40\0\1\u0185\36\0\1\u0186\1\0\2\u0186\1\0"+ - "\1\u0186\132\0\1\u0187\46\0\1\u0188\26\0\1\125\10\0"+ - "\1\125\4\0\1\125\1\0\1\125\4\0\3\125\3\0"+ - "\14\125\1\u0189\12\125\60\0\1\u018a\56\0\1\u018b\54\0"+ - "\1\u018c\101\0\1\u018d\55\0\1\u018e\62\0\1\u018f\72\0"+ - "\1\u0190\40\0\1\u0191\100\0\1\u0192\77\0\1\u0193\47\0"+ - "\1\u0194\101\0\1\u0195\10\0\1\125\1\u0186\1\0\2\u0186"+ - "\1\0\1\u0186\2\0\1\125\4\0\1\125\1\0\1\125"+ - "\4\0\3\125\3\0\27\125\3\0\1\216\10\0\1\216"+ - "\4\0\1\216\1\0\1\216\4\0\3\216\3\0\21\216"+ - "\1\u0196\5\216\36\0\1\u0197\100\0\1\u0198\16\0\1\u0186"+ - "\1\0\2\u0186\1\0\1\u0186\44\0\1\u0199\11\0\1\125"+ + "\20\125\1\u0148\6\125\3\0\1\125\10\0\1\125\4\0"+ + "\1\125\1\0\1\125\4\0\3\125\3\0\1\u0149\26\125"+ + "\3\0\1\125\10\0\1\125\4\0\1\125\1\0\1\125"+ + "\4\0\3\125\3\0\23\125\1\u014a\3\125\3\0\1\216"+ + "\10\0\1\216\4\0\1\216\1\0\1\216\4\0\3\216"+ + "\3\0\4\216\1\u014b\22\216\3\0\1\216\10\0\1\216"+ + "\4\0\1\216\1\0\1\216\4\0\3\216\3\0\12\216"+ + "\1\u014c\14\216\3\0\1\216\10\0\1\216\4\0\1\216"+ + "\1\0\1\216\4\0\3\216\3\0\10\216\1\u014d\16\216"+ + "\44\0\1\u014e\61\0\1\u014f\65\0\1\u0150\63\0\1\u0151"+ + "\63\0\1\u0152\102\0\1\u0153\52\0\1\u0154\76\0\1\u0155"+ + "\11\0\1\125\10\0\1\125\4\0\1\125\1\0\1\125"+ + "\4\0\3\125\3\0\13\125\1\u0156\13\125\36\0\1\u0157"+ + "\76\0\1\u0158\65\0\1\u0159\65\0\1\u015a\54\0\1\u015b"+ + "\64\0\1\u015c\104\0\1\u015d\54\0\1\u015e\70\0\1\u015f"+ + "\67\0\1\u0160\43\0\1\u0161\77\0\1\u0162\57\0\1\u0163"+ + "\60\0\1\u0164\25\0\1\125\10\0\1\125\4\0\1\125"+ + "\1\0\1\125\4\0\3\125\3\0\23\125\1\u0165\3\125"+ + "\3\0\1\125\10\0\1\125\4\0\1\125\1\0\1\125"+ + "\4\0\3\125\3\0\24\125\1\u0166\2\125\3\0\1\125"+ "\10\0\1\125\4\0\1\125\1\0\1\125\4\0\3\125"+ - "\3\0\22\125\1\u019a\4\125\60\0\1\u019b\62\0\1\u019c"+ - "\54\0\1\u019d\60\0\1\u019e\62\0\1\u019f\104\0\1\u01a0"+ - "\67\0\1\u01a1\47\0\1\u01a2\60\0\1\u01a3\102\0\1\u01a4"+ - "\46\0\1\u01a5\25\0\1\125\10\0\1\125\4\0\1\125"+ - "\1\0\1\125\4\0\3\125\3\0\1\u01a6\26\125\36\0"+ - "\1\u01a7\105\0\1\u01a8\60\0\1\u01a9\67\0\1\u01aa\50\0"+ - "\1\u01ab\75\0\1\u01ac\47\0\1\u01ad\101\0\1\u01ae\57\0"+ - "\1\u01af\73\0\1\u01b0\12\0\1\125\10\0\1\125\4\0"+ - "\1\125\1\0\1\125\4\0\3\125\3\0\22\125\1\u01b1"+ - "\4\125\60\0\1\u01b2\56\0\1\u01b3\70\0\1\u01b4\64\0"+ - "\1\u01b5\60\0\1\u01b6\65\0\1\u01b7\72\0\1\u01b8\6\0"+ - "\1\125\10\0\1\125\4\0\1\125\1\0\1\125\4\0"+ - "\3\125\3\0\10\125\1\u01b9\16\125\46\0\1\u01ba\75\0"+ - "\1\u01bb\47\0\1\u01bc\74\0\1\u01bd\60\0\1\u01be\21\0"+ - "\1\125\10\0\1\125\4\0\1\125\1\0\1\125\4\0"+ - "\3\125\3\0\15\125\1\u01bf\11\125\53\0\1\u01c0\70\0"+ - "\1\u01c1\63\0\1\u01c2\11\0\1\125\10\0\1\125\4\0"+ - "\1\125\1\0\1\125\4\0\3\125\3\0\14\125\1\u01c3"+ - "\12\125\52\0\1\u01c4\54\0\1\u01c5\63\0\1\u01c6\26\0"; + "\3\0\3\125\1\u0167\23\125\3\0\1\125\10\0\1\125"+ + "\4\0\1\125\1\0\1\125\4\0\3\125\3\0\3\125"+ + "\1\u0168\23\125\3\0\1\216\10\0\1\216\4\0\1\216"+ + "\1\0\1\216\4\0\3\216\3\0\12\216\1\u0169\14\216"+ + "\3\0\1\216\10\0\1\216\4\0\1\216\1\0\1\216"+ + "\4\0\3\216\3\0\4\216\1\u016a\22\216\3\0\1\216"+ + "\10\0\1\216\4\0\1\216\1\0\1\216\4\0\3\216"+ + "\3\0\2\216\1\u016b\24\216\61\0\1\u016c\62\0\1\u016d"+ + "\46\0\1\u016e\65\0\1\u016f\64\0\1\u0170\64\0\1\u0171"+ + "\25\0\1\125\10\0\1\125\4\0\1\125\1\0\1\125"+ + "\4\0\3\125\3\0\4\125\1\u0172\22\125\40\0\1\u0173"+ + "\104\0\1\u0174\46\0\1\u0175\102\0\1\u0176\52\0\1\u0177"+ + "\57\0\1\u0178\105\0\1\u0179\62\0\1\u017a\46\0\1\u017b"+ + "\74\0\1\u017c\64\0\1\u017d\71\0\1\u017e\10\0\1\125"+ + "\10\0\1\125\4\0\1\125\1\0\1\125\4\0\3\125"+ + "\3\0\12\125\1\u017f\14\125\3\0\1\125\10\0\1\125"+ + "\4\0\1\125\1\0\1\125\4\0\3\125\3\0\10\125"+ + "\1\u0180\16\125\3\0\1\125\10\0\1\125\4\0\1\125"+ + "\1\0\1\125\4\0\3\125\3\0\4\125\1\u0181\22\125"+ + "\3\0\1\216\10\0\1\216\4\0\1\216\1\0\1\216"+ + "\4\0\3\216\3\0\21\216\1\u0182\5\216\3\0\1\216"+ + "\10\0\1\216\4\0\1\216\1\0\1\216\4\0\3\216"+ + "\3\0\4\216\1\u0183\22\216\56\0\1\u0184\40\0\1\u0185"+ + "\36\0\1\u0186\1\0\2\u0186\1\0\1\u0186\132\0\1\u0187"+ + "\46\0\1\u0188\26\0\1\125\10\0\1\125\4\0\1\125"+ + "\1\0\1\125\4\0\3\125\3\0\14\125\1\u0189\12\125"+ + "\60\0\1\u018a\56\0\1\u018b\54\0\1\u018c\101\0\1\u018d"+ + "\55\0\1\u018e\62\0\1\u018f\72\0\1\u0190\40\0\1\u0191"+ + "\100\0\1\u0192\77\0\1\u0193\10\0\1\125\10\0\1\125"+ + "\4\0\1\125\1\0\1\125\4\0\3\125\3\0\4\125"+ + "\1\u0194\22\125\3\0\1\125\10\0\1\125\4\0\1\125"+ + "\1\0\1\125\4\0\3\125\3\0\21\125\1\u0195\5\125"+ + "\3\0\1\125\1\u0186\1\0\2\u0186\1\0\1\u0186\2\0"+ + "\1\125\4\0\1\125\1\0\1\125\4\0\3\125\3\0"+ + "\27\125\3\0\1\216\10\0\1\216\4\0\1\216\1\0"+ + "\1\216\4\0\3\216\3\0\21\216\1\u0196\5\216\36\0"+ + "\1\u0197\100\0\1\u0198\16\0\1\u0186\1\0\2\u0186\1\0"+ + "\1\u0186\44\0\1\u0199\11\0\1\125\10\0\1\125\4\0"+ + "\1\125\1\0\1\125\4\0\3\125\3\0\22\125\1\u019a"+ + "\4\125\60\0\1\u019b\62\0\1\u019c\54\0\1\u019d\60\0"+ + "\1\u019e\62\0\1\u019f\104\0\1\u01a0\67\0\1\u01a1\47\0"+ + "\1\u01a2\21\0\1\125\10\0\1\125\4\0\1\125\1\0"+ + "\1\125\4\0\3\125\3\0\4\125\1\u01a3\22\125\60\0"+ + "\1\u01a4\46\0\1\u01a5\25\0\1\125\10\0\1\125\4\0"+ + "\1\125\1\0\1\125\4\0\3\125\3\0\1\u01a6\26\125"+ + "\36\0\1\u01a7\105\0\1\u01a8\60\0\1\u01a9\67\0\1\u01aa"+ + "\50\0\1\u01ab\75\0\1\u01ac\47\0\1\u01ad\101\0\1\u01ae"+ + "\57\0\1\u01af\73\0\1\u01b0\12\0\1\125\10\0\1\125"+ + "\4\0\1\125\1\0\1\125\4\0\3\125\3\0\22\125"+ + "\1\u01b1\4\125\60\0\1\u01b2\56\0\1\u01b3\70\0\1\u01b4"+ + "\64\0\1\u01b5\60\0\1\u01b6\65\0\1\u01b7\72\0\1\u01b8"+ + "\6\0\1\125\10\0\1\125\4\0\1\125\1\0\1\125"+ + "\4\0\3\125\3\0\10\125\1\u01b9\16\125\46\0\1\u01ba"+ + "\75\0\1\u01bb\47\0\1\u01bc\74\0\1\u01bd\60\0\1\u01be"+ + "\21\0\1\125\10\0\1\125\4\0\1\125\1\0\1\125"+ + "\4\0\3\125\3\0\15\125\1\u01bf\11\125\53\0\1\u01c0"+ + "\70\0\1\u01c1\63\0\1\u01c2\11\0\1\125\10\0\1\125"+ + "\4\0\1\125\1\0\1\125\4\0\3\125\3\0\14\125"+ + "\1\u01c3\12\125\52\0\1\u01c4\54\0\1\u01c5\63\0\1\u01c6"+ + "\26\0"; private static int [] zzUnpacktrans() { int [] result = new int[18550]; @@ -850,20 +890,19 @@ private static int zzUnpacktrans(String packed, int offset, int [] result) { "\4\11\4\1\1\11\2\1\1\11\5\1\2\11\2\1"+ "\1\11\1\1\2\11\2\1\1\11\2\1\4\11\3\1"+ "\1\11\4\1\4\11\2\1\11\0\1\11\4\0\2\11"+ - "\3\0\1\1\31\0\1\11\2\0\1\11\1\0\3\1"+ - "\1\0\4\1\6\0\1\1\5\0\1\1\13\0\1\11"+ - "\15\0\12\1\4\0\1\11\2\0\1\11\2\0\1\1"+ - "\3\0\1\11\6\0\1\11\1\0\1\11\1\0\2\11"+ - "\1\0\1\11\2\0\1\11\4\0\7\1\10\0\1\1"+ - "\16\0\1\11\3\0\4\1\6\0\2\11\1\1\3\0"+ - "\1\11\1\0\1\11\12\0\1\11\4\1\2\0\1\11"+ - "\3\0\1\1\1\0\1\11\5\0\1\11\6\0\3\1"+ - "\3\0\2\11\1\1\1\11\7\0\1\11\1\0\1\11"+ - "\1\0\1\1\1\0\1\11\1\0\1\1\10\0\1\11"+ - "\2\0\1\1\1\0\1\11\1\0\2\11\5\0\1\1"+ - "\1\0\1\11\2\0\1\11\2\0\1\1\1\0\2\11"+ - "\2\0\1\1\1\0\1\11\1\0\1\1\1\11\1\0"+ - "\1\11"; + "\3\0\1\1\23\0\5\1\1\0\1\11\2\0\1\11"+ + "\1\0\3\1\1\0\4\1\6\0\1\1\5\0\1\1"+ + "\13\0\1\11\10\0\17\1\4\0\1\11\2\0\1\11"+ + "\2\0\1\1\3\0\1\11\6\0\1\11\1\0\1\11"+ + "\1\0\2\11\1\0\1\11\2\0\14\1\10\0\1\1"+ + "\16\0\10\1\6\0\2\11\1\1\3\0\1\11\1\0"+ + "\1\11\10\0\7\1\2\0\1\11\3\0\1\1\1\0"+ + "\1\11\5\0\1\11\4\0\5\1\3\0\2\11\1\1"+ + "\1\11\7\0\1\11\1\0\3\1\1\0\1\11\1\0"+ + "\1\1\10\0\1\1\2\0\1\1\1\0\1\11\1\0"+ + "\2\11\5\0\1\1\1\0\1\11\2\0\1\11\2\0"+ + "\1\1\1\0\2\11\2\0\1\1\1\0\1\11\1\0"+ + "\1\1\1\11\1\0\1\11"; private static int [] zzUnpackAttribute() { int [] result = new int[454]; diff --git a/gradle.properties b/gradle.properties index 7a6fd7f..9daad2a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,4 +9,4 @@ org.gradle.caching = true org.gradle.jvmargs=-XX\:MaxHeapSize\=4256m -Xmx4256m -Xms2000m -version = 0.0.13 \ No newline at end of file +version = 0.0.14 \ No newline at end of file diff --git a/grammars/_OapLexer.flex b/grammars/_OapLexer.flex index 0fbe56a..be7b8bf 100644 --- a/grammars/_OapLexer.flex +++ b/grammars/_OapLexer.flex @@ -523,6 +523,13 @@ KEY_NAME=[:jletter:] ([:jletterdigit:]|[-/])* "thread" { yypushState(KEY_VALUE_STRING); return OAP_ID_THREAD; } "delay" { yypushState(KEY_VALUE_STRING); return OAP_ID_DELAY; } "cron" { yypushState(KEY_VALUE_STRING); return OAP_ID_CRON; } + // Fallback for anything that isn't one of the 5 keywords above (a typo, a partial prefix + // mid-completion, or completion's own inserted dummy identifier) - without this, such text has + // no matching rule in this state and falls through to the file-wide catch-all `[^]` rule one + // character at a time, so e.g. typing "su" lexes as two separate single-char BAD_CHARACTER + // tokens instead of one identifier token. Grammar-side, module_services_service_supervision's + // recoverWhile=recover_supervision already contains whatever this produces. + {KEY_NAME} { return OAP_KEY_NAME; } {WHITE_SPACE} { return WHITE_SPACE; } {NEXTLINE} { return handleNextline(); } diff --git a/grammars/oap.bnf b/grammars/oap.bnf index 4a70296..89361d6 100644 --- a/grammars/oap.bnf +++ b/grammars/oap.bnf @@ -348,11 +348,32 @@ module_services_service_supervision ::= 'supervision' ( &'.' dot_supervision | s implements="oap.application.plugin.psi.OapKeyValuePairWithIndentNormal" } -private dot_supervision ::= '.' module_services_service_supervision_entities {pin=1} -private supervision_object ::= supervision_object_brace | supervision_object_colon -private supervision_object_brace ::= '{' module_services_service_supervision_entities* '}' { pin=1 } +// recoverWhile is safe here (unlike the brace-form corruption case documented below): +// dot_supervision is a linear sequence, not one side of an unpinned '|' choice, and it's only +// ever entered through the &'.' lookahead gate at the module_services_service_supervision call +// site - so '.' is guaranteed present and consumeToken(OAP_DOT) can't cleanly fail here. +private dot_supervision ::= '.' module_services_service_supervision_entities {pin=1 recoverWhile=recover_supervision} +// &'{' guard is required, not cosmetic: supervision_object_brace's recoverWhile makes its +// generated exit_section_ call recovery-aware even when the leading '{' check itself fails +// (verified via the generated OapParser.java - the recovery hook is passed unconditionally, not +// gated on pin actually engaging), which corrupts the builder position for the sibling +// supervision_object_colon alternative on unpinned failure. Guarding entry with &'{' means +// supervision_object_brace's body is only ever invoked once a real '{' is confirmed present, so +// that interaction never triggers for colon-form input. +private supervision_object ::= &'{' supervision_object_brace | supervision_object_colon +// recoverWhile is deliberately only on the brace form: the same addition on +// supervision_object_colon breaks otherwise-valid colon-form input (verified - its +// 'indent'/'dedent' bracketing doesn't interact with generated recovery code the same way a +// plain '{'/'}' pair does). Both of the reported completion use cases are brace-form, so +// colon-form completion containment remains a known limitation. +private supervision_object_brace ::= '{' module_services_service_supervision_entities* '}' { pin=1 recoverWhile=recover_supervision } private supervision_object_colon ::= ':' indent module_services_service_supervision_entities* dedent { pin=1 } +// Fences an unrecognized token (e.g. completion's mid-typing prefix "su") inside the +// supervision block instead of letting it bubble past the closing '}' and detach from +// OapModuleServicesServiceSupervision entirely - mirrors module's own top-level recover_module. +private recover_supervision ::= !('supervise' | 'schedule' | 'thread' | 'delay' | 'cron' | '}' | dedent) + private module_services_service_supervision_entities ::= &'supervise' module_services_service_supervision_entities_supervise | &'schedule' module_services_service_supervision_entities_schedule diff --git a/src/main/kotlin/oap/application/plugin/completion/OapSupervisionCompletionContributor.kt b/src/main/kotlin/oap/application/plugin/completion/OapSupervisionCompletionContributor.kt new file mode 100644 index 0000000..ad2c562 --- /dev/null +++ b/src/main/kotlin/oap/application/plugin/completion/OapSupervisionCompletionContributor.kt @@ -0,0 +1,55 @@ +package oap.application.plugin.completion + +import com.intellij.codeInsight.completion.CompletionContributor +import com.intellij.codeInsight.completion.CompletionInitializationContext +import com.intellij.codeInsight.completion.CompletionParameters +import com.intellij.codeInsight.completion.CompletionProvider +import com.intellij.codeInsight.completion.CompletionResultSet +import com.intellij.codeInsight.completion.CompletionType +import com.intellij.codeInsight.lookup.LookupElementBuilder +import com.intellij.patterns.PlatformPatterns +import com.intellij.psi.util.PsiTreeUtil +import com.intellij.util.ProcessingContext +import oap.application.plugin.gen.psi.OapModuleServicesServiceSupervision + +class OapSupervisionCompletionContributor : CompletionContributor() { + init { + extend( + CompletionType.BASIC, + PlatformPatterns.psiElement(), + object : CompletionProvider() { + override fun addCompletions( + parameters: CompletionParameters, + context: ProcessingContext, + result: CompletionResultSet + ) { + val position = parameters.position + + val supervision = PsiTreeUtil.getParentOfType(position, OapModuleServicesServiceSupervision::class.java, false) + ?: return + + val prefix = position.text.removeSuffix(CompletionInitializationContext.DUMMY_IDENTIFIER_TRIMMED) + + val present = buildSet { + if (supervision.moduleServicesServiceSupervisionEntitiesSuperviseList.isNotEmpty()) add("supervise") + if (supervision.moduleServicesServiceSupervisionEntitiesScheduleList.isNotEmpty()) add("schedule") + if (supervision.moduleServicesServiceSupervisionEntitiesThreadList.isNotEmpty()) add("thread") + if (supervision.moduleServicesServiceSupervisionEntitiesDelayList.isNotEmpty()) add("delay") + if (supervision.moduleServicesServiceSupervisionEntitiesCronList.isNotEmpty()) add("cron") + } + + for (key in KEYS) { + if (key in present) continue + if (key.startsWith(prefix)) { + result.addElement(LookupElementBuilder.create(key)) + } + } + } + } + ) + } + + companion object { + val KEYS: List = listOf("supervise", "schedule", "thread", "delay", "cron") + } +} diff --git a/src/main/kotlin/oap/application/plugin/formatter/OapFormattingBlock.kt b/src/main/kotlin/oap/application/plugin/formatter/OapFormattingBlock.kt index 9aeffd1..070be40 100644 --- a/src/main/kotlin/oap/application/plugin/formatter/OapFormattingBlock.kt +++ b/src/main/kotlin/oap/application/plugin/formatter/OapFormattingBlock.kt @@ -50,6 +50,24 @@ class OapFormattingBlock(val formatter: OapFormatter, node: ASTNode, val myInden return myIndent } + // AbstractBlock.getChildAttributes(newChildIndex) - what decides the indent of a brand new, + // not-yet-existing line (i.e. what pressing Enter produces) - delegates to this and defaults + // to null, which resolves to a normal-indent line here regardless of context. Without an + // override, pressing Enter right after "name = test" or after an already-closed "services {}" + // both incorrectly indent the new line, since neither actually has a currently-open indented + // block. Mirror calcIndent's own policy prospectively: a new sibling should be indented iff + // this node already has at least one real child that itself receives normal indent (i.e. + // there's an actually-open indented block here to continue), matching how e.g. a non-empty + // "services { s { ... } }" correctly keeps indenting a new service entry, while an empty + // "services {}" (or the top-level file) does not. + override fun getChildIndent(): Indent { + val hasNormalIndentChild = myNode.getChildren(null).any { child -> + child.textRange.length > 0 && child.elementType != TokenType.WHITE_SPACE && + calcIndent(myNode, child) == Indent.getNormalIndent() + } + return if (hasNormalIndentChild) Indent.getNormalIndent() else Indent.getNoneIndent() + } + override fun buildChildren(): List { val blocks: MutableList = arrayListOf() var child: ASTNode? = myNode.firstChildNode diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index f610a46..ccd2e34 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -49,6 +49,7 @@ + + } + } + } + """.trimIndent() + ) + myFixture.complete(CompletionType.BASIC) + + assertSameElements( + myFixture.lookupElementStrings!!, + "supervise", "schedule", "thread", "delay", "cron" + ) + } + + fun testPresentKeysExcluded() { + myFixture.configureByText( + "testPresentKeysExcluded.oap", """ + name = test + + services { + s { + implementation = a.B + supervision { + supervise = true + schedule = true + + } + } + } + """.trimIndent() + ) + myFixture.complete(CompletionType.BASIC) + + assertSameElements( + myFixture.lookupElementStrings!!, + "thread", "delay", "cron" + ) + } + + fun testPrefixFiltering() { + myFixture.configureByText( + "testPrefixFiltering.oap", """ + name = test + + services { + s { + implementation = a.B + supervision { + s + } + } + } + """.trimIndent() + ) + myFixture.complete(CompletionType.BASIC) + + assertSameElements( + myFixture.lookupElementStrings!!, + "supervise", "schedule" + ) + } + + fun testDotFormAllKeysSuggested() { + myFixture.configureByText( + "testDotFormAllKeysSuggested.oap", """ + name = test + + services { + s { + implementation = a.B + supervision. + } + } + """.trimIndent() + ) + myFixture.complete(CompletionType.BASIC) + + assertSameElements( + myFixture.lookupElementStrings!!, + "supervise", "schedule", "thread", "delay", "cron" + ) + } + + fun testDotFormPrefixFiltering() { + myFixture.configureByText( + "testDotFormPrefixFiltering.oap", """ + name = test + + services { + s { + implementation = a.B + supervision.s + } + } + """.trimIndent() + ) + myFixture.complete(CompletionType.BASIC) + + assertSameElements( + myFixture.lookupElementStrings!!, + "supervise", "schedule" + ) + } +} diff --git a/src/test/kotlin/oap/application/plugin/parser/OapParserTest.kt b/src/test/kotlin/oap/application/plugin/parser/OapParserTest.kt index 55632cb..8ad254d 100644 --- a/src/test/kotlin/oap/application/plugin/parser/OapParserTest.kt +++ b/src/test/kotlin/oap/application/plugin/parser/OapParserTest.kt @@ -318,7 +318,7 @@ class OapParserTest : ParsingTestCase("parser", "oap", OapParserDefinition()) { assertTrue( "expected the supervision block error to still be reported", toParseTreeText(myFile, skipSpaces(), includeRanges()) - .contains("PsiErrorElement:cron, delay, schedule, supervise or thread expected, got 's'") + .contains("PsiErrorElement:cron, delay, schedule, supervise or thread expected, got 'su'") ) } diff --git a/testdata/formatter/array-after.oap b/testdata/formatter/array-after.oap index afe8be4..5747a91 100644 --- a/testdata/formatter/array-after.oap +++ b/testdata/formatter/array-after.oap @@ -1,4 +1,5 @@ name = ArrayFormatter + dependsOn = [ oap-ws-sso-api oap-account diff --git a/testdata/formatter/enterAfterEmptyServicesBlock-after.oap b/testdata/formatter/enterAfterEmptyServicesBlock-after.oap new file mode 100644 index 0000000..d5c646e --- /dev/null +++ b/testdata/formatter/enterAfterEmptyServicesBlock-after.oap @@ -0,0 +1,3 @@ +name = a +services {} + \ No newline at end of file diff --git a/testdata/formatter/enterAfterEmptyServicesBlock.oap b/testdata/formatter/enterAfterEmptyServicesBlock.oap new file mode 100644 index 0000000..aea87b2 --- /dev/null +++ b/testdata/formatter/enterAfterEmptyServicesBlock.oap @@ -0,0 +1,2 @@ +name = a +services {} \ No newline at end of file diff --git a/testdata/formatter/enterAfterModuleName-after.oap b/testdata/formatter/enterAfterModuleName-after.oap new file mode 100644 index 0000000..b2766ec --- /dev/null +++ b/testdata/formatter/enterAfterModuleName-after.oap @@ -0,0 +1,2 @@ +name = test + \ No newline at end of file diff --git a/testdata/formatter/enterAfterModuleName.oap b/testdata/formatter/enterAfterModuleName.oap new file mode 100644 index 0000000..335db33 --- /dev/null +++ b/testdata/formatter/enterAfterModuleName.oap @@ -0,0 +1 @@ +name = test \ No newline at end of file From a9ab98dfc08cbc90ab2a3c6a92c973b9e428a54b Mon Sep 17 00:00:00 2001 From: "igor.petrenko" Date: Mon, 31 Aug 2026 10:56:26 +0300 Subject: [PATCH 2/2] CE-209 oap-plugin: supervision completion --- testdata/formatter/array.oap | 1 + 1 file changed, 1 insertion(+) diff --git a/testdata/formatter/array.oap b/testdata/formatter/array.oap index a5c70ef..46a851d 100644 --- a/testdata/formatter/array.oap +++ b/testdata/formatter/array.oap @@ -1,4 +1,5 @@ name = ArrayFormatter + dependsOn = [ oap-ws-sso-api oap-account