source: trip-planner-front/node_modules/@webassemblyjs/ast/scripts/generateNodeUtils.js@ 6a3a178

Last change on this file since 6a3a178 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 5.2 KB
Line 
1const definitions = require("../src/definitions");
2const flatMap = require("array.prototype.flatmap");
3const {
4 typeSignature,
5 iterateProps,
6 mapProps,
7 filterProps,
8 unique
9} = require("./util");
10
11const stdout = process.stdout;
12
13const jsTypes = ["string", "number", "boolean"];
14
15const quote = value => `"${value}"`;
16
17function params(fields) {
18 const optionalDefault = field => (field.default ? ` = ${field.default}` : "");
19 return mapProps(fields)
20 .map(field => `${typeSignature(field)}${optionalDefault(field)}`)
21 .join(",");
22}
23
24function assertParamType({ assertNodeType, array, name, type }) {
25 if (array) {
26 // TODO - assert contents of array?
27 return `assert(typeof ${name} === "object" && typeof ${name}.length !== "undefined")\n`;
28 } else {
29 if (jsTypes.includes(type)) {
30 return `assert(
31 typeof ${name} === "${type}",
32 "Argument ${name} must be of type ${type}, given: " + typeof ${name}
33 )`;
34 }
35
36 if (assertNodeType === true) {
37 return `assert(
38 ${name}.type === "${type}",
39 "Argument ${name} must be of type ${type}, given: " + ${name}.type
40 )`;
41 }
42
43 return "";
44 }
45}
46
47function assertParam(meta) {
48 const paramAssertion = assertParamType(meta);
49
50 if (paramAssertion === "") {
51 return "";
52 }
53
54 if (meta.maybe || meta.optional) {
55 return `
56 if (${meta.name} !== null && ${meta.name} !== undefined) {
57 ${paramAssertion};
58 }
59 `;
60 } else {
61 return paramAssertion;
62 }
63}
64
65function assertParams(fields) {
66 return mapProps(fields)
67 .map(assertParam)
68 .join("\n");
69}
70
71function buildObject(typeDef) {
72 const optionalField = meta => {
73 if (meta.array) {
74 // omit optional array properties if the constructor function was supplied
75 // with an empty array
76 return `
77 if (typeof ${meta.name} !== "undefined" && ${meta.name}.length > 0) {
78 node.${meta.name} = ${meta.name};
79 }
80 `;
81 } else if (meta.type === "Object") {
82 // omit optional object properties if they have no keys
83 return `
84 if (typeof ${meta.name} !== "undefined" && Object.keys(${
85 meta.name
86 }).length !== 0) {
87 node.${meta.name} = ${meta.name};
88 }
89 `;
90 } else if (meta.type === "boolean") {
91 // omit optional boolean properties if they are not true
92 return `
93 if (${meta.name} === true) {
94 node.${meta.name} = true;
95 }
96 `;
97 } else {
98 return `
99 if (typeof ${meta.name} !== "undefined") {
100 node.${meta.name} = ${meta.name};
101 }
102 `;
103 }
104 };
105
106 const fields = mapProps(typeDef.fields)
107 .filter(f => !f.optional && !f.constant)
108 .map(f => f.name);
109
110 const constants = mapProps(typeDef.fields)
111 .filter(f => f.constant)
112 .map(f => `${f.name}: "${f.value}"`);
113
114 return `
115 const node: ${typeDef.flowTypeName || typeDef.name} = {
116 type: "${typeDef.name}",
117 ${constants.concat(fields).join(",")}
118 }
119
120 ${mapProps(typeDef.fields)
121 .filter(f => f.optional)
122 .map(optionalField)
123 .join("")}
124 `;
125}
126
127function lowerCamelCase(name) {
128 return name.substring(0, 1).toLowerCase() + name.substring(1);
129}
130
131function generate() {
132 stdout.write(`
133 // @flow
134
135 // THIS FILE IS AUTOGENERATED
136 // see scripts/generateNodeUtils.js
137
138 import { assert } from "mamacro";
139
140 function isTypeOf(t: string) {
141 return (n: Node) => n.type === t;
142 }
143
144 function assertTypeOf(t: string) {
145 return (n: Node) => assert(n.type === t);
146 }
147 `);
148
149 // Node builders
150 iterateProps(definitions, typeDefinition => {
151 stdout.write(`
152 export function ${lowerCamelCase(typeDefinition.name)} (
153 ${params(filterProps(typeDefinition.fields, f => !f.constant))}
154 ): ${typeDefinition.name} {
155
156 ${assertParams(filterProps(typeDefinition.fields, f => !f.constant))}
157 ${buildObject(typeDefinition)}
158
159 return node;
160 }
161 `);
162 });
163
164 // Node testers
165 iterateProps(definitions, typeDefinition => {
166 stdout.write(`
167 export const is${typeDefinition.name} =
168 isTypeOf("${typeDefinition.name}");
169 `);
170 });
171
172 // Node union type testers
173 const unionTypes = unique(
174 flatMap(mapProps(definitions).filter(d => d.unionType), d => d.unionType)
175 );
176 unionTypes.forEach(unionType => {
177 stdout.write(
178 `
179 export const is${unionType} = (node: Node) => ` +
180 mapProps(definitions)
181 .filter(d => d.unionType && d.unionType.includes(unionType))
182 .map(d => `is${d.name}(node) `)
183 .join("||") +
184 ";\n\n"
185 );
186 });
187
188 // Node assertion
189 iterateProps(definitions, typeDefinition => {
190 stdout.write(`
191 export const assert${typeDefinition.name} =
192 assertTypeOf("${typeDefinition.name}");
193 `);
194 });
195
196 // a map from node type to its set of union types
197 stdout.write(
198 `
199 export const unionTypesMap = {` +
200 mapProps(definitions)
201 .filter(d => d.unionType)
202 .map(t => `"${t.name}": [${t.unionType.map(quote).join(",")}]\n`) +
203 `};
204 `
205 );
206
207 // an array of all node and union types
208 stdout.write(
209 `
210 export const nodeAndUnionTypes = [` +
211 mapProps(definitions)
212 .map(t => `"${t.name}"`)
213 .concat(unionTypes.map(quote))
214 .join(",") +
215 `];`
216 );
217}
218
219generate();
Note: See TracBrowser for help on using the repository browser.