1 | // @flow
|
2 | import type {LexerInterface} from "./Token";
|
3 |
|
4 | /**
|
5 | * Lexing or parsing positional information for error reporting.
|
6 | * This object is immutable.
|
7 | */
|
8 | export default class SourceLocation {
|
9 | // The + prefix indicates that these fields aren't writeable
|
10 | +lexer: LexerInterface; // Lexer holding the input string.
|
11 | +start: number; // Start offset, zero-based inclusive.
|
12 | +end: number; // End offset, zero-based exclusive.
|
13 |
|
14 | constructor(lexer: LexerInterface, start: number, end: number) {
|
15 | this.lexer = lexer;
|
16 | this.start = start;
|
17 | this.end = end;
|
18 | }
|
19 |
|
20 | /**
|
21 | * Merges two `SourceLocation`s from location providers, given they are
|
22 | * provided in order of appearance.
|
23 | * - Returns the first one's location if only the first is provided.
|
24 | * - Returns a merged range of the first and the last if both are provided
|
25 | * and their lexers match.
|
26 | * - Otherwise, returns null.
|
27 | */
|
28 | static range(
|
29 | first?: {loc: ?SourceLocation},
|
30 | second?: {loc: ?SourceLocation},
|
31 | ): ?SourceLocation {
|
32 | if (!second) {
|
33 | return first && first.loc;
|
34 | } else if (!first || !first.loc || !second.loc ||
|
35 | first.loc.lexer !== second.loc.lexer) {
|
36 | return null;
|
37 | } else {
|
38 | return new SourceLocation(
|
39 | first.loc.lexer, first.loc.start, second.loc.end);
|
40 | }
|
41 | }
|
42 | }
|