From d6790794003180de79d5951eb9af9d6ee8a2bebd Mon Sep 17 00:00:00 2001 From: ArArgon Date: Tue, 18 Jun 2024 14:16:07 -0700 Subject: [PATCH 1/8] fix: correctly parse typed metavariables and update parser --- .../src/semgrep-move-on-aptos/grammar.js | 8 ++++- .../test/corpus/semgrep.txt | 31 ++++++++++++++++++- .../src/tree-sitter-move-on-aptos | 2 +- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/lang/semgrep-grammars/src/semgrep-move-on-aptos/grammar.js b/lang/semgrep-grammars/src/semgrep-move-on-aptos/grammar.js index c0d523f..ecadd09 100644 --- a/lang/semgrep-grammars/src/semgrep-move-on-aptos/grammar.js +++ b/lang/semgrep-grammars/src/semgrep-move-on-aptos/grammar.js @@ -15,6 +15,7 @@ module.exports = grammar(base_grammar, { conflicts: ($, previous) => previous.concat([ [$.quantifier, $._quantifier_directive], [$.var_name, $._bind], + [$.typed_metavariable, $.name_access_chain] ]), /* @@ -25,7 +26,11 @@ module.exports = grammar(base_grammar, { // Semgrep components, source: semgrep-rust ellipsis: $ => '...', deep_ellipsis: $ => seq('<...', $._expr, '...>'), - typed_metavariable: $ => seq($.identifier, ':', $.type), + + // Typed metavariable (an expression, not a parameter) + // This is grammatically indistinguishable from `$.type_hint_expr: $ => seq('(', $._expr, ':', $.type, ')')`. + // This will be handled by the semgrep converter by checking the metavariable name (`$`). + typed_metavariable: $ => seq('(', $.identifier, ':', $.type, ')'), // Alternate "entry point". Allows parsing a standalone expression. semgrep_expression: $ => seq('__SEMGREP_EXPRESSION', $._expr), @@ -93,6 +98,7 @@ module.exports = grammar(base_grammar, { prec(UNARY_PREC, $.ellipsis), prec(UNARY_PREC, $.deep_ellipsis), prec(UNARY_PREC, $.field_access_ellipsis_expr), + $.typed_metavariable, ), // type parameter diff --git a/lang/semgrep-grammars/src/semgrep-move-on-aptos/test/corpus/semgrep.txt b/lang/semgrep-grammars/src/semgrep-move-on-aptos/test/corpus/semgrep.txt index 696aac3..dfdc0c2 100644 --- a/lang/semgrep-grammars/src/semgrep-move-on-aptos/test/corpus/semgrep.txt +++ b/lang/semgrep-grammars/src/semgrep-move-on-aptos/test/corpus/semgrep.txt @@ -155,4 +155,33 @@ module 0xdeadbeef::mod { (identifier)))) (tuple_expr (ellipsis)))) - (ellipsis))))) \ No newline at end of file + (ellipsis))))) + +======================= +Typed Metavariables +======================= + +__SEMGREP_EXPRESSION +call(arr1, arr2, ($VAR: u32), $VAR2) + +--- +(source_file + (semgrep_expression + (call_expr + (name_access_chain + (identifier)) + (call_args + (var + (name_access_chain + (identifier))) + (var + (name_access_chain + (identifier))) + (typed_metavariable + (identifier) + (type + (primitive_type + (number_type)))) + (var + (name_access_chain + (identifier))))))) \ No newline at end of file diff --git a/lang/semgrep-grammars/src/tree-sitter-move-on-aptos b/lang/semgrep-grammars/src/tree-sitter-move-on-aptos index 6af0ab3..b41cf13 160000 --- a/lang/semgrep-grammars/src/tree-sitter-move-on-aptos +++ b/lang/semgrep-grammars/src/tree-sitter-move-on-aptos @@ -1 +1 @@ -Subproject commit 6af0ab3df24f6cfc655528789aa1339a7f741d10 +Subproject commit b41cf131293d4dfe2c72d3afb1e790866dd55bb4 From c1e1df476802e8ea5a96b3109b4541c158ce9649 Mon Sep 17 00:00:00 2001 From: ArArgon Date: Thu, 20 Jun 2024 15:03:36 -0700 Subject: [PATCH 2/8] fix: allow ellipsis in more places --- .../src/semgrep-move-on-aptos/grammar.js | 43 +++++++++- .../test/corpus/semgrep.txt | 80 ++++++++++++++++++- 2 files changed, 119 insertions(+), 4 deletions(-) diff --git a/lang/semgrep-grammars/src/semgrep-move-on-aptos/grammar.js b/lang/semgrep-grammars/src/semgrep-move-on-aptos/grammar.js index ecadd09..e6b2111 100644 --- a/lang/semgrep-grammars/src/semgrep-move-on-aptos/grammar.js +++ b/lang/semgrep-grammars/src/semgrep-move-on-aptos/grammar.js @@ -36,7 +36,10 @@ module.exports = grammar(base_grammar, { semgrep_expression: $ => seq('__SEMGREP_EXPRESSION', $._expr), // Alternate "entry point". Allows parsing a standalone list of sequence items (statements). - semgrep_statement: $ => seq('__SEMGREP_STATEMENT', repeat1($._sequence_item)), + semgrep_statement: $ => seq('__SEMGREP_STATEMENT', repeat1(choice( + $._sequence_item, + $.constant_decl, + ))), // Extend the source_file rule to allow semgrep constructs source_file: ($, previous) => choice( @@ -101,13 +104,47 @@ module.exports = grammar(base_grammar, { $.typed_metavariable, ), - // type parameter - // (e.g. `T: ..., U: ..., ...`) + // function parameter + // (e.g. `call( ..., arg, ...)`) parameter: ($, previous) => choice( previous, $.ellipsis, ), + // for loop ellipsis + // (e.g. `for (...)`) + for_loop_expr: ($, previous) => choice( + previous, + seq('for', '(', $.ellipsis, ')', field('body', $.block)), + ), + + // abilities + // (e.g. struct XXX has ..., YYY) + ability: ($, previous) => choice( + previous, + $.ellipsis, + ), + + // type parameter + // (e.g. `Type<..., T>`) + type_param: ($, previous) => choice( + previous, + $.ellipsis, + ), + + // type + type: ($, previous) => choice( + ...previous.members, + $.ellipsis, + ), + + // pack field + // (e.g. `Pack { ..., field }`) + expr_field: ($, previous) => choice( + ...previous.members, + $.ellipsis, + ), + // trailing field access // (e.g. `foo.bar().baz(). ...`) field_access_ellipsis_expr: $ => prec.left(FIELD_PREC, seq( diff --git a/lang/semgrep-grammars/src/semgrep-move-on-aptos/test/corpus/semgrep.txt b/lang/semgrep-grammars/src/semgrep-move-on-aptos/test/corpus/semgrep.txt index dfdc0c2..ae19d38 100644 --- a/lang/semgrep-grammars/src/semgrep-move-on-aptos/test/corpus/semgrep.txt +++ b/lang/semgrep-grammars/src/semgrep-move-on-aptos/test/corpus/semgrep.txt @@ -184,4 +184,82 @@ call(arr1, arr2, ($VAR: u32), $VAR2) (number_type)))) (var (name_access_chain - (identifier))))))) \ No newline at end of file + (identifier))))))) + +======================= +Type Parameters & Arguments; Struct Bind Field & Pack Field; For Ellipsis +======================= + +module 0xdeadbeef::mod { + struct $STRUCT<$T1, ...> has key { + ... + } + + fun $FUN() { + let $STRUCT { ... } = Struct2 { + ..., + field1: $VAR, + $VAR2, + }; + + for (...) { ... } + } +} + +--- + +(source_file + (module + (numerical_addr + (number)) + (identifier) + (declaration + (struct_decl + (identifier) + (type_params + (type_param + (identifier)) + (type_param + (ellipsis))) + (abilities + (ability)) + (body + (field_annot + (ellipsis))))) + (declaration + (function_decl + (identifier) + (parameters) + (block + (let_expr + (bind_list + (name_access_chain + (identifier)) + (type_args + (type + (primitive_type + (number_type))) + (type + (ellipsis)) + (type + (name_access_chain + (identifier)))) + (fields + (bind_field + (ellipsis)))) + (pack_expr + (name_access_chain + (identifier)) + (expr_field + (ellipsis)) + (expr_field + (identifier) + (var + (name_access_chain + (identifier)))) + (expr_field + (shorthand_field_identifier)))) + (for_loop_expr + (ellipsis) + (block + (ellipsis)))))))) \ No newline at end of file From b3c932fc24dd151766ee86e2503b21739957e3c6 Mon Sep 17 00:00:00 2001 From: ArArgon Date: Thu, 20 Jun 2024 15:38:59 -0700 Subject: [PATCH 3/8] fix: remove type argument ambiguity --- .../test/corpus/semgrep.txt | 52 ++++++++++++++++++- .../src/tree-sitter-move-on-aptos | 2 +- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/lang/semgrep-grammars/src/semgrep-move-on-aptos/test/corpus/semgrep.txt b/lang/semgrep-grammars/src/semgrep-move-on-aptos/test/corpus/semgrep.txt index ae19d38..ef5cfc4 100644 --- a/lang/semgrep-grammars/src/semgrep-move-on-aptos/test/corpus/semgrep.txt +++ b/lang/semgrep-grammars/src/semgrep-move-on-aptos/test/corpus/semgrep.txt @@ -262,4 +262,54 @@ module 0xdeadbeef::mod { (for_loop_expr (ellipsis) (block - (ellipsis)))))))) \ No newline at end of file + (ellipsis)))))))) + +======================= +Function Call with Type Arguments +======================= + +__SEMGREP_EXPRESSION { + borrow_global_mut>(...); + exists<...> (...); + test_fun<..., $T1, ...> (...); +} + +--- + +(source_file + (semgrep_expression + (block + (call_expr + (name_access_chain + (identifier)) + (type_args + (type + (name_access_chain + (identifier)) + (type_args + (type + (name_access_chain + (identifier)))))) + (call_args + (ellipsis))) + (call_expr + (name_access_chain + (discouraged_name)) + (type_args + (type + (ellipsis))) + (call_args + (ellipsis))) + (call_expr + (name_access_chain + (identifier)) + (type_args + (type + (ellipsis)) + (type + (name_access_chain + (identifier))) + (type + (ellipsis))) + (call_args + (ellipsis)))))) \ No newline at end of file diff --git a/lang/semgrep-grammars/src/tree-sitter-move-on-aptos b/lang/semgrep-grammars/src/tree-sitter-move-on-aptos index b41cf13..ce1a8ff 160000 --- a/lang/semgrep-grammars/src/tree-sitter-move-on-aptos +++ b/lang/semgrep-grammars/src/tree-sitter-move-on-aptos @@ -1 +1 @@ -Subproject commit b41cf131293d4dfe2c72d3afb1e790866dd55bb4 +Subproject commit ce1a8ff1b95005ae45e3674c00e795aac24aec35 From 6e4cb30d809d2b097735b261b92a54869395dfdb Mon Sep 17 00:00:00 2001 From: ArArgon Date: Thu, 20 Jun 2024 15:51:38 -0700 Subject: [PATCH 4/8] fix: reformat `semgrep.txt` --- .../test/corpus/semgrep.txt | 229 +++++++++--------- 1 file changed, 115 insertions(+), 114 deletions(-) diff --git a/lang/semgrep-grammars/src/semgrep-move-on-aptos/test/corpus/semgrep.txt b/lang/semgrep-grammars/src/semgrep-move-on-aptos/test/corpus/semgrep.txt index ef5cfc4..6eeed92 100644 --- a/lang/semgrep-grammars/src/semgrep-move-on-aptos/test/corpus/semgrep.txt +++ b/lang/semgrep-grammars/src/semgrep-move-on-aptos/test/corpus/semgrep.txt @@ -8,7 +8,7 @@ __SEMGREP_EXPRESSION --- (source_file - (semgrep_expression + (semgrep_expression (ellipsis))) ======================== @@ -21,15 +21,15 @@ call(..., $VAR) --- (source_file - (semgrep_expression - (call_expr + (semgrep_expression + (call_expr + (name_access_chain + (identifier)) + (call_args + (ellipsis) + (var (name_access_chain - (identifier)) - (call_args - (ellipsis) - (var - (name_access_chain - (identifier))))))) + (identifier))))))) ==== Semgrep Statement @@ -39,33 +39,34 @@ __SEMGREP_STATEMENT let _: u64 = if (cond) { ... } else { s2 + <... $...SOME ...> }.f; --- + (source_file - (semgrep_statement + (semgrep_statement (let_expr - (bind_list + (bind_list (var_name - (identifier))) - (type + (identifier))) + (type (primitive_type - (number_type))) - (access_field + (number_type))) + (access_field (if_expr - (parenthesized_expr + (parenthesized_expr (var - (name_access_chain + (name_access_chain (identifier)))) - (block + (block (ellipsis)) - (block + (block (bin_op_expr - (var + (var (name_access_chain - (identifier))) - (binary_operator) - (deep_ellipsis - (var - (name_access_chain - (identifier))))))) + (identifier))) + (binary_operator) + (deep_ellipsis + (var + (name_access_chain + (identifier))))))) (identifier))))) @@ -111,50 +112,50 @@ module 0xdeadbeef::mod { --- (source_file - (module + (module (numerical_addr - (number)) + (number)) (identifier) (declaration - (use_decl + (use_decl (module_ident - (numerical_addr + (numerical_addr (number)) - (identifier)) + (identifier)) (member - (ellipsis)))) + (ellipsis)))) (declaration - (attributes + (attributes (attribute - (ellipsis)) + (ellipsis)) (attribute - (identifier) - (attribute + (identifier) + (attribute (ellipsis)))) - (spec_block + (spec_block (spec_block_target) (spec_func - (identifier) - (parameters + (identifier) + (parameters (parameter - (identifier) - (type + (identifier) + (type (name_access_chain - (identifier))))) - (type + (identifier))))) + (type (name_access_chain - (identifier))) - (block + (identifier))) + (block (ellipsis))) (spec_axiom - (quantifier + (quantifier (quantifier_bind - (identifier) - (type + (identifier) + (type (name_access_chain - (identifier)))) + (identifier)))) (tuple_expr - (ellipsis)))) + (ellipsis)))) (ellipsis))))) ======================= @@ -166,24 +167,24 @@ call(arr1, arr2, ($VAR: u32), $VAR2) --- (source_file - (semgrep_expression + (semgrep_expression (call_expr - (name_access_chain + (name_access_chain (identifier)) - (call_args + (call_args (var - (name_access_chain + (name_access_chain (identifier))) (var - (name_access_chain + (name_access_chain (identifier))) (typed_metavariable - (identifier) - (type + (identifier) + (type (primitive_type - (number_type)))) + (number_type)))) (var - (name_access_chain + (name_access_chain (identifier))))))) ======================= @@ -209,60 +210,60 @@ module 0xdeadbeef::mod { --- (source_file - (module + (module (numerical_addr - (number)) + (number)) (identifier) (declaration - (struct_decl + (struct_decl (identifier) (type_params - (type_param + (type_param (identifier)) - (type_param + (type_param (ellipsis))) (abilities - (ability)) + (ability)) (body - (field_annot + (field_annot (ellipsis))))) (declaration - (function_decl + (function_decl (identifier) (parameters) (block - (let_expr + (let_expr (bind_list - (name_access_chain + (name_access_chain (identifier)) - (type_args - (type - (primitive_type - (number_type))) - (type - (ellipsis)) - (type - (name_access_chain - (identifier)))) - (fields + (type_args + (type + (primitive_type + (number_type))) + (type + (ellipsis)) + (type + (name_access_chain + (identifier)))) + (fields (bind_field - (ellipsis)))) + (ellipsis)))) (pack_expr - (name_access_chain - (identifier)) - (expr_field - (ellipsis)) - (expr_field - (identifier) - (var - (name_access_chain - (identifier)))) - (expr_field - (shorthand_field_identifier)))) - (for_loop_expr - (ellipsis) - (block - (ellipsis)))))))) + (name_access_chain + (identifier)) + (expr_field + (ellipsis)) + (expr_field + (identifier) + (var + (name_access_chain + (identifier)))) + (expr_field + (shorthand_field_identifier)))) + (for_loop_expr + (ellipsis) + (block + (ellipsis)))))))) ======================= Function Call with Type Arguments @@ -277,39 +278,39 @@ __SEMGREP_EXPRESSION { --- (source_file - (semgrep_expression + (semgrep_expression (block - (call_expr + (call_expr (name_access_chain - (identifier)) + (identifier)) (type_args - (type + (type (name_access_chain - (identifier)) + (identifier)) (type_args - (type + (type (name_access_chain - (identifier)))))) + (identifier)))))) (call_args - (ellipsis))) - (call_expr + (ellipsis))) + (call_expr (name_access_chain - (discouraged_name)) + (discouraged_name)) (type_args - (type + (type (ellipsis))) (call_args - (ellipsis))) - (call_expr + (ellipsis))) + (call_expr (name_access_chain - (identifier)) + (identifier)) (type_args - (type + (type (ellipsis)) - (type + (type (name_access_chain - (identifier))) - (type + (identifier))) + (type (ellipsis))) (call_args - (ellipsis)))))) \ No newline at end of file + (ellipsis)))))) \ No newline at end of file From 6d49c0e8ec55adcefb5ee23df4ebf55da9d3b266 Mon Sep 17 00:00:00 2001 From: ArArgon Date: Fri, 21 Jun 2024 13:57:38 -0700 Subject: [PATCH 5/8] fix: support matching let expressions --- .../src/semgrep-move-on-aptos/grammar.js | 5 +++- .../test/corpus/semgrep.txt | 25 ++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/lang/semgrep-grammars/src/semgrep-move-on-aptos/grammar.js b/lang/semgrep-grammars/src/semgrep-move-on-aptos/grammar.js index e6b2111..280a4e3 100644 --- a/lang/semgrep-grammars/src/semgrep-move-on-aptos/grammar.js +++ b/lang/semgrep-grammars/src/semgrep-move-on-aptos/grammar.js @@ -33,7 +33,10 @@ module.exports = grammar(base_grammar, { typed_metavariable: $ => seq('(', $.identifier, ':', $.type, ')'), // Alternate "entry point". Allows parsing a standalone expression. - semgrep_expression: $ => seq('__SEMGREP_EXPRESSION', $._expr), + semgrep_expression: $ => seq('__SEMGREP_EXPRESSION', choice( + $._expr, + $.let_expr, + )), // Alternate "entry point". Allows parsing a standalone list of sequence items (statements). semgrep_statement: $ => seq('__SEMGREP_STATEMENT', repeat1(choice( diff --git a/lang/semgrep-grammars/src/semgrep-move-on-aptos/test/corpus/semgrep.txt b/lang/semgrep-grammars/src/semgrep-move-on-aptos/test/corpus/semgrep.txt index 6eeed92..47c81fb 100644 --- a/lang/semgrep-grammars/src/semgrep-move-on-aptos/test/corpus/semgrep.txt +++ b/lang/semgrep-grammars/src/semgrep-move-on-aptos/test/corpus/semgrep.txt @@ -313,4 +313,27 @@ __SEMGREP_EXPRESSION { (type (ellipsis))) (call_args - (ellipsis)))))) \ No newline at end of file + (ellipsis)))))) + +======================= +Let Expression Match +======================= + +__SEMGREP_EXPRESSION +let test::Token { ... } = $VAR + +--- + +(source_file + (semgrep_expression + (let_expr + (bind_list + (name_access_chain + (identifier) + (identifier)) + (fields + (bind_field + (ellipsis)))) + (var + (name_access_chain + (identifier)))))) \ No newline at end of file From 7c526b1ee069e8ee1b2012dc9f7ffa9d93b259ee Mon Sep 17 00:00:00 2001 From: ArArgon Date: Fri, 21 Jun 2024 16:09:31 -0700 Subject: [PATCH 6/8] chore: remove unnecessary conflicts --- lang/semgrep-grammars/src/semgrep-move-on-aptos/grammar.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/lang/semgrep-grammars/src/semgrep-move-on-aptos/grammar.js b/lang/semgrep-grammars/src/semgrep-move-on-aptos/grammar.js index 280a4e3..f3f412c 100644 --- a/lang/semgrep-grammars/src/semgrep-move-on-aptos/grammar.js +++ b/lang/semgrep-grammars/src/semgrep-move-on-aptos/grammar.js @@ -13,8 +13,6 @@ module.exports = grammar(base_grammar, { name: 'move_on_aptos', conflicts: ($, previous) => previous.concat([ - [$.quantifier, $._quantifier_directive], - [$.var_name, $._bind], [$.typed_metavariable, $.name_access_chain] ]), From a33e40172898308a2b99d3c70b9f667a71e8661d Mon Sep 17 00:00:00 2001 From: ArArgon Date: Fri, 21 Jun 2024 18:06:07 -0700 Subject: [PATCH 7/8] fix: allow more ellipsis in bindings --- .../src/semgrep-move-on-aptos/grammar.js | 8 ++++++ .../test/corpus/semgrep.txt | 27 ++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/lang/semgrep-grammars/src/semgrep-move-on-aptos/grammar.js b/lang/semgrep-grammars/src/semgrep-move-on-aptos/grammar.js index f3f412c..b6af7ea 100644 --- a/lang/semgrep-grammars/src/semgrep-move-on-aptos/grammar.js +++ b/lang/semgrep-grammars/src/semgrep-move-on-aptos/grammar.js @@ -74,6 +74,14 @@ module.exports = grammar(base_grammar, { $.ellipsis, ), + // struct binding + // (e.g. `let T { field_1, var: ..., } = obj;`) + // (e.g. `let ... = obj;`) + _bind: ($, previous) => choice( + ...previous.members, + $.ellipsis, + ), + // attribute // (e.g. `#[..., attr(...)]`) attribute: ($, previous) => choice( diff --git a/lang/semgrep-grammars/src/semgrep-move-on-aptos/test/corpus/semgrep.txt b/lang/semgrep-grammars/src/semgrep-move-on-aptos/test/corpus/semgrep.txt index 47c81fb..f696972 100644 --- a/lang/semgrep-grammars/src/semgrep-move-on-aptos/test/corpus/semgrep.txt +++ b/lang/semgrep-grammars/src/semgrep-move-on-aptos/test/corpus/semgrep.txt @@ -336,4 +336,29 @@ let test::Token { ... } = $VAR (ellipsis)))) (var (name_access_chain - (identifier)))))) \ No newline at end of file + (identifier)))))) + +==== +Let Expr 2 +==== + +__SEMGREP_EXPRESSION +let Lock { coins, $VAR2: ..., } = ... + +--- + +(source_file + (semgrep_expression + (let_expr + (bind_list + (name_access_chain + (identifier)) + (fields + (bind_field + (shorthand_field_identifier + (identifier))) + (bind_field + (var_name + (identifier)) + (ellipsis)))) + (ellipsis)))) \ No newline at end of file From 32903f849d7fa3d9d4bf8c27b0e60ce495b8be25 Mon Sep 17 00:00:00 2001 From: ArArgon Date: Mon, 24 Jun 2024 11:26:08 -0700 Subject: [PATCH 8/8] fix: support ellipsis statements --- .../src/semgrep-move-on-aptos/grammar.js | 6 +++ .../test/corpus/semgrep.txt | 44 +++++++++++++++++-- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/lang/semgrep-grammars/src/semgrep-move-on-aptos/grammar.js b/lang/semgrep-grammars/src/semgrep-move-on-aptos/grammar.js index b6af7ea..f24dfe7 100644 --- a/lang/semgrep-grammars/src/semgrep-move-on-aptos/grammar.js +++ b/lang/semgrep-grammars/src/semgrep-move-on-aptos/grammar.js @@ -61,6 +61,12 @@ module.exports = grammar(base_grammar, { $.ellipsis, ), + // statement (sequence item) + _sequence_item: ($, previous) => choice( + previous, + $.ellipsis, + ), + // struct field annotations field_annot: ($, previous) => choice( previous, diff --git a/lang/semgrep-grammars/src/semgrep-move-on-aptos/test/corpus/semgrep.txt b/lang/semgrep-grammars/src/semgrep-move-on-aptos/test/corpus/semgrep.txt index f696972..e974ff3 100644 --- a/lang/semgrep-grammars/src/semgrep-move-on-aptos/test/corpus/semgrep.txt +++ b/lang/semgrep-grammars/src/semgrep-move-on-aptos/test/corpus/semgrep.txt @@ -338,9 +338,9 @@ let test::Token { ... } = $VAR (name_access_chain (identifier)))))) -==== +======================= Let Expr 2 -==== +======================= __SEMGREP_EXPRESSION let Lock { coins, $VAR2: ..., } = ... @@ -361,4 +361,42 @@ let Lock { coins, $VAR2: ..., } = ... (var_name (identifier)) (ellipsis)))) - (ellipsis)))) \ No newline at end of file + (ellipsis)))) + +======================= +Multiline Statements 1 +======================= + +__SEMGREP_STATEMENT ... + +--- + +(source_file + (semgrep_statement + (ellipsis))) + +======================= +Multiline Statements 2 +======================= + +__SEMGREP_EXPRESSION { + let t = 100; + ... + t +} + +--- + +(source_file + (semgrep_expression + (block + (let_expr + (bind_list + (var_name + (identifier))) + (value + (number))) + (ellipsis) + (var + (name_access_chain + (identifier)))))) \ No newline at end of file