From 0526a85af232e05255e24e07a43ee720a1bb87f4 Mon Sep 17 00:00:00 2001 From: Valentin Berlier Date: Sat, 6 Aug 2022 04:08:29 +0200 Subject: [PATCH] fix: only allow call expressions on builtins for interpolation --- bolt/parse.py | 39 +++++++++++++- tests/resources/bolt_examples.mcfunction | 16 ++++++ tests/snapshots/bolt__parse_274__0.txt | 34 ++++++++++++ tests/snapshots/bolt__parse_274__1.txt | 4 ++ tests/snapshots/bolt__parse_275__0.txt | 67 ++++++++++++++++++++++++ tests/snapshots/bolt__parse_275__1.txt | 61 +++++++++++++++++++++ tests/snapshots/bolt__parse_276__0.txt | 50 ++++++++++++++++++ tests/snapshots/bolt__parse_276__1.txt | 58 ++++++++++++++++++++ tests/snapshots/bolt__parse_277__0.txt | 5 ++ tests/snapshots/bolt__parse_278__0.txt | 48 +++++++++++++++++ tests/snapshots/bolt__parse_278__1.txt | 39 ++++++++++++++ tests/snapshots/bolt__parse_279__0.txt | 31 +++++++++++ tests/snapshots/bolt__parse_279__1.txt | 36 +++++++++++++ tests/snapshots/bolt__parse_280__0.txt | 34 ++++++++++++ tests/snapshots/bolt__parse_280__1.txt | 4 ++ 15 files changed, 525 insertions(+), 1 deletion(-) create mode 100644 tests/snapshots/bolt__parse_274__0.txt create mode 100644 tests/snapshots/bolt__parse_274__1.txt create mode 100644 tests/snapshots/bolt__parse_275__0.txt create mode 100644 tests/snapshots/bolt__parse_275__1.txt create mode 100644 tests/snapshots/bolt__parse_276__0.txt create mode 100644 tests/snapshots/bolt__parse_276__1.txt create mode 100644 tests/snapshots/bolt__parse_277__0.txt create mode 100644 tests/snapshots/bolt__parse_278__0.txt create mode 100644 tests/snapshots/bolt__parse_278__1.txt create mode 100644 tests/snapshots/bolt__parse_279__0.txt create mode 100644 tests/snapshots/bolt__parse_279__1.txt create mode 100644 tests/snapshots/bolt__parse_280__0.txt create mode 100644 tests/snapshots/bolt__parse_280__1.txt diff --git a/bolt/parse.py b/bolt/parse.py index 8111afd..15377e7 100644 --- a/bolt/parse.py +++ b/bolt/parse.py @@ -1,5 +1,6 @@ __all__ = [ "get_bolt_parsers", + "get_stream_builtins", "get_stream_identifiers", "get_stream_pending_identifiers", "get_stream_identifiers_storage", @@ -52,6 +53,7 @@ "KeywordParser", "LookupParser", "PrimaryParser", + "BuiltinCallRestriction", "parse_dict_item", "LiteralParser", ] @@ -256,7 +258,9 @@ def get_bolt_parsers( "bolt:class_bases": parse_class_bases, "bolt:class_root": parse_class_root, "bolt:del_target": parse_del_target, - "bolt:interpolation": PrimaryParser(delegate("bolt:identifier"), truncate=True), + "bolt:interpolation": BuiltinCallRestriction( + PrimaryParser(delegate("bolt:identifier"), truncate=True) + ), "bolt:identifier": parse_identifier, "bolt:with_expression": TrailingCommaParser(delegate("bolt:expression")), "bolt:with_target": TrailingCommaParser( @@ -439,6 +443,11 @@ def get_bolt_parsers( } +def get_stream_builtins(stream: TokenStream) -> Set[str]: + """Return the set of builtin identifiers currently associated with the token stream.""" + return stream.data.setdefault("builtins", set()) + + def get_stream_identifiers(stream: TokenStream) -> Set[str]: """Return the set of accessible identifiers currently associated with the token stream.""" return stream.data.setdefault("identifiers", set()) @@ -498,6 +507,7 @@ def __call__(self, stream: TokenStream) -> Any: with self.modules.parse_push(current), stream.provide( resource_location=self.modules.database[current].resource_location, + builtins=self.modules.builtins, identifiers=set(self.modules.globals) | self.modules.builtins | {"__name__"}, @@ -2068,6 +2078,33 @@ def __call__(self, stream: TokenStream) -> Any: return node +@dataclass +class BuiltinCallRestriction: + """Only allow call expressions on builtins.""" + + parser: Parser + + def __call__(self, stream: TokenStream) -> Any: + parent = None + node = self.parser(stream) + original = node + + while isinstance(node, (AstAttribute, AstLookup, AstCall)): + parent = node + node = node.value + + if ( + isinstance(node, AstIdentifier) + and not isinstance(parent, AstCall) + and node.value in get_stream_builtins(stream) + and node.value not in get_stream_identifiers_storage(stream) + ): + msg = f'Expected call expression on builtin "{node.value}".' + raise set_location(InvalidSyntax(msg), parent) + + return original + + def parse_dict_item(stream: TokenStream) -> Any: """Parse dict item node.""" identifiers = get_stream_identifiers(stream) diff --git a/tests/resources/bolt_examples.mcfunction b/tests/resources/bolt_examples.mcfunction index af872c1..4254ab6 100644 --- a/tests/resources/bolt_examples.mcfunction +++ b/tests/resources/bolt_examples.mcfunction @@ -1019,3 +1019,19 @@ class B: import math ### particle minecraft:dust 0.00000 (117/255) (164/255) 0.5 ~ ~ ~ 0 0 0 0 1 force @s +### +say @s[tag=hex.summon] +### +hex = 42 +say @s[tag=hex.summon] +### +say @s[tag=hex(42)] +### +time set hex.time +### +hex = 123 +time set hex.time +### +time set hex(123) +### +say @s[tag=id] diff --git a/tests/snapshots/bolt__parse_274__0.txt b/tests/snapshots/bolt__parse_274__0.txt new file mode 100644 index 0000000..45ef3c7 --- /dev/null +++ b/tests/snapshots/bolt__parse_274__0.txt @@ -0,0 +1,34 @@ +say @s[tag=hex.summon] +--- + + location: SourceLocation(pos=0, lineno=1, colno=1) + end_location: SourceLocation(pos=22, lineno=1, colno=23) + commands: + + location: SourceLocation(pos=0, lineno=1, colno=1) + end_location: SourceLocation(pos=22, lineno=1, colno=23) + identifier: 'say:message' + arguments: + + location: SourceLocation(pos=4, lineno=1, colno=5) + end_location: SourceLocation(pos=22, lineno=1, colno=23) + fragments: + + location: SourceLocation(pos=4, lineno=1, colno=5) + end_location: SourceLocation(pos=22, lineno=1, colno=23) + variable: 's' + arguments: + + location: SourceLocation(pos=7, lineno=1, colno=8) + end_location: SourceLocation(pos=21, lineno=1, colno=22) + inverted: False + key: + + location: SourceLocation(pos=7, lineno=1, colno=8) + end_location: SourceLocation(pos=10, lineno=1, colno=11) + value: 'tag' + value: + + location: SourceLocation(pos=11, lineno=1, colno=12) + end_location: SourceLocation(pos=21, lineno=1, colno=22) + value: 'hex.summon' diff --git a/tests/snapshots/bolt__parse_274__1.txt b/tests/snapshots/bolt__parse_274__1.txt new file mode 100644 index 0000000..b7d1062 --- /dev/null +++ b/tests/snapshots/bolt__parse_274__1.txt @@ -0,0 +1,4 @@ +# Nothing +--- +output = None +--- diff --git a/tests/snapshots/bolt__parse_275__0.txt b/tests/snapshots/bolt__parse_275__0.txt new file mode 100644 index 0000000..8e38f80 --- /dev/null +++ b/tests/snapshots/bolt__parse_275__0.txt @@ -0,0 +1,67 @@ +hex = 42 +say @s[tag=hex.summon] +--- + + location: SourceLocation(pos=0, lineno=1, colno=1) + end_location: SourceLocation(pos=31, lineno=2, colno=23) + commands: + + location: SourceLocation(pos=0, lineno=1, colno=1) + end_location: SourceLocation(pos=8, lineno=1, colno=9) + identifier: 'statement' + arguments: + + location: SourceLocation(pos=0, lineno=1, colno=1) + end_location: SourceLocation(pos=8, lineno=1, colno=9) + operator: '=' + target: + + location: SourceLocation(pos=0, lineno=1, colno=1) + end_location: SourceLocation(pos=3, lineno=1, colno=4) + value: 'hex' + rebind: False + value: + + location: SourceLocation(pos=6, lineno=1, colno=7) + end_location: SourceLocation(pos=8, lineno=1, colno=9) + value: 42 + + location: SourceLocation(pos=9, lineno=2, colno=1) + end_location: SourceLocation(pos=31, lineno=2, colno=23) + identifier: 'say:message' + arguments: + + location: SourceLocation(pos=13, lineno=2, colno=5) + end_location: SourceLocation(pos=31, lineno=2, colno=23) + fragments: + + location: SourceLocation(pos=13, lineno=2, colno=5) + end_location: SourceLocation(pos=31, lineno=2, colno=23) + variable: 's' + arguments: + + location: SourceLocation(pos=16, lineno=2, colno=8) + end_location: SourceLocation(pos=30, lineno=2, colno=22) + inverted: False + key: + + location: SourceLocation(pos=16, lineno=2, colno=8) + end_location: SourceLocation(pos=19, lineno=2, colno=11) + value: 'tag' + value: + + location: SourceLocation(pos=20, lineno=2, colno=12) + end_location: SourceLocation(pos=30, lineno=2, colno=22) + prefix: None + unpack: None + converter: 'word' + value: + + location: SourceLocation(pos=20, lineno=2, colno=12) + end_location: SourceLocation(pos=30, lineno=2, colno=22) + name: 'summon' + value: + + location: SourceLocation(pos=20, lineno=2, colno=12) + end_location: SourceLocation(pos=23, lineno=2, colno=15) + value: 'hex' diff --git a/tests/snapshots/bolt__parse_275__1.txt b/tests/snapshots/bolt__parse_275__1.txt new file mode 100644 index 0000000..5df2ff0 --- /dev/null +++ b/tests/snapshots/bolt__parse_275__1.txt @@ -0,0 +1,61 @@ +_bolt_lineno = [1, 9], [1, 2] +_bolt_helper_get_attribute = _bolt_runtime.helpers['get_attribute'] +_bolt_helper_interpolate_word = _bolt_runtime.helpers['interpolate_word'] +_bolt_helper_replace = _bolt_runtime.helpers['replace'] +_bolt_helper_children = _bolt_runtime.helpers['children'] +with _bolt_runtime.scope() as _bolt_var2: + _bolt_var0 = 42 + hex = _bolt_var0 + _bolt_var1 = hex + _bolt_var1 = _bolt_helper_get_attribute(_bolt_var1, 'summon') + _bolt_var1 = _bolt_helper_interpolate_word(_bolt_var1, _bolt_refs[0]) + _bolt_runtime.commands.append(_bolt_helper_replace(_bolt_refs[4], arguments=_bolt_helper_children([_bolt_helper_replace(_bolt_refs[3], fragments=_bolt_helper_children([_bolt_helper_replace(_bolt_refs[2], arguments=_bolt_helper_children([_bolt_helper_replace(_bolt_refs[1], value=_bolt_var1)]))]))]))) +_bolt_var3 = _bolt_helper_replace(_bolt_refs[5], commands=_bolt_helper_children(_bolt_var2)) +--- +output = _bolt_var3 +--- +_bolt_refs[0] + + location: SourceLocation(pos=20, lineno=2, colno=12) + end_location: SourceLocation(pos=30, lineno=2, colno=22) + prefix: None + unpack: None + converter: 'word' + value: + +_bolt_refs[1] + + location: SourceLocation(pos=16, lineno=2, colno=8) + end_location: SourceLocation(pos=30, lineno=2, colno=22) + inverted: False + key: + + value: + +_bolt_refs[2] + + location: SourceLocation(pos=13, lineno=2, colno=5) + end_location: SourceLocation(pos=31, lineno=2, colno=23) + variable: 's' + arguments: + +_bolt_refs[3] + + location: SourceLocation(pos=13, lineno=2, colno=5) + end_location: SourceLocation(pos=31, lineno=2, colno=23) + fragments: + +_bolt_refs[4] + + location: SourceLocation(pos=9, lineno=2, colno=1) + end_location: SourceLocation(pos=31, lineno=2, colno=23) + identifier: 'say:message' + arguments: + +_bolt_refs[5] + + location: SourceLocation(pos=0, lineno=1, colno=1) + end_location: SourceLocation(pos=31, lineno=2, colno=23) + commands: + + diff --git a/tests/snapshots/bolt__parse_276__0.txt b/tests/snapshots/bolt__parse_276__0.txt new file mode 100644 index 0000000..1631d50 --- /dev/null +++ b/tests/snapshots/bolt__parse_276__0.txt @@ -0,0 +1,50 @@ +say @s[tag=hex(42)] +--- + + location: SourceLocation(pos=0, lineno=1, colno=1) + end_location: SourceLocation(pos=19, lineno=1, colno=20) + commands: + + location: SourceLocation(pos=0, lineno=1, colno=1) + end_location: SourceLocation(pos=19, lineno=1, colno=20) + identifier: 'say:message' + arguments: + + location: SourceLocation(pos=4, lineno=1, colno=5) + end_location: SourceLocation(pos=19, lineno=1, colno=20) + fragments: + + location: SourceLocation(pos=4, lineno=1, colno=5) + end_location: SourceLocation(pos=19, lineno=1, colno=20) + variable: 's' + arguments: + + location: SourceLocation(pos=7, lineno=1, colno=8) + end_location: SourceLocation(pos=18, lineno=1, colno=19) + inverted: False + key: + + location: SourceLocation(pos=7, lineno=1, colno=8) + end_location: SourceLocation(pos=10, lineno=1, colno=11) + value: 'tag' + value: + + location: SourceLocation(pos=11, lineno=1, colno=12) + end_location: SourceLocation(pos=18, lineno=1, colno=19) + prefix: None + unpack: None + converter: 'word' + value: + + location: SourceLocation(pos=11, lineno=1, colno=12) + end_location: SourceLocation(pos=18, lineno=1, colno=19) + value: + + location: SourceLocation(pos=11, lineno=1, colno=12) + end_location: SourceLocation(pos=14, lineno=1, colno=15) + value: 'hex' + arguments: + + location: SourceLocation(pos=15, lineno=1, colno=16) + end_location: SourceLocation(pos=17, lineno=1, colno=18) + value: 42 diff --git a/tests/snapshots/bolt__parse_276__1.txt b/tests/snapshots/bolt__parse_276__1.txt new file mode 100644 index 0000000..22242c8 --- /dev/null +++ b/tests/snapshots/bolt__parse_276__1.txt @@ -0,0 +1,58 @@ +_bolt_lineno = [1], [1] +_bolt_helper_interpolate_word = _bolt_runtime.helpers['interpolate_word'] +_bolt_helper_replace = _bolt_runtime.helpers['replace'] +_bolt_helper_children = _bolt_runtime.helpers['children'] +with _bolt_runtime.scope() as _bolt_var2: + _bolt_var0 = hex + _bolt_var1 = 42 + _bolt_var0 = _bolt_var0(_bolt_var1) + _bolt_var0 = _bolt_helper_interpolate_word(_bolt_var0, _bolt_refs[0]) + _bolt_runtime.commands.append(_bolt_helper_replace(_bolt_refs[4], arguments=_bolt_helper_children([_bolt_helper_replace(_bolt_refs[3], fragments=_bolt_helper_children([_bolt_helper_replace(_bolt_refs[2], arguments=_bolt_helper_children([_bolt_helper_replace(_bolt_refs[1], value=_bolt_var0)]))]))]))) +_bolt_var3 = _bolt_helper_replace(_bolt_refs[5], commands=_bolt_helper_children(_bolt_var2)) +--- +output = _bolt_var3 +--- +_bolt_refs[0] + + location: SourceLocation(pos=11, lineno=1, colno=12) + end_location: SourceLocation(pos=18, lineno=1, colno=19) + prefix: None + unpack: None + converter: 'word' + value: + +_bolt_refs[1] + + location: SourceLocation(pos=7, lineno=1, colno=8) + end_location: SourceLocation(pos=18, lineno=1, colno=19) + inverted: False + key: + + value: + +_bolt_refs[2] + + location: SourceLocation(pos=4, lineno=1, colno=5) + end_location: SourceLocation(pos=19, lineno=1, colno=20) + variable: 's' + arguments: + +_bolt_refs[3] + + location: SourceLocation(pos=4, lineno=1, colno=5) + end_location: SourceLocation(pos=19, lineno=1, colno=20) + fragments: + +_bolt_refs[4] + + location: SourceLocation(pos=0, lineno=1, colno=1) + end_location: SourceLocation(pos=19, lineno=1, colno=20) + identifier: 'say:message' + arguments: + +_bolt_refs[5] + + location: SourceLocation(pos=0, lineno=1, colno=1) + end_location: SourceLocation(pos=19, lineno=1, colno=20) + commands: + diff --git a/tests/snapshots/bolt__parse_277__0.txt b/tests/snapshots/bolt__parse_277__0.txt new file mode 100644 index 0000000..bb45f1a --- /dev/null +++ b/tests/snapshots/bolt__parse_277__0.txt @@ -0,0 +1,5 @@ +#>ERROR Expected literal 'day', literal 'midnight', literal 'night', literal 'noon' or time but got literal 'hex.time'. +# line 1, column 10 +# 1 | time set hex.time +# : ^^^^^^^^ +time set hex.time diff --git a/tests/snapshots/bolt__parse_278__0.txt b/tests/snapshots/bolt__parse_278__0.txt new file mode 100644 index 0000000..dc0ee18 --- /dev/null +++ b/tests/snapshots/bolt__parse_278__0.txt @@ -0,0 +1,48 @@ +hex = 123 +time set hex.time +--- + + location: SourceLocation(pos=0, lineno=1, colno=1) + end_location: SourceLocation(pos=28, lineno=3, colno=1) + commands: + + location: SourceLocation(pos=0, lineno=1, colno=1) + end_location: SourceLocation(pos=9, lineno=1, colno=10) + identifier: 'statement' + arguments: + + location: SourceLocation(pos=0, lineno=1, colno=1) + end_location: SourceLocation(pos=9, lineno=1, colno=10) + operator: '=' + target: + + location: SourceLocation(pos=0, lineno=1, colno=1) + end_location: SourceLocation(pos=3, lineno=1, colno=4) + value: 'hex' + rebind: False + value: + + location: SourceLocation(pos=6, lineno=1, colno=7) + end_location: SourceLocation(pos=9, lineno=1, colno=10) + value: 123 + + location: SourceLocation(pos=10, lineno=2, colno=1) + end_location: SourceLocation(pos=27, lineno=2, colno=18) + identifier: 'time:set:time' + arguments: + + location: SourceLocation(pos=19, lineno=2, colno=10) + end_location: SourceLocation(pos=27, lineno=2, colno=18) + prefix: None + unpack: None + converter: 'time' + value: + + location: SourceLocation(pos=19, lineno=2, colno=10) + end_location: SourceLocation(pos=27, lineno=2, colno=18) + name: 'time' + value: + + location: SourceLocation(pos=19, lineno=2, colno=10) + end_location: SourceLocation(pos=22, lineno=2, colno=13) + value: 'hex' diff --git a/tests/snapshots/bolt__parse_278__1.txt b/tests/snapshots/bolt__parse_278__1.txt new file mode 100644 index 0000000..2421431 --- /dev/null +++ b/tests/snapshots/bolt__parse_278__1.txt @@ -0,0 +1,39 @@ +_bolt_lineno = [1, 9], [1, 2] +_bolt_helper_get_attribute = _bolt_runtime.helpers['get_attribute'] +_bolt_helper_interpolate_time = _bolt_runtime.helpers['interpolate_time'] +_bolt_helper_children = _bolt_runtime.helpers['children'] +_bolt_helper_replace = _bolt_runtime.helpers['replace'] +with _bolt_runtime.scope() as _bolt_var2: + _bolt_var0 = 123 + hex = _bolt_var0 + _bolt_var1 = hex + _bolt_var1 = _bolt_helper_get_attribute(_bolt_var1, 'time') + _bolt_var1 = _bolt_helper_interpolate_time(_bolt_var1, _bolt_refs[0]) + _bolt_runtime.commands.append(_bolt_helper_replace(_bolt_refs[1], arguments=_bolt_helper_children([_bolt_var1]))) +_bolt_var3 = _bolt_helper_replace(_bolt_refs[2], commands=_bolt_helper_children(_bolt_var2)) +--- +output = _bolt_var3 +--- +_bolt_refs[0] + + location: SourceLocation(pos=19, lineno=2, colno=10) + end_location: SourceLocation(pos=27, lineno=2, colno=18) + prefix: None + unpack: None + converter: 'time' + value: + +_bolt_refs[1] + + location: SourceLocation(pos=10, lineno=2, colno=1) + end_location: SourceLocation(pos=27, lineno=2, colno=18) + identifier: 'time:set:time' + arguments: + +_bolt_refs[2] + + location: SourceLocation(pos=0, lineno=1, colno=1) + end_location: SourceLocation(pos=28, lineno=3, colno=1) + commands: + + diff --git a/tests/snapshots/bolt__parse_279__0.txt b/tests/snapshots/bolt__parse_279__0.txt new file mode 100644 index 0000000..029166b --- /dev/null +++ b/tests/snapshots/bolt__parse_279__0.txt @@ -0,0 +1,31 @@ +time set hex(123) +--- + + location: SourceLocation(pos=0, lineno=1, colno=1) + end_location: SourceLocation(pos=18, lineno=2, colno=1) + commands: + + location: SourceLocation(pos=0, lineno=1, colno=1) + end_location: SourceLocation(pos=17, lineno=1, colno=18) + identifier: 'time:set:time' + arguments: + + location: SourceLocation(pos=9, lineno=1, colno=10) + end_location: SourceLocation(pos=17, lineno=1, colno=18) + prefix: None + unpack: None + converter: 'time' + value: + + location: SourceLocation(pos=9, lineno=1, colno=10) + end_location: SourceLocation(pos=17, lineno=1, colno=18) + value: + + location: SourceLocation(pos=9, lineno=1, colno=10) + end_location: SourceLocation(pos=12, lineno=1, colno=13) + value: 'hex' + arguments: + + location: SourceLocation(pos=13, lineno=1, colno=14) + end_location: SourceLocation(pos=16, lineno=1, colno=17) + value: 123 diff --git a/tests/snapshots/bolt__parse_279__1.txt b/tests/snapshots/bolt__parse_279__1.txt new file mode 100644 index 0000000..805ec06 --- /dev/null +++ b/tests/snapshots/bolt__parse_279__1.txt @@ -0,0 +1,36 @@ +_bolt_lineno = [1], [1] +_bolt_helper_interpolate_time = _bolt_runtime.helpers['interpolate_time'] +_bolt_helper_children = _bolt_runtime.helpers['children'] +_bolt_helper_replace = _bolt_runtime.helpers['replace'] +with _bolt_runtime.scope() as _bolt_var2: + _bolt_var0 = hex + _bolt_var1 = 123 + _bolt_var0 = _bolt_var0(_bolt_var1) + _bolt_var0 = _bolt_helper_interpolate_time(_bolt_var0, _bolt_refs[0]) + _bolt_runtime.commands.append(_bolt_helper_replace(_bolt_refs[1], arguments=_bolt_helper_children([_bolt_var0]))) +_bolt_var3 = _bolt_helper_replace(_bolt_refs[2], commands=_bolt_helper_children(_bolt_var2)) +--- +output = _bolt_var3 +--- +_bolt_refs[0] + + location: SourceLocation(pos=9, lineno=1, colno=10) + end_location: SourceLocation(pos=17, lineno=1, colno=18) + prefix: None + unpack: None + converter: 'time' + value: + +_bolt_refs[1] + + location: SourceLocation(pos=0, lineno=1, colno=1) + end_location: SourceLocation(pos=17, lineno=1, colno=18) + identifier: 'time:set:time' + arguments: + +_bolt_refs[2] + + location: SourceLocation(pos=0, lineno=1, colno=1) + end_location: SourceLocation(pos=18, lineno=2, colno=1) + commands: + diff --git a/tests/snapshots/bolt__parse_280__0.txt b/tests/snapshots/bolt__parse_280__0.txt new file mode 100644 index 0000000..a9e1462 --- /dev/null +++ b/tests/snapshots/bolt__parse_280__0.txt @@ -0,0 +1,34 @@ +say @s[tag=id] +--- + + location: SourceLocation(pos=0, lineno=1, colno=1) + end_location: SourceLocation(pos=14, lineno=1, colno=15) + commands: + + location: SourceLocation(pos=0, lineno=1, colno=1) + end_location: SourceLocation(pos=14, lineno=1, colno=15) + identifier: 'say:message' + arguments: + + location: SourceLocation(pos=4, lineno=1, colno=5) + end_location: SourceLocation(pos=14, lineno=1, colno=15) + fragments: + + location: SourceLocation(pos=4, lineno=1, colno=5) + end_location: SourceLocation(pos=14, lineno=1, colno=15) + variable: 's' + arguments: + + location: SourceLocation(pos=7, lineno=1, colno=8) + end_location: SourceLocation(pos=13, lineno=1, colno=14) + inverted: False + key: + + location: SourceLocation(pos=7, lineno=1, colno=8) + end_location: SourceLocation(pos=10, lineno=1, colno=11) + value: 'tag' + value: + + location: SourceLocation(pos=11, lineno=1, colno=12) + end_location: SourceLocation(pos=13, lineno=1, colno=14) + value: 'id' diff --git a/tests/snapshots/bolt__parse_280__1.txt b/tests/snapshots/bolt__parse_280__1.txt new file mode 100644 index 0000000..b7d1062 --- /dev/null +++ b/tests/snapshots/bolt__parse_280__1.txt @@ -0,0 +1,4 @@ +# Nothing +--- +output = None +---