Skip to content

Commit c263139

Browse files
committed
Use Locations when adding spans
Prior to this change, we were passing around integers when creating span information. This change uses locations instead. This has no functional change, but will make it easier to start passing through source position information in the following commit.
1 parent 8e08c30 commit c263139

File tree

2 files changed

+30
-18
lines changed

2 files changed

+30
-18
lines changed

fluent.syntax/fluent/syntax/ast.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import sys
44
from typing import Any, Callable, Dict, List, TypeVar, Union, cast
55

6+
from .stream import Location
7+
68
Node = TypeVar("Node", bound="BaseNode")
79
ToJsonFn = Callable[[Dict[str, Any]], Any]
810

@@ -121,7 +123,7 @@ def __init__(self, span: Union["Span", None] = None, **kwargs: Any):
121123
super().__init__(**kwargs)
122124
self.span = span
123125

124-
def add_span(self, start: int, end: int) -> None:
126+
def add_span(self, start: Location, end: Location) -> None:
125127
self.span = Span(start, end)
126128

127129

@@ -378,11 +380,19 @@ def add_annotation(self, annot: "Annotation") -> None:
378380

379381

380382
class Span(BaseNode):
381-
def __init__(self, start: int, end: int, **kwargs: Any):
383+
def __init__(self, start: Location, end: Location, **kwargs: Any):
382384
super().__init__(**kwargs)
383385
self.start = start
384386
self.end = end
385387

388+
@property
389+
def start_location(self) -> Location:
390+
return self.start
391+
392+
@property
393+
def end_location(self) -> Location:
394+
return self.end
395+
386396

387397
class Annotation(SyntaxNode):
388398
def __init__(

fluent.syntax/fluent/syntax/parser.py

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from . import ast
55
from .errors import ParseError
6-
from .stream import EOL, FluentParserStream
6+
from .stream import EOL, FluentParserStream, Location
77

88
R = TypeVar("R", bound=ast.SyntaxNode)
99

@@ -15,15 +15,15 @@ def decorated(
1515
if not self.with_spans:
1616
return fn(self, ps, *args, **kwargs)
1717

18-
start = ps.index
18+
start = ps.current_location
1919
node = fn(self, ps, *args, **kwargs)
2020

2121
# Don't re-add the span if the node already has it. This may happen
2222
# when one decorated function calls another decorated function.
2323
if node.span is not None:
2424
return node
2525

26-
end = ps.index
26+
end = ps.current_location
2727
node.add_span(start, end)
2828
return node
2929

@@ -85,7 +85,7 @@ def parse(self, source: str) -> ast.Resource:
8585
res = ast.Resource(entries)
8686

8787
if self.with_spans:
88-
res.add_span(0, ps.index)
88+
res.add_span(0, ps.current_location)
8989

9090
return res
9191

@@ -112,29 +112,31 @@ def parse_entry(self, source: str) -> ast.EntryType:
112112

113113
def get_entry_or_junk(self, ps: FluentParserStream) -> ast.EntryType:
114114
entry_start_index = ps.index
115+
entry_start_location = ps.current_location
115116

116117
try:
117118
entry = self.get_entry(ps)
118119
ps.expect_line_end()
119120
return entry
120121
except ParseError as err:
121122
error_index = ps.index
123+
error_location = ps.current_location
122124

123125
ps.skip_to_next_entry_start(entry_start_index)
124126
next_entry_start_index = ps.index
125127
if next_entry_start_index < error_index:
126128
# The position of the error must be inside of the Junk's span.
127-
error_index = next_entry_start_index
129+
error_location = ps.current_location
128130

129131
# Create a Junk instance
130132
slice = ps.string[entry_start_index:next_entry_start_index]
131133
junk = ast.Junk(slice)
132134
if self.with_spans:
133-
junk.add_span(entry_start_index, next_entry_start_index)
135+
junk.add_span(entry_start_location, ps.current_location)
134136
annot = ast.Annotation(
135137
err.code, list(err.args) if err.args else None, err.message
136138
)
137-
annot.add_span(error_index, error_index)
139+
annot.add_span(error_location, error_location)
138140
junk.add_annotation(annot)
139141
return junk
140142

@@ -380,24 +382,24 @@ def get_pattern(self, ps: FluentParserStream, is_block: bool) -> ast.Pattern:
380382
if is_block:
381383
# A block pattern is a pattern which starts on a new line. Measure
382384
# the indent of this first line for the dedentation logic.
383-
blank_start = ps.index
385+
blank_start = ps.current_location
384386
first_indent = ps.skip_blank_inline()
385-
elements.append(self.Indent(first_indent, blank_start, ps.index))
387+
elements.append(self.Indent(first_indent, blank_start, ps.current_location))
386388
common_indent_length = len(first_indent)
387389
else:
388390
# Should get fixed by the subsequent min() operation
389391
common_indent_length = cast(int, float("infinity"))
390392

391393
while ps.current_char:
392394
if ps.current_char == EOL:
393-
blank_start = ps.index
395+
blank_start = ps.current_location
394396
blank_lines = ps.peek_blank_block()
395397
if ps.is_value_continuation():
396398
ps.skip_to_peek()
397399
indent = ps.skip_blank_inline()
398400
common_indent_length = min(common_indent_length, len(indent))
399401
elements.append(
400-
self.Indent(blank_lines + indent, blank_start, ps.index)
402+
self.Indent(blank_lines + indent, blank_start, ps.current_location)
401403
)
402404
continue
403405

@@ -421,7 +423,7 @@ def get_pattern(self, ps: FluentParserStream, is_block: bool) -> ast.Pattern:
421423
return ast.Pattern(dedented)
422424

423425
class Indent(ast.SyntaxNode):
424-
def __init__(self, value: str, start: int, end: int):
426+
def __init__(self, value: str, start: Location, end: Location):
425427
super(FluentParser.Indent, self).__init__()
426428
self.value = value
427429
self.add_span(start, end)
@@ -454,8 +456,8 @@ def dedent(
454456
sum = ast.TextElement(prev.value + element.value)
455457
if self.with_spans:
456458
sum.add_span(
457-
cast(ast.Span, prev.span).start,
458-
cast(ast.Span, element.span).end,
459+
cast(ast.Span, prev.span).start_location,
460+
cast(ast.Span, element.span).end_location,
459461
)
460462
trimmed[-1] = sum
461463
continue
@@ -466,8 +468,8 @@ def dedent(
466468
text_element = ast.TextElement(element.value)
467469
if self.with_spans:
468470
text_element.add_span(
469-
cast(ast.Span, element.span).start,
470-
cast(ast.Span, element.span).end,
471+
cast(ast.Span, element.span).start_location,
472+
cast(ast.Span, element.span).end_location,
471473
)
472474
element = text_element
473475

0 commit comments

Comments
 (0)