forked from prettier/prettier
/
typescript.js
77 lines (66 loc) · 2.4 KB
/
typescript.js
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
"use strict";
const isNonEmptyArray = require("../../../utils/is-non-empty-array.js");
const visitNode = require("./visit-node.js");
const throwSyntaxError = require("./throw-syntax-error.js");
// Copied from https://unpkg.com/typescript@4.8.2/lib/typescript.js
function getSourceFileOfNode(node) {
while (node && node.kind !== 305 /* SyntaxKind.SourceFile */) {
node = node.parent;
}
return node;
}
// Invalid decorators are removed since `@typescript-eslint/typescript-estree` v4
// https://github.com/typescript-eslint/typescript-eslint/pull/2375
// There is a `checkGrammarDecorators` in `typescript` package, consider use it directly in future
function throwErrorForInvalidDecorator(tsNode) {
const { illegalDecorators } = tsNode;
if (!isNonEmptyArray(illegalDecorators)) {
return;
}
const [{ expression }] = illegalDecorators;
const sourceFile = getSourceFileOfNode(expression);
const [start, end] = [expression.pos, expression.end].map((position) => {
const { line, character: column } =
sourceFile.getLineAndCharacterOfPosition(position);
return { line: line + 1, column };
});
throwSyntaxError({ loc: { start, end } }, "Decorators are not valid here.");
}
// Values of abstract property is removed since `@typescript-eslint/typescript-estree` v5
// https://github.com/typescript-eslint/typescript-eslint/releases/tag/v5.0.0
function throwErrorForInvalidAbstractProperty(tsNode, esTreeNode) {
const SYNTAX_KIND_PROPERTY_DEFINITION = 167;
const SYNTAX_KIND_ABSTRACT_KEYWORD = 126;
if (
tsNode.kind !== SYNTAX_KIND_PROPERTY_DEFINITION ||
(tsNode.modifiers &&
!tsNode.modifiers.some(
(modifier) => modifier.kind === SYNTAX_KIND_ABSTRACT_KEYWORD
))
) {
return;
}
if (tsNode.initializer && esTreeNode.value === null) {
throwSyntaxError(
esTreeNode,
"Abstract property cannot have an initializer"
);
}
}
function throwErrorForInvalidNodes(ast, options) {
const { esTreeNodeToTSNodeMap, tsNodeToESTreeNodeMap } =
options.tsParseResult;
visitNode(ast, (node) => {
const tsNode = esTreeNodeToTSNodeMap.get(node);
if (!tsNode) {
return;
}
const esTreeNode = tsNodeToESTreeNodeMap.get(tsNode);
if (esTreeNode !== node) {
return;
}
throwErrorForInvalidDecorator(tsNode);
throwErrorForInvalidAbstractProperty(tsNode, esTreeNode);
});
}
module.exports = { throwErrorForInvalidNodes };