@marko/compiler 5.38.4 → 5.39.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,199 @@
1
+ "use strict";exports.__esModule = true;exports.parseArgs = parseArgs;exports.parseExpression = parseExpression;exports.parseParams = parseParams;exports.parseStatements = parseStatements;exports.parseTemplateLiteral = parseTemplateLiteral;exports.parseTypeArgs = parseTypeArgs;exports.parseTypeParams = parseTypeParams;exports.parseVar = parseVar;var babelParser = _interopRequireWildcard(require("@babel/parser"));
2
+ var _compiler = require("@marko/compiler");
3
+
4
+ var _loc = require("./loc");function _getRequireWildcardCache(e) {if ("function" != typeof WeakMap) return null;var r = new WeakMap(),t = new WeakMap();return (_getRequireWildcardCache = function (e) {return e ? t : r;})(e);}function _interopRequireWildcard(e, r) {if (!r && e && e.__esModule) return e;if (null === e || "object" != typeof e && "function" != typeof e) return { default: e };var t = _getRequireWildcardCache(r);if (t && t.has(e)) return t.get(e);var n = { __proto__: null },a = Object.defineProperty && Object.getOwnPropertyDescriptor;for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) {var i = a ? Object.getOwnPropertyDescriptor(e, u) : null;i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u];}return n.default = e, t && t.set(e, n), n;}
5
+
6
+ function parseStatements(
7
+ file,
8
+ str,
9
+ sourceStart,
10
+ sourceEnd,
11
+ sourceOffset)
12
+ {
13
+ return tryParse(file, false, str, sourceStart, sourceEnd, sourceOffset);
14
+ }
15
+
16
+ function parseExpression(
17
+ file,
18
+ str,
19
+ sourceStart,
20
+ sourceEnd,
21
+ sourceOffset)
22
+ {
23
+ return tryParse(file, true, str, sourceStart, sourceEnd, sourceOffset);
24
+ }
25
+
26
+ function parseParams(file, str, sourceStart, sourceEnd) {
27
+ const parsed = parseExpression(
28
+ file,
29
+ `(${str})=>{}`,
30
+ sourceStart,
31
+ sourceEnd,
32
+ 1
33
+ );
34
+
35
+ if (parsed.type === "ArrowFunctionExpression") {
36
+ return parsed.params;
37
+ }
38
+
39
+ return [ensureParseError(file, parsed, sourceStart, sourceEnd)];
40
+ }
41
+
42
+ function parseArgs(file, str, sourceStart, sourceEnd) {
43
+ const parsed = parseExpression(file, `_(${str})`, sourceStart, sourceEnd, 2);
44
+
45
+ if (parsed.type === "CallExpression") {
46
+ return parsed.arguments;
47
+ }
48
+
49
+ return [ensureParseError(file, parsed, sourceStart, sourceEnd)];
50
+ }
51
+
52
+ function parseVar(file, str, sourceStart, sourceEnd) {
53
+ const parsed = parseExpression(
54
+ file,
55
+ `(${str})=>{}`,
56
+ sourceStart,
57
+ sourceEnd,
58
+ 1
59
+ );
60
+
61
+ if (parsed.type === "ArrowFunctionExpression" && parsed.params.length === 1) {
62
+ return parsed.params[0];
63
+ }
64
+
65
+ return ensureParseError(file, parsed, sourceStart, sourceEnd);
66
+ }
67
+
68
+ function parseTemplateLiteral(file, str, sourceStart, sourceEnd) {
69
+ const parsed = parseExpression(
70
+ file,
71
+ "`" + str + "`",
72
+ sourceStart,
73
+ sourceEnd,
74
+ 1
75
+ );
76
+
77
+ if (parsed.type === "TemplateLiteral") {
78
+ return parsed;
79
+ }
80
+
81
+ return ensureParseError(file, parsed, sourceStart, sourceEnd);
82
+ }
83
+
84
+ function parseTypeArgs(file, str, sourceStart, sourceEnd) {
85
+ const parsed = parseExpression(file, `_<${str}>`, sourceStart, sourceEnd, 2);
86
+
87
+ if (parsed.type === "TSInstantiationExpression") {
88
+ // typeArguments is Flow only (not TS), we need to use typeParameters
89
+ return parsed.typeParameters;
90
+ }
91
+
92
+ return [ensureParseError(file, parsed, sourceStart, sourceEnd)];
93
+ }
94
+
95
+ function parseTypeParams(file, str, sourceStart, sourceEnd) {
96
+ const parsed = parseExpression(
97
+ file,
98
+ `<${str}>()=>{}`,
99
+ sourceStart,
100
+ sourceEnd,
101
+ 1
102
+ );
103
+
104
+ if (parsed.type === "ArrowFunctionExpression") {
105
+ return parsed.typeParameters;
106
+ }
107
+
108
+ return [ensureParseError(file, parsed, sourceStart, sourceEnd)];
109
+ }
110
+
111
+ function tryParse(
112
+ file,
113
+ isExpression,
114
+ code,
115
+ sourceStart,
116
+ sourceEnd,
117
+ sourceOffset)
118
+ {
119
+ const { parserOpts } = file.opts;
120
+
121
+ if (typeof sourceStart === "number") {
122
+ const startIndex = sourceStart - (sourceOffset || 0);
123
+ const startLoc = (0, _loc.getLoc)(file, startIndex);
124
+ parserOpts.startIndex = startIndex;
125
+ parserOpts.startColumn = startLoc.column;
126
+ parserOpts.startLine = startLoc.line;
127
+
128
+ try {
129
+ return isExpression ?
130
+ babelParser.parseExpression(code, parserOpts) :
131
+ babelParser.parse(code, parserOpts).program.body;
132
+ } catch (err) {
133
+ const parseError = createParseError(
134
+ file,
135
+ sourceStart,
136
+ sourceEnd,
137
+ err.message,
138
+ err.loc
139
+ );
140
+
141
+ if (isExpression) {
142
+ return parseError;
143
+ } else {
144
+ return [parseError];
145
+ }
146
+ } finally {
147
+ parserOpts.startIndex = 0;
148
+ parserOpts.startColumn = 0;
149
+ parserOpts.startLine = 1;
150
+ }
151
+ } else {
152
+ return isExpression ?
153
+ _compiler.types.cloneDeepWithoutLoc(babelParser.parseExpression(code, parserOpts)) :
154
+ babelParser.
155
+ parse(code, parserOpts).
156
+ program.body.map((node) => _compiler.types.cloneDeepWithoutLoc(node));
157
+ }
158
+ }
159
+
160
+ function ensureParseError(file, node, sourceStart, sourceEnd) {
161
+ if (node.type === "MarkoParseError") return node;
162
+ return createParseError(
163
+ file,
164
+ sourceStart,
165
+ sourceEnd,
166
+ `Unexpected node of type ${node.type} returned while parsing.`
167
+ );
168
+ }
169
+
170
+ function createParseError(file, sourceStart, sourceEnd, label, errorLoc) {
171
+ file.___hasParseErrors = true;
172
+ const loc = (0, _loc.getLocRange)(file, sourceStart, sourceEnd);
173
+ return {
174
+ type: "MarkoParseError",
175
+ source: file.code.slice(sourceStart, sourceEnd),
176
+ label: label.replace(/ *\(\d+:\d+\)$/, ""),
177
+ errorLoc: errorLoc && getBoundedRange(loc, errorLoc),
178
+ loc,
179
+ start: sourceStart,
180
+ end: sourceEnd
181
+ };
182
+ }
183
+
184
+ function getBoundedRange(range, loc) {
185
+ if (loc && typeof loc.line === "number") {
186
+ const { start, end } = range;
187
+ // If start is out of bounds return the source.
188
+ if (
189
+ loc.line < start.line ||
190
+ loc.line === start.line && loc.column < start.column ||
191
+ loc.line > end.line ||
192
+ loc.line === end.line && loc.column > end.column)
193
+ {
194
+ return range;
195
+ }
196
+
197
+ return { start: loc, end: loc };
198
+ }
199
+ }
@@ -0,0 +1,27 @@
1
+ "use strict";exports.__esModule = true;exports.getTagDefForTagName = getTagDefForTagName;exports.getTaglibLookup = getTaglibLookup;const SEEN_TAGS_KEY = Symbol();
2
+
3
+ function getTaglibLookup(file) {
4
+ return file.___taglibLookup;
5
+ }
6
+
7
+ function getTagDefForTagName(file, tagName) {
8
+ const tagDef = getTaglibLookup(file).getTag(tagName);
9
+
10
+ if (tagDef) {
11
+ let seen = file.metadata.marko[SEEN_TAGS_KEY];
12
+ if (!seen) {
13
+ seen = file.metadata.marko[SEEN_TAGS_KEY] = new Set();
14
+ }
15
+
16
+ if (!seen.has(tagDef)) {
17
+ seen.add(tagName);
18
+ const { filePath } = tagDef;
19
+ const len = filePath.length;
20
+
21
+ if (filePath[len - 14] === "m" && filePath.endsWith("marko-tag.json")) {
22
+ file.metadata.marko.watchFiles.push(filePath);
23
+ }
24
+ }
25
+ }
26
+ return tagDef;
27
+ }
@@ -0,0 +1,430 @@
1
+ "use strict";var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");exports.__esModule = true;exports.findAttributeTags = findAttributeTags;exports.findParentTag = findParentTag;exports.getArgOrSequence = getArgOrSequence;exports.getFullyResolvedTagName = getFullyResolvedTagName;exports.getMacroIdentifier = getMacroIdentifier;exports.getMacroIdentifierForName = getMacroIdentifierForName;exports.getTagDef = getTagDef;exports.getTagTemplate = getTagTemplate;exports.getTemplateId = getTemplateId;exports.hasMacro = hasMacro;exports.isAttributeTag = isAttributeTag;exports.isDynamicTag = isDynamicTag;exports.isLoopTag = isLoopTag;exports.isMacroTag = isMacroTag;exports.isNativeTag = isNativeTag;exports.isTransparentTag = isTransparentTag;exports.loadFileForImport = loadFileForImport;exports.loadFileForTag = loadFileForTag;exports.registerMacro = registerMacro;exports.resolveTagImport = resolveTagImport;var _compiler = require("@marko/compiler");
2
+ var _crypto = require("crypto");
3
+ var _lassoPackageRoot = require("lasso-package-root");
4
+ var _path = require("path");
5
+ var _resolveFrom = _interopRequireDefault(require("resolve-from"));
6
+
7
+ var _diagnostics = require("./diagnostics");
8
+ var _imports = require("./imports");
9
+ var _taglib = require("./taglib");
10
+
11
+ const MACRO_IDS_KEY = Symbol();
12
+ const MACRO_NAMES_KEY = "__marko_macro_names__"; // must be a string literal since it is used across compiler stages.
13
+ const TRANSPARENT_TAGS = new Set([
14
+ "for",
15
+ "while",
16
+ "if",
17
+ "else",
18
+ "else-if",
19
+ "_no-update"]
20
+ );
21
+
22
+ const CWD = process.cwd();
23
+ let ROOT = CWD;
24
+ try {
25
+ ROOT = (0, _lassoPackageRoot.getRootDir)(ROOT) || ROOT;
26
+ // eslint-disable-next-line no-empty
27
+ } catch {}
28
+
29
+ function isNativeTag(path) {
30
+ if (path.node._isDynamicString) {
31
+ return true;
32
+ }
33
+
34
+ const tagDef = getTagDef(path);
35
+ return (
36
+ tagDef &&
37
+ tagDef.html && (
38
+ tagDef.htmlType === "custom-element" ||
39
+ !tagDef.template && !tagDef.renderer));
40
+
41
+ }
42
+
43
+ function isDynamicTag(path) {
44
+ return !_compiler.types.isStringLiteral(path.node.name);
45
+ }
46
+
47
+ function isAttributeTag(path) {
48
+ const {
49
+ node: { name }
50
+ } = path;
51
+ return _compiler.types.isStringLiteral(name) && name.value[0] === "@";
52
+ }
53
+
54
+ function isTransparentTag(path) {
55
+ const {
56
+ node: { name }
57
+ } = path;
58
+ return _compiler.types.isStringLiteral(name) && TRANSPARENT_TAGS.has(name.value);
59
+ }
60
+
61
+ function registerMacro(path, name) {
62
+ const { file } = path.hub;
63
+ const markoMeta = file.metadata.marko;
64
+ const macroNames = markoMeta[MACRO_NAMES_KEY];
65
+
66
+ if (macroNames) {
67
+ if (macroNames[name]) {
68
+ (0, _diagnostics.diagnosticWarn)(path, {
69
+ label: `A macro with the name "${name}" already exists.`,
70
+ fix() {
71
+ findParentTag(path).remove();
72
+ }
73
+ });
74
+ }
75
+ macroNames[name] = true;
76
+ } else {
77
+ markoMeta[MACRO_NAMES_KEY] = { [name]: true };
78
+ }
79
+ }
80
+
81
+ function hasMacro(path, name) {
82
+ const macroNames = path.hub.file.metadata.marko[MACRO_NAMES_KEY];
83
+ return !!(macroNames && macroNames[name]);
84
+ }
85
+
86
+ function isMacroTag(path) {
87
+ const { name } = path.node;
88
+ return _compiler.types.isStringLiteral(name) && hasMacro(path, name.value);
89
+ }
90
+
91
+ function getMacroIdentifierForName(path, name) {
92
+ const { file } = path.hub;
93
+
94
+ if (file.___compileStage !== "translate") {
95
+ throw new Error(
96
+ "getMacroIdentifierForName can only be called during the translate phase of the compiler."
97
+ );
98
+ }
99
+
100
+ const markoMeta = file.metadata.marko;
101
+ let macroIds = markoMeta[MACRO_IDS_KEY];
102
+
103
+ if (!macroIds) {
104
+ macroIds = markoMeta[MACRO_IDS_KEY] = {};
105
+
106
+ for (const macroName in markoMeta[MACRO_NAMES_KEY]) {
107
+ macroIds[macroName] = file.path.scope.generateUid(macroName);
108
+ }
109
+ }
110
+
111
+ const id = macroIds[name];
112
+
113
+ if (!id) {
114
+ throw new Error(
115
+ "<macro> was added programmatically, but was not registered via the 'registerMacro' api in @marko/compiler/babel-utils."
116
+ );
117
+ }
118
+
119
+ return _compiler.types.identifier(id);
120
+ }
121
+
122
+ function getMacroIdentifier(path) {
123
+ const { file } = path.hub;
124
+
125
+ if (file.___compileStage !== "translate") {
126
+ throw new Error(
127
+ "getMacroIdentifier can only be called during the translate phase of the compiler."
128
+ );
129
+ }
130
+
131
+ if (!isMacroTag(path)) {
132
+ throw path.buildCodeFrameError(
133
+ "getMacroIdentifier called on non macro referencing tag."
134
+ );
135
+ }
136
+
137
+ return getMacroIdentifierForName(path, path.node.name.value);
138
+ }
139
+
140
+ function getTagTemplate(tag) {
141
+ const {
142
+ node,
143
+ hub: { file }
144
+ } = tag;
145
+
146
+ if (node.extra?.tagNameImported) {
147
+ return (0, _path.join)(file.opts.filename, node.extra.tagNameImported);
148
+ }
149
+ return getTagDef(tag)?.template;
150
+ }
151
+
152
+ function getTagDef(path) {
153
+ const {
154
+ node,
155
+ hub: { file }
156
+ } = path;
157
+
158
+ if (node.tagDef === undefined) {
159
+ if (isDynamicTag(path) || isMacroTag(path)) {
160
+ node.tagDef = null;
161
+ } else {
162
+ node.tagDef =
163
+ (0, _taglib.getTagDefForTagName)(
164
+ file,
165
+ isAttributeTag(path) ?
166
+ getFullyResolvedTagName(path) :
167
+ node.name.value
168
+ ) || null;
169
+ }
170
+ }
171
+
172
+ return node.tagDef;
173
+ }
174
+
175
+ function getFullyResolvedTagName(path) {
176
+ const parts = [];
177
+ let cur;
178
+ do {
179
+ cur = path.node.name.value;
180
+
181
+ if (isAttributeTag(path)) {
182
+ parts.push(cur.slice(1));
183
+ } else {
184
+ parts.push(cur || "*");
185
+ break;
186
+ }
187
+ } while (path = findParentTag(path));
188
+
189
+ return parts.reverse().join(":");
190
+ }
191
+
192
+ function findParentTag(path) {
193
+ let cur = path.parentPath;
194
+
195
+ while (cur.node) {
196
+ if (cur.isMarkoTagBody()) {
197
+ cur = cur.parentPath;
198
+ continue;
199
+ }
200
+
201
+ if (!cur.isMarkoTag()) {
202
+ cur = undefined;
203
+ break;
204
+ }
205
+
206
+ if (isTransparentTag(cur)) {
207
+ cur = cur.parentPath;
208
+ continue;
209
+ }
210
+
211
+ return cur;
212
+ }
213
+ }
214
+
215
+ function findAttributeTags(path, attributeTags = []) {
216
+ const attrTags = path.node.body.attributeTags ?
217
+ path.get("body").get("body") :
218
+ path.get("attributeTags");
219
+ attrTags.forEach((child) => {
220
+ if (isAttributeTag(child)) {
221
+ attributeTags.push(child);
222
+ } else if (isTransparentTag(child)) {
223
+ findAttributeTags(child, attributeTags);
224
+ }
225
+ });
226
+
227
+ return attributeTags;
228
+ }
229
+
230
+ function getArgOrSequence(path) {
231
+ const {
232
+ node: { arguments: args }
233
+ } = path;
234
+ const len = args && args.length;
235
+
236
+ if (len) {
237
+ if (len > 1) {
238
+ return _compiler.types.sequenceExpression(args);
239
+ } else {
240
+ return args[0];
241
+ }
242
+ }
243
+ }
244
+
245
+ function isLoopTag(path) {
246
+ if (!path.isMarkoTag()) {
247
+ return false;
248
+ }
249
+
250
+ const tagName = path.node.name.value;
251
+ return tagName === "while" || tagName === "for";
252
+ }
253
+
254
+ function loadFileForTag(tag) {
255
+ const { file } = tag.hub;
256
+ if (tag.node.extra?.tagNameImported) {
257
+ return loadFileForImport(file, tag.node.extra?.tagNameImported);
258
+ }
259
+
260
+ const def = getTagDef(tag);
261
+ const fs = file.markoOpts.fileSystem;
262
+ const filename = def && def.template;
263
+
264
+ if (filename) {
265
+ const markoMeta = file.metadata.marko;
266
+ const relativeFileName = (0, _imports.resolveRelativePath)(file, filename);
267
+ const { analyzedTags } = markoMeta;
268
+ if (analyzedTags) {
269
+ analyzedTags.add(relativeFileName);
270
+ } else {
271
+ markoMeta.analyzedTags = new Set([relativeFileName]);
272
+ }
273
+
274
+ return resolveMarkoFile(file, filename);
275
+ }
276
+ }
277
+
278
+ function loadFileForImport(file, request) {
279
+ const fs = file.markoOpts.fileSystem;
280
+ const relativeRequest = resolveTagImport(file.path, request);
281
+
282
+ if (relativeRequest) {
283
+ const filename =
284
+ relativeRequest[0] === "." ?
285
+ (0, _path.resolve)(file.opts.filename, "..", relativeRequest) :
286
+ (0, _resolveFrom.default)((0, _path.dirname)(file.opts.filename), relativeRequest);
287
+ const markoMeta = file.metadata.marko;
288
+ const { analyzedTags } = markoMeta;
289
+ if (analyzedTags) {
290
+ analyzedTags.add(relativeRequest);
291
+ } else {
292
+ markoMeta.analyzedTags = new Set([relativeRequest]);
293
+ }
294
+
295
+ return resolveMarkoFile(file, filename);
296
+ }
297
+ }
298
+
299
+ function resolveMarkoFile(file, filename) {
300
+ if (filename === file.opts.filename) {
301
+ if (file.___compileStage === "analyze") {
302
+ return file;
303
+ }
304
+
305
+ return file.___getMarkoFile(file.code, file.opts, file.markoOpts);
306
+ }
307
+
308
+ try {
309
+ return file.___getMarkoFile(
310
+ file.markoOpts.fileSystem.readFileSync(filename).toString("utf-8"),
311
+ createNewFileOpts(file.opts, filename),
312
+ file.markoOpts
313
+ );
314
+ } catch (_) {
315
+
316
+ // ignore
317
+ }}
318
+
319
+ const idCache = new WeakMap();
320
+ const templateIdHashOpts = { outputLength: 5 };
321
+ function getTemplateId(opts, request, child) {
322
+ const id = (0, _path.relative)(ROOT, request);
323
+ const optimize = typeof opts === "object" ? opts.optimize : opts;
324
+
325
+ if (optimize) {
326
+ const optimizeKnownTemplates =
327
+ typeof opts === "object" && opts.optimizeKnownTemplates;
328
+ const knownTemplatesSize = optimizeKnownTemplates?.length || 0;
329
+ if (knownTemplatesSize) {
330
+ let lookup = idCache.get(optimizeKnownTemplates);
331
+ if (!lookup) {
332
+ lookup = new Map();
333
+ idCache.set(optimizeKnownTemplates, lookup);
334
+ for (let i = 0; i < knownTemplatesSize; i++) {
335
+ lookup.set(optimizeKnownTemplates[i], {
336
+ id: encodeTemplateId(i),
337
+ children: new Map()
338
+ });
339
+ }
340
+ }
341
+ let registered = lookup.get(request);
342
+ if (registered) {
343
+ if (child) {
344
+ let childId = registered.children.get(child);
345
+ if (childId === undefined) {
346
+ childId = registered.children.size;
347
+ registered.children.set(child, childId);
348
+ }
349
+ return registered.id + childId;
350
+ }
351
+ return registered.id;
352
+ }
353
+ }
354
+
355
+ const hash = (0, _crypto.createHash)("shake256", templateIdHashOpts).update(id);
356
+ if (child) {
357
+ hash.update(child);
358
+ }
359
+
360
+ return encodeTemplateId(parseInt(hash.digest("hex"), 16));
361
+ }
362
+
363
+ return id + (child ? `_${child}` : "");
364
+ }
365
+
366
+ function resolveTagImport(path, request) {
367
+ const {
368
+ hub: { file }
369
+ } = path;
370
+ if (request[0] === "<") {
371
+ const tagName = request.slice(1, -1);
372
+ const tagDef = (0, _taglib.getTagDefForTagName)(file, tagName);
373
+ const tagEntry = tagDef && (tagDef.renderer || tagDef.template);
374
+ const relativePath = tagEntry && (0, _imports.resolveRelativePath)(file, tagEntry);
375
+
376
+ if (!relativePath) {
377
+ throw path.buildCodeFrameError(
378
+ `Unable to find entry point for custom tag <${tagName}>.`
379
+ );
380
+ }
381
+
382
+ return relativePath;
383
+ }
384
+
385
+ if (request.endsWith(".marko")) {
386
+ return (0, _imports.resolveRelativePath)(file, request);
387
+ }
388
+ }
389
+
390
+ function createNewFileOpts(opts, filename) {
391
+ const sourceFileName = (0, _path.basename)(filename);
392
+ const sourceRoot = (0, _path.dirname)(filename);
393
+ const filenameRelative = (0, _path.relative)(CWD, filename);
394
+ return {
395
+ ...opts,
396
+ filename,
397
+ sourceRoot,
398
+ sourceFileName,
399
+ filenameRelative,
400
+ parserOpts: {
401
+ ...opts.parserOpts,
402
+ sourceFileName
403
+ },
404
+ generatorOpts: {
405
+ ...opts.generatorOpts,
406
+ filename,
407
+ sourceRoot,
408
+ sourceFileName
409
+ }
410
+ };
411
+ }
412
+
413
+ function encodeTemplateId(index) {
414
+ const encodeChars =
415
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_0123456789";
416
+ const encodeLen = encodeChars.length;
417
+ const encodeStartLen = encodeLen - 11; // Avoids chars that cannot start a property name and _ (reserved).
418
+ let cur = index;
419
+ let mod = cur % encodeStartLen;
420
+ let id = encodeChars[mod];
421
+ cur = (cur - mod) / encodeStartLen;
422
+
423
+ while (cur > 0) {
424
+ mod = cur % encodeLen;
425
+ id += encodeChars[mod];
426
+ cur = (cur - mod) / encodeLen;
427
+ }
428
+
429
+ return id;
430
+ }
@@ -0,0 +1,56 @@
1
+ "use strict";var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");exports.__esModule = true;exports.normalizeTemplateString = normalizeTemplateString;var _compiler = require("@marko/compiler");
2
+ var _jsesc = _interopRequireDefault(require("jsesc"));
3
+
4
+ function normalizeTemplateString(quasis, ...expressions) {
5
+ quasis = quasis.map((q) => _compiler.types.isTemplateElement(q) ? q.value.cooked : q);
6
+
7
+ for (let i = expressions.length; i--;) {
8
+ let v = expressions[i];
9
+ if (_compiler.types.isTemplateLiteral(v)) {
10
+ quasis[i] += v.quasis[0].value.cooked;
11
+ quasis[i + 1] =
12
+ v.quasis[v.quasis.length - 1].value.cooked + (quasis[i + 1] || "");
13
+ quasis.splice(
14
+ i + 1,
15
+ 0,
16
+ ...v.quasis.slice(1, -1).map((q) => q.value.cooked)
17
+ );
18
+ expressions.splice(i, 1, ...v.expressions);
19
+ i += v.expressions.length;
20
+ } else if (_compiler.types.isStringLiteral(v) || typeof v === "string") {
21
+ const value = _compiler.types.isStringLiteral(v) ? v.value : v;
22
+ quasis[i] += value + quasis[i + 1];
23
+ expressions.splice(i, 1);
24
+ quasis.splice(i + 1, 1);
25
+ }
26
+ }
27
+
28
+ if (!expressions.length) {
29
+ // No expression, just return a literal or empty.
30
+ const literal = quasis.join("");
31
+ return literal === "" ? undefined : _compiler.types.stringLiteral(literal);
32
+ }
33
+
34
+ if (
35
+ expressions.length === 1 &&
36
+ quasis.length === 2 &&
37
+ quasis.every(isEmptyString))
38
+ {
39
+ // Only expression `${expr}` just return the expr.
40
+ return expressions[0];
41
+ }
42
+
43
+ // Do it.
44
+ return _compiler.types.templateLiteral(quasis.map(getTemplateElement), expressions);
45
+ }
46
+
47
+ function getTemplateElement(s = "") {
48
+ return _compiler.types.templateElement({
49
+ cooked: s,
50
+ raw: (0, _jsesc.default)(s, { quotes: "backtick" })
51
+ });
52
+ }
53
+
54
+ function isEmptyString(s = "") {
55
+ return s === "";
56
+ }