/
angular.js
115 lines (108 loc) · 3.09 KB
/
angular.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
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
import { join, line, group } from "../../document/builders.js";
import UnexpectedNodeError from "../../utils/unexpected-node-error.js";
import {
hasNode,
hasComment,
getComments,
createTypeCheckFunction,
} from "../utils/index.js";
import { printBinaryishExpression } from "./binaryish.js";
/** @typedef {import("../../common/ast-path.js").default} AstPath */
function printAngular(path, options, print) {
const { node } = path;
// Angular nodes always starts with `NG`
if (!node.type.startsWith("NG")) {
return;
}
switch (node.type) {
case "NGRoot":
return [
print("node"),
hasComment(node.node)
? " //" + getComments(node.node)[0].value.trimEnd()
: "",
];
case "NGPipeExpression":
return printBinaryishExpression(path, options, print);
case "NGChainedExpression":
return group(
join(
[";", line],
path.map(
() => (hasNgSideEffect(path) ? print() : ["(", print(), ")"]),
"expressions",
),
),
);
case "NGEmptyExpression":
return "";
case "NGMicrosyntax":
return path.map(
() => [
path.isFirst ? "" : isNgForOf(path) ? " " : [";", line],
print(),
],
"body",
);
case "NGMicrosyntaxKey":
return /^[$_a-z][\w$]*(?:-[$_a-z][\w$])*$/i.test(node.name)
? node.name
: JSON.stringify(node.name);
case "NGMicrosyntaxExpression":
return [
print("expression"),
node.alias === null ? "" : [" as ", print("alias")],
];
case "NGMicrosyntaxKeyedExpression": {
const { index, parent } = path;
const shouldNotPrintColon =
isNgForOf(path) ||
(((index === 1 &&
(node.key.name === "then" || node.key.name === "else")) ||
(index === 2 &&
node.key.name === "else" &&
parent.body[index - 1].type === "NGMicrosyntaxKeyedExpression" &&
parent.body[index - 1].key.name === "then")) &&
parent.body[0].type === "NGMicrosyntaxExpression");
return [
print("key"),
shouldNotPrintColon ? " " : ": ",
print("expression"),
];
}
case "NGMicrosyntaxLet":
return [
"let ",
print("key"),
node.value === null ? "" : [" = ", print("value")],
];
case "NGMicrosyntaxAs":
return [print("key"), " as ", print("alias")];
default:
/* c8 ignore next */
throw new UnexpectedNodeError(node, "Angular");
}
}
function isNgForOf({ node, index, parent }) {
return (
node.type === "NGMicrosyntaxKeyedExpression" &&
node.key.name === "of" &&
index === 1 &&
parent.body[0].type === "NGMicrosyntaxLet" &&
parent.body[0].value === null
);
}
const hasSideEffect = createTypeCheckFunction([
"CallExpression",
"OptionalCallExpression",
"AssignmentExpression",
]);
/** identify if an angular expression seems to have side effects */
/**
* @param {AstPath} path
* @returns {boolean}
*/
function hasNgSideEffect({ node }) {
return hasNode(node, hasSideEffect);
}
export { printAngular };