From cafdbf34df07ddcd9a5adc42361d23a4efd5bebe Mon Sep 17 00:00:00 2001 From: Eric Le Goff Date: Fri, 19 Nov 2021 10:27:02 +0100 Subject: [PATCH 01/18] meta attributes --- .../main/java/org/sonar/rust/RustGrammar.java | 24 +++++++++++-- .../rust/parser/attributes/AttributeTest.java | 36 ++++++++++++++++++- 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java index 95278914..9e5f85c1 100644 --- a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java +++ b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java @@ -197,6 +197,14 @@ public enum RustGrammar implements GrammarRuleKey { MAYBE_NAMED_FUNCTION_PARAMETERS, MAYBE_NAMED_FUNCTION_PARAMETERS_VARIADIC, MAYBE_NAMED_PARAM, STRUCT_FIELDS, + META_ITEM, + META_ITEM_INNER, + META_LIST_IDENTS, + META_LIST_NAME_VALUE_STR, + META_LIST_PATHS, + META_NAME_VALUE_STR, + META_SEQ, + META_WORD, METHOD_CALL_EXPRESSION, MINUSEQ_EXPRESSION, MODULE, @@ -1902,8 +1910,20 @@ public static void attributes(LexerlessGrammarBuilder b) { b.rule(OUTER_ATTRIBUTE).is("#[", SPC, ATTR, SPC, "]"); b.rule(ATTR).is(SIMPLE_PATH, SPC, b.optional(ATTR_INPUT, SPC)); b.rule(ATTR_INPUT).is(b.firstOf(DELIM_TOKEN_TREE, - b.sequence(RustPunctuator.EQ, SPC, - LITERAL_EXPRESSION))); + b.sequence(RustPunctuator.EQ, SPC,EXPRESSION))); + b.rule(META_ITEM).is(b.firstOf( + b.sequence(SIMPLE_PATH, SPC, RustPunctuator.EQ, SPC, EXPRESSION), + b.sequence(SIMPLE_PATH, SPC, "(", SPC, META_SEQ, SPC, ")"), + SIMPLE_PATH)); + b.rule(META_SEQ).is(seq(b,META_ITEM_INNER, RustPunctuator.COMMA)); + b.rule(META_ITEM_INNER).is(b.firstOf(META_ITEM, EXPRESSION)); + b.rule(META_WORD).is(IDENTIFIER); + b.rule(META_NAME_VALUE_STR).is(IDENTIFIER, SPC, RustPunctuator.EQ, SPC, b.firstOf(STRING_LITERAL, RAW_STRING_LITERAL)); + b.rule(META_LIST_PATHS).is(IDENTIFIER, "(", b.optional(seq(b,SIMPLE_PATH, RustPunctuator.COMMA)), ")"); + b.rule(META_LIST_IDENTS).is(IDENTIFIER, "(", b.optional(seq(b,IDENTIFIER, RustPunctuator.COMMA)), ")"); + b.rule(META_LIST_NAME_VALUE_STR).is(IDENTIFIER, "(", b.optional(seq(b,META_NAME_VALUE_STR, RustPunctuator.COMMA)), ")"); + + } /* https://doc.rust-lang.org/reference/expressions/closure-expr.html*/ diff --git a/community-rust-frontend/src/test/java/org/sonar/rust/parser/attributes/AttributeTest.java b/community-rust-frontend/src/test/java/org/sonar/rust/parser/attributes/AttributeTest.java index e7e404a6..e53d29b6 100644 --- a/community-rust-frontend/src/test/java/org/sonar/rust/parser/attributes/AttributeTest.java +++ b/community-rust-frontend/src/test/java/org/sonar/rust/parser/attributes/AttributeTest.java @@ -35,7 +35,6 @@ public void testAttribute() { .matches("foo_bar") .matches("foo_type") .matches("crate_type") - ; } @@ -58,4 +57,39 @@ public void testOuterAttribute() { .matches("#[cfg(not(any(target_os = \"macos\", windows)))]") ; } + + @Test + public void testMetaWord() { + assertThat(RustGrammar.create().build().rule(RustGrammar.META_WORD)) + .matches("no_std") + ; + } + + @Test + public void testMetaNameValueStr() { + assertThat(RustGrammar.create().build().rule(RustGrammar.META_NAME_VALUE_STR)) + .matches("doc = \"example\"") + ; + } + + @Test + public void testMetaListPaths() { + assertThat(RustGrammar.create().build().rule(RustGrammar.META_LIST_PATHS)) + .matches("allow(unused, clippy::inline_always)") + ; + } + + @Test + public void testMetaListIdents() { + assertThat(RustGrammar.create().build().rule(RustGrammar.META_LIST_IDENTS)) + .matches("macro_use(foo, bar)") + ; + } + + @Test + public void testMetaListNameValueStr() { + assertThat(RustGrammar.create().build().rule(RustGrammar.META_LIST_NAME_VALUE_STR)) + .matches("link(name = \"CoreFoundation\", kind = \"framework\")") + ; + } } \ No newline at end of file From 595c85767c7306c1e32e9c69936defd222a31cbf Mon Sep 17 00:00:00 2001 From: Eric Le Goff Date: Fri, 19 Nov 2021 11:02:19 +0100 Subject: [PATCH 02/18] Remove enum variant expression --- .../main/java/org/sonar/rust/RustGrammar.java | 48 +---------- .../expressions/EnumExpressionTest.java | 84 ------------------- 2 files changed, 3 insertions(+), 129 deletions(-) delete mode 100644 community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/EnumExpressionTest.java diff --git a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java index 9e5f85c1..ea3b48ee 100644 --- a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java +++ b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java @@ -87,12 +87,6 @@ public enum RustGrammar implements GrammarRuleKey { DEREFERENCE_EXPRESSION, DIVISION_EXPRESSION, ENUMERATION, - ENUMERATION_VARIANT_EXPRESSION, - ENUM_EXPR_FIELD, - ENUM_EXPR_FIELDLESS, - ENUM_EXPR_FIELDS, - ENUM_EXPR_STRUCT, - ENUM_EXPR_TUPLE, ENUM_ITEMS, ENUM_ITEM, ENUM_ITEM_DISCRIMINANT, @@ -1191,7 +1185,6 @@ public static void expressions(LexerlessGrammarBuilder b) { array(b); tuple(b); struct(b); - enums(b); call(b); closure(b); loops(b); @@ -1231,7 +1224,6 @@ public static void expressions(LexerlessGrammarBuilder b) { b.sequence(GROUPED_EXPRESSION, b.zeroOrMore(SPC, EXPRESSION_TERM)), b.sequence(ARRAY_EXPRESSION, b.zeroOrMore(SPC, EXPRESSION_TERM)), b.sequence(TUPLE_EXPRESSION, b.zeroOrMore(SPC, EXPRESSION_TERM)), - b.sequence(ENUMERATION_VARIANT_EXPRESSION, b.zeroOrMore(SPC, EXPRESSION_TERM)), b.sequence(CONTINUE_EXPRESSION, b.zeroOrMore(SPC, EXPRESSION_TERM)) @@ -1266,10 +1258,7 @@ public static void expressions(LexerlessGrammarBuilder b) { b.sequence(PATH_EXPRESSION, b.zeroOrMore(SPC, EXPRESSION_TERM_EXCEPT_STRUCT)), b.sequence(GROUPED_EXPRESSION, b.zeroOrMore(SPC, EXPRESSION_TERM_EXCEPT_STRUCT)), b.sequence(ARRAY_EXPRESSION, b.zeroOrMore(SPC, EXPRESSION_TERM_EXCEPT_STRUCT)), - b.sequence(TUPLE_EXPRESSION, b.zeroOrMore(SPC, EXPRESSION_TERM_EXCEPT_STRUCT)), - b.sequence(ENUMERATION_VARIANT_EXPRESSION, b.zeroOrMore(SPC, EXPRESSION_TERM_EXCEPT_STRUCT)) - - + b.sequence(TUPLE_EXPRESSION, b.zeroOrMore(SPC, EXPRESSION_TERM_EXCEPT_STRUCT)) )); b.rule(EXPRESSION_TERM).is( @@ -1454,10 +1443,7 @@ public static void expressions(LexerlessGrammarBuilder b) { b.sequence(GROUPED_EXPRESSION, b.zeroOrMore(SPC, EXPRESSION_TERM)), b.sequence(ARRAY_EXPRESSION, b.zeroOrMore(SPC, EXPRESSION_TERM)), - b.sequence(TUPLE_EXPRESSION, b.zeroOrMore(SPC, EXPRESSION_TERM)), - b.sequence(ENUMERATION_VARIANT_EXPRESSION, b.zeroOrMore(SPC, EXPRESSION_TERM)) - - + b.sequence(TUPLE_EXPRESSION, b.zeroOrMore(SPC, EXPRESSION_TERM)) )); b.rule(EXPRESSION_WITH_BLOCK).is(b.zeroOrMore(OUTER_ATTRIBUTE, SPC), @@ -1599,35 +1585,7 @@ private static void call(LexerlessGrammarBuilder b) { b.rule(CALL_PARAMS).is(seq(b, EXPRESSION, RustPunctuator.COMMA)); } - /* https://doc.rust-lang.org/reference/expressions/enum-variant-expr.html */ - private static void enums(LexerlessGrammarBuilder b) { - b.rule(ENUMERATION_VARIANT_EXPRESSION).is(b.firstOf( - ENUM_EXPR_STRUCT, - ENUM_EXPR_TUPLE, - ENUM_EXPR_FIELDLESS - )); - b.rule(ENUM_EXPR_STRUCT).is(PATH_IN_EXPRESSION, SPC, "{", SPC, - b.optional(ENUM_EXPR_FIELDS, SPC), "}" - ); - b.rule(ENUM_EXPR_FIELDS).is( - ENUM_EXPR_FIELD, SPC, - b.zeroOrMore(b.sequence(RustPunctuator.COMMA, SPC, ENUM_EXPR_FIELDS), b.optional(RustPunctuator.COMMA, SPC)) - ); - b.rule(ENUM_EXPR_FIELD).is(b.firstOf( - b.sequence(b.firstOf(IDENTIFIER, TUPLE_INDEX), SPC, - RustPunctuator.COLON, SPC, EXPRESSION), - IDENTIFIER - )); - b.rule(ENUM_EXPR_TUPLE).is( - PATH_IN_EXPRESSION, SPC, "(", SPC, - b.optional(b.sequence( - EXPRESSION, SPC, - b.zeroOrMore(b.sequence(RustPunctuator.COMMA, SPC, EXPRESSION)), - b.optional(RustPunctuator.COMMA, SPC) - )), ")" - ); - b.rule(ENUM_EXPR_FIELDLESS).is(PATH_IN_EXPRESSION); - } + private static void tuple(LexerlessGrammarBuilder b) { b.rule(TUPLE_EXPRESSION).is("(", SPC, b.zeroOrMore(INNER_ATTRIBUTE, SPC), diff --git a/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/EnumExpressionTest.java b/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/EnumExpressionTest.java deleted file mode 100644 index c35a825b..00000000 --- a/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/EnumExpressionTest.java +++ /dev/null @@ -1,84 +0,0 @@ -/** - * Community Rust Plugin - * Copyright (C) 2021 Eric Le Goff - * mailto:community-rust AT pm DOT me - * http://github.com/elegoff/sonar-rust - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.rust.parser.expressions; - -import org.junit.Test; -import org.sonar.rust.RustGrammar; - -import static org.sonar.sslr.tests.Assertions.assertThat; - -public class EnumExpressionTest { - - - @Test - public void testEnumExprField() { - assertThat(RustGrammar.create().build().rule(RustGrammar.ENUM_EXPR_FIELD)) - .matches("x:50") - ; - } - - @Test - public void testEnumExprFields() { - assertThat(RustGrammar.create().build().rule(RustGrammar.ENUM_EXPR_FIELDS)) - .matches("x:50, y:200") - ; - } - - @Test - public void testEnumExprStruct() { - assertThat(RustGrammar.create().build().rule(RustGrammar.ENUM_EXPR_STRUCT)) - .matches("Message::Move{x:50,y:200}") - - - ; - } - - @Test - public void testEnumExprTuple() { - assertThat(RustGrammar.create().build().rule(RustGrammar.ENUM_EXPR_TUPLE)) - - .matches("Message::WriteString(\"Some string\".to_string())") - - - ; - } - - @Test - public void testEnumExprFieldLess() { - assertThat(RustGrammar.create().build().rule(RustGrammar.ENUM_EXPR_FIELDLESS)) - .matches("Message::Quit") - - - ; - } - - - @Test - public void testEnumVariantExpression() { - assertThat(RustGrammar.create().build().rule(RustGrammar.ENUMERATION_VARIANT_EXPRESSION)) - .matches("Message::Quit") - .matches("Message::Move { x: 50, y: 200 }") - .matches("Message::WriteString(\"Some string\".to_string())") - - - ; - } -} From 62f5dc74c91fd69b0fc084084279a3416ce448f8 Mon Sep 17 00:00:00 2001 From: Eric Le Goff Date: Fri, 19 Nov 2021 11:17:48 +0100 Subject: [PATCH 03/18] Array expression --- .../src/main/java/org/sonar/rust/RustGrammar.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java index ea3b48ee..d4af4f55 100644 --- a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java +++ b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java @@ -1600,17 +1600,13 @@ private static void tuple(LexerlessGrammarBuilder b) { } private static void array(LexerlessGrammarBuilder b) { - b.rule(ARRAY_EXPRESSION).is("[", SPC, b.zeroOrMore(INNER_ATTRIBUTE, SPC), - b.optional(ARRAY_ELEMENTS, SPC), SPC, - "]"); + b.rule(ARRAY_EXPRESSION).is("[", SPC, b.optional(ARRAY_ELEMENTS, SPC), SPC,"]"); b.rule(ARRAY_ELEMENTS).is(b.firstOf( b.sequence(SPC, EXPRESSION, SPC, RustPunctuator.SEMI, SPC, EXPRESSION), b.sequence(SPC, EXPRESSION, SPC, b.zeroOrMore(RustPunctuator.COMMA, SPC, EXPRESSION), b.optional(RustPunctuator.COMMA, SPC)) - )); - b.rule(INDEX_EXPRESSION).is(EXPRESSION, SPC, "[", SPC, EXPRESSION, SPC, "]"); b.rule(FIELD_EXPRESSION).is(EXPRESSION, RustPunctuator.DOT, IDENTIFIER); From 1de0c8bbe3a5eb1a3779ef44f171ffaba2ccc6c6 Mon Sep 17 00:00:00 2001 From: Eric Le Goff Date: Fri, 19 Nov 2021 12:16:44 +0100 Subject: [PATCH 04/18] Closure expression and patterns --- .../main/java/org/sonar/rust/RustGrammar.java | 7 +- .../rust/parser/patterns/PatternTest.java | 75 ++++++++----------- 2 files changed, 38 insertions(+), 44 deletions(-) diff --git a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java index d4af4f55..5ae2e5e8 100644 --- a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java +++ b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java @@ -224,6 +224,7 @@ public enum RustGrammar implements GrammarRuleKey { PATH_IN_EXPRESSION, PATH_PATTERN, PATTERN, + PATTERN_NO_TOP_ALT, PERCENTEQ_EXPRESSION, PLUSEQ_EXPRESSION, PREDICATE_LOOP_EXPRESSION, @@ -973,7 +974,9 @@ private static void macrosByExample(LexerlessGrammarBuilder b) { } private static void patterns(LexerlessGrammarBuilder b) { - b.rule(PATTERN).is(b.firstOf( + + b.rule(PATTERN).is(b.optional(RustPunctuator.OR), PATTERN_NO_TOP_ALT, b.zeroOrMore(RustPunctuator.OR, PATTERN_NO_TOP_ALT)); + b.rule(PATTERN_NO_TOP_ALT).is(b.firstOf( RANGE_PATTERN, TUPLE_STRUCT_PATTERN, @@ -1890,7 +1893,7 @@ public static void closure(LexerlessGrammarBuilder b) { ); b.rule(CLOSURE_PARAMETERS).is(seq(b, CLOSURE_PARAM, RustPunctuator.COMMA)); b.rule(CLOSURE_PARAM).is(b.zeroOrMore(OUTER_ATTRIBUTE, SPC), - PATTERN, SPC, + PATTERN_NO_TOP_ALT, SPC, b.optional(RustPunctuator.COLON, SPC, TYPE) ); } diff --git a/community-rust-frontend/src/test/java/org/sonar/rust/parser/patterns/PatternTest.java b/community-rust-frontend/src/test/java/org/sonar/rust/parser/patterns/PatternTest.java index a5a3686b..b7eb2128 100644 --- a/community-rust-frontend/src/test/java/org/sonar/rust/parser/patterns/PatternTest.java +++ b/community-rust-frontend/src/test/java/org/sonar/rust/parser/patterns/PatternTest.java @@ -3,17 +3,17 @@ * Copyright (C) 2021 Eric Le Goff * mailto:community-rust AT pm DOT me * http://github.com/elegoff/sonar-rust - * + *

* This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + *

* You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. @@ -40,7 +40,7 @@ public void testLitteralPattern() { @Test - public void testIdentifierPattern(){ + public void testIdentifierPattern() { assertThat(RustGrammar.create().build().rule(RustGrammar.IDENTIFIER_PATTERN)) .matches("e @ 1..=5") .matches("f @ 'a'..='z'") @@ -52,8 +52,9 @@ public void testIdentifierPattern(){ ; } + @Test - public void testWildcardPattern(){ + public void testWildcardPattern() { assertThat(RustGrammar.create().build().rule(RustGrammar.WILDCARD_PATTERN)) .matches("_") @@ -62,7 +63,7 @@ public void testWildcardPattern(){ } @Test - public void testRestPattern(){ + public void testRestPattern() { assertThat(RustGrammar.create().build().rule(RustGrammar.REST_PATTERN)) .matches("..") @@ -71,7 +72,7 @@ public void testRestPattern(){ } @Test - public void testRangePatternBound(){ + public void testRangePatternBound() { assertThat(RustGrammar.create().build().rule(RustGrammar.RANGE_PATTERN_BOUND)) .matches("1") .matches("'a'") @@ -83,29 +84,27 @@ public void testRangePatternBound(){ } @Test - public void testRangePattern(){ + public void testRangePattern() { assertThat(RustGrammar.create().build().rule(RustGrammar.RANGE_PATTERN)) .matches("1..=9") - ; } @Test - public void testObsoleteRangePattern(){ + public void testObsoleteRangePattern() { assertThat(RustGrammar.create().build().rule(RustGrammar.OBSOLETE_RANGE_PATTERN)) .matches("1...9") - ; } @Test - public void testReferencePattern(){ + public void testReferencePattern() { assertThat(RustGrammar.create().build().rule(RustGrammar.REFERENCE_PATTERN)) .matches("&42") .matches("&&42") @@ -117,7 +116,7 @@ public void testReferencePattern(){ } @Test - public void testStructPatternElements(){ + public void testStructPatternElements() { assertThat(RustGrammar.create().build().rule(RustGrammar.STRUCT_PATTERN_ELEMENTS)) .matches("..") .matches("x: 10") @@ -127,13 +126,12 @@ public void testStructPatternElements(){ .matches("x,y") - ; } @Test - public void testStructPatternField(){ + public void testStructPatternField() { assertThat(RustGrammar.create().build().rule(RustGrammar.STRUCT_PATTERN_FIELD)) .matches("1:42") .matches("#[outer]1:42") @@ -143,13 +141,12 @@ public void testStructPatternField(){ .matches("x:10") - ; } @Test - public void testStructPattern(){ + public void testStructPattern() { assertThat(RustGrammar.create().build().rule(RustGrammar.STRUCT_PATTERN)) .matches("Point{}") .matches("Point{..}") @@ -161,8 +158,9 @@ public void testStructPattern(){ ; } + @Test - public void testTupleStructPattern(){ + public void testTupleStructPattern() { assertThat(RustGrammar.create().build().rule(RustGrammar.TUPLE_STRUCT_PATTERN)) .matches("local_var()") .matches("S(z @ 1, _)") @@ -170,15 +168,12 @@ public void testTupleStructPattern(){ .matches("Error::Engine(box EngineError(EngineErrorInner::Request(e)))") - - - ; } @Test - public void testTuplePatternItems(){ + public void testTuplePatternItems() { assertThat(RustGrammar.create().build().rule(RustGrammar.TUPLE_PATTERN_ITEMS)) .matches("42,") .matches("..") @@ -196,9 +191,8 @@ public void testTuplePatternItems(){ } - @Test - public void testTuplePattern(){ + public void testTuplePattern() { assertThat(RustGrammar.create().build().rule(RustGrammar.TUPLE_PATTERN)) .matches("()") .matches("(42,)") @@ -208,25 +202,23 @@ public void testTuplePattern(){ .matches("( field_1, )") - ; } @Test - public void testGroupedPattern(){ + public void testGroupedPattern() { assertThat(RustGrammar.create().build().rule(RustGrammar.GROUPED_PATTERN)) .matches("(42)") .matches("( foo )") - ; } @Test - public void testSlicePattern(){ + public void testSlicePattern() { assertThat(RustGrammar.create().build().rule(RustGrammar.SLICE_PATTERN)) .matches("[]") .matches("[42]") @@ -236,32 +228,26 @@ public void testSlicePattern(){ .notMatches("[b'#'](") - - ; } @Test - public void testPathPattern(){ + public void testPathPattern() { assertThat(RustGrammar.create().build().rule(RustGrammar.PATH_PATTERN)) .matches("Vec::::with_capacity") .matches("::f") .matches("Token::BackQuote") - - - ; } - @Test - public void testPattern() { - assertThat(RustGrammar.create().build().rule(RustGrammar.PATTERN)) + public void testPatternNoTopAlt() { + assertThat(RustGrammar.create().build().rule(RustGrammar.PATTERN_NO_TOP_ALT)) .matches("Token::BackQuote") //path pattern //range patterns .matches("1..=9") @@ -319,12 +305,17 @@ public void testPattern() { .matches("([b'#'], b'8')") .matches("(b'8', [b'#'])") .matches("OK(_)") - //.matches("Err(true_prior)") - - - - + .matches("Err(true_prior)") + ; + } + @Test + public void testPattern() { + assertThat(RustGrammar.create().build().rule(RustGrammar.PATTERN)) + .matches("42") + .matches("|42") + .notMatches("|42|") + .matches("|42|43") ; } From d1edef46335704068534235c270e8d15d422d384 Mon Sep 17 00:00:00 2001 From: Eric Le Goff Date: Fri, 19 Nov 2021 14:15:04 +0100 Subject: [PATCH 05/18] Scrutinee and if let expressions --- .../main/java/org/sonar/rust/RustGrammar.java | 143 +++++++++--------- .../parser/expressions/ExpressionTest.java | 4 +- .../expressions/GroupedExpressionTest.java | 1 - 3 files changed, 73 insertions(+), 75 deletions(-) diff --git a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java index 5ae2e5e8..b3301859 100644 --- a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java +++ b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java @@ -96,7 +96,6 @@ public enum RustGrammar implements GrammarRuleKey { EQ_EXPRESSION, ERROR_PROPAGATION_EXPRESSION, EXPRESSION, - EXPRESSION_EXCEPT_STRUCT, EXPRESSION_STATEMENT, EXPRESSION_TERM, EXPRESSION_TERM_EXCEPT_STRUCT, @@ -256,6 +255,7 @@ public enum RustGrammar implements GrammarRuleKey { REMAINDER_EXPRESSION, REST_PATTERN, RETURN_EXPRESSION, + SCRUTINEE, SELF_PARAM, SHLEQ_EXPRESSION, SHL_EXPRESSION, @@ -1232,7 +1232,7 @@ public static void expressions(LexerlessGrammarBuilder b) { )); - b.rule(EXPRESSION_EXCEPT_STRUCT).is( + b.rule(SCRUTINEE).is( b.zeroOrMore(OUTER_ATTRIBUTE, SPC), b.firstOf( b.sequence(BREAK_EXPRESSION, b.zeroOrMore(SPC, EXPRESSION_TERM_EXCEPT_STRUCT)), @@ -1241,7 +1241,7 @@ public static void expressions(LexerlessGrammarBuilder b) { b.sequence(RustPunctuator.DOTDOT, b.next(")")), b.sequence(RANGE_TO_INCLUSIVE_EXPR, b.zeroOrMore(SPC, EXPRESSION_TERM_EXCEPT_STRUCT)), b.sequence(RustPunctuator.DOTDOT, b.nextNot(RustPunctuator.EQ), b.endOfInput()), - b.sequence(RustPunctuator.DOTDOT, b.nextNot(RustPunctuator.EQ), EXPRESSION_EXCEPT_STRUCT), + b.sequence(RustPunctuator.DOTDOT, b.nextNot(RustPunctuator.EQ), SCRUTINEE), b.sequence(LITERAL_EXPRESSION, b.zeroOrMore(SPC, EXPRESSION_TERM_EXCEPT_STRUCT)), b.sequence(BLOCK_EXPRESSION, b.zeroOrMore(SPC, EXPRESSION_TERM_EXCEPT_STRUCT)), b.sequence(MATCH_EXPRESSION, b.zeroOrMore(SPC, EXPRESSION_TERM_EXCEPT_STRUCT)), @@ -1347,8 +1347,8 @@ public static void expressions(LexerlessGrammarBuilder b) { b.rule(EXPRESSION_TERM_EXCEPT_STRUCT).is( b.firstOf( b.sequence(RustPunctuator.DOTDOT, b.nextNot(RustPunctuator.EQ), b.endOfInput()), - b.sequence(RustPunctuator.DOTDOTEQ, EXPRESSION_EXCEPT_STRUCT), - b.sequence(RustPunctuator.DOTDOT, b.nextNot(RustPunctuator.EQ), b.optional(EXPRESSION_EXCEPT_STRUCT)), + b.sequence(RustPunctuator.DOTDOTEQ, SCRUTINEE), + b.sequence(RustPunctuator.DOTDOT, b.nextNot(RustPunctuator.EQ), b.optional(SCRUTINEE)), b.sequence(RustPunctuator.DOT, RustKeyword.KW_AWAIT, SPC, EXPRESSION_TERM), b.sequence(RustPunctuator.DOT, PATH_EXPR_SEGMENT, SPC, "(", SPC, b.optional(CALL_PARAMS, SPC), ")", SPC, EXPRESSION_TERM_EXCEPT_STRUCT), b.sequence(RustPunctuator.DOT, TUPLE_INDEX, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), @@ -1356,35 +1356,35 @@ public static void expressions(LexerlessGrammarBuilder b) { b.sequence("(", SPC, b.optional(CALL_PARAMS), SPC, ")", SPC, EXPRESSION_TERM_EXCEPT_STRUCT), b.sequence(RustPunctuator.QUESTION, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), b.sequence(RustKeyword.KW_AS, SPC, TYPE_NO_BOUNDS, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), - b.sequence("[", SPC, EXPRESSION_EXCEPT_STRUCT, SPC, "]", SPC, EXPRESSION_TERM_EXCEPT_STRUCT), - b.sequence(RustPunctuator.OROR, SPC, EXPRESSION_EXCEPT_STRUCT, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), - b.sequence(RustPunctuator.ANDAND, SPC, EXPRESSION_EXCEPT_STRUCT, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), - b.sequence(RustPunctuator.NE, SPC, EXPRESSION_EXCEPT_STRUCT, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), - b.sequence(RustPunctuator.GT, SPC, EXPRESSION_EXCEPT_STRUCT, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), - b.sequence(RustPunctuator.LT, SPC, EXPRESSION_EXCEPT_STRUCT, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), - b.sequence(RustPunctuator.GE, SPC, EXPRESSION_EXCEPT_STRUCT, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), - b.sequence(RustPunctuator.LE, SPC, EXPRESSION_EXCEPT_STRUCT, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), - b.sequence(RustPunctuator.PLUS, SPC, EXPRESSION_EXCEPT_STRUCT, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), - b.sequence(RustPunctuator.MINUS, SPC, EXPRESSION_EXCEPT_STRUCT, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), - b.sequence(RustPunctuator.STAR, SPC, EXPRESSION_EXCEPT_STRUCT, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), - b.sequence(RustPunctuator.SLASH, SPC, EXPRESSION_EXCEPT_STRUCT, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), - b.sequence(RustPunctuator.PERCENT, SPC, EXPRESSION_EXCEPT_STRUCT, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), - b.sequence(RustPunctuator.AND, SPC, EXPRESSION_EXCEPT_STRUCT, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), - b.sequence(RustPunctuator.OR, SPC, EXPRESSION_EXCEPT_STRUCT, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), - b.sequence(RustPunctuator.CARET, SPC, EXPRESSION_EXCEPT_STRUCT, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), - b.sequence(RustPunctuator.SHL, SPC, EXPRESSION_EXCEPT_STRUCT, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), - b.sequence(RustPunctuator.SHR, SPC, EXPRESSION_EXCEPT_STRUCT, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), - b.sequence(RustPunctuator.EQ, SPC, EXPRESSION_EXCEPT_STRUCT, EXPRESSION_TERM_EXCEPT_STRUCT), - b.sequence(RustPunctuator.PLUSEQ, SPC, EXPRESSION_EXCEPT_STRUCT, EXPRESSION_TERM_EXCEPT_STRUCT), - b.sequence(RustPunctuator.MINUSEQ, SPC, EXPRESSION_EXCEPT_STRUCT, EXPRESSION_TERM_EXCEPT_STRUCT), - b.sequence(RustPunctuator.STAREQ, SPC, EXPRESSION_EXCEPT_STRUCT, EXPRESSION_TERM_EXCEPT_STRUCT), - b.sequence(RustPunctuator.SLASHEQ, SPC, EXPRESSION_EXCEPT_STRUCT, EXPRESSION_TERM_EXCEPT_STRUCT), - b.sequence(RustPunctuator.PERCENTEQ, SPC, EXPRESSION_EXCEPT_STRUCT, EXPRESSION_TERM_EXCEPT_STRUCT), - b.sequence(RustPunctuator.ANDEQ, SPC, EXPRESSION_EXCEPT_STRUCT, EXPRESSION_TERM_EXCEPT_STRUCT), - b.sequence(RustPunctuator.OREQ, SPC, EXPRESSION_EXCEPT_STRUCT, EXPRESSION_TERM_EXCEPT_STRUCT), - b.sequence(RustPunctuator.CARETEQ, SPC, EXPRESSION_EXCEPT_STRUCT, EXPRESSION_TERM_EXCEPT_STRUCT), - b.sequence(RustPunctuator.SHLEQ, SPC, EXPRESSION_EXCEPT_STRUCT, EXPRESSION_TERM_EXCEPT_STRUCT), - b.sequence(RustPunctuator.SHREQ, SPC, EXPRESSION_EXCEPT_STRUCT, EXPRESSION_TERM_EXCEPT_STRUCT), + b.sequence("[", SPC, SCRUTINEE, SPC, "]", SPC, EXPRESSION_TERM_EXCEPT_STRUCT), + b.sequence(RustPunctuator.OROR, SPC, SCRUTINEE, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), + b.sequence(RustPunctuator.ANDAND, SPC, SCRUTINEE, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), + b.sequence(RustPunctuator.NE, SPC, SCRUTINEE, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), + b.sequence(RustPunctuator.GT, SPC, SCRUTINEE, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), + b.sequence(RustPunctuator.LT, SPC, SCRUTINEE, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), + b.sequence(RustPunctuator.GE, SPC, SCRUTINEE, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), + b.sequence(RustPunctuator.LE, SPC, SCRUTINEE, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), + b.sequence(RustPunctuator.PLUS, SPC, SCRUTINEE, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), + b.sequence(RustPunctuator.MINUS, SPC, SCRUTINEE, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), + b.sequence(RustPunctuator.STAR, SPC, SCRUTINEE, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), + b.sequence(RustPunctuator.SLASH, SPC, SCRUTINEE, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), + b.sequence(RustPunctuator.PERCENT, SPC, SCRUTINEE, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), + b.sequence(RustPunctuator.AND, SPC, SCRUTINEE, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), + b.sequence(RustPunctuator.OR, SPC, SCRUTINEE, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), + b.sequence(RustPunctuator.CARET, SPC, SCRUTINEE, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), + b.sequence(RustPunctuator.SHL, SPC, SCRUTINEE, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), + b.sequence(RustPunctuator.SHR, SPC, SCRUTINEE, SPC, EXPRESSION_TERM_EXCEPT_STRUCT), + b.sequence(RustPunctuator.EQ, SPC, SCRUTINEE, EXPRESSION_TERM_EXCEPT_STRUCT), + b.sequence(RustPunctuator.PLUSEQ, SPC, SCRUTINEE, EXPRESSION_TERM_EXCEPT_STRUCT), + b.sequence(RustPunctuator.MINUSEQ, SPC, SCRUTINEE, EXPRESSION_TERM_EXCEPT_STRUCT), + b.sequence(RustPunctuator.STAREQ, SPC, SCRUTINEE, EXPRESSION_TERM_EXCEPT_STRUCT), + b.sequence(RustPunctuator.SLASHEQ, SPC, SCRUTINEE, EXPRESSION_TERM_EXCEPT_STRUCT), + b.sequence(RustPunctuator.PERCENTEQ, SPC, SCRUTINEE, EXPRESSION_TERM_EXCEPT_STRUCT), + b.sequence(RustPunctuator.ANDEQ, SPC, SCRUTINEE, EXPRESSION_TERM_EXCEPT_STRUCT), + b.sequence(RustPunctuator.OREQ, SPC, SCRUTINEE, EXPRESSION_TERM_EXCEPT_STRUCT), + b.sequence(RustPunctuator.CARETEQ, SPC, SCRUTINEE, EXPRESSION_TERM_EXCEPT_STRUCT), + b.sequence(RustPunctuator.SHLEQ, SPC, SCRUTINEE, EXPRESSION_TERM_EXCEPT_STRUCT), + b.sequence(RustPunctuator.SHREQ, SPC, SCRUTINEE, EXPRESSION_TERM_EXCEPT_STRUCT), b.sequence(RustPunctuator.DOT, RustKeyword.KW_AWAIT), b.sequence(RustPunctuator.DOT, PATH_EXPR_SEGMENT, SPC, "(", SPC, b.optional(CALL_PARAMS, SPC), ")"), b.sequence(RustPunctuator.DOT, TUPLE_INDEX), @@ -1393,35 +1393,35 @@ public static void expressions(LexerlessGrammarBuilder b) { RustPunctuator.QUESTION, b.sequence(RustKeyword.KW_AS, SPC, TYPE_NO_BOUNDS), b.sequence("[", SPC, EXPRESSION, SPC, "]"), - b.sequence(RustPunctuator.OROR, SPC, EXPRESSION_EXCEPT_STRUCT), - b.sequence(RustPunctuator.ANDAND, SPC, EXPRESSION_EXCEPT_STRUCT), - b.sequence(RustPunctuator.EQEQ, SPC, EXPRESSION_EXCEPT_STRUCT), - b.sequence(RustPunctuator.NE, SPC, EXPRESSION_EXCEPT_STRUCT), - b.sequence(RustPunctuator.GT, SPC, EXPRESSION_EXCEPT_STRUCT), - b.sequence(RustPunctuator.LT, SPC, EXPRESSION_EXCEPT_STRUCT), - b.sequence(RustPunctuator.GE, SPC, EXPRESSION_EXCEPT_STRUCT), - b.sequence(RustPunctuator.LE, SPC, EXPRESSION_EXCEPT_STRUCT), - b.sequence(RustPunctuator.PLUS, SPC, EXPRESSION_EXCEPT_STRUCT), - b.sequence(RustPunctuator.MINUS, SPC, EXPRESSION_EXCEPT_STRUCT), - b.sequence(RustPunctuator.STAR, SPC, EXPRESSION_EXCEPT_STRUCT), - b.sequence(RustPunctuator.SLASH, SPC, EXPRESSION_EXCEPT_STRUCT), - b.sequence(RustPunctuator.PERCENT, SPC, EXPRESSION_EXCEPT_STRUCT), - b.sequence(RustPunctuator.AND, SPC, EXPRESSION_EXCEPT_STRUCT), - b.sequence(RustPunctuator.OR, SPC, EXPRESSION_EXCEPT_STRUCT), - b.sequence(RustPunctuator.CARET, SPC, EXPRESSION_EXCEPT_STRUCT), - b.sequence(RustPunctuator.SHL, SPC, EXPRESSION_EXCEPT_STRUCT), - b.sequence(RustPunctuator.SHR, SPC, EXPRESSION_EXCEPT_STRUCT), - b.sequence(RustPunctuator.EQ, SPC, EXPRESSION_EXCEPT_STRUCT), - b.sequence(RustPunctuator.PLUSEQ, SPC, EXPRESSION_EXCEPT_STRUCT), - b.sequence(RustPunctuator.MINUSEQ, SPC, EXPRESSION_EXCEPT_STRUCT), - b.sequence(RustPunctuator.STAREQ, SPC, EXPRESSION_EXCEPT_STRUCT), - b.sequence(RustPunctuator.SLASHEQ, SPC, EXPRESSION_EXCEPT_STRUCT), - b.sequence(RustPunctuator.PERCENTEQ, SPC, EXPRESSION_EXCEPT_STRUCT), - b.sequence(RustPunctuator.ANDEQ, SPC, EXPRESSION_EXCEPT_STRUCT), - b.sequence(RustPunctuator.OREQ, SPC, EXPRESSION_EXCEPT_STRUCT), - b.sequence(RustPunctuator.CARETEQ, SPC, EXPRESSION_EXCEPT_STRUCT), - b.sequence(RustPunctuator.SHLEQ, SPC, EXPRESSION_EXCEPT_STRUCT), - b.sequence(RustPunctuator.SHREQ, SPC, EXPRESSION_EXCEPT_STRUCT) + b.sequence(RustPunctuator.OROR, SPC, SCRUTINEE), + b.sequence(RustPunctuator.ANDAND, SPC, SCRUTINEE), + b.sequence(RustPunctuator.EQEQ, SPC, SCRUTINEE), + b.sequence(RustPunctuator.NE, SPC, SCRUTINEE), + b.sequence(RustPunctuator.GT, SPC, SCRUTINEE), + b.sequence(RustPunctuator.LT, SPC, SCRUTINEE), + b.sequence(RustPunctuator.GE, SPC, SCRUTINEE), + b.sequence(RustPunctuator.LE, SPC, SCRUTINEE), + b.sequence(RustPunctuator.PLUS, SPC, SCRUTINEE), + b.sequence(RustPunctuator.MINUS, SPC, SCRUTINEE), + b.sequence(RustPunctuator.STAR, SPC, SCRUTINEE), + b.sequence(RustPunctuator.SLASH, SPC, SCRUTINEE), + b.sequence(RustPunctuator.PERCENT, SPC, SCRUTINEE), + b.sequence(RustPunctuator.AND, SPC, SCRUTINEE), + b.sequence(RustPunctuator.OR, SPC, SCRUTINEE), + b.sequence(RustPunctuator.CARET, SPC, SCRUTINEE), + b.sequence(RustPunctuator.SHL, SPC, SCRUTINEE), + b.sequence(RustPunctuator.SHR, SPC, SCRUTINEE), + b.sequence(RustPunctuator.EQ, SPC, SCRUTINEE), + b.sequence(RustPunctuator.PLUSEQ, SPC, SCRUTINEE), + b.sequence(RustPunctuator.MINUSEQ, SPC, SCRUTINEE), + b.sequence(RustPunctuator.STAREQ, SPC, SCRUTINEE), + b.sequence(RustPunctuator.SLASHEQ, SPC, SCRUTINEE), + b.sequence(RustPunctuator.PERCENTEQ, SPC, SCRUTINEE), + b.sequence(RustPunctuator.ANDEQ, SPC, SCRUTINEE), + b.sequence(RustPunctuator.OREQ, SPC, SCRUTINEE), + b.sequence(RustPunctuator.CARETEQ, SPC, SCRUTINEE), + b.sequence(RustPunctuator.SHLEQ, SPC, SCRUTINEE), + b.sequence(RustPunctuator.SHREQ, SPC, SCRUTINEE) )); b.rule(EXPRESSION_WITHOUT_BLOCK).is(b.zeroOrMore(OUTER_ATTRIBUTE, SPC), @@ -1476,7 +1476,7 @@ private static void match(LexerlessGrammarBuilder b) { b.rule(MATCH_EXPRESSION).is( RustKeyword.KW_MATCH, SPC, b.optional( RustKeyword.KW_MATCH, b.next(IDENTIFIER)), - EXPRESSION_EXCEPT_STRUCT, + SCRUTINEE, SPC, "{", SPC, b.zeroOrMore(INNER_ATTRIBUTE, SPC), b.optional(MATCH_ARMS, SPC), @@ -1509,7 +1509,7 @@ private static void ifExpr(LexerlessGrammarBuilder b) { b.rule(IF_EXPRESSION).is( RustKeyword.KW_IF, SPC, b.optional( RustKeyword.KW_IF,b.next(IDENTIFIER)), - EXPRESSION_EXCEPT_STRUCT, b.next(SPC, "{") + SCRUTINEE, b.next(SPC, "{") , SPC, BLOCK_EXPRESSION, SPC, b.optional( @@ -1517,7 +1517,7 @@ private static void ifExpr(LexerlessGrammarBuilder b) { ) ); b.rule(IF_LET_EXPRESSION).is( - RustKeyword.KW_IF, SPC, RustKeyword.KW_LET, SPC, MATCH_ARM_PATTERNS, SPC, RustPunctuator.EQ, SPC, EXPRESSION_EXCEPT_STRUCT, //except struct or lazy boolean operator expression + RustKeyword.KW_IF, SPC, RustKeyword.KW_LET, SPC, PATTERN, SPC, RustPunctuator.EQ, SPC, SCRUTINEE, //except struct or lazy boolean operator expression SPC, BLOCK_EXPRESSION, SPC, b.optional(RustKeyword.KW_ELSE, SPC, b.firstOf(BLOCK_EXPRESSION, IF_EXPRESSION, IF_LET_EXPRESSION) ) @@ -1555,16 +1555,16 @@ private static void loops(LexerlessGrammarBuilder b) { b.rule(INFINITE_LOOP_EXPRESSION).is( RustKeyword.KW_LOOP, SPC, BLOCK_EXPRESSION); b.rule(PREDICATE_LOOP_EXPRESSION).is( - RustKeyword.KW_WHILE, SPC, EXPRESSION_EXCEPT_STRUCT, SPC, + RustKeyword.KW_WHILE, SPC, SCRUTINEE, SPC, BLOCK_EXPRESSION ); b.rule(PREDICATE_PATTERN_LOOP_EXPRESSION).is( RustKeyword.KW_WHILE, SPC, RustKeyword.KW_LET, SPC, MATCH_ARM_PATTERNS, SPC, RustPunctuator.EQ, - SPC, EXPRESSION_EXCEPT_STRUCT, + SPC, SCRUTINEE, SPC, BLOCK_EXPRESSION ); b.rule(ITERATOR_LOOP_EXPRESSION).is( - RustKeyword.KW_FOR, SPC, PATTERN, SPC, RustKeyword.KW_IN, SPC, EXPRESSION_EXCEPT_STRUCT, + RustKeyword.KW_FOR, SPC, PATTERN, SPC, RustKeyword.KW_IN, SPC, SCRUTINEE, SPC, BLOCK_EXPRESSION ); b.rule(LOOP_LABEL).is(LIFETIME_OR_LABEL, SPC, RustPunctuator.COLON); @@ -1616,8 +1616,7 @@ private static void array(LexerlessGrammarBuilder b) { } private static void grouped(LexerlessGrammarBuilder b) { - b.rule(GROUPED_EXPRESSION).is("(", SPC, b.zeroOrMore(INNER_ATTRIBUTE, SPC), EXPRESSION - , SPC, ")"); + b.rule(GROUPED_EXPRESSION).is("(", SPC, EXPRESSION, SPC, ")"); } private static void operator(LexerlessGrammarBuilder b) { @@ -1650,7 +1649,7 @@ private static void operator(LexerlessGrammarBuilder b) { )); b.rule(NEGATION_EXPRESSION_EXCEPT_STRUCT).is(b.firstOf( - b.sequence(RustPunctuator.NOT, SPC, EXPRESSION_EXCEPT_STRUCT), b.sequence("-", SPC, EXPRESSION_EXCEPT_STRUCT) + b.sequence(RustPunctuator.NOT, SPC, SCRUTINEE), b.sequence("-", SPC, SCRUTINEE) )); b.rule(ARITHMETIC_OR_LOGICAL_EXPRESSION).is(b.firstOf( diff --git a/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/ExpressionTest.java b/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/ExpressionTest.java index aead52ac..b090af76 100644 --- a/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/ExpressionTest.java +++ b/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/ExpressionTest.java @@ -28,8 +28,8 @@ public class ExpressionTest { @Test - public void testExpressionExceptStruct() { - assertThat(RustGrammar.create().build().rule(RustGrammar.EXPRESSION_EXCEPT_STRUCT)) + public void testScrutinee() { + assertThat(RustGrammar.create().build().rule(RustGrammar.SCRUTINEE)) .matches("a") .matches("a || b") .matches("a() || b") diff --git a/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/GroupedExpressionTest.java b/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/GroupedExpressionTest.java index 0027fbbc..005a99d3 100644 --- a/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/GroupedExpressionTest.java +++ b/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/GroupedExpressionTest.java @@ -34,7 +34,6 @@ public void testGroupedExpression() { .matches("( 1 + 1 )") .matches("(foo)") .matches("(1 +(2+3))") - .matches("( #![crate_type = \"lib\"] 40+2 )") .matches("(state.get_error_class_fn)") .matches("(state.borrow().get_error_class_fn)") .matches("(disk_byte as char)") From 98661d3d57b889eb51bfbd6bd3d5f4ddc4b453fa Mon Sep 17 00:00:00 2001 From: Eric Le Goff Date: Fri, 19 Nov 2021 14:51:55 +0100 Subject: [PATCH 06/18] Match expression --- .../main/java/org/sonar/rust/RustGrammar.java | 17 ++++++++--------- .../parser/expressions/LoopExpressionTest.java | 3 +++ .../parser/expressions/MatchExpressionTest.java | 11 ----------- .../sonar/rust/parser/patterns/PatternTest.java | 6 ++++++ 4 files changed, 17 insertions(+), 20 deletions(-) diff --git a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java index b3301859..ade137bb 100644 --- a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java +++ b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java @@ -185,7 +185,6 @@ public enum RustGrammar implements GrammarRuleKey { MATCH_ARM, MATCH_ARMS, MATCH_ARM_GUARD, - MATCH_ARM_PATTERNS, MATCH_EXPRESSION, MAYBE_NAMED_FUNCTION_PARAMETERS, MAYBE_NAMED_FUNCTION_PARAMETERS_VARIADIC, @@ -975,7 +974,11 @@ private static void macrosByExample(LexerlessGrammarBuilder b) { private static void patterns(LexerlessGrammarBuilder b) { - b.rule(PATTERN).is(b.optional(RustPunctuator.OR), PATTERN_NO_TOP_ALT, b.zeroOrMore(RustPunctuator.OR, PATTERN_NO_TOP_ALT)); + b.rule(PATTERN).is( + b.optional(RustPunctuator.OR, SPC), + PATTERN_NO_TOP_ALT, SPC, + b.zeroOrMore(b.sequence(RustPunctuator.OR, SPC, PATTERN_NO_TOP_ALT, SPC)) + ); b.rule(PATTERN_NO_TOP_ALT).is(b.firstOf( RANGE_PATTERN, @@ -1493,14 +1496,10 @@ private static void match(LexerlessGrammarBuilder b) { b.rule(MATCH_ARM).is( b.zeroOrMore(OUTER_ATTRIBUTE, SPC), - MATCH_ARM_PATTERNS, + PATTERN, b.optional(MATCH_ARM_GUARD) ); - b.rule(MATCH_ARM_PATTERNS).is( - b.optional(RustPunctuator.OR, SPC), - PATTERN, SPC, - b.zeroOrMore(b.sequence(RustPunctuator.OR, SPC, PATTERN, SPC)) - ); + b.rule(MATCH_ARM_GUARD).is(RustKeyword.KW_IF, SPC, EXPRESSION); } @@ -1559,7 +1558,7 @@ private static void loops(LexerlessGrammarBuilder b) { BLOCK_EXPRESSION ); b.rule(PREDICATE_PATTERN_LOOP_EXPRESSION).is( - RustKeyword.KW_WHILE, SPC, RustKeyword.KW_LET, SPC, MATCH_ARM_PATTERNS, SPC, RustPunctuator.EQ, + RustKeyword.KW_WHILE, SPC, RustKeyword.KW_LET, SPC, PATTERN, SPC, RustPunctuator.EQ, SPC, SCRUTINEE, SPC, BLOCK_EXPRESSION ); diff --git a/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/LoopExpressionTest.java b/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/LoopExpressionTest.java index 502880ac..b07f5a6c 100644 --- a/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/LoopExpressionTest.java +++ b/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/LoopExpressionTest.java @@ -61,10 +61,13 @@ public void testLoopExpression() { " println!(\"Irrefutable patterns are always true\");\n" + " break;\n" + "}") + .matches("while let Some(v @ 1) | Some(v @ 2) = vals.pop() {\n" + " // Prints 2, 2, then 1\n" + " println!(\"{}\", v);\n" + "}") + + .matches("for text in v {\n" + " println!(\"I like {}.\", text);\n" + "}") diff --git a/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/MatchExpressionTest.java b/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/MatchExpressionTest.java index fd5a5c31..b10d03d6 100644 --- a/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/MatchExpressionTest.java +++ b/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/MatchExpressionTest.java @@ -36,17 +36,6 @@ public void tesMatchArmGuard() { ; } - @Test - public void tesMatchArmPattern() { - assertThat(RustGrammar.create().build().rule(RustGrammar.MATCH_ARM_PATTERNS)) - .matches("42") - .matches("foo") - .matches("S(z @ 1, _)") - .matches("(\"Bacon\", b)") - - - ; - } @Test public void tesMatchArm() { diff --git a/community-rust-frontend/src/test/java/org/sonar/rust/parser/patterns/PatternTest.java b/community-rust-frontend/src/test/java/org/sonar/rust/parser/patterns/PatternTest.java index b7eb2128..87eec915 100644 --- a/community-rust-frontend/src/test/java/org/sonar/rust/parser/patterns/PatternTest.java +++ b/community-rust-frontend/src/test/java/org/sonar/rust/parser/patterns/PatternTest.java @@ -316,7 +316,13 @@ public void testPattern() { .matches("|42") .notMatches("|42|") .matches("|42|43") + .matches("foo") + .matches("S(z @ 1, _)") + .matches("(\"Bacon\", b)") + .matches("Some(v @ 1) | Some(v @ 2)") ; } + + } \ No newline at end of file From 90b436ed69775a2e4ea832eb486af8df6dde75a7 Mon Sep 17 00:00:00 2001 From: Eric Le Goff Date: Fri, 19 Nov 2021 18:10:12 +0100 Subject: [PATCH 07/18] WIP XID_Start --- .../src/main/java/org/sonar/rust/RustGrammar.java | 6 +----- .../rust/parser/expressions/StructExpressionTest.java | 3 +-- .../rust/parser/expressions/TupleExpressionTest.java | 1 - .../org/sonar/rust/parser/lexer/IdentifierTest.java | 11 ++++++++--- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java index ade137bb..cbab79f1 100644 --- a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java +++ b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java @@ -1590,9 +1590,7 @@ private static void call(LexerlessGrammarBuilder b) { private static void tuple(LexerlessGrammarBuilder b) { - b.rule(TUPLE_EXPRESSION).is("(", SPC, b.zeroOrMore(INNER_ATTRIBUTE, SPC), - b.optional(TUPLE_ELEMENT), SPC, - ")"); + b.rule(TUPLE_EXPRESSION).is("(", SPC, b.optional(TUPLE_ELEMENT), SPC, ")"); b.rule(TUPLE_ELEMENT).is(b.oneOrMore(b.sequence(EXPRESSION, SPC, RustPunctuator.COMMA, SPC)), b.optional(EXPRESSION, SPC)); @@ -1822,7 +1820,6 @@ public static void struct(LexerlessGrammarBuilder b) { STRUCT_EXPR_UNIT )); b.rule(STRUCT_EXPR_STRUCT).is(PATH_IN_EXPRESSION, SPC, "{", SPC, - b.zeroOrMore(INNER_ATTRIBUTE, SPC), b.optional(b.firstOf(STRUCT_EXPR_FIELDS, STRUCT_BASE)), SPC, "}" @@ -1846,7 +1843,6 @@ public static void struct(LexerlessGrammarBuilder b) { b.rule(STRUCT_BASE).is(RustPunctuator.DOTDOT, SPC, EXPRESSION); b.rule(STRUCT_EXPR_TUPLE).is( PATH_IN_EXPRESSION, "(", SPC, - b.zeroOrMore(INNER_ATTRIBUTE, SPC), b.optional( b.sequence( EXPRESSION, SPC, diff --git a/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/StructExpressionTest.java b/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/StructExpressionTest.java index e9c1d2d4..5d8efabf 100644 --- a/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/StructExpressionTest.java +++ b/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/StructExpressionTest.java @@ -45,9 +45,8 @@ public void testStructExprTuple() { assertThat(RustGrammar.create().build().rule(RustGrammar.STRUCT_EXPR_TUPLE)) .matches("Vec::::with_capacity()") .matches("collect::>()") - .matches("some_fn::(#![inner])") + .matches("some_fn::()") .matches("some_fn::(Cookie)") - .matches("some_fn::(#![inner] Cookie)") ; } diff --git a/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/TupleExpressionTest.java b/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/TupleExpressionTest.java index 5d95bcde..0a3e26e8 100644 --- a/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/TupleExpressionTest.java +++ b/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/TupleExpressionTest.java @@ -41,7 +41,6 @@ public void testTupleElement() { @Test public void testTupleIndexingExpression() { -// assertThat(RustGrammar.create().build().rule(RustGrammar.TUPLE_INDEXING_EXPRESSION)) assertThat(RustGrammar.create().build().rule(RustGrammar.EXPRESSION)) .matches("point.1") .matches("self.0") diff --git a/community-rust-frontend/src/test/java/org/sonar/rust/parser/lexer/IdentifierTest.java b/community-rust-frontend/src/test/java/org/sonar/rust/parser/lexer/IdentifierTest.java index e1284c1b..826a8add 100644 --- a/community-rust-frontend/src/test/java/org/sonar/rust/parser/lexer/IdentifierTest.java +++ b/community-rust-frontend/src/test/java/org/sonar/rust/parser/lexer/IdentifierTest.java @@ -3,17 +3,17 @@ * Copyright (C) 2021 Eric Le Goff * mailto:community-rust AT pm DOT me * http://github.com/elegoff/sonar-rust - * + *

* This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + *

* You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. @@ -78,6 +78,11 @@ public void testIdentifier() { .matches("crate_type") .matches("await_token") .matches("if_ok") + .matches("foo") + .matches("_identifier") + .matches("r#true") + //.matches("Москва") + //.matches("東京") ; From 6ba5434c5376b3f0fdd6c236fe81e78f82f454a4 Mon Sep 17 00:00:00 2001 From: Eric Le Goff Date: Mon, 22 Nov 2021 08:46:17 +0100 Subject: [PATCH 08/18] wip identifiers --- .../main/java/org/sonar/rust/RustGrammar.java | 15 +++++++-- .../java/org/sonar/rust/RustLexerTest.java | 2 +- .../rust/parser/lexer/IdentifierTest.java | 31 ++++++++++++++++++- .../org/sonar/rust/parser/types/TypeTest.java | 1 + 4 files changed, 45 insertions(+), 4 deletions(-) diff --git a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java index cbab79f1..7533af7c 100644 --- a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java +++ b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java @@ -340,6 +340,8 @@ public enum RustGrammar implements GrammarRuleKey { private static final String IDFREGEXP1 = "[a-zA-Z][a-zA-Z0-9_]*"; private static final String IDFREGEXP2 = "_[a-zA-Z0-9_]+"; private static final String DOLLAR_CRATE_REGEX = "^\\$crate$"; + private static final String XID_START="[_\\p{L}\\p{Nl}]"; + private static final String XID_CONTINUE="[\\pL\\p{Nl}\\p{Mn}\\p{Mc}\\p{Nd}\\p{Pc}]"; public static LexerlessGrammarBuilder create() { @@ -2170,10 +2172,17 @@ private static void bytes(LexerlessGrammarBuilder b) { private static void identifiers(LexerlessGrammarBuilder b) { - b.rule(IDENTIFIER_OR_KEYWORD).is(b.firstOf(b.regexp("^" + IDFREGEXP1), b.regexp("^" + IDFREGEXP2))); + b.rule(IDENTIFIER_OR_KEYWORD).is(b.firstOf( + b.sequence(b.regexp(XID_START),b.zeroOrMore(b.regexp(XID_CONTINUE))), + b.sequence("_", b.oneOrMore(XID_CONTINUE)))); + b.rule(RAW_IDENTIFIER).is("r#", + b.nextNot("crate"), + b.nextNot("self"), + b.nextNot("super"), + b.nextNot("Self"), + IDENTIFIER_OR_KEYWORD); - b.rule(RAW_IDENTIFIER).is(b.firstOf(b.regexp("^r#" + IDFREGEXP1 + "(?::default()") .matches("Token![#]") + .matches("Self") From ad00cbcc1a9518b77d2f051e516295558b35e6bc Mon Sep 17 00:00:00 2001 From: Eric Le Goff Date: Mon, 22 Nov 2021 15:43:22 +0100 Subject: [PATCH 09/18] identifiers --- .../main/java/org/sonar/rust/RustGrammar.java | 26 ++++++++++------ .../java/org/sonar/rust/RustLexerTest.java | 6 +--- .../rust/parser/lexer/IdentifierTest.java | 31 +++++++++++++------ 3 files changed, 38 insertions(+), 25 deletions(-) diff --git a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java index 7533af7c..1d7b957b 100644 --- a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java +++ b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java @@ -337,11 +337,13 @@ public enum RustGrammar implements GrammarRuleKey { WHERE_CLAUSE_ITEM, WILDCARD_PATTERN; - private static final String IDFREGEXP1 = "[a-zA-Z][a-zA-Z0-9_]*"; - private static final String IDFREGEXP2 = "_[a-zA-Z0-9_]+"; + //private static final String IDFREGEXP1 = "[a-zA-Z][a-zA-Z0-9_]*"; + //private static final String IDFREGEXP2 = "_[a-zA-Z0-9_]+"; + + private static final String IDFREGEXP1 = "[_\\p{L}\\p{Nl}]*"; + private static final String IDFREGEXP2 = "[\\pL\\p{Nl}\\p{Mn}\\p{Mc}\\p{Nd}\\p{Pc}]+"; private static final String DOLLAR_CRATE_REGEX = "^\\$crate$"; - private static final String XID_START="[_\\p{L}\\p{Nl}]"; - private static final String XID_CONTINUE="[\\pL\\p{Nl}\\p{Mn}\\p{Mc}\\p{Nd}\\p{Pc}]"; + public static LexerlessGrammarBuilder create() { @@ -2172,6 +2174,9 @@ private static void bytes(LexerlessGrammarBuilder b) { private static void identifiers(LexerlessGrammarBuilder b) { + final String XID_START="[_\\p{L}\\p{Nl}]"; + final String XID_CONTINUE="[\\pL\\p{Nl}\\p{Mn}\\p{Mc}\\p{Nd}\\p{Pc}]"; + b.rule(IDENTIFIER_OR_KEYWORD).is(b.firstOf( b.sequence(b.regexp(XID_START),b.zeroOrMore(b.regexp(XID_CONTINUE))), b.sequence("_", b.oneOrMore(XID_CONTINUE)))); @@ -2183,16 +2188,17 @@ private static void identifiers(LexerlessGrammarBuilder b) { b.nextNot("Self"), IDENTIFIER_OR_KEYWORD); - - b.rule(NON_KEYWORD_IDENTIFIER).is(b.firstOf( - b.regexp("^" + IDFREGEXP1 + exceptKeywords()), - b.regexp("^" + IDFREGEXP2 + exceptKeywords()) - - ));//Except a strict or reserved keyword + b.regexp(XID_START+XID_CONTINUE+"*"+ exceptKeywords()), + b.regexp("^_"+XID_CONTINUE+"+"+ exceptKeywords()) + )); b.rule(IDENTIFIER).is(b.token(RustTokenType.IDENTIFIER, b.firstOf(RAW_IDENTIFIER, NON_KEYWORD_IDENTIFIER))).skip(); + + + + } private static String exceptKeywords() { diff --git a/community-rust-frontend/src/test/java/org/sonar/rust/RustLexerTest.java b/community-rust-frontend/src/test/java/org/sonar/rust/RustLexerTest.java index 32895c54..ca336869 100644 --- a/community-rust-frontend/src/test/java/org/sonar/rust/RustLexerTest.java +++ b/community-rust-frontend/src/test/java/org/sonar/rust/RustLexerTest.java @@ -68,11 +68,7 @@ public void testTokens() { @Test public void testParsing() { - - - String sexpr = "const foo : Circle;"; - - + String sexpr = "const foo : Self;"; //Print out Ast node content for debugging purpose diff --git a/community-rust-frontend/src/test/java/org/sonar/rust/parser/lexer/IdentifierTest.java b/community-rust-frontend/src/test/java/org/sonar/rust/parser/lexer/IdentifierTest.java index a1836a73..9a2fc63a 100644 --- a/community-rust-frontend/src/test/java/org/sonar/rust/parser/lexer/IdentifierTest.java +++ b/community-rust-frontend/src/test/java/org/sonar/rust/parser/lexer/IdentifierTest.java @@ -35,28 +35,38 @@ public void checkRawIdentifier() { .matches("r#_52") .matches("r#V123") .notMatches("s#52") - //corner cases + .matches("r#東京") + //corner cases using keywords .notMatches("r#crate") .notMatches("r#self") .notMatches("r#super") .notMatches("r#Self"); + } @Test public void testNonKeywords() { Assertions.assertThat(RustGrammar.create().build().rule(RustGrammar.NON_KEYWORD_IDENTIFIER)) - .notMatches("trait") //keyword - .notMatches("Self") //keyword .matches("a") .matches("bc") .matches("Abc") - .notMatches("as") - .matches("prefix_trait") - .matches("traitsuffix") - .matches("foo_bar") - .notMatches("a b") - .notMatches("a self") - .matches("_context") + .notMatches("as") //keyword + .notMatches("trait") //keyword + .notMatches("super") //keyword + .notMatches("foo ") + .notMatches("r#") + .notMatches("r#a") + .notMatches("r#_52") + .notMatches("r#V123") + .matches("phenotype") + .matches("crate_type") + .matches("await_token") + .matches("fnas") //concatenated keywords + .matches("if_ok") + .matches("foo") + .matches("_identifier") + .matches("Москва") + .matches("東京") ; } @@ -103,6 +113,7 @@ public void testIdentifier() { .matches("r#_52") .matches("r#V123") .notMatches("s#52") + .matches("traitsuffix") .matches("phenotype") .matches("crate_type") .matches("await_token") From e2904d04d17e1a34d86862ef857b976a2cd90c7f Mon Sep 17 00:00:00 2001 From: Eric Le Goff Date: Mon, 22 Nov 2021 16:41:04 +0100 Subject: [PATCH 10/18] functions --- .../main/java/org/sonar/rust/RustGrammar.java | 88 +++++++++---------- .../sonar/rust/parser/items/StaticTest.java | 1 + 2 files changed, 42 insertions(+), 47 deletions(-) diff --git a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java index 1d7b957b..8a5dad11 100644 --- a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java +++ b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java @@ -3,17 +3,17 @@ * Copyright (C) 2021 Eric Le Goff * mailto:community-rust AT pm DOT me * http://github.com/elegoff/sonar-rust - * + *

* This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + *

* You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. @@ -44,6 +44,7 @@ public enum RustGrammar implements GrammarRuleKey { ASCII_FOR_CHAR, ASCII_FOR_STRING, ASSIGNMENT_EXPRESSION, + ASSOCIATED_ITEM, ASYNC_BLOCK_EXPRESSION, AS_CLAUSE, ATTR, @@ -140,7 +141,6 @@ public enum RustGrammar implements GrammarRuleKey { INFERRED_TYPE, INFINITE_LOOP_EXPRESSION, INHERENT_IMPL, - ASSOCIATED_ITEM, INNER_ATTRIBUTE, INNER_BLOCK_DOC, INNER_LINE_DOC, @@ -345,7 +345,6 @@ public enum RustGrammar implements GrammarRuleKey { private static final String DOLLAR_CRATE_REGEX = "^\\$crate$"; - public static LexerlessGrammarBuilder create() { LexerlessGrammarBuilder b = LexerlessGrammarBuilder.create(); @@ -632,16 +631,14 @@ private static void functionsItem(LexerlessGrammarBuilder b) { b.optional(RustKeyword.KW_CONST, SPC), b.optional(RustKeyword.KW_ASYNC, SPC), b.optional(RustKeyword.KW_UNSAFE, SPC), - - b.optional(RustKeyword.KW_EXTERN, SPC, b.optional(ABI)) ); b.rule(ABI).is(b.firstOf(RAW_STRING_LITERAL, STRING_LITERAL)); b.rule(FUNCTION_PARAMETERS).is( - b.firstOf(b.sequence(SELF_PARAM, b.optional(RustPunctuator.COMMA), SPC, b.optional(seq(b, FUNCTION_PARAM, RustPunctuator.COMMA))), + b.firstOf(b.sequence(SELF_PARAM, b.optional(RustPunctuator.COMMA), SPC, + b.optional(seq(b, FUNCTION_PARAM, RustPunctuator.COMMA))), seq(b, FUNCTION_PARAM, RustPunctuator.COMMA) - )); @@ -649,10 +646,25 @@ private static void functionsItem(LexerlessGrammarBuilder b) { b.zeroOrMore(OUTER_ATTRIBUTE), SPC, b.firstOf(FUNCTION_PARAM_PATTERN, RustPunctuator.DOTDOTDOT, TYPE)); - b.rule(FUNCTION_PARAM_PATTERN).is(PATTERN, SPC, RustPunctuator.COLON, SPC, b.firstOf(TYPE, RustPunctuator.DOTDOTDOT)); + b.rule(FUNCTION_PARAM_PATTERN).is(PATTERN_NO_TOP_ALT, SPC, RustPunctuator.COLON, + SPC, b.firstOf(TYPE, RustPunctuator.DOTDOTDOT)); b.rule(FUNCTION_RETURN_TYPE).is(RustPunctuator.RARROW, SPC, TYPE); + b.rule(SELF_PARAM).is(b.zeroOrMore(OUTER_ATTRIBUTE, SPC), b.firstOf( + TYPED_SELF, SHORTHAND_SELF + )); + + + b.rule(SHORTHAND_SELF).is( + b.optional(b.firstOf(b.sequence(RustPunctuator.AND, LIFETIME, SPC), RustPunctuator.AND)), + b.optional(RustKeyword.KW_MUT, SPC), RustKeyword.KW_SELFVALUE + ); + + + b.rule(TYPED_SELF).is(b.optional(RustKeyword.KW_MUT, SPC), RustKeyword.KW_SELFVALUE, SPC, + RustPunctuator.COLON, SPC, TYPE); + } /* https://doc.rust-lang.org/reference/items/structs.html */ @@ -706,8 +718,7 @@ private static void constantsItem(LexerlessGrammarBuilder b) { private static void staticItem(LexerlessGrammarBuilder b) { b.rule(STATIC_ITEM).is( RustKeyword.KW_STATIC, SPC, b.optional(RustKeyword.KW_MUT, SPC), IDENTIFIER, - SPC, RustPunctuator.COLON, SPC, TYPE, SPC, b.optional(RustPunctuator.EQ, SPC, - EXPRESSION, SPC), RustPunctuator.SEMI + SPC, RustPunctuator.COLON, SPC, TYPE, SPC, b.optional(RustPunctuator.EQ, SPC, EXPRESSION, SPC), RustPunctuator.SEMI ); } @@ -805,19 +816,6 @@ private static void assocItem(LexerlessGrammarBuilder b) { TYPE_ALIAS, CONSTANT_ITEM, FUNCTION )))); - b.rule(SELF_PARAM).is(b.zeroOrMore(OUTER_ATTRIBUTE, SPC), b.firstOf( - TYPED_SELF, SHORTHAND_SELF - )); - - - b.rule(SHORTHAND_SELF).is( - b.optional(b.firstOf(b.sequence(RustPunctuator.AND, LIFETIME, SPC), RustPunctuator.AND)), - b.optional(RustKeyword.KW_MUT, SPC), RustKeyword.KW_SELFVALUE - ); - - - b.rule(TYPED_SELF).is(b.optional(RustKeyword.KW_MUT, SPC), RustKeyword.KW_SELFVALUE, SPC, - RustPunctuator.COLON, SPC, TYPE); } @@ -996,7 +994,7 @@ private static void patterns(LexerlessGrammarBuilder b) { b.sequence(b.optional(RustPunctuator.PATHSEP), //PATH_EXPR_SEGMENT, b.sequence(b.firstOf( - b.sequence(RustKeyword.KW_SUPER,b.nextNot(IDENTIFIER)), + b.sequence(RustKeyword.KW_SUPER, b.nextNot(IDENTIFIER)), b.regexp("^[sS]elf$"), RustKeyword.KW_CRATE, b.regexp(DOLLAR_CRATE_REGEX), IDENTIFIER ) , b.optional(b.sequence(RustPunctuator.PATHSEP, GENERIC_ARGS))), @@ -1276,7 +1274,7 @@ public static void expressions(LexerlessGrammarBuilder b) { b.sequence(RustPunctuator.DOTDOT, b.nextNot(RustPunctuator.EQ), b.endOfInput()), b.sequence(RustPunctuator.DOTDOTEQ, EXPRESSION), b.sequence(RustPunctuator.DOTDOT, b.nextNot(RustPunctuator.EQ), b.optional(EXPRESSION)), - b.sequence(RustPunctuator.DOT, RustKeyword.KW_AWAIT,b.nextNot(IDENTIFIER), SPC, EXPRESSION_TERM), + b.sequence(RustPunctuator.DOT, RustKeyword.KW_AWAIT, b.nextNot(IDENTIFIER), SPC, EXPRESSION_TERM), b.sequence(RustPunctuator.DOT, PATH_EXPR_SEGMENT, SPC, "(", SPC, b.optional(CALL_PARAMS, SPC), ")", SPC, EXPRESSION_TERM), b.sequence(RustPunctuator.DOT, TUPLE_INDEX, SPC, EXPRESSION_TERM), b.sequence(RustPunctuator.DOT, IDENTIFIER, SPC, EXPRESSION_TERM), @@ -1482,7 +1480,7 @@ private static void returnExpr(LexerlessGrammarBuilder b) { private static void match(LexerlessGrammarBuilder b) { b.rule(MATCH_EXPRESSION).is( RustKeyword.KW_MATCH, SPC, - b.optional( RustKeyword.KW_MATCH, b.next(IDENTIFIER)), + b.optional(RustKeyword.KW_MATCH, b.next(IDENTIFIER)), SCRUTINEE, SPC, "{", SPC, b.zeroOrMore(INNER_ATTRIBUTE, SPC), @@ -1511,7 +1509,7 @@ private static void match(LexerlessGrammarBuilder b) { private static void ifExpr(LexerlessGrammarBuilder b) { b.rule(IF_EXPRESSION).is( RustKeyword.KW_IF, SPC, - b.optional( RustKeyword.KW_IF,b.next(IDENTIFIER)), + b.optional(RustKeyword.KW_IF, b.next(IDENTIFIER)), SCRUTINEE, b.next(SPC, "{") , SPC, BLOCK_EXPRESSION, SPC, b.optional( @@ -1592,7 +1590,6 @@ private static void call(LexerlessGrammarBuilder b) { } - private static void tuple(LexerlessGrammarBuilder b) { b.rule(TUPLE_EXPRESSION).is("(", SPC, b.optional(TUPLE_ELEMENT), SPC, ")"); @@ -1604,7 +1601,7 @@ private static void tuple(LexerlessGrammarBuilder b) { } private static void array(LexerlessGrammarBuilder b) { - b.rule(ARRAY_EXPRESSION).is("[", SPC, b.optional(ARRAY_ELEMENTS, SPC), SPC,"]"); + b.rule(ARRAY_EXPRESSION).is("[", SPC, b.optional(ARRAY_ELEMENTS, SPC), SPC, "]"); b.rule(ARRAY_ELEMENTS).is(b.firstOf( b.sequence(SPC, EXPRESSION, SPC, RustPunctuator.SEMI, SPC, EXPRESSION), @@ -1865,18 +1862,18 @@ public static void attributes(LexerlessGrammarBuilder b) { b.rule(OUTER_ATTRIBUTE).is("#[", SPC, ATTR, SPC, "]"); b.rule(ATTR).is(SIMPLE_PATH, SPC, b.optional(ATTR_INPUT, SPC)); b.rule(ATTR_INPUT).is(b.firstOf(DELIM_TOKEN_TREE, - b.sequence(RustPunctuator.EQ, SPC,EXPRESSION))); + b.sequence(RustPunctuator.EQ, SPC, EXPRESSION))); b.rule(META_ITEM).is(b.firstOf( b.sequence(SIMPLE_PATH, SPC, RustPunctuator.EQ, SPC, EXPRESSION), b.sequence(SIMPLE_PATH, SPC, "(", SPC, META_SEQ, SPC, ")"), SIMPLE_PATH)); - b.rule(META_SEQ).is(seq(b,META_ITEM_INNER, RustPunctuator.COMMA)); + b.rule(META_SEQ).is(seq(b, META_ITEM_INNER, RustPunctuator.COMMA)); b.rule(META_ITEM_INNER).is(b.firstOf(META_ITEM, EXPRESSION)); b.rule(META_WORD).is(IDENTIFIER); b.rule(META_NAME_VALUE_STR).is(IDENTIFIER, SPC, RustPunctuator.EQ, SPC, b.firstOf(STRING_LITERAL, RAW_STRING_LITERAL)); - b.rule(META_LIST_PATHS).is(IDENTIFIER, "(", b.optional(seq(b,SIMPLE_PATH, RustPunctuator.COMMA)), ")"); - b.rule(META_LIST_IDENTS).is(IDENTIFIER, "(", b.optional(seq(b,IDENTIFIER, RustPunctuator.COMMA)), ")"); - b.rule(META_LIST_NAME_VALUE_STR).is(IDENTIFIER, "(", b.optional(seq(b,META_NAME_VALUE_STR, RustPunctuator.COMMA)), ")"); + b.rule(META_LIST_PATHS).is(IDENTIFIER, "(", b.optional(seq(b, SIMPLE_PATH, RustPunctuator.COMMA)), ")"); + b.rule(META_LIST_IDENTS).is(IDENTIFIER, "(", b.optional(seq(b, IDENTIFIER, RustPunctuator.COMMA)), ")"); + b.rule(META_LIST_NAME_VALUE_STR).is(IDENTIFIER, "(", b.optional(seq(b, META_NAME_VALUE_STR, RustPunctuator.COMMA)), ")"); } @@ -1917,7 +1914,6 @@ public static void type(LexerlessGrammarBuilder b) { QUALIFIED_PATH_IN_TYPE - )); b.rule(TYPE_NO_BOUNDS).is(b.firstOf( MACRO_INVOCATION, @@ -1992,7 +1988,7 @@ public static void lexicalpath(LexerlessGrammarBuilder b) { b.zeroOrMore(b.sequence(RustPunctuator.PATHSEP, SIMPLE_PATH_SEGMENT)) ); b.rule(SIMPLE_PATH_SEGMENT).is(b.firstOf( - b.sequence(RustKeyword.KW_SUPER,b.nextNot(IDENTIFIER)), + b.sequence(RustKeyword.KW_SUPER, b.nextNot(IDENTIFIER)), RustKeyword.KW_SELFVALUE, b.regexp("^crate$"), b.regexp(DOLLAR_CRATE_REGEX), IDENTIFIER )); @@ -2007,7 +2003,7 @@ public static void lexicalpath(LexerlessGrammarBuilder b) { ); b.rule(PATH_IDENT_SEGMENT).is(b.firstOf( - b.sequence(RustKeyword.KW_SUPER,b.nextNot(IDENTIFIER)), + b.sequence(RustKeyword.KW_SUPER, b.nextNot(IDENTIFIER)), b.regexp("^[sS]elf$"), RustKeyword.KW_CRATE, b.regexp(DOLLAR_CRATE_REGEX), @@ -2046,7 +2042,7 @@ public static void lexicalpath(LexerlessGrammarBuilder b) { QUALIFIED_PATH_TYPE, b.oneOrMore(b.sequence(RustPunctuator.PATHSEP, PATH_EXPR_SEGMENT))); b.rule(QUALIFIED_PATH_TYPE).is( - RustPunctuator.LT, SPC, TYPE, b.optional(SPC, RustKeyword.KW_AS, SPC, TYPE_PATH),SPC, RustPunctuator.GT + RustPunctuator.LT, SPC, TYPE, b.optional(SPC, RustKeyword.KW_AS, SPC, TYPE_PATH), SPC, RustPunctuator.GT ); b.rule(QUALIFIED_PATH_IN_TYPE).is(QUALIFIED_PATH_TYPE, b.oneOrMore( @@ -2174,11 +2170,11 @@ private static void bytes(LexerlessGrammarBuilder b) { private static void identifiers(LexerlessGrammarBuilder b) { - final String XID_START="[_\\p{L}\\p{Nl}]"; - final String XID_CONTINUE="[\\pL\\p{Nl}\\p{Mn}\\p{Mc}\\p{Nd}\\p{Pc}]"; + final String XID_START = "[_\\p{L}\\p{Nl}]"; + final String XID_CONTINUE = "[\\pL\\p{Nl}\\p{Mn}\\p{Mc}\\p{Nd}\\p{Pc}]"; b.rule(IDENTIFIER_OR_KEYWORD).is(b.firstOf( - b.sequence(b.regexp(XID_START),b.zeroOrMore(b.regexp(XID_CONTINUE))), + b.sequence(b.regexp(XID_START), b.zeroOrMore(b.regexp(XID_CONTINUE))), b.sequence("_", b.oneOrMore(XID_CONTINUE)))); b.rule(RAW_IDENTIFIER).is("r#", @@ -2189,16 +2185,14 @@ private static void identifiers(LexerlessGrammarBuilder b) { IDENTIFIER_OR_KEYWORD); b.rule(NON_KEYWORD_IDENTIFIER).is(b.firstOf( - b.regexp(XID_START+XID_CONTINUE+"*"+ exceptKeywords()), - b.regexp("^_"+XID_CONTINUE+"+"+ exceptKeywords()) + b.regexp(XID_START + XID_CONTINUE + "*" + exceptKeywords()), + b.regexp("^_" + XID_CONTINUE + "+" + exceptKeywords()) )); b.rule(IDENTIFIER).is(b.token(RustTokenType.IDENTIFIER, b.firstOf(RAW_IDENTIFIER, NON_KEYWORD_IDENTIFIER))).skip(); - - } private static String exceptKeywords() { diff --git a/community-rust-frontend/src/test/java/org/sonar/rust/parser/items/StaticTest.java b/community-rust-frontend/src/test/java/org/sonar/rust/parser/items/StaticTest.java index 1d7f054f..e6dde6d8 100644 --- a/community-rust-frontend/src/test/java/org/sonar/rust/parser/items/StaticTest.java +++ b/community-rust-frontend/src/test/java/org/sonar/rust/parser/items/StaticTest.java @@ -30,6 +30,7 @@ public class StaticTest { public void testStatic() { assertThat(RustGrammar.create().build().rule(RustGrammar.STATIC_ITEM)) .matches("static mut LEVELS: u32 = 0;") + .matches("static mut LEVELS: u32;") ; From fbbf52746b0f7fdc8f77bbf330edbbbbfce7b11e Mon Sep 17 00:00:00 2001 From: Eric Le Goff Date: Mon, 22 Nov 2021 17:42:02 +0100 Subject: [PATCH 11/18] generic params --- .../main/java/org/sonar/rust/RustGrammar.java | 18 +++-------- .../sonar/rust/parser/RustGrammarTest.java | 4 +-- .../sonar/rust/parser/items/LifeTimeTest.java | 31 ------------------- 3 files changed, 6 insertions(+), 47 deletions(-) diff --git a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java index 8a5dad11..cd2f57c5 100644 --- a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java +++ b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java @@ -159,7 +159,6 @@ public enum RustGrammar implements GrammarRuleKey { LIFETIME_BOUNDS, LIFETIME_OR_LABEL, LIFETIME_PARAM, - LIFETIME_PARAMS, LIFETIME_TOKEN, LIFETIME_WHERE_CLAUSE_ITEM, LINE_COMMENT, @@ -318,7 +317,6 @@ public enum RustGrammar implements GrammarRuleKey { TYPE_CAST_EXPRESSION, TYPE_NO_BOUNDS, TYPE_PARAM, - TYPE_PARAMS, TYPE_PARAM_BOUND, TYPE_PARAM_BOUNDS, TYPE_PATH, @@ -771,18 +769,12 @@ private static void genericItem(LexerlessGrammarBuilder b) { )); - b.rule(GENERIC_PARAM).is(b.zeroOrMore(OUTER_ATTRIBUTE, SPC), b.firstOf(LIFETIME_PARAM, CONST_PARAM, TYPE_PARAM) + b.rule(GENERIC_PARAM).is(b.zeroOrMore(OUTER_ATTRIBUTE, SPC), + b.firstOf(LIFETIME_PARAM, CONST_PARAM, TYPE_PARAM) ); - - b.rule(LIFETIME_PARAMS).is( - b.zeroOrMore(LIFETIME_PARAM, SPC, RustPunctuator.COMMA, SPC), b.optional(LIFETIME_PARAM, SPC) - ); - b.rule(LIFETIME_PARAM).is( - b.optional(OUTER_ATTRIBUTE, SPC), LIFETIME_OR_LABEL, SPC, b.optional(RustPunctuator.COLON, LIFETIME_BOUNDS, SPC) - ); - b.rule(TYPE_PARAMS).is( - b.zeroOrMore(TYPE_PARAM, SPC, RustPunctuator.COMMA, SPC), b.optional(TYPE_PARAM, SPC) + b.rule(LIFETIME_PARAM).is(LIFETIME_OR_LABEL, SPC, + b.optional(RustPunctuator.COLON, SPC, LIFETIME_BOUNDS, SPC) ); b.rule(TYPE_PARAM).is( b.optional(OUTER_ATTRIBUTE, SPC), NON_KEYWORD_IDENTIFIER, SPC, @@ -802,7 +794,7 @@ private static void genericItem(LexerlessGrammarBuilder b) { b.optional(FOR_LIFETIMES), TYPE, RustPunctuator.COLON, b.optional(TYPE_PARAM_BOUNDS) ); - b.rule(FOR_LIFETIMES).is(RustKeyword.KW_FOR, SPC, RustPunctuator.LT, SPC, LIFETIME_PARAMS, SPC, RustPunctuator.GT); + b.rule(FOR_LIFETIMES).is(RustKeyword.KW_FOR, SPC, GENERIC_PARAMS); } diff --git a/community-rust-frontend/src/test/java/org/sonar/rust/parser/RustGrammarTest.java b/community-rust-frontend/src/test/java/org/sonar/rust/parser/RustGrammarTest.java index b0c23765..961da591 100644 --- a/community-rust-frontend/src/test/java/org/sonar/rust/parser/RustGrammarTest.java +++ b/community-rust-frontend/src/test/java/org/sonar/rust/parser/RustGrammarTest.java @@ -42,9 +42,7 @@ public void matchingEmpty() { RustGrammar.EOF, RustGrammar.FUNCTION_QUALIFIERS, RustGrammar.LIFETIME_BOUNDS, - RustGrammar.LIFETIME_PARAMS, - RustGrammar.SPC, - RustGrammar.TYPE_PARAMS + RustGrammar.SPC )); for (RustGrammar r : rustGrammars) { diff --git a/community-rust-frontend/src/test/java/org/sonar/rust/parser/items/LifeTimeTest.java b/community-rust-frontend/src/test/java/org/sonar/rust/parser/items/LifeTimeTest.java index f8206efc..9a1019d4 100644 --- a/community-rust-frontend/src/test/java/org/sonar/rust/parser/items/LifeTimeTest.java +++ b/community-rust-frontend/src/test/java/org/sonar/rust/parser/items/LifeTimeTest.java @@ -195,18 +195,6 @@ public void testConstParam(){ ; } - @Test - public void testTypeParams(){ - assertThat(RustGrammar.create().build().rule(RustGrammar.TYPE_PARAMS)) - .matches("") - .matches("AAA") - .matches("AAA,BBB,CCC") - .matches("#[test] AAA") - .matches("#[test] AAA, BBB") - .matches("#[test] AAA : i32, BBB : f64, CCC : bool") - .matches("T") - ; - } @Test public void testLifetimeParam(){ @@ -220,28 +208,9 @@ public void testLifetimeParam(){ .notMatches("<'as") .notMatches("<'as>") .notMatches("'trait>") - .matches("#[outer]'ABC") ; } - @Test - public void testLifetimeParams(){ - assertThat(RustGrammar.create().build().rule(RustGrammar.LIFETIME_PARAMS)) - .matches("'a") - .matches("'a,'b") - .matches("'de") - .matches("'ABC") - .matches("'ABC , 'DEF") - .notMatches("'trait") - .notMatches("'as") - .notMatches("'as>") - .notMatches("<'as") - .notMatches("<'as>") - .matches("#[outer]'ABC") - ; - } - - @Test public void testLifetimeBounds(){ assertThat(RustGrammar.create().build().rule(RustGrammar.LIFETIME_BOUNDS)) From c2a9ec20f5ca39e8bdc5aaaf78aad3847dda2a09 Mon Sep 17 00:00:00 2001 From: Eric Le Goff Date: Mon, 22 Nov 2021 17:51:21 +0100 Subject: [PATCH 12/18] implementations --- .../src/main/java/org/sonar/rust/RustGrammar.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java index cd2f57c5..d8bebb62 100644 --- a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java +++ b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java @@ -726,16 +726,16 @@ private static void implItem(LexerlessGrammarBuilder b) { b.rule(INHERENT_IMPL).is( RustKeyword.KW_IMPL, SPC, b.optional(GENERIC_PARAMS, SPC), TYPE, SPC, b.optional(WHERE_CLAUSE, SPC), "{", SPC, - b.zeroOrMore(b.firstOf(INNER_ATTRIBUTE, OUTER_ATTRIBUTE), SPC), + b.zeroOrMore(INNER_ATTRIBUTE, SPC), b.zeroOrMore(ASSOCIATED_ITEM, SPC), "}" ); - b.rule(TRAIT_IMPL).is( - b.optional(RustKeyword.KW_UNSAFE, SPC), RustKeyword.KW_IMPL, SPC, b.optional(GENERIC_PARAMS, SPC), - b.optional(RustPunctuator.NOT), TYPE_PATH, SPC, RustKeyword.KW_FOR, SPC, TYPE, SPC, + b.optional(RustKeyword.KW_UNSAFE, SPC), RustKeyword.KW_IMPL, SPC, + b.optional(GENERIC_PARAMS, SPC), + b.optional(RustPunctuator.NOT,SPC), TYPE_PATH, SPC, RustKeyword.KW_FOR, SPC, TYPE, SPC, b.optional(WHERE_CLAUSE, SPC), "{", SPC, - b.zeroOrMore(b.firstOf(INNER_ATTRIBUTE, OUTER_ATTRIBUTE), SPC), + b.zeroOrMore(INNER_ATTRIBUTE, SPC), b.zeroOrMore(ASSOCIATED_ITEM, SPC), "}" ); From c2edcad14876b12ae6eb4a803a88aa79a7da0048 Mon Sep 17 00:00:00 2001 From: Eric Le Goff Date: Tue, 23 Nov 2021 14:40:36 +0100 Subject: [PATCH 13/18] range patterns --- .../main/java/org/sonar/rust/RustGrammar.java | 25 ++++++--------- .../sonar/rust/parser/macro/MacroTest.java | 31 ++++++++++++------- .../rust/parser/patterns/PatternTest.java | 23 +++++++++----- 3 files changed, 44 insertions(+), 35 deletions(-) diff --git a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java index d8bebb62..57c11122 100644 --- a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java +++ b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java @@ -127,6 +127,7 @@ public enum RustGrammar implements GrammarRuleKey { GROUPED_EXPRESSION, GROUPED_PATTERN, GT_EXPRESSION, + HALF_OPEN_RANGE_PATTERN, HEX_DIGIT, HEX_LITERAL, IDENTIFIER, @@ -137,6 +138,7 @@ public enum RustGrammar implements GrammarRuleKey { IMPLEMENTATION, IMPL_TRAIT_TYPE, IMPL_TRAIT_TYPE_ONE_BOUND, + INCLUSIVE_RANGE_PATTERN, INDEX_EXPRESSION, INFERRED_TYPE, INFINITE_LOOP_EXPRESSION, @@ -594,10 +596,10 @@ private static void aliasItem(LexerlessGrammarBuilder b) { b.rule(TYPE_ALIAS).is( - RustKeyword.KW_TYPE, SPC, IDENTIFIER, SPC, b.optional(GENERIC_PARAMS), SPC, + RustKeyword.KW_TYPE, SPC, IDENTIFIER, SPC, b.optional(GENERIC_PARAMS, SPC), + b.optional(RustPunctuator.COLON, SPC, TYPE_PARAM_BOUNDS, SPC), b.optional(WHERE_CLAUSE, SPC), b.optional(RustPunctuator.EQ, SPC, TYPE, SPC), - b.optional(RustPunctuator.COLON, b.optional(SPC, TYPE_PARAM_BOUNDS, SPC)), RustPunctuator.SEMI ); } @@ -913,7 +915,7 @@ private static void macrosByExample(LexerlessGrammarBuilder b) { LIFETIMES, PUNCTUATION_EXCEPT_DOLLAR)); b.rule(MACRO_FRAG_SPEC).is(b.firstOf( "block", "expr", "ident", "item", "lifetime", "literal" - , "meta", "path", "pat", "stmt", "tt", "ty", "vis" + , "meta", "path", "pat_param", "pat", "stmt", "tt", "ty", "vis" )); b.rule(MACRO_REP_SEP).is(b.firstOf(LITERALS, IDENTIFIER_OR_KEYWORD, LIFETIMES, @@ -974,13 +976,10 @@ private static void patterns(LexerlessGrammarBuilder b) { b.zeroOrMore(b.sequence(RustPunctuator.OR, SPC, PATTERN_NO_TOP_ALT, SPC)) ); b.rule(PATTERN_NO_TOP_ALT).is(b.firstOf( - RANGE_PATTERN, TUPLE_STRUCT_PATTERN, STRUCT_PATTERN, MACRO_INVOCATION, - - //unambigous PATH_PATTERN, b.firstOf( b.sequence(b.optional(RustPunctuator.PATHSEP), @@ -992,7 +991,6 @@ private static void patterns(LexerlessGrammarBuilder b) { , b.optional(b.sequence(RustPunctuator.PATHSEP, GENERIC_ARGS))), b.oneOrMore(b.sequence(RustPunctuator.PATHSEP, PATH_EXPR_SEGMENT))) , QUALIFIED_PATH_IN_EXPRESSION), - BYTE_LITERAL, RAW_STRING_LITERAL, BYTE_STRING_LITERAL, @@ -1000,22 +998,15 @@ private static void patterns(LexerlessGrammarBuilder b) { IDENTIFIER_PATTERN, BOOLEAN_LITERAL, CHAR_LITERAL, - STRING_LITERAL, - b.sequence(b.optional("-"), INTEGER_LITERAL, b.nextNot(RustPunctuator.DOTDOT)), b.sequence(b.optional("-"), FLOAT_LITERAL), - WILDCARD_PATTERN, REST_PATTERN, - OBSOLETE_RANGE_PATTERN, REFERENCE_PATTERN, - TUPLE_PATTERN, GROUPED_PATTERN, SLICE_PATTERN - - )); b.rule(LITERAL_PATTERN).is(b.firstOf( BOOLEAN_LITERAL, @@ -1038,8 +1029,10 @@ private static void patterns(LexerlessGrammarBuilder b) { b.rule(WILDCARD_PATTERN).is(RustPunctuator.UNDERSCORE); b.rule(REST_PATTERN).is(RustPunctuator.DOTDOT); - b.rule(OBSOLETE_RANGE_PATTERN).is(b.sequence(RANGE_PATTERN_BOUND, RustPunctuator.DOTDOTDOT, RANGE_PATTERN_BOUND)); - b.rule(RANGE_PATTERN).is(b.sequence(RANGE_PATTERN_BOUND, RustPunctuator.DOTDOTEQ, RANGE_PATTERN_BOUND)); + b.rule(RANGE_PATTERN).is(b.firstOf(OBSOLETE_RANGE_PATTERN,INCLUSIVE_RANGE_PATTERN, HALF_OPEN_RANGE_PATTERN )); + b.rule(INCLUSIVE_RANGE_PATTERN).is(b.sequence(RANGE_PATTERN_BOUND, RustPunctuator.DOTDOTEQ, RANGE_PATTERN_BOUND)); + b.rule(HALF_OPEN_RANGE_PATTERN).is(b.sequence(RANGE_PATTERN_BOUND, RustPunctuator.DOTDOT)); + b.rule(OBSOLETE_RANGE_PATTERN).is(b.sequence(RANGE_PATTERN_BOUND, RustPunctuator.DOTDOTDOT ,RANGE_PATTERN_BOUND)); b.rule(RANGE_PATTERN_BOUND).is(b.firstOf( CHAR_LITERAL, BYTE_LITERAL, b.sequence(b.optional("-"), INTEGER_LITERAL), b.sequence(b.optional("-"), FLOAT_LITERAL), diff --git a/community-rust-frontend/src/test/java/org/sonar/rust/parser/macro/MacroTest.java b/community-rust-frontend/src/test/java/org/sonar/rust/parser/macro/MacroTest.java index 8b2f9bb4..dba6baaf 100644 --- a/community-rust-frontend/src/test/java/org/sonar/rust/parser/macro/MacroTest.java +++ b/community-rust-frontend/src/test/java/org/sonar/rust/parser/macro/MacroTest.java @@ -3,17 +3,17 @@ * Copyright (C) 2021 Eric Le Goff * mailto:community-rust AT pm DOT me * http://github.com/elegoff/sonar-rust - * + *

* This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + *

* You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. @@ -100,10 +100,19 @@ public void testMacroInvocation() { public void testMacroFragSpec() { assertThat(RustGrammar.create().build().rule(RustGrammar.MACRO_FRAG_SPEC)) .matches("block") - .matches("expr") .matches("ident") .matches("item") .matches("lifetime") + .matches("expr") + .matches("ident") + .matches("item") + .matches("lifetime") .matches("literal") - .matches("meta") .matches("pat").matches("path") .matches("stmt") - .matches("tt") .matches("ty").matches("vis") + .matches("meta") + .matches("path") + .matches("pat") + .matches("pat_param") + .matches("stmt") + .matches("tt") + .matches("ty") + .matches("vis") ; } @@ -119,7 +128,6 @@ public void testRepOp() { .notMatches("+a+") - ; } @@ -138,7 +146,7 @@ public void testMacroMatch() { .matches("($($i:ident)*)") .matches("$($key:expr => $value:expr)+") .matches("$($key:expr => $value:expr),+") - ; + ; } @Test @@ -159,14 +167,14 @@ public void testMacroMatcher() { .matches("{ $($key:expr => $value:expr)+ }") .matches("{ $($key:expr => $value:expr),+ }") .matches("($($f:ident $(< $($generic:ty),* > )? )::+($($arg:ty),*): Send & Sync)") - ; + ; } @Test public void testMacroRules() { assertThat(RustGrammar.create().build().rule(RustGrammar.MACRO_RULES)) - .matches("($l:tt) => { bar!($l); }" ) + .matches("($l:tt) => { bar!($l); }") .matches("($($name:ident($ty:ty, $to:ident, $lt:lifetime);)*) => {\n" + " $(fn $name(self, v: $ty) -> JsResult<$lt> {\n" + " self.$to(v as _)\n" + @@ -188,7 +196,7 @@ public void testMacroRules() { @Test public void testMacroRulesDef() { assertThat(RustGrammar.create().build().rule(RustGrammar.MACRO_RULES_DEF)) - .matches("{($l:tt) => { bar!($l); }}" ) + .matches("{($l:tt) => { bar!($l); }}") .matches("{($($name:ident($ty:ty, $to:ident, $lt:lifetime);)*) => {\n" + " $(fn $name(self, v: $ty) -> JsResult<$lt> {\n" + " self.$to(v as _)\n" + @@ -266,5 +274,4 @@ public void testMacroRulesDefinition() { } - } diff --git a/community-rust-frontend/src/test/java/org/sonar/rust/parser/patterns/PatternTest.java b/community-rust-frontend/src/test/java/org/sonar/rust/parser/patterns/PatternTest.java index 87eec915..83c2a199 100644 --- a/community-rust-frontend/src/test/java/org/sonar/rust/parser/patterns/PatternTest.java +++ b/community-rust-frontend/src/test/java/org/sonar/rust/parser/patterns/PatternTest.java @@ -84,23 +84,33 @@ public void testRangePatternBound() { } @Test - public void testRangePattern() { - assertThat(RustGrammar.create().build().rule(RustGrammar.RANGE_PATTERN)) + public void testInclusiveRangePattern() { + assertThat(RustGrammar.create().build().rule(RustGrammar.INCLUSIVE_RANGE_PATTERN)) .matches("1..=9") - - ; + } + @Test + public void testHalfOpenRangePattern() { + assertThat(RustGrammar.create().build().rule(RustGrammar.HALF_OPEN_RANGE_PATTERN)) + .matches("1..") + ; } @Test public void testObsoleteRangePattern() { assertThat(RustGrammar.create().build().rule(RustGrammar.OBSOLETE_RANGE_PATTERN)) .matches("1...9") - - ; + } + @Test + public void testRangePattern() { + assertThat(RustGrammar.create().build().rule(RustGrammar.RANGE_PATTERN)) + .matches("1..=9") + .matches("1..") + .matches("1...9") + ; } @Test @@ -251,7 +261,6 @@ public void testPatternNoTopAlt() { .matches("Token::BackQuote") //path pattern //range patterns .matches("1..=9") - .matches("1...9") // obsolete //literal .matches("42") .matches("foo") From a880ba9a7fa523ed77e5a6a59d4a0c694e404eda Mon Sep 17 00:00:00 2001 From: Eric Le Goff Date: Wed, 24 Nov 2021 11:44:00 +0100 Subject: [PATCH 14/18] bare function type --- .../src/main/java/org/sonar/rust/RustGrammar.java | 12 ++++++------ .../java/org/sonar/rust/parser/RustGrammarTest.java | 1 + 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java index 57c11122..02619d33 100644 --- a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java +++ b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java @@ -117,6 +117,7 @@ public enum RustGrammar implements GrammarRuleKey { FUNCTION_PARAMETERS_MAYBE_NAMED_VARIADIC, FUNCTION_QUALIFIERS, FUNCTION_RETURN_TYPE, + FUNCTION_TYPE_QUALIFIERS, GE_EXPRESSION, GENERIC_ARG, GENERIC_ARGS, @@ -1111,10 +1112,13 @@ private static void types(LexerlessGrammarBuilder b) { /* https://doc.rust-lang.org/reference/types/function-pointer.html */ private static void functionpointer(LexerlessGrammarBuilder b) { b.rule(BARE_FUNCTION_TYPE).is( - b.optional(FOR_LIFETIMES), FUNCTION_QUALIFIERS, SPC, RustKeyword.KW_FN, + b.optional(FOR_LIFETIMES), FUNCTION_TYPE_QUALIFIERS, SPC, RustKeyword.KW_FN, "(", SPC, b.optional(FUNCTION_PARAMETERS_MAYBE_NAMED_VARIADIC), SPC, ")", SPC, b.optional(BARE_FUNCTION_RETURN_TYPE) ); + + b.rule(FUNCTION_TYPE_QUALIFIERS).is(b.optional(RustKeyword.KW_UNSAFE), b.optional(SPC,RustKeyword.KW_EXTERN, SPC, b.optional(ABI))); + b.rule(BARE_FUNCTION_RETURN_TYPE).is(RustPunctuator.RARROW, SPC, TYPE_NO_BOUNDS); b.rule(FUNCTION_PARAMETERS_MAYBE_NAMED_VARIADIC).is(b.firstOf( MAYBE_NAMED_FUNCTION_PARAMETERS, MAYBE_NAMED_FUNCTION_PARAMETERS_VARIADIC @@ -1145,7 +1149,7 @@ public static void statement(LexerlessGrammarBuilder b) { )); b.rule(LET_STATEMENT).is( b.zeroOrMore(OUTER_ATTRIBUTE, SPC), - RustKeyword.KW_LET, SPC, PATTERN, SPC, + RustKeyword.KW_LET, SPC, PATTERN_NO_TOP_ALT, SPC, b.optional(RustPunctuator.COLON, SPC, TYPE, SPC), b.optional(RustPunctuator.EQ, SPC, EXPRESSION, SPC), RustPunctuator.SEMI); @@ -1153,11 +1157,7 @@ public static void statement(LexerlessGrammarBuilder b) { b.rule(EXPRESSION_STATEMENT).is(b.firstOf( b.sequence(EXPRESSION_WITH_BLOCK, b.optional(SPC, RustPunctuator.SEMI)), b.sequence(EXPRESSION_WITHOUT_BLOCK, SPC, RustPunctuator.SEMI) - - )); - - b.rule(ANY_TOKEN).is( b.firstOf( DELIMITERS, diff --git a/community-rust-frontend/src/test/java/org/sonar/rust/parser/RustGrammarTest.java b/community-rust-frontend/src/test/java/org/sonar/rust/parser/RustGrammarTest.java index 961da591..66ed2a02 100644 --- a/community-rust-frontend/src/test/java/org/sonar/rust/parser/RustGrammarTest.java +++ b/community-rust-frontend/src/test/java/org/sonar/rust/parser/RustGrammarTest.java @@ -41,6 +41,7 @@ public void matchingEmpty() { RustGrammar.COMPILATION_UNIT, RustGrammar.EOF, RustGrammar.FUNCTION_QUALIFIERS, + RustGrammar.FUNCTION_TYPE_QUALIFIERS, RustGrammar.LIFETIME_BOUNDS, RustGrammar.SPC )); From 8e6e1c94381d5be50cabe91a0cf964a607d4bd0c Mon Sep 17 00:00:00 2001 From: Eric Le Goff Date: Wed, 24 Nov 2021 11:55:32 +0100 Subject: [PATCH 15/18] unsafe modules --- .../main/java/org/sonar/rust/RustGrammar.java | 4 ++-- .../rust/parser/attributes/AttributeTest.java | 8 ++++--- .../sonar/rust/parser/items/ModuleTest.java | 24 +++++++++++++++++++ 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java index 02619d33..03527df4 100644 --- a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java +++ b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java @@ -837,8 +837,8 @@ private static void externcrates(LexerlessGrammarBuilder b) { private static void modules(LexerlessGrammarBuilder b) { b.rule(MODULE).is(b.firstOf( - b.sequence(RustKeyword.KW_MOD, SPC, IDENTIFIER, SPC, RustPunctuator.SEMI), - b.sequence(RustKeyword.KW_MOD, SPC, IDENTIFIER, SPC, "{", SPC, + b.sequence(b.optional(RustKeyword.KW_UNSAFE, SPC),RustKeyword.KW_MOD, SPC, IDENTIFIER, SPC, RustPunctuator.SEMI), + b.sequence(b.optional(RustKeyword.KW_UNSAFE, SPC),RustKeyword.KW_MOD, SPC, IDENTIFIER, SPC, "{", SPC, b.zeroOrMore(INNER_ATTRIBUTE, SPC), b.zeroOrMore(ITEM, SPC), "}" ))); diff --git a/community-rust-frontend/src/test/java/org/sonar/rust/parser/attributes/AttributeTest.java b/community-rust-frontend/src/test/java/org/sonar/rust/parser/attributes/AttributeTest.java index e53d29b6..e589e993 100644 --- a/community-rust-frontend/src/test/java/org/sonar/rust/parser/attributes/AttributeTest.java +++ b/community-rust-frontend/src/test/java/org/sonar/rust/parser/attributes/AttributeTest.java @@ -3,17 +3,17 @@ * Copyright (C) 2021 Eric Le Goff * mailto:community-rust AT pm DOT me * http://github.com/elegoff/sonar-rust - * + *

* This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. - * + *

* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + *

* You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. @@ -44,6 +44,7 @@ public void testInnerAttribute() { assertThat(RustGrammar.create().build().rule(RustGrammar.INNER_ATTRIBUTE)) .matches("#![crate_type = \"lib\"]") .matches("#![feature(const_fn_fn_ptr_basics)]") + .matches("#![allow(unused_variables)]") ; } @@ -55,6 +56,7 @@ public void testOuterAttribute() { .matches("#[inline]") .matches("#[allow(unrooted_must_root)]") .matches("#[cfg(not(any(target_os = \"macos\", windows)))]") + .matches("#[allow(non_camel_case_types)]") ; } diff --git a/community-rust-frontend/src/test/java/org/sonar/rust/parser/items/ModuleTest.java b/community-rust-frontend/src/test/java/org/sonar/rust/parser/items/ModuleTest.java index f473f0b9..f825607e 100644 --- a/community-rust-frontend/src/test/java/org/sonar/rust/parser/items/ModuleTest.java +++ b/community-rust-frontend/src/test/java/org/sonar/rust/parser/items/ModuleTest.java @@ -41,6 +41,30 @@ public void testModule() { " use super::Version;\n" + " use std::result;\n" + "}") + .matches("mod math {\n" + + " type Complex = (f64, f64);\n" + + " fn sin(f: f64) -> f64 {\n" + + " /* ... */\n" + + " }\n" + + " fn cos(f: f64) -> f64 {\n" + + " /* ... */\n" + + " }\n" + + " fn tan(f: f64) -> f64 {\n" + + " /* ... */\n" + + " }\n" + + "}") + .matches("unsafe mod math {\n" + + " type Complex = (f64, f64);\n" + + " fn sin(f: f64) -> f64 {\n" + + " /* ... */\n" + + " }\n" + + " fn cos(f: f64) -> f64 {\n" + + " /* ... */\n" + + " }\n" + + " fn tan(f: f64) -> f64 {\n" + + " /* ... */\n" + + " }\n" + + "}") ; From f78acbdf5fd83de83de05ab2dac59e6e602b0bf8 Mon Sep 17 00:00:00 2001 From: Eric Le Goff Date: Wed, 24 Nov 2021 12:06:50 +0100 Subject: [PATCH 16/18] add a couple of tests --- .../java/org/sonar/rust/parser/items/ConstantTest.java | 1 + .../test/java/org/sonar/rust/parser/macro/MacroTest.java | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/community-rust-frontend/src/test/java/org/sonar/rust/parser/items/ConstantTest.java b/community-rust-frontend/src/test/java/org/sonar/rust/parser/items/ConstantTest.java index 1e38e0ee..195cfae9 100644 --- a/community-rust-frontend/src/test/java/org/sonar/rust/parser/items/ConstantTest.java +++ b/community-rust-frontend/src/test/java/org/sonar/rust/parser/items/ConstantTest.java @@ -36,6 +36,7 @@ public void testConstant() { .matches("const STRING: &'static str = \"bitstring\";") .matches("const WHITE: Color = Color(255, 255, 255);") .matches("const MAX: Self;") + .matches("const EMPTY: Vec = Vec::new();") ; } diff --git a/community-rust-frontend/src/test/java/org/sonar/rust/parser/macro/MacroTest.java b/community-rust-frontend/src/test/java/org/sonar/rust/parser/macro/MacroTest.java index dba6baaf..fd0d1587 100644 --- a/community-rust-frontend/src/test/java/org/sonar/rust/parser/macro/MacroTest.java +++ b/community-rust-frontend/src/test/java/org/sonar/rust/parser/macro/MacroTest.java @@ -268,6 +268,13 @@ public void testMacroRulesDefinition() { " }\n" + " }\n" + ");") + .matches("macro_rules! a {\n" + + " () => { a!(1); };\n" + + " (1) => { a!(2); };\n" + + " (2) => { a!(3); };\n" + + " (3) => { a!(4); };\n" + + " (4) => { };\n" + + "}") ; From 860fb3b398ceedcab5affc233dd80cbce5321903 Mon Sep 17 00:00:00 2001 From: Eric Le Goff Date: Wed, 24 Nov 2021 15:37:19 +0100 Subject: [PATCH 17/18] closure parameter --- .../src/main/java/org/sonar/rust/RustGrammar.java | 6 +++--- .../parser/expressions/CallExpressionTest.java | 2 ++ .../parser/expressions/ClosureExpressionTest.java | 15 +++++++++++++++ .../rust/parser/expressions/ExpressionTest.java | 2 ++ .../rust/parser/expressions/IfExpressionTest.java | 10 ++++++++++ 5 files changed, 32 insertions(+), 3 deletions(-) diff --git a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java index 03527df4..69476c53 100644 --- a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java +++ b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java @@ -1041,7 +1041,7 @@ private static void patterns(LexerlessGrammarBuilder b) { )); b.rule(REFERENCE_PATTERN).is( - b.firstOf(RustPunctuator.AND, RustPunctuator.ANDAND), + b.firstOf(RustPunctuator.ANDAND, RustPunctuator.AND), b.optional(RustKeyword.KW_MUT), PATTERN ); @@ -1619,8 +1619,8 @@ private static void operator(LexerlessGrammarBuilder b) { b.rule(BORROW_EXPRESSION).is(b.firstOf( - b.sequence(b.firstOf(RustPunctuator.AND, RustPunctuator.ANDAND), SPC, RustKeyword.KW_MUT, SPC, EXPRESSION), - b.sequence(b.firstOf(RustPunctuator.AND, RustPunctuator.ANDAND), SPC, EXPRESSION) + b.sequence(b.firstOf(RustPunctuator.ANDAND, RustPunctuator.AND), SPC, RustKeyword.KW_MUT, SPC, EXPRESSION), + b.sequence(b.firstOf(RustPunctuator.ANDAND, RustPunctuator.AND), SPC, EXPRESSION) )); b.rule(DEREFERENCE_EXPRESSION).is(RustPunctuator.STAR, EXPRESSION); diff --git a/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/CallExpressionTest.java b/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/CallExpressionTest.java index 5eccfeb4..eac88822 100644 --- a/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/CallExpressionTest.java +++ b/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/CallExpressionTest.java @@ -47,6 +47,8 @@ public void testCallParams() { " node,\n" + " media_element,\n" + " }") + .matches("|| 42") + .matches("|i| 42") diff --git a/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/ClosureExpressionTest.java b/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/ClosureExpressionTest.java index 7fd87e9b..787d967e 100644 --- a/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/ClosureExpressionTest.java +++ b/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/ClosureExpressionTest.java @@ -37,6 +37,17 @@ public void testClosureParameters() { ; } + @Test + public void testClosureParameter() { + assertThat(RustGrammar.create().build().rule(RustGrammar.CLOSURE_PARAM)) + .matches("k:i32") + .matches("j") + .matches("state: Rc>") + .matches("bufs : BufVec") + .matches("&i") + ; + } + @Test public void testClosureExpression() { assertThat(RustGrammar.create().build().rule(RustGrammar.CLOSURE_EXPRESSION)) @@ -54,6 +65,10 @@ public void testClosureExpression() { " a\n" + " .boxed_local()\n" + " }") + .matches("|&i|{i==NUM_MSG}") + .matches("|| i == NUM_MSG") + .matches("|i| i == NUM_MSG") + //TODO .matches("| &i | i == NUM_MSG") ; } diff --git a/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/ExpressionTest.java b/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/ExpressionTest.java index b090af76..24cea878 100644 --- a/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/ExpressionTest.java +++ b/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/ExpressionTest.java @@ -59,6 +59,8 @@ public void testScrutinee() { " }") .matches("if_ok") .matches("match_ok") + .matches("next.iter().all(|i| i == 42)") + .matches("i == NUM_MSG") ; } diff --git a/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/IfExpressionTest.java b/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/IfExpressionTest.java index 78b31746..6ba7899b 100644 --- a/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/IfExpressionTest.java +++ b/community-rust-frontend/src/test/java/org/sonar/rust/parser/expressions/IfExpressionTest.java @@ -126,6 +126,16 @@ public void tesIfExpression() { " }\n" + " _ => false,\n" + " } {}") + .matches("if next.iter().all(|i| i == 42) {\n" + + " \n" + + " break;\n" + + " }") + /*TODO .matches("if next.iter().all(|&i| i == 42) {\n" + + " \n" + + " break;\n" + + " }") + + */ ; From f3a7cee571ee5f09ef0a262baa6b5214ee65871c Mon Sep 17 00:00:00 2001 From: Eric Le Goff Date: Wed, 24 Nov 2021 17:00:51 +0100 Subject: [PATCH 18/18] remove dead code --- .../src/main/java/org/sonar/rust/RustGrammar.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java index 69476c53..1745d940 100644 --- a/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java +++ b/community-rust-frontend/src/main/java/org/sonar/rust/RustGrammar.java @@ -338,11 +338,7 @@ public enum RustGrammar implements GrammarRuleKey { WHERE_CLAUSE_ITEM, WILDCARD_PATTERN; - //private static final String IDFREGEXP1 = "[a-zA-Z][a-zA-Z0-9_]*"; - //private static final String IDFREGEXP2 = "_[a-zA-Z0-9_]+"; - private static final String IDFREGEXP1 = "[_\\p{L}\\p{Nl}]*"; - private static final String IDFREGEXP2 = "[\\pL\\p{Nl}\\p{Mn}\\p{Mc}\\p{Nd}\\p{Pc}]+"; private static final String DOLLAR_CRATE_REGEX = "^\\$crate$"; @@ -2190,8 +2186,6 @@ private static String exceptKeywords() { } sb.append("))"); - //System.out.println(exceptKeywords()); - return sb.toString(); }