@grey-ts/transpiler 1.1.1 → 1.2.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.
Files changed (2) hide show
  1. package/dist/index.js +93 -40
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -44,6 +44,7 @@ class NodeHandler {
44
44
  }
45
45
  NodeHandler.register(ts.SyntaxKind.TypeAliasDeclaration, () => "");
46
46
  NodeHandler.register(ts.SyntaxKind.InterfaceDeclaration, () => "");
47
+ NodeHandler.register(ts.SyntaxKind.ModuleDeclaration, () => "");
47
48
  NodeHandler.register(ts.SyntaxKind.EndOfFileToken, () => "");
48
49
  NodeHandler.register(ts.SyntaxKind.EmptyStatement, () => "");
49
50
 
@@ -415,20 +416,28 @@ NodeHandler.register(ts5.SyntaxKind.ClassDeclaration, (node) => {
415
416
  let output = `${name} = {}`;
416
417
  if (extensions && extensions.length && extensions[0].types.length)
417
418
  output = `${name} = new ${NodeHandler.handle(extensions[0].types[0].expression)}`;
419
+ const declaredNames = new Set;
420
+ let hasConstructor = false;
418
421
  for (const member of node.members) {
419
- if (ts5.isMethodDeclaration(member) || ts5.isConstructorDeclaration(member)) {
420
- if (!member.body)
421
- continue;
422
- output += `
423
- ${name}.${NodeHandler.handle(member)}`;
424
- } else if (ts5.isPropertyDeclaration(member)) {
425
- output += `
426
- ${name}.${NodeHandler.handle(member)}`;
427
- } else {
428
- output += `
429
- ${name}.${NodeHandler.handle(member)}`;
422
+ if (ts5.isFunctionLike(member) && "body" in member && !member.body)
423
+ continue;
424
+ if (member.name) {
425
+ const memberName = NodeHandler.handle(member.name);
426
+ if (declaredNames.has(memberName))
427
+ throw `The transpiled version of class '${name}' has a duplicate member '${memberName}'.
428
+ Modifiers such as 'static' are only for TypeScript for now and are not differentiated in the transpiled version from normal declarations for now`;
429
+ declaredNames.add(memberName);
430
430
  }
431
+ if (ts5.isConstructorDeclaration(member))
432
+ hasConstructor = true;
433
+ output += `
434
+ ${name}.${NodeHandler.handle(member)}`;
431
435
  }
436
+ if (!hasConstructor && !node.modifiers?.some((m) => m.kind === ts5.SyntaxKind.AbstractKeyword))
437
+ output += `
438
+ ${name}.constructor = function
439
+ return self
440
+ end function`;
432
441
  return output;
433
442
  });
434
443
  NodeHandler.register(ts5.SyntaxKind.Constructor, (node) => {
@@ -598,14 +607,7 @@ NodeHandler.register(ts7.SyntaxKind.ElementAccessExpression, (node, ctx) => {
598
607
  } else {
599
608
  right = NodeHandler.handle(node.argumentExpression);
600
609
  }
601
- const asd = ts7.findAncestor(node, (ancestor) => {
602
- if (ancestor.parent && ts7.isBinaryExpression(ancestor.parent) && ancestor === ancestor.parent.left) {
603
- const token = ts7.tokenToString(ancestor.parent.operatorToken.kind) || ancestor.parent.operatorToken.getText();
604
- return assignmentOperators.has(token);
605
- }
606
- return false;
607
- });
608
- if (!asd && !ts7.isNumericLiteral(node.argumentExpression)) {
610
+ if (!valueIsBeingAssignedToNode(node) && !ts7.isNumericLiteral(node.argumentExpression)) {
609
611
  return callUtilFunction("get_property", left, `${right}`);
610
612
  }
611
613
  return `${left}[${right}]`;
@@ -614,7 +616,7 @@ function handleObjectLiteralExpression(node, ctx, currObj, outObjects, funcs) {
614
616
  currObj ??= [];
615
617
  outObjects ??= [];
616
618
  funcs ??= [];
617
- const objectName = ts7.isVariableDeclaration(node.parent) ? NodeHandler.handle(node.parent.name) : ts7.isBinaryExpression(node.parent) && node === node.parent.right ? NodeHandler.handle(node.parent.left) : "";
619
+ const objectName = ts7.hasOnlyExpressionInitializer(node.parent) ? NodeHandler.handle(node.parent.name) : ts7.isBinaryExpression(node.parent) && node === node.parent.right ? NodeHandler.handle(node.parent.left) : "";
618
620
  function pushObj() {
619
621
  if (!currObj?.length)
620
622
  return "";
@@ -970,13 +972,26 @@ NodeHandler.register(ts8.SyntaxKind.AsExpression, (node) => {
970
972
  return NodeHandler.handle(node.expression);
971
973
  });
972
974
  NodeHandler.register(ts8.SyntaxKind.DeleteExpression, (node) => {
973
- if (!ts8.isPropertyAccessExpression(node.expression))
974
- throw `Cant handle delete expression for ${ts8.SyntaxKind[node.expression.kind]}`;
975
- const pnode = node.expression;
976
- const left = NodeHandler.handle(pnode.expression);
977
- const leftType = checker.getTypeAtLocation(pnode.expression);
978
- const right = replaceIdentifier(NodeHandler.handle(pnode.name), leftType, pnode.name.text);
979
- return `${left}.remove(${right})`;
975
+ if (ts8.isPropertyAccessExpression(node.expression)) {
976
+ const pnode = node.expression;
977
+ const left = NodeHandler.handle(pnode.expression);
978
+ const leftType = checker.getTypeAtLocation(pnode.expression);
979
+ const right = replaceIdentifier(NodeHandler.handle(pnode.name), leftType, pnode.name.text);
980
+ return `${left}.remove("${right}")`;
981
+ }
982
+ if (ts8.isElementAccessExpression(node.expression)) {
983
+ const pnode = node.expression;
984
+ const left = NodeHandler.handle(pnode.expression);
985
+ let right;
986
+ if (ts8.isStringLiteral(pnode.argumentExpression)) {
987
+ const leftType = checker.getTypeAtLocation(pnode.expression);
988
+ right = `"${replaceIdentifier(pnode.argumentExpression.text, leftType, pnode.argumentExpression.text)}"`;
989
+ } else {
990
+ right = NodeHandler.handle(pnode.argumentExpression);
991
+ }
992
+ return `${left}.remove(${right})`;
993
+ }
994
+ throw `Cant handle delete expression for ${ts8.SyntaxKind[node.expression.kind]}`;
980
995
  });
981
996
 
982
997
  // src/visitors/functions.ts
@@ -1016,7 +1031,7 @@ NodeHandler.register(ts9.SyntaxKind.ArrowFunction, (node) => {
1016
1031
  if (ts9.isCallOrNewExpression(node.parent) || ts9.isParenthesizedExpression(node.parent)) {
1017
1032
  return "@" + createAnonFunction(body, params).name;
1018
1033
  }
1019
- if (ts9.isPropertyAssignment(node.parent) || ts9.isVariableDeclaration(node.parent) || ts9.isBinaryExpression(node.parent) || ts9.isReturnStatement(node.parent)) {
1034
+ if (ts9.hasOnlyExpressionInitializer(node.parent) || ts9.isBinaryExpression(node.parent) || ts9.isReturnStatement(node.parent)) {
1020
1035
  return `function(${params.join(", ")})
1021
1036
  ${body}
1022
1037
  end function`;
@@ -1165,11 +1180,13 @@ NodeHandler.register(ts12.SyntaxKind.ForStatement, (node) => {
1165
1180
  }
1166
1181
  return false;
1167
1182
  }
1183
+ const labelIf = ts12.isLabeledStatement(node.parent) ? ` if ${node.parent.label.text}Broke then break` : "";
1168
1184
  if (!hasContinue(node)) {
1169
1185
  return [
1170
1186
  `${initializer}`,
1171
1187
  `while ${condition}`,
1172
1188
  ` ${statement.trimStart()}`,
1189
+ ...labelIf ? [labelIf] : [],
1173
1190
  ` ${incrementor}`,
1174
1191
  `end while`
1175
1192
  ].join(`
@@ -1186,6 +1203,7 @@ NodeHandler.register(ts12.SyntaxKind.ForStatement, (node) => {
1186
1203
  ` end if`,
1187
1204
  ` ${incrementedStateVarName} = 0`,
1188
1205
  ` ${statement.trimStart()}`,
1206
+ ...labelIf ? [labelIf] : [],
1189
1207
  ` ${incrementor}`,
1190
1208
  ` ${incrementedStateVarName} = 1`,
1191
1209
  `end while`
@@ -1202,9 +1220,14 @@ NodeHandler.register(ts12.SyntaxKind.ForOfStatement, (node) => {
1202
1220
  }
1203
1221
  const varName = NodeHandler.handle(node.initializer.declarations[0].name);
1204
1222
  const objToLoop = NodeHandler.handle(node.expression);
1205
- return `for ${varName} in ${objToLoop}
1206
- ${NodeHandler.handle(node.statement)}
1207
- end for`;
1223
+ const labelIf = ts12.isLabeledStatement(node.parent) ? ` if ${node.parent.label.text}Broke then break` : "";
1224
+ return [
1225
+ `for ${varName} in ${objToLoop}`,
1226
+ `${NodeHandler.handle(node.statement)}`,
1227
+ ...labelIf ? [labelIf] : [],
1228
+ `end for`
1229
+ ].join(`
1230
+ `);
1208
1231
  });
1209
1232
  NodeHandler.register(ts12.SyntaxKind.ForInStatement, (node) => {
1210
1233
  if (!ts12.isVariableDeclarationList(node.initializer)) {
@@ -1215,9 +1238,14 @@ NodeHandler.register(ts12.SyntaxKind.ForInStatement, (node) => {
1215
1238
  }
1216
1239
  const varName = NodeHandler.handle(node.initializer.declarations[0].name);
1217
1240
  const objToLoop = NodeHandler.handle(node.expression);
1218
- return `for ${varName} in ${objToLoop}.indexes
1219
- ${NodeHandler.handle(node.statement)}
1220
- end for`;
1241
+ const labelIf = ts12.isLabeledStatement(node.parent) ? ` if ${node.parent.label.text}Broke then break` : "";
1242
+ return [
1243
+ `for ${varName} in ${objToLoop}.indexes`,
1244
+ `${NodeHandler.handle(node.statement)}`,
1245
+ ...labelIf ? [labelIf] : [],
1246
+ `end for`
1247
+ ].join(`
1248
+ `);
1221
1249
  });
1222
1250
  NodeHandler.register(ts12.SyntaxKind.IfStatement, (node) => {
1223
1251
  const condition = NodeHandler.handle(node.expression);
@@ -1247,20 +1275,24 @@ end if`;
1247
1275
  });
1248
1276
  NodeHandler.register(ts12.SyntaxKind.WhileStatement, (node, ctx) => {
1249
1277
  const expression = NodeHandler.handle(node.expression);
1278
+ const labelIf = ts12.isLabeledStatement(node.parent) ? ` if ${node.parent.label.text}Broke then break` : "";
1250
1279
  return [
1251
1280
  `while ${expression}`,
1252
1281
  ` ${NodeHandler.handle(node.statement).trimStart()}`,
1282
+ ...labelIf ? [labelIf] : [],
1253
1283
  `end while`
1254
1284
  ].join(`
1255
1285
  `);
1256
1286
  });
1257
1287
  NodeHandler.register(ts12.SyntaxKind.DoStatement, (node, ctx) => {
1258
1288
  const expression = NodeHandler.handle(node.expression);
1289
+ const labelIf = ts12.isLabeledStatement(node.parent) ? ` if ${node.parent.label.text}Broke then break` : "";
1259
1290
  return [
1260
1291
  `did_once = 0`,
1261
1292
  `while not did_once or ${expression}`,
1262
1293
  ` did_once = 1`,
1263
1294
  ` ${NodeHandler.handle(node.statement).trimStart()}`,
1295
+ ...labelIf ? [labelIf] : [],
1264
1296
  `end while`
1265
1297
  ].join(`
1266
1298
  `);
@@ -1269,6 +1301,12 @@ NodeHandler.register(ts12.SyntaxKind.ContinueStatement, (node) => {
1269
1301
  return "continue";
1270
1302
  });
1271
1303
  NodeHandler.register(ts12.SyntaxKind.BreakStatement, (node) => {
1304
+ if (node.label) {
1305
+ if (!ts12.isBlock(node.parent))
1306
+ throw "A break statement with a label must be in a block";
1307
+ return `${NodeHandler.handle(node.label)}Broke = 1
1308
+ break`;
1309
+ }
1272
1310
  return "break";
1273
1311
  });
1274
1312
  NodeHandler.register(ts12.SyntaxKind.ReturnStatement, (node) => {
@@ -1280,13 +1318,17 @@ NodeHandler.register(ts12.SyntaxKind.ReturnStatement, (node) => {
1280
1318
  }
1281
1319
  return `return ${NodeHandler.handle(node.expression)}`;
1282
1320
  });
1321
+ NodeHandler.register(ts12.SyntaxKind.LabeledStatement, (node) => {
1322
+ return `${NodeHandler.handle(node.label)}Broke = 0
1323
+ ${NodeHandler.handle(node.statement)}`;
1324
+ });
1283
1325
 
1284
1326
  // src/visitors/variables.ts
1285
1327
  import ts13 from "typescript";
1286
1328
  function handleVariableDeclaration(node, ctx) {
1287
1329
  const left = NodeHandler.handle(node.name);
1288
1330
  const initializerType = node.initializer ? checker.getTypeAtLocation(node.initializer) : undefined;
1289
- if (ts13.isPropertyDeclaration(node) && initializerType?.flags === ts13.TypeFlags.Object && !node.modifiers?.some((mod) => mod.kind === ts13.SyntaxKind.StaticKeyword)) {
1331
+ if (ts13.isPropertyDeclaration(node) && initializerType?.flags === ts13.TypeFlags.Object && !node.modifiers?.some((mod) => mod.kind === ts13.SyntaxKind.StaticKeyword) && !ts13.isFunctionLike(node.initializer)) {
1290
1332
  console.warn(`You shouldn't initialize '${left}' with an Array or an Object because in GreyScript, every instantiation refers to the same '${left}' variable.
1291
1333
  Initialize them in the constructor instead`);
1292
1334
  }
@@ -1308,16 +1350,27 @@ NodeHandler.register(ts13.SyntaxKind.VariableStatement, (node, ctx) => {
1308
1350
  NodeHandler.register(ts13.SyntaxKind.VariableDeclaration, handleVariableDeclaration);
1309
1351
  NodeHandler.register(ts13.SyntaxKind.PropertyDeclaration, handleVariableDeclaration);
1310
1352
  NodeHandler.register(ts13.SyntaxKind.EnumDeclaration, (node) => {
1311
- const members = node.members.map((member, index) => {
1312
- const name = NodeHandler.handle(member.name);
1353
+ const members = [];
1354
+ function addMember(name, initializer) {
1355
+ members.push(`${name}: ${initializer}`);
1356
+ if (isNaN(+initializer))
1357
+ return;
1358
+ members.push(`${initializer}: ${name}`);
1359
+ }
1360
+ node.members.forEach((member, index) => {
1361
+ let name = NodeHandler.handle(member.name);
1362
+ if (!ts13.isStringLiteral(member.name))
1363
+ name = `"${name}"`;
1313
1364
  if (member.initializer) {
1314
- return `${name}: ${NodeHandler.handle(member.initializer)}`;
1365
+ addMember(name, NodeHandler.handle(member.initializer));
1366
+ return;
1315
1367
  }
1316
1368
  const type = checker.getTypeAtLocation(member);
1317
1369
  if ("value" in type) {
1318
- return `${name}: ${type.value}`;
1370
+ addMember(name, String(type.value));
1371
+ return;
1319
1372
  }
1320
- return `${name}: ${index}`;
1373
+ addMember(name, index.toString());
1321
1374
  });
1322
1375
  return `${node.name.text} = { ${members.join(", ")} }`;
1323
1376
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grey-ts/transpiler",
3
- "version": "1.1.1",
3
+ "version": "1.2.0",
4
4
  "description": "Transpiles TypeScript into GreyScript",
5
5
  "author": "Okka",
6
6
  "module": "src/index.ts",
@@ -40,6 +40,6 @@
40
40
  "typescript": "^5"
41
41
  },
42
42
  "dependencies": {
43
- "@grey-ts/types": "^2.0.0"
43
+ "@grey-ts/types": "^2.0.1"
44
44
  }
45
45
  }