@xaendar/compiler 0.6.18 → 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:
@@ -384,12 +385,19 @@ function consumeEventParameter(cursor, _context) {
384
385
  parts: [eventParameter]
385
386
  });
386
387
  cursor.advance();
388
+ cursor.skipSpaces();
387
389
  eventParameter = "";
388
390
  } else eventParameter = addCharacter$2(cursor, eventParameter);
389
391
  break;
390
392
  case 41:
391
393
  cursor.advance();
392
- read = false;
394
+ if (!charDelimiter) {
395
+ retVal.tokens.push({
396
+ type: TokenType.EVENT_PAREMETER,
397
+ parts: [eventParameter]
398
+ });
399
+ read = false;
400
+ }
393
401
  default: eventParameter = addCharacter$2(cursor, eventParameter);
394
402
  }
395
403
  return retVal;
@@ -651,29 +659,6 @@ function addCharacter(cursor, interpolation) {
651
659
  return `${interpolation}${cursor.currentChar.value}`;
652
660
  }
653
661
  //#endregion
654
- //#region ../packages/compiler/src/utils/chars.utils.ts
655
- /**
656
- * Checks whether a string contains at least one non-whitespace character.
657
- *
658
- * Whitespace characters include space, `\n`, `\r`, `\t`, `\f`, and `\v`.
659
- *
660
- * @param str - The string to check.
661
- * @returns `true` if the string is not blank, `false` if it consists entirely of whitespace.
662
- */
663
- function isNotBlank(str) {
664
- return /\S/.test(str);
665
- }
666
- /**
667
- * Checks whether the given ASCII code is a valid first character for a
668
- * JavaScript identifier (`A`–`Z`, `a`–`z`, `$`, `_`).
669
- *
670
- * @param code - The ASCII code to evaluate.
671
- * @returns `true` if the code can start a JS identifier, `false` otherwise.
672
- */
673
- function isJSIdentifierStart(code) {
674
- return code >= 65 && code <= 90 || code >= 97 && code <= 122 || code === 36 || code === 95;
675
- }
676
- //#endregion
677
662
  //#region ../packages/compiler/src/lexer/states/interpolation.state.ts
678
663
  /**
679
664
  * Dispatches between an expression and a literal interpolation after the opening `{`.
@@ -685,14 +670,9 @@ function isJSIdentifierStart(code) {
685
670
  * @returns Transition result with the appropriate interpolation sub-state.
686
671
  */
687
672
  function consumeInterpolation(cursor, _context) {
688
- let retVal;
689
673
  cursor.advance();
690
674
  cursor.skipSpaces();
691
- const nextChar = cursor.peek();
692
- if (nextChar === 96) retVal = { state: LexerState.INTERPOLATION_LITERAL };
693
- else if (isJSIdentifierStart(nextChar)) retVal = { state: LexerState.INTERPOLATION_EXPRESSION };
694
- else throw new Error(`Unrecognized First Character ${String.fromCharCode(nextChar)} in interpolation`);
695
- return retVal;
675
+ return cursor.peek() === 96 ? { state: LexerState.INTERPOLATION_LITERAL } : { state: LexerState.INTERPOLATION_EXPRESSION };
696
676
  }
697
677
  //#endregion
698
678
  //#region ../packages/compiler/src/lexer/states/tag-body.state.ts
@@ -835,6 +815,19 @@ function consumeTagOpenName(cursor, _context) {
835
815
  return retVal;
836
816
  }
837
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
838
831
  //#region ../packages/compiler/src/lexer/states/text.state.ts
839
832
  /**
840
833
  * Consumes plain text content, accumulating characters until a structural boundary
@@ -1308,7 +1301,7 @@ var ASTNodeType = /* @__PURE__ */ function(ASTNodeType) {
1308
1301
  * // "'await' is not allowed inside template expressions."
1309
1302
  */
1310
1303
  function validateExpression(source) {
1311
- 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;
1312
1305
  const diagnostics = new Array();
1313
1306
  visitNode(expression, 10, diagnostics);
1314
1307
  if (diagnostics.length) throw new Error(diagnostics.reduce((acc, d) => `${acc}${d.message}\n`, ""));
@@ -1328,7 +1321,7 @@ function validateExpression(source) {
1328
1321
  */
1329
1322
  function visitNode(node, offset, diagnostics) {
1330
1323
  if (!isAllowedNode(node)) throw new Error(buildDisallowedMessage(node));
1331
- ts.forEachChild(node, (child) => visitNode(child, offset, diagnostics));
1324
+ forEachChild(node, (child) => visitNode(child, offset, diagnostics));
1332
1325
  if (diagnostics.length) throw new Error(diagnostics[0].message);
1333
1326
  }
1334
1327
  /**
@@ -1341,62 +1334,63 @@ function visitNode(node, offset, diagnostics) {
1341
1334
  */
1342
1335
  function isAllowedNode(node) {
1343
1336
  switch (node.kind) {
1344
- case ts.SyntaxKind.StringLiteral:
1345
- case ts.SyntaxKind.NumericLiteral:
1346
- case ts.SyntaxKind.BigIntLiteral:
1347
- case ts.SyntaxKind.TrueKeyword:
1348
- case ts.SyntaxKind.FalseKeyword:
1349
- case ts.SyntaxKind.NullKeyword:
1350
- case ts.SyntaxKind.UndefinedKeyword:
1351
- case ts.SyntaxKind.Identifier:
1352
- case ts.SyntaxKind.PropertyAccessExpression:
1353
- case ts.SyntaxKind.ElementAccessExpression:
1354
- case ts.SyntaxKind.CallExpression:
1355
- case ts.SyntaxKind.BinaryExpression:
1356
- case ts.SyntaxKind.EqualsEqualsToken:
1357
- case ts.SyntaxKind.EqualsEqualsEqualsToken:
1358
- case ts.SyntaxKind.ExclamationEqualsToken:
1359
- case ts.SyntaxKind.ExclamationEqualsEqualsToken:
1360
- case ts.SyntaxKind.LessThanToken:
1361
- case ts.SyntaxKind.LessThanEqualsToken:
1362
- case ts.SyntaxKind.GreaterThanToken:
1363
- case ts.SyntaxKind.GreaterThanEqualsToken:
1364
- case ts.SyntaxKind.PlusToken:
1365
- case ts.SyntaxKind.MinusToken:
1366
- case ts.SyntaxKind.AsteriskToken:
1367
- case ts.SyntaxKind.SlashToken:
1368
- case ts.SyntaxKind.PercentToken:
1369
- case ts.SyntaxKind.AsteriskAsteriskToken:
1370
- case ts.SyntaxKind.AmpersandAmpersandToken:
1371
- case ts.SyntaxKind.BarBarToken:
1372
- case ts.SyntaxKind.QuestionQuestionToken:
1373
- case ts.SyntaxKind.AmpersandToken:
1374
- case ts.SyntaxKind.BarToken:
1375
- case ts.SyntaxKind.CaretToken:
1376
- case ts.SyntaxKind.LessThanLessThanToken:
1377
- case ts.SyntaxKind.GreaterThanGreaterThanToken:
1378
- case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken:
1379
- case ts.SyntaxKind.InstanceOfKeyword:
1380
- case ts.SyntaxKind.InKeyword:
1381
- case ts.SyntaxKind.PrefixUnaryExpression:
1382
- case ts.SyntaxKind.PostfixUnaryExpression:
1383
- case ts.SyntaxKind.TypeOfExpression:
1384
- case ts.SyntaxKind.VoidExpression:
1385
- case ts.SyntaxKind.ConditionalExpression:
1386
- case ts.SyntaxKind.ParenthesizedExpression:
1387
- case ts.SyntaxKind.TemplateExpression:
1388
- case ts.SyntaxKind.NoSubstitutionTemplateLiteral:
1389
- case ts.SyntaxKind.TemplateHead:
1390
- case ts.SyntaxKind.TemplateMiddle:
1391
- case ts.SyntaxKind.TemplateTail:
1392
- case ts.SyntaxKind.TemplateSpan:
1393
- case ts.SyntaxKind.ArrayLiteralExpression:
1394
- case ts.SyntaxKind.ObjectLiteralExpression:
1395
- case ts.SyntaxKind.PropertyAssignment:
1396
- case ts.SyntaxKind.ShorthandPropertyAssignment:
1397
- case ts.SyntaxKind.SpreadAssignment:
1398
- case ts.SyntaxKind.SpreadElement:
1399
- 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;
1400
1394
  default: return false;
1401
1395
  }
1402
1396
  }
@@ -1409,25 +1403,25 @@ function isAllowedNode(node) {
1409
1403
  */
1410
1404
  function buildDisallowedMessage(node) {
1411
1405
  switch (node.kind) {
1412
- case ts.SyntaxKind.AwaitExpression: return "'await' is not allowed inside template expressions.";
1413
- case ts.SyntaxKind.YieldExpression: return "'yield' is not allowed inside template expressions.";
1414
- case ts.SyntaxKind.NewExpression: return "'new' is not allowed inside template expressions.";
1415
- case ts.SyntaxKind.ArrowFunction:
1416
- case ts.SyntaxKind.FunctionExpression: return "Function expressions are not allowed inside template expressions.";
1417
- case ts.SyntaxKind.TaggedTemplateExpression: return "Tagged template expressions are not allowed inside template expressions.";
1418
- 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.`;
1419
- 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.`;
1420
1414
  }
1421
1415
  }
1422
1416
  /**
1423
- * Returns `true` if the given {@link ts.SyntaxKind} is an assignment operator.
1417
+ * Returns `true` if the given {@link SyntaxKind} is an assignment operator.
1424
1418
  *
1425
1419
  * Covers simple assignment (`=`) as well as all compound assignment operators
1426
1420
  * (`+=`, `-=`, `&&=`, `||=`, `??=`, etc.) as defined by the TypeScript
1427
1421
  * `FirstAssignment`–`LastAssignment` range.
1428
1422
  */
1429
1423
  function isAssignmentOperator(kind) {
1430
- return kind >= ts.SyntaxKind.FirstAssignment && kind <= ts.SyntaxKind.LastAssignment;
1424
+ return kind >= SyntaxKind.FirstAssignment && kind <= SyntaxKind.LastAssignment;
1431
1425
  }
1432
1426
  //#endregion
1433
1427
  //#region ../packages/compiler/src/parser/states/parse-interpolation.state.ts
@@ -1749,8 +1743,8 @@ function splitForSections(source) {
1749
1743
  */
1750
1744
  function isValidIdentifier(name) {
1751
1745
  if (!name.length) return false;
1752
- const statement = ts.createSourceFile("__id.ts", name, ts.ScriptTarget.ESNext, false).statements[0];
1753
- 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;
1754
1748
  }
1755
1749
  //#endregion
1756
1750
  //#region ../packages/compiler/src/parser/states/parse-if.state.ts
@@ -2327,7 +2321,14 @@ function mapAttributes(attributes, compilerContext) {
2327
2321
  function mapEvents(events, compilerContext) {
2328
2322
  compilerContext.addIdentifier("$event");
2329
2323
  const mappedEvents = events?.map((event) => {
2330
- const parameters = event.parameters.map((parameter) => `() => ${resolveExpression(parameter, compilerContext)},`);
2324
+ let parsedEventParameter = false;
2325
+ const parameters = event.parameters.map((parameter) => {
2326
+ const resolvedParameter = resolveExpression(parameter, compilerContext);
2327
+ if (!parsedEventParameter && resolvedParameter === "$event") {
2328
+ parsedEventParameter = true;
2329
+ return `($event) => ${resolvedParameter},`;
2330
+ } else return `() => ${resolvedParameter},`;
2331
+ });
2331
2332
  return [
2332
2333
  "{",
2333
2334
  ...indent([
@@ -2412,7 +2413,7 @@ function processFor(node, nodeName, parentNode, compilerContext) {
2412
2413
  counterName
2413
2414
  ]
2414
2415
  });
2415
- 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));`);
2416
2417
  return {
2417
2418
  mainBlock,
2418
2419
  fns: functionsToProcess
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xaendar/compiler",
3
- "version": "0.6.18",
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.18",
20
- "@xaendar/types": "0.6.18",
19
+ "@xaendar/common": "0.6.20",
20
+ "@xaendar/types": "0.6.20",
21
21
  "typescript": "^6.0.3"
22
22
  }
23
23
  }