forked from prettier/angular-estree-parser
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathangular-parser.ts
More file actions
95 lines (82 loc) · 2.46 KB
/
angular-parser.ts
File metadata and controls
95 lines (82 loc) · 2.46 KB
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
import {
type ASTWithSource,
Lexer,
ParseLocation,
Parser,
ParseSourceFile,
ParseSourceSpan,
type TemplateBindingParseResult,
} from '@angular/compiler';
import { type CommentLine } from './types.ts';
import { sourceSpanToLocationInformation } from './utils.ts';
let parseSourceSpan: ParseSourceSpan;
// https://github.com/angular/angular/blob/5e9707dc84e6590ec8c9d41e7d3be7deb2fa7c53/packages/compiler/test/expression_parser/utils/span.ts
function getParseSourceSpan() {
if (!parseSourceSpan) {
const file = new ParseSourceFile('', 'test.html');
const location = new ParseLocation(file, -1, -1, -1);
parseSourceSpan = new ParseSourceSpan(location, location);
}
return parseSourceSpan;
}
let parser: Parser;
function getParser() {
return (parser ??= new Parser(new Lexer()));
}
const getCommentStart = (text: string): number | null =>
// @ts-expect-error -- need to call private _commentStart
Parser.prototype._commentStart(text);
function extractComments(text: string) {
const commentStart = getCommentStart(text);
if (commentStart === null) {
return [];
}
const comment: CommentLine = {
type: 'CommentLine',
value: text.slice(commentStart + '//'.length),
...sourceSpanToLocationInformation({
start: commentStart,
end: text.length,
}),
};
return [comment];
}
function throwErrors<
ResultType extends ASTWithSource | TemplateBindingParseResult,
>(result: ResultType) {
if (result.errors.length !== 0) {
const [{ message }] = result.errors;
throw new SyntaxError(
message.replace(/^Parser Error: | at column \d+ in [^]*$/g, ''),
);
}
return result;
}
const createAstParser =
(
name:
| 'parseBinding'
| 'parseSimpleBinding'
| 'parseAction'
| 'parseInterpolationExpression',
) =>
(text: string) => ({
result: throwErrors<ASTWithSource>(
getParser()[name](text, getParseSourceSpan(), 0),
),
text,
comments: extractComments(text),
});
export const parseAction = createAstParser('parseAction');
export const parseBinding = createAstParser('parseBinding');
export const parseSimpleBinding = createAstParser('parseSimpleBinding');
export const parseInterpolationExpression = createAstParser(
'parseInterpolationExpression',
);
export const parseTemplateBindings = (text: string) => ({
result: throwErrors<TemplateBindingParseResult>(
getParser().parseTemplateBindings('', text, getParseSourceSpan(), 0, 0),
),
text,
comments: [],
});