Skip to content

Commit 1f59784

Browse files
authored
elixir allows metavariables as keywords (#467)
Previously, keywords (as in keyword/value pairs) didn't allow metavariables, so cases like ```elixir foo($KEYWORD: $VALUE) %{$KEYWORD: $VALUE} ``` would fail to parse. This PR adds support for that. Tested with make test and added a test.
1 parent 326025a commit 1f59784

File tree

2 files changed

+41
-8
lines changed

2 files changed

+41
-8
lines changed

lang/semgrep-grammars/src/semgrep-elixir/grammar.js

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@ module.exports = grammar(base_grammar, {
2828
);
2929
},
3030

31+
_keyword: ($, previous) => {
32+
return choice(
33+
...previous.members,
34+
$.metavariable_keyword
35+
);
36+
},
37+
38+
metavariable_keyword: $ => seq($._semgrep_metavariable, /:\s/),
39+
3140
_semgrep_metavariable: $ => token(/\$[A-Z_][A-Z_0-9]*/),
3241

3342
// Ellipsis
@@ -40,16 +49,24 @@ module.exports = grammar(base_grammar, {
4049
// keyword/pairs, such as
4150
// foo(some_arg: 0, ...)
4251
// %{some_item: 0, ...}
43-
// Also note that now there is ambiguity whether foo(...) is an
44-
// identity or pair, we set the pair rule to have a lower
45-
// precedence
4652
pair: ($, previous) => {
47-
return prec(-1, choice(
53+
return choice(
4854
previous,
49-
'...',
50-
));
55+
$.semgrep_ellipsis,
56+
);
5157
},
5258

59+
// Note that because of the pair rule above, now there is
60+
// ambiguity whether the ellipsis in foo(...) is an
61+
// ellipsis for positional or keyword arguments. If ... matches
62+
// with the identity rule, it will be considered a positional
63+
// argument. If ... matches with semgrep_ellipsis, it will be
64+
// part of parsing the pair rule, which means its a keyword
65+
// argument. In practice, this doesn't matter because either
66+
// way, they will become ParamEllipsis in the Generic AST
67+
// anyway.
68+
semgrep_ellipsis: $ => prec(-1, '...'),
69+
5370
_expression: ($, previous) => choice(
5471
...previous.members,
5572
$.deep_ellipsis,

lang/semgrep-grammars/src/semgrep-elixir/test/corpus/semgrep.txt

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,22 @@ end
1313
(arguments (identifier))
1414
(do_block (call (identifier) (arguments (integer) (integer))))))
1515

16+
=====================================
17+
Metavariables as key value pairs
18+
=====================================
19+
20+
%{$KEY: $VALUE}
21+
22+
---
23+
24+
(source
25+
(map
26+
(map_content
27+
(keywords
28+
(pair
29+
(metavariable_keyword)
30+
(identifier))))))
31+
1632
=====================================
1733
Ellipsis in calls
1834
=====================================
@@ -30,9 +46,9 @@ end
3046
(identifier)
3147
(keywords
3248
(pair (keyword) (integer))
33-
(pair)
49+
(pair (semgrep_ellipsis))
3450
(pair (keyword) (integer))
35-
(pair)))))))
51+
(pair (semgrep_ellipsis))))))))
3652

3753
=====================================
3854
Deep Ellipsis

0 commit comments

Comments
 (0)