@thigasdevelopment/luam 0.10.1 → 0.10.3

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 +95 -10
  2. package/package.json +1 -1
package/luam.mjs CHANGED
@@ -4836,6 +4836,19 @@ function createObjectType(members) {
4836
4836
  );
4837
4837
  return createRecord(keys.length === 0 ? "{}" : `{ ${keys.join(", ")} }`, members);
4838
4838
  }
4839
+ function createLiteralRecord(members) {
4840
+ const literal = createObjectType(members);
4841
+ return literal.kind === "record" ? { ...literal, isLiteral: true } : literal;
4842
+ }
4843
+ function isEmptyLiteral(type) {
4844
+ return type.kind === "record" && type.isLiteral === true && type.members.size === 0;
4845
+ }
4846
+ function widenInferred(type) {
4847
+ if (type.kind !== "record" || type.isLiteral !== true) {
4848
+ return widenLiteral(type);
4849
+ }
4850
+ return type.members.size === 0 ? TABLE_TYPE : createRecord(type.name, type.members, type.origin);
4851
+ }
4839
4852
  function createFunction(parameters, returnType, minimumArguments2, isVariadic = false) {
4840
4853
  return { kind: "function", parameters, returnType, minimumArguments: minimumArguments2 ?? parameters.length, isVariadic };
4841
4854
  }
@@ -5034,7 +5047,7 @@ function isAssignable(source, target, options = { allowNil: false }) {
5034
5047
  return source.kind === "record" ? isRecordAssignable(source, target, options) : source.kind === "table";
5035
5048
  }
5036
5049
  if (target.kind === "array") {
5037
- return source.kind === "table" || source.kind === "array" && isAssignable(source.element, target.element, options);
5050
+ return source.kind === "table" || isEmptyLiteral(source) || source.kind === "array" && isAssignable(source.element, target.element, options);
5038
5051
  }
5039
5052
  if (target.kind === "map") {
5040
5053
  return isMapAssignable(source, target, options);
@@ -6037,7 +6050,7 @@ import { tmpdir } from "node:os";
6037
6050
  import { join as join2 } from "node:path";
6038
6051
 
6039
6052
  // src/cli/version.ts
6040
- var VERSION = true ? "0.10.1" : "0.0.0-dev";
6053
+ var VERSION = true ? "0.10.3" : "0.0.0-dev";
6041
6054
  var PROGRAM_NAME = "luam";
6042
6055
  var PROGRAM_DESCRIPTION = "luam \u2014 the Luam compiler for Multi Theft Auto resources.";
6043
6056
 
@@ -8338,11 +8351,11 @@ var MTA_SETTINGS_SERVER = {
8338
8351
 
8339
8352
  // ../mta-types/src/generated/api/mta-sql-server.ts
8340
8353
  var MTA_SQL_SERVER = {
8341
- dbConnect: fn([STRING, STRING, STRING, STRING, STRING], named("Element"), 2),
8342
- dbExec: fn([named("Element"), STRING, ANY], BOOLEAN, 2, true),
8354
+ dbConnect: fn([STRING, STRING, STRING, STRING, STRING], named("Connection"), 2),
8355
+ dbExec: fn([named("Connection"), STRING, ANY], BOOLEAN, 2, true),
8343
8356
  dbFree: fn([ANY], BOOLEAN, 1),
8344
8357
  dbPoll: fn([ANY, NUMBER, BOOLEAN], TABLE, 2),
8345
- dbPrepareString: fn([named("Element"), STRING, ANY], STRING, 2, true),
8358
+ dbPrepareString: fn([named("Connection"), STRING, ANY], STRING, 2, true),
8346
8359
  dbQuery: fn([ANY, ANY, ANY, ANY, ANY], ANY, 2, true),
8347
8360
  executeSQLQuery: fn([STRING, ANY], TABLE, 1, true)
8348
8361
  };
@@ -9410,6 +9423,17 @@ var MTA_OOP_1 = [
9410
9423
  ],
9411
9424
  null
9412
9425
  ),
9426
+ oopClass(
9427
+ "Connection",
9428
+ null,
9429
+ [
9430
+ oopMethod("exec", "server", "dbExec", fn([STRING, ANY], BOOLEAN, 1, true)),
9431
+ oopMethod("prepareString", "server", "dbPrepareString", fn([STRING, ANY], STRING, 1, true)),
9432
+ oopMethod("query", "server", "dbQuery", fn([ANY, ANY, ANY, ANY, ANY], ANY, 2, true))
9433
+ ],
9434
+ [],
9435
+ oopConstructor("server", fn([STRING, STRING, STRING, STRING, STRING], named("Connection"), 2))
9436
+ ),
9413
9437
  oopClass(
9414
9438
  "DxFont",
9415
9439
  null,
@@ -10090,7 +10114,7 @@ var MTA_OOP_4 = [
10090
10114
  oopMethod("toggleRespawn", "client", "toggleObjectRespawn", fn([BOOLEAN], BOOLEAN, 1))
10091
10115
  ],
10092
10116
  [],
10093
- oopConstructor("shared", fn([NUMBER, NUMBER, NUMBER, NUMBER, NUMBER, NUMBER, NUMBER, BOOLEAN], named("MTASAObject"), 4))
10117
+ oopConstructor("shared", fn([NUMBER, NUMBER, NUMBER, NUMBER, NUMBER, NUMBER, NUMBER, BOOLEAN], named("Object"), 4))
10094
10118
  ),
10095
10119
  oopClass("Ped", "Element", [
10096
10120
  oopMethod("addClothes", "shared", "addPedClothes", fn([STRING, STRING, NUMBER], BOOLEAN, 3)),
@@ -11074,6 +11098,55 @@ function mtaMember(className, member) {
11074
11098
  return mtaClassRegistry().lookupMember(className, member);
11075
11099
  }
11076
11100
 
11101
+ // ../compiler/src/checker/shape-hint.ts
11102
+ function matchesDiscriminants(source, candidate) {
11103
+ for (const [name, member] of candidate.members) {
11104
+ const written = source.members.get(name);
11105
+ if (!isLiteralType(member) || written === void 0) {
11106
+ continue;
11107
+ }
11108
+ if (!isAssignable(written, member)) {
11109
+ return false;
11110
+ }
11111
+ }
11112
+ return true;
11113
+ }
11114
+ function chooseCandidate(source, candidates) {
11115
+ const [only] = candidates;
11116
+ if (candidates.length === 1 && only !== void 0) {
11117
+ return only;
11118
+ }
11119
+ const matching = candidates.filter((candidate) => matchesDiscriminants(source, candidate));
11120
+ const [best] = matching;
11121
+ return matching.length === 1 && best !== void 0 ? best : null;
11122
+ }
11123
+ function missingKeys(source, target) {
11124
+ const missing = [];
11125
+ for (const [name, member] of target.members) {
11126
+ if (member.kind !== "optional" && !source.members.has(name)) {
11127
+ missing.push(`"${name}"`);
11128
+ }
11129
+ }
11130
+ return missing;
11131
+ }
11132
+ function missingKeyHint(source, target) {
11133
+ if (source.kind !== "record" || source.isLiteral !== true) {
11134
+ return "";
11135
+ }
11136
+ const options = target.kind === "union" ? target.options : [target];
11137
+ const candidates = options.filter((option) => option.kind === "record");
11138
+ const candidate = chooseCandidate(source, candidates);
11139
+ if (candidate === null) {
11140
+ return "";
11141
+ }
11142
+ const missing = missingKeys(source, candidate);
11143
+ if (missing.length === 0) {
11144
+ return "";
11145
+ }
11146
+ const label2 = missing.length === 1 ? `Key ${missing[0]} is` : `Keys ${missing.join(", ")} are`;
11147
+ return ` ${label2} missing from "${typeToString(candidate)}".`;
11148
+ }
11149
+
11077
11150
  // ../compiler/src/checker/type-intersection.ts
11078
11151
  function namedMembers(context, name) {
11079
11152
  if (context.declarations.lookupInterface(name) === null && context.declarations.lookupClass(name) === null) {
@@ -11297,7 +11370,7 @@ var CheckContext = class {
11297
11370
  return this.returnStack[this.returnStack.length - 1]?.expected ?? null;
11298
11371
  }
11299
11372
  inferReturnType(type) {
11300
- this.returnStack[this.returnStack.length - 1]?.inferred.push(widenLiteral(type));
11373
+ this.returnStack[this.returnStack.length - 1]?.inferred.push(widenInferred(type));
11301
11374
  }
11302
11375
  pushClassMethod(frame) {
11303
11376
  this.methodStack.push(frame);
@@ -11358,7 +11431,8 @@ var CheckContext = class {
11358
11431
  }
11359
11432
  const received = isLiteralType(target) || target.kind === "union" ? source : widenLiteral(source);
11360
11433
  const message = `${subject} expects "${typeToString(target)}" but received "${typeToString(received)}".`;
11361
- this.report("check-type-mismatch", `${message}${nilHint(source, target, this.mode)}`, position2);
11434
+ const hint = `${nilHint(source, target, this.mode)}${missingKeyHint(source, target)}`;
11435
+ this.report("check-type-mismatch", `${message}${hint}`, position2);
11362
11436
  }
11363
11437
  declareProject(project) {
11364
11438
  for (const declaration of project.globals) {
@@ -12096,6 +12170,7 @@ var ELEMENT_TYPES = [
12096
12170
  { name: "Browser", parent: "Element" },
12097
12171
  { name: "Camera", parent: "Element" },
12098
12172
  { name: "ColShape", parent: "Element" },
12173
+ { name: "Connection", parent: null },
12099
12174
  { name: "DxFont", parent: null },
12100
12175
  { name: "DxRenderTarget", parent: null },
12101
12176
  { name: "DxScreenSource", parent: null },
@@ -12600,8 +12675,18 @@ function checkTable(context, expression) {
12600
12675
  }
12601
12676
  return checkExpression(context, field2.value);
12602
12677
  });
12678
+ const isRecord = expression.fields.every((field2) => field2.name !== null);
12679
+ if (isRecord) {
12680
+ const members = /* @__PURE__ */ new Map();
12681
+ expression.fields.forEach((field2, index) => {
12682
+ if (field2.name !== null) {
12683
+ members.set(field2.name, valueTypes[index] ?? ANY_TYPE);
12684
+ }
12685
+ });
12686
+ return context.record(expression, createLiteralRecord(members));
12687
+ }
12603
12688
  const isArray = expression.fields.every((field2) => field2.key === null && field2.name === null);
12604
- if (!isArray || valueTypes.length === 0) {
12689
+ if (!isArray) {
12605
12690
  return context.record(expression, TABLE_TYPE);
12606
12691
  }
12607
12692
  return context.record(expression, createArray(createUnion(valueTypes)));
@@ -13173,7 +13258,7 @@ function checkLocal(context, statement) {
13173
13258
  const valueType = valueTypes[index] ?? NIL_TYPE;
13174
13259
  context.forgetNarrowing(declaration.name);
13175
13260
  if (declaration.annotation === null) {
13176
- const inferred = context.allowNil || value === void 0 ? ANY_TYPE : widenLiteral(valueType);
13261
+ const inferred = context.allowNil || value === void 0 ? ANY_TYPE : widenInferred(valueType);
13177
13262
  context.binder.declare({ name: declaration.name, type: inferred, isLocal: true, position: declaration.position });
13178
13263
  return;
13179
13264
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thigasdevelopment/luam",
3
- "version": "0.10.1",
3
+ "version": "0.10.3",
4
4
  "description": "The Luam compiler for Multi Theft Auto resources.",
5
5
  "keywords": [
6
6
  "mta",