@thigasdevelopment/luam 0.19.8 → 0.19.11

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/luam.mjs +122 -8
  2. package/package.json +1 -1
package/luam.mjs CHANGED
@@ -4427,13 +4427,16 @@ function isCallStart(stream) {
4427
4427
  return stream.check("punctuation", "(") || stream.check("punctuation", "{") || stream.check("string") || stream.check("template");
4428
4428
  }
4429
4429
  function parseSuffixed(stream) {
4430
+ const checkpoint = stream.checkpoint();
4430
4431
  let expression = parsePrimary(stream);
4432
+ stream.recordSpan(expression, checkpoint);
4431
4433
  for (; ; ) {
4432
4434
  const token = stream.current();
4433
4435
  if (token.kind === "punctuation" && token.value === ".") {
4434
4436
  stream.next();
4435
4437
  const property = stream.expectName().value;
4436
4438
  expression = { kind: "member-expression", object: expression, property, position: token.position };
4439
+ stream.recordSpan(expression, checkpoint);
4437
4440
  continue;
4438
4441
  }
4439
4442
  if (token.kind === "punctuation" && token.value === "[") {
@@ -4441,6 +4444,7 @@ function parseSuffixed(stream) {
4441
4444
  const index = parseExpression(stream);
4442
4445
  stream.expect("punctuation", "]");
4443
4446
  expression = { kind: "index-expression", object: expression, index, position: token.position };
4447
+ stream.recordSpan(expression, checkpoint);
4444
4448
  continue;
4445
4449
  }
4446
4450
  if (token.kind === "punctuation" && token.value === ":" && stream.checkName(1)) {
@@ -4448,11 +4452,13 @@ function parseSuffixed(stream) {
4448
4452
  const method = stream.next().value;
4449
4453
  const typeArguments2 = parseCallTypeArguments(stream);
4450
4454
  expression = { kind: "call-expression", callee: expression, method, typeArguments: typeArguments2, args: parseArguments(stream), position: token.position };
4455
+ stream.recordSpan(expression, checkpoint);
4451
4456
  continue;
4452
4457
  }
4453
4458
  const typeArguments = parseCallTypeArguments(stream);
4454
4459
  if (typeArguments.length > 0 || isCallStart(stream)) {
4455
4460
  expression = { kind: "call-expression", callee: expression, method: null, typeArguments, args: parseArguments(stream), position: token.position };
4461
+ stream.recordSpan(expression, checkpoint);
4456
4462
  continue;
4457
4463
  }
4458
4464
  return expression;
@@ -6972,7 +6978,7 @@ import { tmpdir } from "node:os";
6972
6978
  import { join as join2 } from "node:path";
6973
6979
 
6974
6980
  // src/cli/version.ts
6975
- var VERSION = true ? "0.19.8" : "0.0.0-dev";
6981
+ var VERSION = true ? "0.19.11" : "0.0.0-dev";
6976
6982
  var PROGRAM_NAME = "luam";
6977
6983
  var PROGRAM_DESCRIPTION = "luam \u2014 the Luam compiler for Multi Theft Auto resources.";
6978
6984
 
@@ -21909,14 +21915,15 @@ function canonicalEdit(input, statement, span) {
21909
21915
  if (trimmed.length === 0) {
21910
21916
  return erasedEdit(source, span);
21911
21917
  }
21912
- const authored = source.slice(span.start, span.end);
21913
- const replacement = reindent(trimmed, indentOf(source, span.start));
21918
+ const end = erasedEnd(source, span);
21919
+ const authored = source.slice(span.start, end);
21920
+ const replacement = `${reindent(trimmed, indentOf(source, span.start))}${source.slice(span.end, end).trim()}`;
21914
21921
  const missing2 = lineCount2(authored) - lineCount2(replacement);
21915
21922
  if (missing2 < 0 && input.development) {
21916
21923
  return null;
21917
21924
  }
21918
- const padded = missing2 > 0 && source.slice(span.end).trim().length > 0 ? `${replacement}${"\n".repeat(missing2)}` : replacement;
21919
- return { start: span.start, end: span.end, replacement: padded, lines: emitted2.lines };
21925
+ const padded = missing2 > 0 && source.slice(end).trim().length > 0 ? `${replacement}${"\n".repeat(missing2)}` : replacement;
21926
+ return { start: span.start, end, replacement: padded, lines: emitted2.lines };
21920
21927
  }
21921
21928
 
21922
21929
  // ../compiler/src/emitter/preserve-decorators.ts
@@ -22059,7 +22066,11 @@ function selfEdit(source, member, span) {
22059
22066
  return { start: parenthesis + 1, end: parenthesis + 1, replacement: "self" };
22060
22067
  }
22061
22068
  function isKept(member) {
22062
- return !isLazyField(member) && (member.kind === "class-method" || member.value !== null);
22069
+ return !isLazyField(member);
22070
+ }
22071
+ function declaredFieldEdit(source, member, end, separator) {
22072
+ const start = member.position.offset;
22073
+ return { start, end, replacement: `${member.name} = nil${separator}${blankSpan(source.slice(start, end))}` };
22063
22074
  }
22064
22075
  function isLazyField(member) {
22065
22076
  return member.kind === "class-field" && member.decorators.some((decorator) => decorator.name === "Lazy");
@@ -22120,6 +22131,13 @@ function classEdits(input, statement, spans) {
22120
22131
  edits.push({ start: span.start, end, replacement: isLazyField(member) ? longComment(text) : blankSpan(text) });
22121
22132
  continue;
22122
22133
  }
22134
+ const needsSeparator2 = separator === null && (member !== kept[kept.length - 1] || injected !== null);
22135
+ if (member.kind === "class-field" && member.value === null) {
22136
+ const end = separator === null ? span.end : separator + 1;
22137
+ const written = separator === null ? needsSeparator2 ? "," : "" : source.slice(separator, separator + 1);
22138
+ edits.push(declaredFieldEdit(source, member, end, written));
22139
+ continue;
22140
+ }
22123
22141
  if (member.kind === "class-method" && !member.isStatic) {
22124
22142
  const self = selfEdit(source, member, span);
22125
22143
  if (self === null) {
@@ -22127,7 +22145,7 @@ function classEdits(input, statement, spans) {
22127
22145
  }
22128
22146
  edits.push(self);
22129
22147
  }
22130
- if (separator === null && (member !== kept[kept.length - 1] || injected !== null)) {
22148
+ if (needsSeparator2) {
22131
22149
  edits.push({ start: span.end, end: span.end, replacement: "," });
22132
22150
  }
22133
22151
  }
@@ -22146,6 +22164,99 @@ function classEdits(input, statement, spans) {
22146
22164
  return edits;
22147
22165
  }
22148
22166
 
22167
+ // ../compiler/src/emitter/preserve-expressions.ts
22168
+ function children(expression) {
22169
+ switch (expression.kind) {
22170
+ case "member-expression":
22171
+ return [expression.object];
22172
+ case "index-expression":
22173
+ return [expression.object, expression.index];
22174
+ case "call-expression":
22175
+ return [expression.callee, ...expression.args];
22176
+ case "new-expression":
22177
+ return [...expression.args];
22178
+ case "table-expression":
22179
+ return expression.fields.flatMap((field2) => field2.key === null ? [field2.value] : [field2.key, field2.value]);
22180
+ case "binary-expression":
22181
+ return [expression.left, expression.right];
22182
+ case "unary-expression":
22183
+ return [expression.operand];
22184
+ case "group-expression":
22185
+ return [expression.expression];
22186
+ default:
22187
+ return [];
22188
+ }
22189
+ }
22190
+ function isOwnFailure(expression, types, statics) {
22191
+ switch (expression.kind) {
22192
+ case "template-literal":
22193
+ case "new-expression":
22194
+ return true;
22195
+ case "member-expression":
22196
+ return statics.has(expression) || resolvePropertyExtension(types.get(expression.object) ?? null, expression.property) !== null;
22197
+ case "call-expression":
22198
+ if (expression.method === null && expression.callee.kind === "identifier" && expression.callee.name === "super") {
22199
+ return true;
22200
+ }
22201
+ return expression.callee.kind === "member-expression" && resolveCallExtension(types.get(expression.callee.object) ?? null, expression.callee.property) !== null;
22202
+ default:
22203
+ return false;
22204
+ }
22205
+ }
22206
+ function holdsFunction(expression) {
22207
+ return expression.kind === "function-expression" || children(expression).some(holdsFunction);
22208
+ }
22209
+ function collect2(input, expression, found) {
22210
+ if (isPreservableExpression(expression, input.types, input.staticAccess)) {
22211
+ return true;
22212
+ }
22213
+ if (isOwnFailure(expression, input.types, input.staticAccess)) {
22214
+ found.push(expression);
22215
+ return true;
22216
+ }
22217
+ return children(expression).every((child) => collect2(input, child, found));
22218
+ }
22219
+ function statementExpressions3(statement) {
22220
+ switch (statement.kind) {
22221
+ case "local-statement":
22222
+ return [...statement.values];
22223
+ case "assignment-statement":
22224
+ return statement.operator === "=" ? [...statement.targets, ...statement.values] : null;
22225
+ case "call-statement":
22226
+ return [statement.expression];
22227
+ case "return-statement":
22228
+ return [...statement.values];
22229
+ case "if-statement":
22230
+ return statement.clauses.map((clause) => clause.condition);
22231
+ default:
22232
+ return null;
22233
+ }
22234
+ }
22235
+ function expressionEdits(input, statement) {
22236
+ const slots = input.development ? statementExpressions3(statement) : null;
22237
+ if (slots === null) {
22238
+ return null;
22239
+ }
22240
+ const found = [];
22241
+ if (!slots.every((slot) => collect2(input, slot, found)) || found.length === 0) {
22242
+ return null;
22243
+ }
22244
+ const edits = [];
22245
+ for (const expression of found) {
22246
+ const span = input.spans.get(expression);
22247
+ if (span === void 0 || holdsFunction(expression)) {
22248
+ return null;
22249
+ }
22250
+ const state = createEmitState(input.types, input.references, input.generatedMembers, input.staticAccess);
22251
+ const replacement = emitExpression(state, expression);
22252
+ if (replacement.includes("\n") || input.source.slice(span.start, span.end).includes("\n")) {
22253
+ return null;
22254
+ }
22255
+ edits.push({ start: span.start, end: span.end, replacement });
22256
+ }
22257
+ return edits;
22258
+ }
22259
+
22149
22260
  // ../compiler/src/emitter/preserve-loops.ts
22150
22261
  var BREAK_KEYWORD = "break";
22151
22262
  var CONTINUE_KEYWORD = "continue";
@@ -22263,8 +22374,11 @@ function visit(collector, statement, wrapped) {
22263
22374
  descend(collector, statement, false, surgical.wrapsBody);
22264
22375
  return;
22265
22376
  }
22266
- if (isPreservableStatement(statement, collector.input.types, collector.input.staticAccess) && keepsScaffolding(statement)) {
22377
+ const preservable = isPreservableStatement(statement, collector.input.types, collector.input.staticAccess);
22378
+ const narrowed = preservable ? null : expressionEdits(collector.input, statement);
22379
+ if ((preservable || narrowed !== null) && keepsScaffolding(statement)) {
22267
22380
  const inherited = statement.kind === "do-statement" || statement.kind === "if-statement" ? wrapped : false;
22381
+ collector.edits.push(...narrowed ?? []);
22268
22382
  descend(collector, statement, inherited, false);
22269
22383
  return;
22270
22384
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thigasdevelopment/luam",
3
- "version": "0.19.8",
3
+ "version": "0.19.11",
4
4
  "description": "The Luam compiler for Multi Theft Auto resources.",
5
5
  "keywords": [
6
6
  "mta",