Skip to content

Commit

Permalink
Merge pull request #489 from aptos-labs/feat/support_partials
Browse files Browse the repository at this point in the history
Move-on-Aptos: Support More Declarations and Partial Signatures
  • Loading branch information
Yoann Padioleau authored Jul 10, 2024
2 parents 9c2f3e0 + b6960ca commit 33fd498
Show file tree
Hide file tree
Showing 4 changed files with 323 additions and 19 deletions.
65 changes: 57 additions & 8 deletions lang/semgrep-grammars/src/semgrep-move-on-aptos/grammar.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,14 @@ module.exports = grammar(base_grammar, {
name: 'move_on_aptos',

conflicts: ($, previous) => previous.concat([
[$.typed_metavariable, $.name_access_chain]
[$.typed_metavariable, $.name_access_chain],
[$.term, $.declaration],
[$._module_path, $.spec_block_target]
]),

precedences: ($, previous) => previous.concat([
[$._sequence_item, $.declaration],
[$._script_use_decl, $._script_constant_decl, $._script_func_decl, $._script_spec_block],
]),

/*
Expand All @@ -24,29 +31,40 @@ module.exports = grammar(base_grammar, {
// Semgrep components, source: semgrep-rust
ellipsis: $ => '...',
deep_ellipsis: $ => seq('<...', $._expr, '...>'),

// 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', choice(
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(
semgrep_statement: $ => repeat1(choice(
$._sequence_item,
$.constant_decl,
))),
$.declaration,
)),

// Alternate "entry point". Allows parsing partial declarations (signatures).
semgrep_partial: $ => seq(
optional($.attributes),
repeat($.module_member_modifier),
choice(
$._function_signature,
$._struct_signature,
)
),

// Extend the source_file rule to allow semgrep constructs
source_file: ($, previous) => choice(
previous,
$.semgrep_expression,
$.semgrep_statement,
$.semgrep_partial,
),

// Module declaration
Expand All @@ -55,6 +73,19 @@ module.exports = grammar(base_grammar, {
$.ellipsis,
),

// Script members
// We cannot mimic the `declaration` trick here, as the script members are strictly ordered.
_script_use_decl: ($, previous) => choice(previous, $.ellipsis),
_script_constant_decl: ($, previous) => choice(previous, $.ellipsis),
_script_func_decl: ($, previous) => choice(previous, $.ellipsis),
_script_spec_block: ($, previous) => choice(previous, $.ellipsis),

// Address block members
_address_member: ($, previous) => choice(
previous,
$.ellipsis,
),

// Spec block members
_spec_block_member: ($, previous) => choice(
previous,
Expand Down Expand Up @@ -95,19 +126,32 @@ module.exports = grammar(base_grammar, {
$.ellipsis,
),

// attribute value
// (e.g. `#[attr(key = ...)]`)
_attribute_val: ($, previous) => choice(
previous,
$.ellipsis,
),

// use member
// (e.g. `use module_ident::...;`, `use module_ident::{..., item_ident}`)
_use_member: ($, previous) => choice(
previous,
$.ellipsis,
),

// term
term: ($, previous) => choice(
...previous.members,
$.ellipsis,
$.deep_ellipsis,
),

// expression
_expr: ($, previous) => choice(
...previous.members,
$.ellipsis,
$.deep_ellipsis,
$.field_access_ellipsis_expr,
),

// unary expression
Expand All @@ -119,6 +163,11 @@ module.exports = grammar(base_grammar, {
$.typed_metavariable,
),

_dot_or_index_chain: ($, previous) => choice(
...previous.members,
$.field_access_ellipsis_expr,
),

// function parameter
// (e.g. `call( ..., arg, ...)`)
parameter: ($, previous) => choice(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
=======================
Function in Statement
=======================

fun $TEST (...) : ... { ... }

---

(source_file
(semgrep_statement
(declaration
(function_decl
(identifier)
(parameters
(parameter
(ellipsis)))
(type
(ellipsis))
(block
(ellipsis))))))

=======================
Declarations
=======================

use 0xabcd::ff;
struct $STRUCT has ... { ... }
const $CONST : ... = $FOO(...);
...
fun hello (...) {
let XXX = $STRUCT { ... };
...
}

---

(source_file
(semgrep_statement
(declaration
(use_decl
(module_ident
(numerical_addr
(number))
(identifier))))
(declaration
(struct_decl
(identifier)
(abilities
(ability
(ellipsis)))
(body
(field_annot
(ellipsis)))))
(declaration
(constant_decl
(identifier)
(type
(ellipsis))
(call_expr
(name_access_chain
(identifier))
(call_args
(ellipsis)))))
(ellipsis)
(declaration
(function_decl
(identifier)
(parameters
(parameter
(ellipsis)))
(block
(let_expr
(bind_list
(var_name
(identifier)))
(pack_expr
(name_access_chain
(identifier))
(expr_field
(ellipsis))))
(ellipsis))))))

=======================
Function Signature
=======================

#[test]
public(friend) fun $FUNC (...)

---

(source_file
(semgrep_partial
(attributes
(attribute
(identifier)))
(module_member_modifier
(visibility))
(identifier)
(parameters
(parameter
(ellipsis)))))

=======================
Struct Signature
=======================

public native struct $STRUCT has ...

---

(source_file
(semgrep_partial
(module_member_modifier
(visibility))
(module_member_modifier)
(identifier)
(abilities
(ability
(ellipsis)))))

=======================
Function Attributes
=======================

#[attr(key = ...), attr2 = ..., attr3(...), ...]
fun $FUN (...)

---

(source_file
(semgrep_partial
(attributes
(attribute
(identifier)
(attribute
(identifier)
(ellipsis)))
(attribute
(identifier)
(ellipsis))
(attribute
(identifier)
(attribute
(ellipsis)))
(attribute
(ellipsis)))
(identifier)
(parameters
(parameter
(ellipsis)))))
Loading

0 comments on commit 33fd498

Please sign in to comment.