@intlify/message-compiler 11.1.2 → 12.0.0-alpha.2

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.
@@ -1,26 +1,11 @@
1
1
  /*!
2
- * message-compiler v11.1.2
3
- * (c) 2025 kazuya kawaguchi
2
+ * message-compiler v12.0.0-alpha.2
3
+ * (c) 2016-present kazuya kawaguchi and contributors
4
4
  * Released under the MIT License.
5
5
  */
6
6
  var IntlifyMessageCompiler = (function (exports) {
7
7
  'use strict';
8
8
 
9
- const LOCATION_STUB = {
10
- start: { line: 1, column: 1, offset: 0 },
11
- end: { line: 1, column: 1, offset: 0 }
12
- };
13
- function createPosition(line, column, offset) {
14
- return { line, column, offset };
15
- }
16
- function createLocation(start, end, source) {
17
- const loc = { start, end };
18
- if (source != null) {
19
- loc.source = source;
20
- }
21
- return loc;
22
- }
23
-
24
9
  /**
25
10
  * Original Utilities
26
11
  * written by kazuya kawaguchi
@@ -46,6 +31,21 @@ var IntlifyMessageCompiler = (function (exports) {
46
31
  return items.reduce((str, item, index) => (index === 0 ? str + item : str + separator + item), '');
47
32
  }
48
33
 
34
+ const LOCATION_STUB = {
35
+ start: { line: 1, column: 1, offset: 0 },
36
+ end: { line: 1, column: 1, offset: 0 }
37
+ };
38
+ function createPosition(line, column, offset) {
39
+ return { line, column, offset };
40
+ }
41
+ function createLocation(start, end, source) {
42
+ const loc = { start, end };
43
+ if (source != null) {
44
+ loc.source = source;
45
+ }
46
+ return loc;
47
+ }
48
+
49
49
  const CompileErrorCodes = {
50
50
  // tokenizer error codes
51
51
  EXPECTED_TOKEN: 1,
@@ -112,164 +112,473 @@ var IntlifyMessageCompiler = (function (exports) {
112
112
  throw error;
113
113
  }
114
114
 
115
- // eslint-disable-next-line no-useless-escape
116
- const RE_HTML_TAG = /<\/?[\w\s="/.':;#-\/]+>/;
117
- const detectHtmlTag = (source) => RE_HTML_TAG.test(source);
118
-
119
- const CHAR_SP = ' ';
120
- const CHAR_CR = '\r';
121
- const CHAR_LF = '\n';
122
- const CHAR_LS = String.fromCharCode(0x2028);
123
- const CHAR_PS = String.fromCharCode(0x2029);
124
- function createScanner(str) {
125
- const _buf = str;
126
- let _index = 0;
127
- let _line = 1;
128
- let _column = 1;
129
- let _peekOffset = 0;
130
- const isCRLF = (index) => _buf[index] === CHAR_CR && _buf[index + 1] === CHAR_LF;
131
- const isLF = (index) => _buf[index] === CHAR_LF;
132
- const isPS = (index) => _buf[index] === CHAR_PS;
133
- const isLS = (index) => _buf[index] === CHAR_LS;
134
- const isLineEnd = (index) => isCRLF(index) || isLF(index) || isPS(index) || isLS(index);
135
- const index = () => _index;
136
- const line = () => _line;
137
- const column = () => _column;
138
- const peekOffset = () => _peekOffset;
139
- const charAt = (offset) => isCRLF(offset) || isPS(offset) || isLS(offset) ? CHAR_LF : _buf[offset];
140
- const currentChar = () => charAt(_index);
141
- const currentPeek = () => charAt(_index + _peekOffset);
142
- function next() {
143
- _peekOffset = 0;
144
- if (isLineEnd(_index)) {
145
- _line++;
146
- _column = 0;
147
- }
148
- if (isCRLF(_index)) {
149
- _index++;
150
- }
151
- _index++;
152
- _column++;
153
- return _buf[_index];
115
+ // eslint-disable-next-line @typescript-eslint/triple-slash-reference
116
+ /// <reference types="source-map-js" />
117
+ const ERROR_DOMAIN$3 = 'parser';
118
+ function createCodeGenerator(ast, options) {
119
+ const { sourceMap, filename, breakLineCode, needIndent: _needIndent } = options;
120
+ const location = options.location !== false;
121
+ const _context = {
122
+ filename,
123
+ code: '',
124
+ column: 1,
125
+ line: 1,
126
+ offset: 0,
127
+ map: undefined,
128
+ breakLineCode,
129
+ needIndent: _needIndent,
130
+ indentLevel: 0
131
+ };
132
+ if (location && ast.loc) {
133
+ _context.source = ast.loc.source;
154
134
  }
155
- function peek() {
156
- if (isCRLF(_index + _peekOffset)) {
157
- _peekOffset++;
158
- }
159
- _peekOffset++;
160
- return _buf[_index + _peekOffset];
135
+ const context = () => _context;
136
+ function push(code, node) {
137
+ _context.code += code;
161
138
  }
162
- function reset() {
163
- _index = 0;
164
- _line = 1;
165
- _column = 1;
166
- _peekOffset = 0;
139
+ function _newline(n, withBreakLine = true) {
140
+ const _breakLineCode = withBreakLine ? breakLineCode : '';
141
+ push(_needIndent ? _breakLineCode + ` `.repeat(n) : _breakLineCode);
167
142
  }
168
- function resetPeek(offset = 0) {
169
- _peekOffset = offset;
143
+ function indent(withNewLine = true) {
144
+ const level = ++_context.indentLevel;
145
+ withNewLine && _newline(level);
170
146
  }
171
- function skipToPeek() {
172
- const target = _index + _peekOffset;
173
- while (target !== _index) {
174
- next();
175
- }
176
- _peekOffset = 0;
147
+ function deindent(withNewLine = true) {
148
+ const level = --_context.indentLevel;
149
+ withNewLine && _newline(level);
150
+ }
151
+ function newline() {
152
+ _newline(_context.indentLevel);
177
153
  }
154
+ const helper = (key) => `_${key}`;
155
+ const needIndent = () => _context.needIndent;
178
156
  return {
179
- index,
180
- line,
181
- column,
182
- peekOffset,
183
- charAt,
184
- currentChar,
185
- currentPeek,
186
- next,
187
- peek,
188
- reset,
189
- resetPeek,
190
- skipToPeek
157
+ context,
158
+ push,
159
+ indent,
160
+ deindent,
161
+ newline,
162
+ helper,
163
+ needIndent
191
164
  };
192
165
  }
193
-
194
- const EOF = undefined;
195
- const DOT = '.';
196
- const LITERAL_DELIMITER = "'";
197
- const ERROR_DOMAIN$3 = 'tokenizer';
198
- function createTokenizer(source, options = {}) {
199
- const location = options.location !== false;
200
- const _scnr = createScanner(source);
201
- const currentOffset = () => _scnr.index();
202
- const currentPosition = () => createPosition(_scnr.line(), _scnr.column(), _scnr.index());
203
- const _initLoc = currentPosition();
204
- const _initOffset = currentOffset();
205
- const _context = {
206
- currentType: 13 /* TokenTypes.EOF */,
207
- offset: _initOffset,
208
- startLoc: _initLoc,
209
- endLoc: _initLoc,
210
- lastType: 13 /* TokenTypes.EOF */,
211
- lastOffset: _initOffset,
212
- lastStartLoc: _initLoc,
213
- lastEndLoc: _initLoc,
214
- braceNest: 0,
215
- inLinked: false,
216
- text: ''
217
- };
218
- const context = () => _context;
219
- const { onError } = options;
220
- function emitError(code, pos, offset, ...args) {
221
- const ctx = context();
222
- pos.column += offset;
223
- pos.offset += offset;
224
- if (onError) {
225
- const loc = location ? createLocation(ctx.startLoc, pos) : null;
226
- const err = createCompileError(code, loc, {
227
- domain: ERROR_DOMAIN$3,
228
- args
229
- });
230
- onError(err);
231
- }
166
+ function generateLinkedNode(generator, node) {
167
+ const { helper } = generator;
168
+ generator.push(`${helper("linked" /* HelperNameMap.LINKED */)}(`);
169
+ generateNode(generator, node.key);
170
+ if (node.modifier) {
171
+ generator.push(`, `);
172
+ generateNode(generator, node.modifier);
173
+ generator.push(`, _type`);
232
174
  }
233
- function getToken(context, type, value) {
234
- context.endLoc = currentPosition();
235
- context.currentType = type;
236
- const token = { type };
237
- if (location) {
238
- token.loc = createLocation(context.startLoc, context.endLoc);
239
- }
240
- if (value != null) {
241
- token.value = value;
242
- }
243
- return token;
175
+ else {
176
+ generator.push(`, undefined, _type`);
244
177
  }
245
- const getEndToken = (context) => getToken(context, 13 /* TokenTypes.EOF */);
246
- function eat(scnr, ch) {
247
- if (scnr.currentChar() === ch) {
248
- scnr.next();
249
- return ch;
250
- }
251
- else {
252
- emitError(CompileErrorCodes.EXPECTED_TOKEN, currentPosition(), 0, ch);
253
- return '';
178
+ generator.push(`)`);
179
+ }
180
+ function generateMessageNode(generator, node) {
181
+ const { helper, needIndent } = generator;
182
+ generator.push(`${helper("normalize" /* HelperNameMap.NORMALIZE */)}([`);
183
+ generator.indent(needIndent());
184
+ const length = node.items.length;
185
+ for (let i = 0; i < length; i++) {
186
+ generateNode(generator, node.items[i]);
187
+ if (i === length - 1) {
188
+ break;
254
189
  }
190
+ generator.push(', ');
255
191
  }
256
- function peekSpaces(scnr) {
257
- let buf = '';
258
- while (scnr.currentPeek() === CHAR_SP || scnr.currentPeek() === CHAR_LF) {
259
- buf += scnr.currentPeek();
260
- scnr.peek();
192
+ generator.deindent(needIndent());
193
+ generator.push('])');
194
+ }
195
+ function generatePluralNode(generator, node) {
196
+ const { helper, needIndent } = generator;
197
+ if (node.cases.length > 1) {
198
+ generator.push(`${helper("plural" /* HelperNameMap.PLURAL */)}([`);
199
+ generator.indent(needIndent());
200
+ const length = node.cases.length;
201
+ for (let i = 0; i < length; i++) {
202
+ generateNode(generator, node.cases[i]);
203
+ if (i === length - 1) {
204
+ break;
205
+ }
206
+ generator.push(', ');
261
207
  }
262
- return buf;
208
+ generator.deindent(needIndent());
209
+ generator.push(`])`);
263
210
  }
264
- function skipSpaces(scnr) {
265
- const buf = peekSpaces(scnr);
266
- scnr.skipToPeek();
267
- return buf;
211
+ }
212
+ function generateResource(generator, node) {
213
+ if (node.body) {
214
+ generateNode(generator, node.body);
268
215
  }
269
- function isIdentifierStart(ch) {
270
- if (ch === EOF) {
271
- return false;
272
- }
216
+ else {
217
+ generator.push('null');
218
+ }
219
+ }
220
+ function generateNode(generator, node) {
221
+ const { helper } = generator;
222
+ switch (node.type) {
223
+ case 0 /* NodeTypes.Resource */:
224
+ generateResource(generator, node);
225
+ break;
226
+ case 1 /* NodeTypes.Plural */:
227
+ generatePluralNode(generator, node);
228
+ break;
229
+ case 2 /* NodeTypes.Message */:
230
+ generateMessageNode(generator, node);
231
+ break;
232
+ case 6 /* NodeTypes.Linked */:
233
+ generateLinkedNode(generator, node);
234
+ break;
235
+ case 8 /* NodeTypes.LinkedModifier */:
236
+ generator.push(JSON.stringify(node.value), node);
237
+ break;
238
+ case 7 /* NodeTypes.LinkedKey */:
239
+ generator.push(JSON.stringify(node.value), node);
240
+ break;
241
+ case 5 /* NodeTypes.List */:
242
+ generator.push(`${helper("interpolate" /* HelperNameMap.INTERPOLATE */)}(${helper("list" /* HelperNameMap.LIST */)}(${node.index}))`, node);
243
+ break;
244
+ case 4 /* NodeTypes.Named */:
245
+ generator.push(`${helper("interpolate" /* HelperNameMap.INTERPOLATE */)}(${helper("named" /* HelperNameMap.NAMED */)}(${JSON.stringify(node.key)}))`, node);
246
+ break;
247
+ case 9 /* NodeTypes.Literal */:
248
+ generator.push(JSON.stringify(node.value), node);
249
+ break;
250
+ case 3 /* NodeTypes.Text */:
251
+ generator.push(JSON.stringify(node.value), node);
252
+ break;
253
+ default:
254
+ {
255
+ throw createCompileError(CompileErrorCodes.UNHANDLED_CODEGEN_NODE_TYPE, null, {
256
+ domain: ERROR_DOMAIN$3,
257
+ args: [node.type]
258
+ });
259
+ }
260
+ }
261
+ }
262
+ // generate code from AST
263
+ const generate = (ast, options = {}) => {
264
+ const mode = isString(options.mode) ? options.mode : 'normal';
265
+ const filename = isString(options.filename)
266
+ ? options.filename
267
+ : 'message.intl';
268
+ const sourceMap = !!options.sourceMap;
269
+ // prettier-ignore
270
+ const breakLineCode = options.breakLineCode != null
271
+ ? options.breakLineCode
272
+ : mode === 'arrow'
273
+ ? ';'
274
+ : '\n';
275
+ const needIndent = options.needIndent ? options.needIndent : mode !== 'arrow';
276
+ const helpers = ast.helpers || [];
277
+ const generator = createCodeGenerator(ast, {
278
+ mode,
279
+ filename,
280
+ sourceMap,
281
+ breakLineCode,
282
+ needIndent
283
+ });
284
+ generator.push(mode === 'normal' ? `function __msg__ (ctx) {` : `(ctx) => {`);
285
+ generator.indent(needIndent);
286
+ if (helpers.length > 0) {
287
+ generator.push(`const { ${join(helpers.map(s => `${s}: _${s}`), ', ')} } = ctx`);
288
+ generator.newline();
289
+ }
290
+ generator.push(`return `);
291
+ generateNode(generator, ast);
292
+ generator.deindent(needIndent);
293
+ generator.push(`}`);
294
+ delete ast.helpers;
295
+ const { code, map } = generator.context();
296
+ return {
297
+ ast,
298
+ code,
299
+ map: map ? map.toJSON() : undefined // eslint-disable-line @typescript-eslint/no-explicit-any
300
+ };
301
+ };
302
+
303
+ const ERROR_DOMAIN$2 = 'minifier';
304
+ /* eslint-disable @typescript-eslint/no-explicit-any */
305
+ function mangle(node) {
306
+ node.t = node.type;
307
+ switch (node.type) {
308
+ case 0 /* NodeTypes.Resource */: {
309
+ const resource = node;
310
+ mangle(resource.body);
311
+ resource.b = resource.body;
312
+ delete resource.body;
313
+ break;
314
+ }
315
+ case 1 /* NodeTypes.Plural */: {
316
+ const plural = node;
317
+ const cases = plural.cases;
318
+ for (let i = 0; i < cases.length; i++) {
319
+ mangle(cases[i]);
320
+ }
321
+ plural.c = cases;
322
+ delete plural.cases;
323
+ break;
324
+ }
325
+ case 2 /* NodeTypes.Message */: {
326
+ const message = node;
327
+ const items = message.items;
328
+ for (let i = 0; i < items.length; i++) {
329
+ mangle(items[i]);
330
+ }
331
+ message.i = items;
332
+ delete message.items;
333
+ if (message.static) {
334
+ message.s = message.static;
335
+ delete message.static;
336
+ }
337
+ break;
338
+ }
339
+ case 3 /* NodeTypes.Text */:
340
+ case 9 /* NodeTypes.Literal */:
341
+ case 8 /* NodeTypes.LinkedModifier */:
342
+ case 7 /* NodeTypes.LinkedKey */: {
343
+ const valueNode = node;
344
+ if (valueNode.value) {
345
+ valueNode.v = valueNode.value;
346
+ delete valueNode.value;
347
+ }
348
+ break;
349
+ }
350
+ case 6 /* NodeTypes.Linked */: {
351
+ const linked = node;
352
+ mangle(linked.key);
353
+ linked.k = linked.key;
354
+ delete linked.key;
355
+ if (linked.modifier) {
356
+ mangle(linked.modifier);
357
+ linked.m = linked.modifier;
358
+ delete linked.modifier;
359
+ }
360
+ break;
361
+ }
362
+ case 5 /* NodeTypes.List */: {
363
+ const list = node;
364
+ list.i = list.index;
365
+ delete list.index;
366
+ break;
367
+ }
368
+ case 4 /* NodeTypes.Named */: {
369
+ const named = node;
370
+ named.k = named.key;
371
+ delete named.key;
372
+ break;
373
+ }
374
+ default:
375
+ {
376
+ throw createCompileError(CompileErrorCodes.UNHANDLED_MINIFIER_NODE_TYPE, null, {
377
+ domain: ERROR_DOMAIN$2,
378
+ args: [node.type]
379
+ });
380
+ }
381
+ }
382
+ delete node.type;
383
+ }
384
+ /* eslint-enable @typescript-eslint/no-explicit-any */
385
+
386
+ function optimize(ast) {
387
+ const body = ast.body;
388
+ if (body.type === 2 /* NodeTypes.Message */) {
389
+ optimizeMessageNode(body);
390
+ }
391
+ else {
392
+ body.cases.forEach(c => optimizeMessageNode(c));
393
+ }
394
+ return ast;
395
+ }
396
+ function optimizeMessageNode(message) {
397
+ if (message.items.length === 1) {
398
+ const item = message.items[0];
399
+ if (item.type === 3 /* NodeTypes.Text */ || item.type === 9 /* NodeTypes.Literal */) {
400
+ message.static = item.value;
401
+ delete item.value; // optimization for size
402
+ }
403
+ }
404
+ else {
405
+ const values = [];
406
+ for (let i = 0; i < message.items.length; i++) {
407
+ const item = message.items[i];
408
+ if (!(item.type === 3 /* NodeTypes.Text */ || item.type === 9 /* NodeTypes.Literal */)) {
409
+ break;
410
+ }
411
+ if (item.value == null) {
412
+ break;
413
+ }
414
+ values.push(item.value);
415
+ }
416
+ if (values.length === message.items.length) {
417
+ message.static = join(values);
418
+ for (let i = 0; i < message.items.length; i++) {
419
+ const item = message.items[i];
420
+ if (item.type === 3 /* NodeTypes.Text */ || item.type === 9 /* NodeTypes.Literal */) {
421
+ delete item.value; // optimization for size
422
+ }
423
+ }
424
+ }
425
+ }
426
+ }
427
+
428
+ const CHAR_SP = ' ';
429
+ const CHAR_CR = '\r';
430
+ const CHAR_LF = '\n';
431
+ const CHAR_LS = String.fromCharCode(0x2028);
432
+ const CHAR_PS = String.fromCharCode(0x2029);
433
+ function createScanner(str) {
434
+ const _buf = str;
435
+ let _index = 0;
436
+ let _line = 1;
437
+ let _column = 1;
438
+ let _peekOffset = 0;
439
+ const isCRLF = (index) => _buf[index] === CHAR_CR && _buf[index + 1] === CHAR_LF;
440
+ const isLF = (index) => _buf[index] === CHAR_LF;
441
+ const isPS = (index) => _buf[index] === CHAR_PS;
442
+ const isLS = (index) => _buf[index] === CHAR_LS;
443
+ const isLineEnd = (index) => isCRLF(index) || isLF(index) || isPS(index) || isLS(index);
444
+ const index = () => _index;
445
+ const line = () => _line;
446
+ const column = () => _column;
447
+ const peekOffset = () => _peekOffset;
448
+ const charAt = (offset) => isCRLF(offset) || isPS(offset) || isLS(offset) ? CHAR_LF : _buf[offset];
449
+ const currentChar = () => charAt(_index);
450
+ const currentPeek = () => charAt(_index + _peekOffset);
451
+ function next() {
452
+ _peekOffset = 0;
453
+ if (isLineEnd(_index)) {
454
+ _line++;
455
+ _column = 0;
456
+ }
457
+ if (isCRLF(_index)) {
458
+ _index++;
459
+ }
460
+ _index++;
461
+ _column++;
462
+ return _buf[_index];
463
+ }
464
+ function peek() {
465
+ if (isCRLF(_index + _peekOffset)) {
466
+ _peekOffset++;
467
+ }
468
+ _peekOffset++;
469
+ return _buf[_index + _peekOffset];
470
+ }
471
+ function reset() {
472
+ _index = 0;
473
+ _line = 1;
474
+ _column = 1;
475
+ _peekOffset = 0;
476
+ }
477
+ function resetPeek(offset = 0) {
478
+ _peekOffset = offset;
479
+ }
480
+ function skipToPeek() {
481
+ const target = _index + _peekOffset;
482
+ while (target !== _index) {
483
+ next();
484
+ }
485
+ _peekOffset = 0;
486
+ }
487
+ return {
488
+ index,
489
+ line,
490
+ column,
491
+ peekOffset,
492
+ charAt,
493
+ currentChar,
494
+ currentPeek,
495
+ next,
496
+ peek,
497
+ reset,
498
+ resetPeek,
499
+ skipToPeek
500
+ };
501
+ }
502
+
503
+ const EOF = undefined;
504
+ const DOT = '.';
505
+ const LITERAL_DELIMITER = "'";
506
+ const ERROR_DOMAIN$1 = 'tokenizer';
507
+ function createTokenizer(source, options = {}) {
508
+ const location = options.location !== false;
509
+ const _scnr = createScanner(source);
510
+ const currentOffset = () => _scnr.index();
511
+ const currentPosition = () => createPosition(_scnr.line(), _scnr.column(), _scnr.index());
512
+ const _initLoc = currentPosition();
513
+ const _initOffset = currentOffset();
514
+ const _context = {
515
+ currentType: 13 /* TokenTypes.EOF */,
516
+ offset: _initOffset,
517
+ startLoc: _initLoc,
518
+ endLoc: _initLoc,
519
+ lastType: 13 /* TokenTypes.EOF */,
520
+ lastOffset: _initOffset,
521
+ lastStartLoc: _initLoc,
522
+ lastEndLoc: _initLoc,
523
+ braceNest: 0,
524
+ inLinked: false,
525
+ text: ''
526
+ };
527
+ const context = () => _context;
528
+ const { onError } = options;
529
+ function emitError(code, pos, offset, ...args) {
530
+ const ctx = context();
531
+ pos.column += offset;
532
+ pos.offset += offset;
533
+ if (onError) {
534
+ const loc = location ? createLocation(ctx.startLoc, pos) : null;
535
+ const err = createCompileError(code, loc, {
536
+ domain: ERROR_DOMAIN$1,
537
+ args
538
+ });
539
+ onError(err);
540
+ }
541
+ }
542
+ function getToken(context, type, value) {
543
+ context.endLoc = currentPosition();
544
+ context.currentType = type;
545
+ const token = { type };
546
+ if (location) {
547
+ token.loc = createLocation(context.startLoc, context.endLoc);
548
+ }
549
+ if (value != null) {
550
+ token.value = value;
551
+ }
552
+ return token;
553
+ }
554
+ const getEndToken = (context) => getToken(context, 13 /* TokenTypes.EOF */);
555
+ function eat(scnr, ch) {
556
+ if (scnr.currentChar() === ch) {
557
+ scnr.next();
558
+ return ch;
559
+ }
560
+ else {
561
+ emitError(CompileErrorCodes.EXPECTED_TOKEN, currentPosition(), 0, ch);
562
+ return '';
563
+ }
564
+ }
565
+ function peekSpaces(scnr) {
566
+ let buf = '';
567
+ while (scnr.currentPeek() === CHAR_SP || scnr.currentPeek() === CHAR_LF) {
568
+ buf += scnr.currentPeek();
569
+ scnr.peek();
570
+ }
571
+ return buf;
572
+ }
573
+ function skipSpaces(scnr) {
574
+ const buf = peekSpaces(scnr);
575
+ scnr.skipToPeek();
576
+ return buf;
577
+ }
578
+ function isIdentifierStart(ch) {
579
+ if (ch === EOF) {
580
+ return false;
581
+ }
273
582
  const cc = ch.charCodeAt(0);
274
583
  return ((cc >= 97 && cc <= 122) || // a-z
275
584
  (cc >= 65 && cc <= 90) || // A-Z
@@ -845,7 +1154,7 @@ var IntlifyMessageCompiler = (function (exports) {
845
1154
  };
846
1155
  }
847
1156
 
848
- const ERROR_DOMAIN$2 = 'parser';
1157
+ const ERROR_DOMAIN = 'parser';
849
1158
  // Backslash backslash, backslash quote, uHHHH, UHHHHHH.
850
1159
  const KNOWN_ESCAPES = /(?:\\\\|\\'|\\u([0-9a-fA-F]{4})|\\U([0-9a-fA-F]{6}))/g;
851
1160
  function fromEscapeSequence(match, codePoint4, codePoint6) {
@@ -877,7 +1186,7 @@ var IntlifyMessageCompiler = (function (exports) {
877
1186
  if (onError) {
878
1187
  const loc = location ? createLocation(start, end) : null;
879
1188
  const err = createCompileError(code, loc, {
880
- domain: ERROR_DOMAIN$2,
1189
+ domain: ERROR_DOMAIN,
881
1190
  args
882
1191
  });
883
1192
  onError(err);
@@ -1110,420 +1419,109 @@ var IntlifyMessageCompiler = (function (exports) {
1110
1419
  const context = tokenizer.context();
1111
1420
  const { offset, startLoc } = context;
1112
1421
  const msgNode = parseMessage(tokenizer);
1113
- if (context.currentType === 13 /* TokenTypes.EOF */) {
1114
- return msgNode;
1115
- }
1116
- else {
1117
- return parsePlural(tokenizer, offset, startLoc, msgNode);
1118
- }
1119
- }
1120
- function parse(source) {
1121
- const tokenizer = createTokenizer(source, assign({}, options));
1122
- const context = tokenizer.context();
1123
- const node = startNode(0 /* NodeTypes.Resource */, context.offset, context.startLoc);
1124
- if (location && node.loc) {
1125
- node.loc.source = source;
1126
- }
1127
- node.body = parseResource(tokenizer);
1128
- if (options.onCacheKey) {
1129
- node.cacheKey = options.onCacheKey(source);
1130
- }
1131
- // assert whether achieved to EOF
1132
- if (context.currentType !== 13 /* TokenTypes.EOF */) {
1133
- emitError(tokenizer, CompileErrorCodes.UNEXPECTED_LEXICAL_ANALYSIS, context.lastStartLoc, 0, source[context.offset] || '');
1134
- }
1135
- endNode(node, tokenizer.currentOffset(), tokenizer.currentPosition());
1136
- return node;
1137
- }
1138
- return { parse };
1139
- }
1140
- function getTokenCaption(token) {
1141
- if (token.type === 13 /* TokenTypes.EOF */) {
1142
- return 'EOF';
1143
- }
1144
- const name = (token.value || '').replace(/\r?\n/gu, '\\n');
1145
- return name.length > 10 ? name.slice(0, 9) + '…' : name;
1146
- }
1147
-
1148
- function createTransformer(ast, options = {} // eslint-disable-line
1149
- ) {
1150
- const _context = {
1151
- ast,
1152
- helpers: new Set()
1153
- };
1154
- const context = () => _context;
1155
- const helper = (name) => {
1156
- _context.helpers.add(name);
1157
- return name;
1158
- };
1159
- return { context, helper };
1160
- }
1161
- function traverseNodes(nodes, transformer) {
1162
- for (let i = 0; i < nodes.length; i++) {
1163
- traverseNode(nodes[i], transformer);
1164
- }
1165
- }
1166
- function traverseNode(node, transformer) {
1167
- // TODO: if we need pre-hook of transform, should be implemented to here
1168
- switch (node.type) {
1169
- case 1 /* NodeTypes.Plural */:
1170
- traverseNodes(node.cases, transformer);
1171
- transformer.helper("plural" /* HelperNameMap.PLURAL */);
1172
- break;
1173
- case 2 /* NodeTypes.Message */:
1174
- traverseNodes(node.items, transformer);
1175
- break;
1176
- case 6 /* NodeTypes.Linked */: {
1177
- const linked = node;
1178
- traverseNode(linked.key, transformer);
1179
- transformer.helper("linked" /* HelperNameMap.LINKED */);
1180
- transformer.helper("type" /* HelperNameMap.TYPE */);
1181
- break;
1182
- }
1183
- case 5 /* NodeTypes.List */:
1184
- transformer.helper("interpolate" /* HelperNameMap.INTERPOLATE */);
1185
- transformer.helper("list" /* HelperNameMap.LIST */);
1186
- break;
1187
- case 4 /* NodeTypes.Named */:
1188
- transformer.helper("interpolate" /* HelperNameMap.INTERPOLATE */);
1189
- transformer.helper("named" /* HelperNameMap.NAMED */);
1190
- break;
1191
- }
1192
- // TODO: if we need post-hook of transform, should be implemented to here
1193
- }
1194
- // transform AST
1195
- function transform(ast, options = {} // eslint-disable-line
1196
- ) {
1197
- const transformer = createTransformer(ast);
1198
- transformer.helper("normalize" /* HelperNameMap.NORMALIZE */);
1199
- // traverse
1200
- ast.body && traverseNode(ast.body, transformer);
1201
- // set meta information
1202
- const context = transformer.context();
1203
- ast.helpers = Array.from(context.helpers);
1204
- }
1205
-
1206
- function optimize(ast) {
1207
- const body = ast.body;
1208
- if (body.type === 2 /* NodeTypes.Message */) {
1209
- optimizeMessageNode(body);
1210
- }
1211
- else {
1212
- body.cases.forEach(c => optimizeMessageNode(c));
1213
- }
1214
- return ast;
1215
- }
1216
- function optimizeMessageNode(message) {
1217
- if (message.items.length === 1) {
1218
- const item = message.items[0];
1219
- if (item.type === 3 /* NodeTypes.Text */ || item.type === 9 /* NodeTypes.Literal */) {
1220
- message.static = item.value;
1221
- delete item.value; // optimization for size
1222
- }
1223
- }
1224
- else {
1225
- const values = [];
1226
- for (let i = 0; i < message.items.length; i++) {
1227
- const item = message.items[i];
1228
- if (!(item.type === 3 /* NodeTypes.Text */ || item.type === 9 /* NodeTypes.Literal */)) {
1229
- break;
1230
- }
1231
- if (item.value == null) {
1232
- break;
1233
- }
1234
- values.push(item.value);
1235
- }
1236
- if (values.length === message.items.length) {
1237
- message.static = join(values);
1238
- for (let i = 0; i < message.items.length; i++) {
1239
- const item = message.items[i];
1240
- if (item.type === 3 /* NodeTypes.Text */ || item.type === 9 /* NodeTypes.Literal */) {
1241
- delete item.value; // optimization for size
1242
- }
1243
- }
1244
- }
1245
- }
1246
- }
1247
-
1248
- const ERROR_DOMAIN$1 = 'minifier';
1249
- /* eslint-disable @typescript-eslint/no-explicit-any */
1250
- function minify(node) {
1251
- node.t = node.type;
1252
- switch (node.type) {
1253
- case 0 /* NodeTypes.Resource */: {
1254
- const resource = node;
1255
- minify(resource.body);
1256
- resource.b = resource.body;
1257
- delete resource.body;
1258
- break;
1259
- }
1260
- case 1 /* NodeTypes.Plural */: {
1261
- const plural = node;
1262
- const cases = plural.cases;
1263
- for (let i = 0; i < cases.length; i++) {
1264
- minify(cases[i]);
1265
- }
1266
- plural.c = cases;
1267
- delete plural.cases;
1268
- break;
1269
- }
1270
- case 2 /* NodeTypes.Message */: {
1271
- const message = node;
1272
- const items = message.items;
1273
- for (let i = 0; i < items.length; i++) {
1274
- minify(items[i]);
1275
- }
1276
- message.i = items;
1277
- delete message.items;
1278
- if (message.static) {
1279
- message.s = message.static;
1280
- delete message.static;
1281
- }
1282
- break;
1283
- }
1284
- case 3 /* NodeTypes.Text */:
1285
- case 9 /* NodeTypes.Literal */:
1286
- case 8 /* NodeTypes.LinkedModifier */:
1287
- case 7 /* NodeTypes.LinkedKey */: {
1288
- const valueNode = node;
1289
- if (valueNode.value) {
1290
- valueNode.v = valueNode.value;
1291
- delete valueNode.value;
1292
- }
1293
- break;
1294
- }
1295
- case 6 /* NodeTypes.Linked */: {
1296
- const linked = node;
1297
- minify(linked.key);
1298
- linked.k = linked.key;
1299
- delete linked.key;
1300
- if (linked.modifier) {
1301
- minify(linked.modifier);
1302
- linked.m = linked.modifier;
1303
- delete linked.modifier;
1304
- }
1305
- break;
1422
+ if (context.currentType === 13 /* TokenTypes.EOF */) {
1423
+ return msgNode;
1306
1424
  }
1307
- case 5 /* NodeTypes.List */: {
1308
- const list = node;
1309
- list.i = list.index;
1310
- delete list.index;
1311
- break;
1425
+ else {
1426
+ return parsePlural(tokenizer, offset, startLoc, msgNode);
1312
1427
  }
1313
- case 4 /* NodeTypes.Named */: {
1314
- const named = node;
1315
- named.k = named.key;
1316
- delete named.key;
1317
- break;
1428
+ }
1429
+ function parse(source) {
1430
+ const tokenizer = createTokenizer(source, assign({}, options));
1431
+ const context = tokenizer.context();
1432
+ const node = startNode(0 /* NodeTypes.Resource */, context.offset, context.startLoc);
1433
+ if (location && node.loc) {
1434
+ node.loc.source = source;
1318
1435
  }
1319
- default:
1320
- {
1321
- throw createCompileError(CompileErrorCodes.UNHANDLED_MINIFIER_NODE_TYPE, null, {
1322
- domain: ERROR_DOMAIN$1,
1323
- args: [node.type]
1324
- });
1325
- }
1436
+ node.body = parseResource(tokenizer);
1437
+ if (options.onCacheKey) {
1438
+ node.cacheKey = options.onCacheKey(source);
1439
+ }
1440
+ // assert whether achieved to EOF
1441
+ if (context.currentType !== 13 /* TokenTypes.EOF */) {
1442
+ emitError(tokenizer, CompileErrorCodes.UNEXPECTED_LEXICAL_ANALYSIS, context.lastStartLoc, 0, source[context.offset] || '');
1443
+ }
1444
+ endNode(node, tokenizer.currentOffset(), tokenizer.currentPosition());
1445
+ return node;
1326
1446
  }
1327
- delete node.type;
1447
+ return { parse };
1448
+ }
1449
+ function getTokenCaption(token) {
1450
+ if (token.type === 13 /* TokenTypes.EOF */) {
1451
+ return 'EOF';
1452
+ }
1453
+ const name = (token.value || '').replace(/\r?\n/gu, '\\n');
1454
+ return name.length > 10 ? name.slice(0, 9) + '…' : name;
1328
1455
  }
1329
- /* eslint-enable @typescript-eslint/no-explicit-any */
1330
1456
 
1331
- // eslint-disable-next-line @typescript-eslint/triple-slash-reference
1332
- /// <reference types="source-map-js" />
1333
- const ERROR_DOMAIN = 'parser';
1334
- function createCodeGenerator(ast, options) {
1335
- const { sourceMap, filename, breakLineCode, needIndent: _needIndent } = options;
1336
- const location = options.location !== false;
1457
+ function createTransformer(ast, options = {} // eslint-disable-line
1458
+ ) {
1337
1459
  const _context = {
1338
- filename,
1339
- code: '',
1340
- column: 1,
1341
- line: 1,
1342
- offset: 0,
1343
- map: undefined,
1344
- breakLineCode,
1345
- needIndent: _needIndent,
1346
- indentLevel: 0
1460
+ ast,
1461
+ helpers: new Set()
1347
1462
  };
1348
- if (location && ast.loc) {
1349
- _context.source = ast.loc.source;
1350
- }
1351
1463
  const context = () => _context;
1352
- function push(code, node) {
1353
- _context.code += code;
1354
- }
1355
- function _newline(n, withBreakLine = true) {
1356
- const _breakLineCode = withBreakLine ? breakLineCode : '';
1357
- push(_needIndent ? _breakLineCode + ` `.repeat(n) : _breakLineCode);
1358
- }
1359
- function indent(withNewLine = true) {
1360
- const level = ++_context.indentLevel;
1361
- withNewLine && _newline(level);
1362
- }
1363
- function deindent(withNewLine = true) {
1364
- const level = --_context.indentLevel;
1365
- withNewLine && _newline(level);
1366
- }
1367
- function newline() {
1368
- _newline(_context.indentLevel);
1369
- }
1370
- const helper = (key) => `_${key}`;
1371
- const needIndent = () => _context.needIndent;
1372
- return {
1373
- context,
1374
- push,
1375
- indent,
1376
- deindent,
1377
- newline,
1378
- helper,
1379
- needIndent
1464
+ const helper = (name) => {
1465
+ _context.helpers.add(name);
1466
+ return name;
1380
1467
  };
1468
+ return { context, helper };
1381
1469
  }
1382
- function generateLinkedNode(generator, node) {
1383
- const { helper } = generator;
1384
- generator.push(`${helper("linked" /* HelperNameMap.LINKED */)}(`);
1385
- generateNode(generator, node.key);
1386
- if (node.modifier) {
1387
- generator.push(`, `);
1388
- generateNode(generator, node.modifier);
1389
- generator.push(`, _type`);
1390
- }
1391
- else {
1392
- generator.push(`, undefined, _type`);
1393
- }
1394
- generator.push(`)`);
1395
- }
1396
- function generateMessageNode(generator, node) {
1397
- const { helper, needIndent } = generator;
1398
- generator.push(`${helper("normalize" /* HelperNameMap.NORMALIZE */)}([`);
1399
- generator.indent(needIndent());
1400
- const length = node.items.length;
1401
- for (let i = 0; i < length; i++) {
1402
- generateNode(generator, node.items[i]);
1403
- if (i === length - 1) {
1404
- break;
1405
- }
1406
- generator.push(', ');
1407
- }
1408
- generator.deindent(needIndent());
1409
- generator.push('])');
1410
- }
1411
- function generatePluralNode(generator, node) {
1412
- const { helper, needIndent } = generator;
1413
- if (node.cases.length > 1) {
1414
- generator.push(`${helper("plural" /* HelperNameMap.PLURAL */)}([`);
1415
- generator.indent(needIndent());
1416
- const length = node.cases.length;
1417
- for (let i = 0; i < length; i++) {
1418
- generateNode(generator, node.cases[i]);
1419
- if (i === length - 1) {
1420
- break;
1421
- }
1422
- generator.push(', ');
1423
- }
1424
- generator.deindent(needIndent());
1425
- generator.push(`])`);
1426
- }
1427
- }
1428
- function generateResource(generator, node) {
1429
- if (node.body) {
1430
- generateNode(generator, node.body);
1431
- }
1432
- else {
1433
- generator.push('null');
1470
+ function traverseNodes(nodes, transformer) {
1471
+ for (let i = 0; i < nodes.length; i++) {
1472
+ traverseNode(nodes[i], transformer);
1434
1473
  }
1435
1474
  }
1436
- function generateNode(generator, node) {
1437
- const { helper } = generator;
1475
+ function traverseNode(node, transformer) {
1476
+ // TODO: if we need pre-hook of transform, should be implemented to here
1438
1477
  switch (node.type) {
1439
- case 0 /* NodeTypes.Resource */:
1440
- generateResource(generator, node);
1441
- break;
1442
1478
  case 1 /* NodeTypes.Plural */:
1443
- generatePluralNode(generator, node);
1479
+ traverseNodes(node.cases, transformer);
1480
+ transformer.helper("plural" /* HelperNameMap.PLURAL */);
1444
1481
  break;
1445
1482
  case 2 /* NodeTypes.Message */:
1446
- generateMessageNode(generator, node);
1447
- break;
1448
- case 6 /* NodeTypes.Linked */:
1449
- generateLinkedNode(generator, node);
1450
- break;
1451
- case 8 /* NodeTypes.LinkedModifier */:
1452
- generator.push(JSON.stringify(node.value), node);
1483
+ traverseNodes(node.items, transformer);
1453
1484
  break;
1454
- case 7 /* NodeTypes.LinkedKey */:
1455
- generator.push(JSON.stringify(node.value), node);
1485
+ case 6 /* NodeTypes.Linked */: {
1486
+ const linked = node;
1487
+ traverseNode(linked.key, transformer);
1488
+ transformer.helper("linked" /* HelperNameMap.LINKED */);
1489
+ transformer.helper("type" /* HelperNameMap.TYPE */);
1456
1490
  break;
1491
+ }
1457
1492
  case 5 /* NodeTypes.List */:
1458
- generator.push(`${helper("interpolate" /* HelperNameMap.INTERPOLATE */)}(${helper("list" /* HelperNameMap.LIST */)}(${node.index}))`, node);
1493
+ transformer.helper("interpolate" /* HelperNameMap.INTERPOLATE */);
1494
+ transformer.helper("list" /* HelperNameMap.LIST */);
1459
1495
  break;
1460
1496
  case 4 /* NodeTypes.Named */:
1461
- generator.push(`${helper("interpolate" /* HelperNameMap.INTERPOLATE */)}(${helper("named" /* HelperNameMap.NAMED */)}(${JSON.stringify(node.key)}))`, node);
1462
- break;
1463
- case 9 /* NodeTypes.Literal */:
1464
- generator.push(JSON.stringify(node.value), node);
1465
- break;
1466
- case 3 /* NodeTypes.Text */:
1467
- generator.push(JSON.stringify(node.value), node);
1497
+ transformer.helper("interpolate" /* HelperNameMap.INTERPOLATE */);
1498
+ transformer.helper("named" /* HelperNameMap.NAMED */);
1468
1499
  break;
1469
- default:
1470
- {
1471
- throw createCompileError(CompileErrorCodes.UNHANDLED_CODEGEN_NODE_TYPE, null, {
1472
- domain: ERROR_DOMAIN,
1473
- args: [node.type]
1474
- });
1475
- }
1476
1500
  }
1501
+ // TODO: if we need post-hook of transform, should be implemented to here
1502
+ }
1503
+ // transform AST
1504
+ function transform(ast, options = {} // eslint-disable-line
1505
+ ) {
1506
+ const transformer = createTransformer(ast);
1507
+ transformer.helper("normalize" /* HelperNameMap.NORMALIZE */);
1508
+ // traverse
1509
+ ast.body && traverseNode(ast.body, transformer);
1510
+ // set meta information
1511
+ const context = transformer.context();
1512
+ ast.helpers = Array.from(context.helpers);
1477
1513
  }
1478
- // generate code from AST
1479
- const generate = (ast, options = {}) => {
1480
- const mode = isString(options.mode) ? options.mode : 'normal';
1481
- const filename = isString(options.filename)
1482
- ? options.filename
1483
- : 'message.intl';
1484
- const sourceMap = !!options.sourceMap;
1485
- // prettier-ignore
1486
- const breakLineCode = options.breakLineCode != null
1487
- ? options.breakLineCode
1488
- : mode === 'arrow'
1489
- ? ';'
1490
- : '\n';
1491
- const needIndent = options.needIndent ? options.needIndent : mode !== 'arrow';
1492
- const helpers = ast.helpers || [];
1493
- const generator = createCodeGenerator(ast, {
1494
- mode,
1495
- filename,
1496
- sourceMap,
1497
- breakLineCode,
1498
- needIndent
1499
- });
1500
- generator.push(mode === 'normal' ? `function __msg__ (ctx) {` : `(ctx) => {`);
1501
- generator.indent(needIndent);
1502
- if (helpers.length > 0) {
1503
- generator.push(`const { ${join(helpers.map(s => `${s}: _${s}`), ', ')} } = ctx`);
1504
- generator.newline();
1505
- }
1506
- generator.push(`return `);
1507
- generateNode(generator, ast);
1508
- generator.deindent(needIndent);
1509
- generator.push(`}`);
1510
- delete ast.helpers;
1511
- const { code, map } = generator.context();
1512
- return {
1513
- ast,
1514
- code,
1515
- map: map ? map.toJSON() : undefined // eslint-disable-line @typescript-eslint/no-explicit-any
1516
- };
1517
- };
1518
1514
 
1519
1515
  function baseCompile(source, options = {}) {
1520
1516
  const assignedOptions = assign({}, options);
1521
1517
  const jit = !!assignedOptions.jit;
1522
- const enalbeMinify = !!assignedOptions.minify;
1523
- const enambeOptimize = assignedOptions.optimize == null ? true : assignedOptions.optimize;
1518
+ const enableMangle = !!assignedOptions.mangle;
1519
+ const enableOptimize = assignedOptions.optimize == null ? true : assignedOptions.optimize;
1524
1520
  // parse source codes
1525
1521
  const parser = createParser(assignedOptions);
1526
1522
  const ast = parser.parse(source);
1523
+ // TODO:
1524
+ // With the introduction of Jit compilation, code generation is no longer necessary. This function may no longer be needed since tree-shaking is not possible.
1527
1525
  if (!jit) {
1528
1526
  // transform ASTs
1529
1527
  transform(ast, assignedOptions);
@@ -1532,17 +1530,21 @@ var IntlifyMessageCompiler = (function (exports) {
1532
1530
  }
1533
1531
  else {
1534
1532
  // optimize ASTs
1535
- enambeOptimize && optimize(ast);
1533
+ enableOptimize && optimize(ast);
1536
1534
  // minimize ASTs
1537
- enalbeMinify && minify(ast);
1535
+ enableMangle && mangle(ast);
1538
1536
  // In JIT mode, no ast transform, no code generation.
1539
1537
  return { ast, code: '' };
1540
1538
  }
1541
1539
  }
1542
1540
 
1541
+ // eslint-disable-next-line no-useless-escape
1542
+ const RE_HTML_TAG = /<\/?[\w\s="/.':;#-\/]+>/;
1543
+ const detectHtmlTag = (source) => RE_HTML_TAG.test(source);
1544
+
1543
1545
  exports.COMPILE_ERROR_CODES_EXTEND_POINT = COMPILE_ERROR_CODES_EXTEND_POINT;
1544
1546
  exports.CompileErrorCodes = CompileErrorCodes;
1545
- exports.ERROR_DOMAIN = ERROR_DOMAIN$2;
1547
+ exports.ERROR_DOMAIN = ERROR_DOMAIN;
1546
1548
  exports.LOCATION_STUB = LOCATION_STUB;
1547
1549
  exports.baseCompile = baseCompile;
1548
1550
  exports.createCompileError = createCompileError;
@@ -1552,6 +1554,8 @@ var IntlifyMessageCompiler = (function (exports) {
1552
1554
  exports.defaultOnError = defaultOnError;
1553
1555
  exports.detectHtmlTag = detectHtmlTag;
1554
1556
  exports.errorMessages = errorMessages;
1557
+ exports.mangle = mangle;
1558
+ exports.optimize = optimize;
1555
1559
 
1556
1560
  return exports;
1557
1561