-
-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathparser.ts
116 lines (105 loc) · 2.98 KB
/
parser.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import {
Lexer,
Parser,
type ASTWithSource,
type Interpolation,
type ParserError,
} from '@angular/compiler';
import { type RawNGComment } from './types.js';
import { Context } from './context.js';
const NG_PARSE_FAKE_LOCATION = 'angular-estree-parser';
const NG_PARSE_TEMPLATE_BINDINGS_FAKE_PREFIX = 'NgEstreeParser';
const NG_PARSE_FAKE_ABSOLUTE_OFFSET = 0;
const NG_PARSE_SHARED_PARAMS: readonly [string, number] = [
NG_PARSE_FAKE_LOCATION,
NG_PARSE_FAKE_ABSOLUTE_OFFSET,
];
function createParser() {
return new Parser(new Lexer());
}
function parse(
text: string,
parse: (text: string, parser: Parser) => ASTWithSource,
) {
const context = new Context(text);
const parser = createParser();
const { text: textToParse, comments } = extractComments(text, parser);
const { ast, errors } = parse(textToParse, parser);
assertAstErrors(errors);
return { ast, comments, context };
}
function parseBinding(text: string) {
return parse(text, (text, parser) =>
parser.parseBinding(text, ...NG_PARSE_SHARED_PARAMS),
);
}
function parseSimpleBinding(text: string) {
return parse(text, (text, parser) =>
parser.parseSimpleBinding(text, ...NG_PARSE_SHARED_PARAMS),
);
}
function parseAction(text: string) {
return parse(text, (text, parser) =>
parser.parseAction(text, false, ...NG_PARSE_SHARED_PARAMS),
);
}
function parseInterpolationExpression(text: string) {
return parse(text, (text, parser) => {
const result = parser.parseInterpolationExpression(
text,
...NG_PARSE_SHARED_PARAMS,
);
result.ast = (result.ast as Interpolation).expressions[0];
return result;
});
}
function parseTemplateBindings(text: string) {
const context = new Context(text);
const parser = createParser();
const { templateBindings: expressions, errors } =
parser.parseTemplateBindings(
'',
text,
NG_PARSE_FAKE_LOCATION,
NG_PARSE_FAKE_ABSOLUTE_OFFSET,
NG_PARSE_FAKE_ABSOLUTE_OFFSET,
);
assertAstErrors(errors);
return { expressions, context };
}
function assertAstErrors(errors: ParserError[]) {
if (errors.length !== 0) {
const [{ message }] = errors;
throw new SyntaxError(
message.replace(/^Parser Error: | at column \d+ in [^]*$/g, ''),
);
}
}
function extractComments(
text: string,
parser: Parser,
): { text: string; comments: RawNGComment[] } {
// @ts-expect-error -- need to call private _commentStart
const getCommentStart = parser._commentStart;
const commentStart: number | null = getCommentStart(text);
return commentStart === null
? { text, comments: [] }
: {
text: text.slice(0, commentStart),
comments: [
{
type: 'Comment',
value: text.slice(commentStart + '//'.length),
sourceSpan: { start: commentStart, end: text.length },
},
],
};
}
export {
NG_PARSE_TEMPLATE_BINDINGS_FAKE_PREFIX,
parseBinding,
parseSimpleBinding,
parseAction,
parseInterpolationExpression,
parseTemplateBindings,
};