@xaendar/compiler 0.6.19 → 0.6.20

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,5 +1,5 @@
1
1
  import { Stack, indent } from "@xaendar/common";
2
- import ts from "typescript";
2
+ import ts, { ScriptTarget, SyntaxKind, createSourceFile, forEachChild, isExpressionStatement, isIdentifier } from "typescript";
3
3
  //#region ../packages/compiler/src/lexer/types/lexer-state.enum.ts
4
4
  /**
5
5
  * Represents the set of states the lexer can be in while processing template input.
@@ -196,7 +196,8 @@ function consumeAttributeValue(cursor, _context) {
196
196
  tokens: [{
197
197
  type: TokenType.ATTRIBUTE_VALUE,
198
198
  parts: [value]
199
- }]
199
+ }],
200
+ popState: true
200
201
  };
201
202
  break;
202
203
  default:
@@ -658,29 +659,6 @@ function addCharacter(cursor, interpolation) {
658
659
  return `${interpolation}${cursor.currentChar.value}`;
659
660
  }
660
661
  //#endregion
661
- //#region ../packages/compiler/src/utils/chars.utils.ts
662
- /**
663
- * Checks whether a string contains at least one non-whitespace character.
664
- *
665
- * Whitespace characters include space, `\n`, `\r`, `\t`, `\f`, and `\v`.
666
- *
667
- * @param str - The string to check.
668
- * @returns `true` if the string is not blank, `false` if it consists entirely of whitespace.
669
- */
670
- function isNotBlank(str) {
671
- return /\S/.test(str);
672
- }
673
- /**
674
- * Checks whether the given ASCII code is a valid first character for a
675
- * JavaScript identifier (`A`–`Z`, `a`–`z`, `$`, `_`).
676
- *
677
- * @param code - The ASCII code to evaluate.
678
- * @returns `true` if the code can start a JS identifier, `false` otherwise.
679
- */
680
- function isJSIdentifierStart(code) {
681
- return code >= 65 && code <= 90 || code >= 97 && code <= 122 || code === 36 || code === 95;
682
- }
683
- //#endregion
684
662
  //#region ../packages/compiler/src/lexer/states/interpolation.state.ts
685
663
  /**
686
664
  * Dispatches between an expression and a literal interpolation after the opening `{`.
@@ -692,14 +670,9 @@ function isJSIdentifierStart(code) {
692
670
  * @returns Transition result with the appropriate interpolation sub-state.
693
671
  */
694
672
  function consumeInterpolation(cursor, _context) {
695
- let retVal;
696
673
  cursor.advance();
697
674
  cursor.skipSpaces();
698
- const nextChar = cursor.peek();
699
- if (nextChar === 96) retVal = { state: LexerState.INTERPOLATION_LITERAL };
700
- else if (isJSIdentifierStart(nextChar)) retVal = { state: LexerState.INTERPOLATION_EXPRESSION };
701
- else throw new Error(`Unrecognized First Character ${String.fromCharCode(nextChar)} in interpolation`);
702
- return retVal;
675
+ return cursor.peek() === 96 ? { state: LexerState.INTERPOLATION_LITERAL } : { state: LexerState.INTERPOLATION_EXPRESSION };
703
676
  }
704
677
  //#endregion
705
678
  //#region ../packages/compiler/src/lexer/states/tag-body.state.ts
@@ -842,6 +815,19 @@ function consumeTagOpenName(cursor, _context) {
842
815
  return retVal;
843
816
  }
844
817
  //#endregion
818
+ //#region ../packages/compiler/src/utils/chars.utils.ts
819
+ /**
820
+ * Checks whether a string contains at least one non-whitespace character.
821
+ *
822
+ * Whitespace characters include space, `\n`, `\r`, `\t`, `\f`, and `\v`.
823
+ *
824
+ * @param str - The string to check.
825
+ * @returns `true` if the string is not blank, `false` if it consists entirely of whitespace.
826
+ */
827
+ function isNotBlank(str) {
828
+ return /\S/.test(str);
829
+ }
830
+ //#endregion
845
831
  //#region ../packages/compiler/src/lexer/states/text.state.ts
846
832
  /**
847
833
  * Consumes plain text content, accumulating characters until a structural boundary
@@ -1315,7 +1301,7 @@ var ASTNodeType = /* @__PURE__ */ function(ASTNodeType) {
1315
1301
  * // "'await' is not allowed inside template expressions."
1316
1302
  */
1317
1303
  function validateExpression(source) {
1318
- const expression = ts.createSourceFile("expression.ts", `const x = ${source}`, ts.ScriptTarget.ESNext, true).statements[0].declarationList.declarations[0].initializer;
1304
+ const expression = createSourceFile("expression.ts", `const x = ${source}`, ScriptTarget.ESNext, true).statements[0].declarationList.declarations[0].initializer;
1319
1305
  const diagnostics = new Array();
1320
1306
  visitNode(expression, 10, diagnostics);
1321
1307
  if (diagnostics.length) throw new Error(diagnostics.reduce((acc, d) => `${acc}${d.message}\n`, ""));
@@ -1335,7 +1321,7 @@ function validateExpression(source) {
1335
1321
  */
1336
1322
  function visitNode(node, offset, diagnostics) {
1337
1323
  if (!isAllowedNode(node)) throw new Error(buildDisallowedMessage(node));
1338
- ts.forEachChild(node, (child) => visitNode(child, offset, diagnostics));
1324
+ forEachChild(node, (child) => visitNode(child, offset, diagnostics));
1339
1325
  if (diagnostics.length) throw new Error(diagnostics[0].message);
1340
1326
  }
1341
1327
  /**
@@ -1348,62 +1334,63 @@ function visitNode(node, offset, diagnostics) {
1348
1334
  */
1349
1335
  function isAllowedNode(node) {
1350
1336
  switch (node.kind) {
1351
- case ts.SyntaxKind.StringLiteral:
1352
- case ts.SyntaxKind.NumericLiteral:
1353
- case ts.SyntaxKind.BigIntLiteral:
1354
- case ts.SyntaxKind.TrueKeyword:
1355
- case ts.SyntaxKind.FalseKeyword:
1356
- case ts.SyntaxKind.NullKeyword:
1357
- case ts.SyntaxKind.UndefinedKeyword:
1358
- case ts.SyntaxKind.Identifier:
1359
- case ts.SyntaxKind.PropertyAccessExpression:
1360
- case ts.SyntaxKind.ElementAccessExpression:
1361
- case ts.SyntaxKind.CallExpression:
1362
- case ts.SyntaxKind.BinaryExpression:
1363
- case ts.SyntaxKind.EqualsEqualsToken:
1364
- case ts.SyntaxKind.EqualsEqualsEqualsToken:
1365
- case ts.SyntaxKind.ExclamationEqualsToken:
1366
- case ts.SyntaxKind.ExclamationEqualsEqualsToken:
1367
- case ts.SyntaxKind.LessThanToken:
1368
- case ts.SyntaxKind.LessThanEqualsToken:
1369
- case ts.SyntaxKind.GreaterThanToken:
1370
- case ts.SyntaxKind.GreaterThanEqualsToken:
1371
- case ts.SyntaxKind.PlusToken:
1372
- case ts.SyntaxKind.MinusToken:
1373
- case ts.SyntaxKind.AsteriskToken:
1374
- case ts.SyntaxKind.SlashToken:
1375
- case ts.SyntaxKind.PercentToken:
1376
- case ts.SyntaxKind.AsteriskAsteriskToken:
1377
- case ts.SyntaxKind.AmpersandAmpersandToken:
1378
- case ts.SyntaxKind.BarBarToken:
1379
- case ts.SyntaxKind.QuestionQuestionToken:
1380
- case ts.SyntaxKind.AmpersandToken:
1381
- case ts.SyntaxKind.BarToken:
1382
- case ts.SyntaxKind.CaretToken:
1383
- case ts.SyntaxKind.LessThanLessThanToken:
1384
- case ts.SyntaxKind.GreaterThanGreaterThanToken:
1385
- case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken:
1386
- case ts.SyntaxKind.InstanceOfKeyword:
1387
- case ts.SyntaxKind.InKeyword:
1388
- case ts.SyntaxKind.PrefixUnaryExpression:
1389
- case ts.SyntaxKind.PostfixUnaryExpression:
1390
- case ts.SyntaxKind.TypeOfExpression:
1391
- case ts.SyntaxKind.VoidExpression:
1392
- case ts.SyntaxKind.ConditionalExpression:
1393
- case ts.SyntaxKind.ParenthesizedExpression:
1394
- case ts.SyntaxKind.TemplateExpression:
1395
- case ts.SyntaxKind.NoSubstitutionTemplateLiteral:
1396
- case ts.SyntaxKind.TemplateHead:
1397
- case ts.SyntaxKind.TemplateMiddle:
1398
- case ts.SyntaxKind.TemplateTail:
1399
- case ts.SyntaxKind.TemplateSpan:
1400
- case ts.SyntaxKind.ArrayLiteralExpression:
1401
- case ts.SyntaxKind.ObjectLiteralExpression:
1402
- case ts.SyntaxKind.PropertyAssignment:
1403
- case ts.SyntaxKind.ShorthandPropertyAssignment:
1404
- case ts.SyntaxKind.SpreadAssignment:
1405
- case ts.SyntaxKind.SpreadElement:
1406
- case ts.SyntaxKind.SyntaxList: return true;
1337
+ case SyntaxKind.StringLiteral:
1338
+ case SyntaxKind.NumericLiteral:
1339
+ case SyntaxKind.BigIntLiteral:
1340
+ case SyntaxKind.TrueKeyword:
1341
+ case SyntaxKind.FalseKeyword:
1342
+ case SyntaxKind.NullKeyword:
1343
+ case SyntaxKind.UndefinedKeyword:
1344
+ case SyntaxKind.Identifier:
1345
+ case SyntaxKind.PropertyAccessExpression:
1346
+ case SyntaxKind.ElementAccessExpression:
1347
+ case SyntaxKind.CallExpression:
1348
+ case SyntaxKind.BinaryExpression:
1349
+ case SyntaxKind.EqualsEqualsToken:
1350
+ case SyntaxKind.EqualsEqualsEqualsToken:
1351
+ case SyntaxKind.ExclamationEqualsToken:
1352
+ case SyntaxKind.ExclamationEqualsEqualsToken:
1353
+ case SyntaxKind.LessThanToken:
1354
+ case SyntaxKind.LessThanEqualsToken:
1355
+ case SyntaxKind.GreaterThanToken:
1356
+ case SyntaxKind.GreaterThanEqualsToken:
1357
+ case SyntaxKind.PlusToken:
1358
+ case SyntaxKind.MinusToken:
1359
+ case SyntaxKind.AsteriskToken:
1360
+ case SyntaxKind.SlashToken:
1361
+ case SyntaxKind.PercentToken:
1362
+ case SyntaxKind.AsteriskAsteriskToken:
1363
+ case SyntaxKind.AmpersandAmpersandToken:
1364
+ case SyntaxKind.BarBarToken:
1365
+ case SyntaxKind.QuestionQuestionToken:
1366
+ case SyntaxKind.QuestionDotToken:
1367
+ case SyntaxKind.AmpersandToken:
1368
+ case SyntaxKind.BarToken:
1369
+ case SyntaxKind.CaretToken:
1370
+ case SyntaxKind.LessThanLessThanToken:
1371
+ case SyntaxKind.GreaterThanGreaterThanToken:
1372
+ case SyntaxKind.GreaterThanGreaterThanGreaterThanToken:
1373
+ case SyntaxKind.InstanceOfKeyword:
1374
+ case SyntaxKind.InKeyword:
1375
+ case SyntaxKind.PrefixUnaryExpression:
1376
+ case SyntaxKind.PostfixUnaryExpression:
1377
+ case SyntaxKind.TypeOfExpression:
1378
+ case SyntaxKind.VoidExpression:
1379
+ case SyntaxKind.ConditionalExpression:
1380
+ case SyntaxKind.ParenthesizedExpression:
1381
+ case SyntaxKind.TemplateExpression:
1382
+ case SyntaxKind.NoSubstitutionTemplateLiteral:
1383
+ case SyntaxKind.TemplateHead:
1384
+ case SyntaxKind.TemplateMiddle:
1385
+ case SyntaxKind.TemplateTail:
1386
+ case SyntaxKind.TemplateSpan:
1387
+ case SyntaxKind.ArrayLiteralExpression:
1388
+ case SyntaxKind.ObjectLiteralExpression:
1389
+ case SyntaxKind.PropertyAssignment:
1390
+ case SyntaxKind.ShorthandPropertyAssignment:
1391
+ case SyntaxKind.SpreadAssignment:
1392
+ case SyntaxKind.SpreadElement:
1393
+ case SyntaxKind.SyntaxList: return true;
1407
1394
  default: return false;
1408
1395
  }
1409
1396
  }
@@ -1416,25 +1403,25 @@ function isAllowedNode(node) {
1416
1403
  */
1417
1404
  function buildDisallowedMessage(node) {
1418
1405
  switch (node.kind) {
1419
- case ts.SyntaxKind.AwaitExpression: return "'await' is not allowed inside template expressions.";
1420
- case ts.SyntaxKind.YieldExpression: return "'yield' is not allowed inside template expressions.";
1421
- case ts.SyntaxKind.NewExpression: return "'new' is not allowed inside template expressions.";
1422
- case ts.SyntaxKind.ArrowFunction:
1423
- case ts.SyntaxKind.FunctionExpression: return "Function expressions are not allowed inside template expressions.";
1424
- case ts.SyntaxKind.TaggedTemplateExpression: return "Tagged template expressions are not allowed inside template expressions.";
1425
- case ts.SyntaxKind.BinaryExpression: return isAssignmentOperator(node.operatorToken.kind) ? "Assignments are not allowed inside template expressions. Use @const to declare local template variables instead." : `'${ts.SyntaxKind[node.kind]}' is not allowed inside template expressions.`;
1426
- default: return `'${ts.SyntaxKind[node.kind]}' is not allowed inside template expressions.`;
1406
+ case SyntaxKind.AwaitExpression: return "'await' is not allowed inside template expressions.";
1407
+ case SyntaxKind.YieldExpression: return "'yield' is not allowed inside template expressions.";
1408
+ case SyntaxKind.NewExpression: return "'new' is not allowed inside template expressions.";
1409
+ case SyntaxKind.ArrowFunction:
1410
+ case SyntaxKind.FunctionExpression: return "Function expressions are not allowed inside template expressions.";
1411
+ case SyntaxKind.TaggedTemplateExpression: return "Tagged template expressions are not allowed inside template expressions.";
1412
+ case SyntaxKind.BinaryExpression: return isAssignmentOperator(node.operatorToken.kind) ? "Assignments are not allowed inside template expressions. Use @const to declare local template variables instead." : `'${SyntaxKind[node.kind]}' is not allowed inside template expressions.`;
1413
+ default: return `'${SyntaxKind[node.kind]}' is not allowed inside template expressions.`;
1427
1414
  }
1428
1415
  }
1429
1416
  /**
1430
- * Returns `true` if the given {@link ts.SyntaxKind} is an assignment operator.
1417
+ * Returns `true` if the given {@link SyntaxKind} is an assignment operator.
1431
1418
  *
1432
1419
  * Covers simple assignment (`=`) as well as all compound assignment operators
1433
1420
  * (`+=`, `-=`, `&&=`, `||=`, `??=`, etc.) as defined by the TypeScript
1434
1421
  * `FirstAssignment`–`LastAssignment` range.
1435
1422
  */
1436
1423
  function isAssignmentOperator(kind) {
1437
- return kind >= ts.SyntaxKind.FirstAssignment && kind <= ts.SyntaxKind.LastAssignment;
1424
+ return kind >= SyntaxKind.FirstAssignment && kind <= SyntaxKind.LastAssignment;
1438
1425
  }
1439
1426
  //#endregion
1440
1427
  //#region ../packages/compiler/src/parser/states/parse-interpolation.state.ts
@@ -1756,8 +1743,8 @@ function splitForSections(source) {
1756
1743
  */
1757
1744
  function isValidIdentifier(name) {
1758
1745
  if (!name.length) return false;
1759
- const statement = ts.createSourceFile("__id.ts", name, ts.ScriptTarget.ESNext, false).statements[0];
1760
- return !!statement && ts.isExpressionStatement(statement) && ts.isIdentifier(statement.expression) && statement.expression.text === name;
1746
+ const statement = createSourceFile("__id.ts", name, ScriptTarget.ESNext, false).statements[0];
1747
+ return !!statement && isExpressionStatement(statement) && isIdentifier(statement.expression) && statement.expression.text === name;
1761
1748
  }
1762
1749
  //#endregion
1763
1750
  //#region ../packages/compiler/src/parser/states/parse-if.state.ts
@@ -2426,7 +2413,7 @@ function processFor(node, nodeName, parentNode, compilerContext) {
2426
2413
  counterName
2427
2414
  ]
2428
2415
  });
2429
- mainBlock.push(`_for(${parentNode}, context, () => ${iterableExpr}, this.${forKey}.bind(this));`);
2416
+ mainBlock.push(`_for(${parentNode}, context, () => ${iterableExpr}, (${node.itemAlias}) => ${resolveExpression(node.trackExpression, forContext)}, this.${forKey}.bind(this));`);
2430
2417
  return {
2431
2418
  mainBlock,
2432
2419
  fns: functionsToProcess
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xaendar/compiler",
3
- "version": "0.6.19",
3
+ "version": "0.6.20",
4
4
  "description": "A library for transpiling Xaendar Templates into JavaScript code",
5
5
  "sideEffects": false,
6
6
  "type": "module",
@@ -16,8 +16,8 @@
16
16
  }
17
17
  },
18
18
  "dependencies": {
19
- "@xaendar/common": "0.6.19",
20
- "@xaendar/types": "0.6.19",
19
+ "@xaendar/common": "0.6.20",
20
+ "@xaendar/types": "0.6.20",
21
21
  "typescript": "^6.0.3"
22
22
  }
23
23
  }