@thigasdevelopment/luam 0.19.11 → 1.0.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/luam.mjs +1069 -177
  2. package/package.json +1 -1
package/luam.mjs CHANGED
@@ -3161,6 +3161,7 @@ var DEFAULT_COMPILER_OPTIONS = {
3161
3161
  oop: false,
3162
3162
  noUnusedLocals: false,
3163
3163
  noUnusedParameters: false,
3164
+ noImplicitGlobals: false,
3164
3165
  warningsAsErrors: false
3165
3166
  };
3166
3167
  var DEFAULT_SOURCE_MAPPING = {
@@ -3838,7 +3839,21 @@ function parseTypeName(stream) {
3838
3839
  }
3839
3840
  return { kind: "type-name", name: token.value, typeArguments, position: token.position };
3840
3841
  }
3842
+ function parseOptionalParameterType(stream) {
3843
+ const name = stream.next().value;
3844
+ const marker = stream.next();
3845
+ stream.next();
3846
+ const annotation = parseTypeAnnotation(stream);
3847
+ if (annotation.kind === "type-optional") {
3848
+ stream.report("parse-redundant-optional", 'The marker on the name already allows "nil". Remove the "?" after the type.', annotation.position);
3849
+ }
3850
+ const element = annotation.kind === "type-optional" ? annotation.element : annotation;
3851
+ return { name, annotation: { kind: "type-optional", element, position: marker.position } };
3852
+ }
3841
3853
  function parseParameterType(stream) {
3854
+ if (stream.check("identifier") && stream.checkAhead(1, "operator", "?") && stream.checkAhead(2, "punctuation", ":")) {
3855
+ return parseOptionalParameterType(stream);
3856
+ }
3842
3857
  let name = null;
3843
3858
  if (stream.check("identifier") && stream.checkAhead(1, "punctuation", ":")) {
3844
3859
  name = stream.next().value;
@@ -3889,7 +3904,7 @@ function parseGroupedType(stream) {
3889
3904
  return { kind: "type-tuple", elements, position: position2 };
3890
3905
  }
3891
3906
  function parseObjectMember(stream) {
3892
- const token = stream.expectName();
3907
+ const token = stream.expectMemberKey();
3893
3908
  const annotation = parseNamedAnnotation(stream, "field");
3894
3909
  if (annotation === null) {
3895
3910
  throw stream.error(`Key "${token.value}" of an object type requires a type annotation.`, "parse-invalid-type");
@@ -4034,9 +4049,16 @@ var TokenStream = class {
4034
4049
  index = 0;
4035
4050
  erased = [];
4036
4051
  spans = /* @__PURE__ */ new Map();
4052
+ breaksIndexAtNewline = false;
4037
4053
  constructor(tokens) {
4038
4054
  this.tokens = tokens;
4039
4055
  }
4056
+ stopIndexAtNewline(active) {
4057
+ this.breaksIndexAtNewline = active;
4058
+ }
4059
+ indexContinues(bracket) {
4060
+ return !this.breaksIndexAtNewline || this.index === 0 || bracket.position.line === this.peek(-1).end.line;
4061
+ }
4040
4062
  peek(offset = 0) {
4041
4063
  const token = this.tokens[Math.min(this.index + offset, this.tokens.length - 1)];
4042
4064
  return token;
@@ -4127,6 +4149,33 @@ var TokenStream = class {
4127
4149
  const token = this.peek(offset);
4128
4150
  return token.kind === "identifier" || token.kind === "keyword" && isLuamKeyword(token.value);
4129
4151
  }
4152
+ checkMemberKey(offset = 0) {
4153
+ return this.checkName(offset) || this.peek(offset).kind === "punctuation" && this.peek(offset).value === "[";
4154
+ }
4155
+ expectMemberKey() {
4156
+ if (!this.check("punctuation", "[")) {
4157
+ return this.expectName();
4158
+ }
4159
+ const open = this.next();
4160
+ const literal2 = this.current();
4161
+ if (literal2.kind !== "string") {
4162
+ throw this.error(`Expected a quoted key but found "${this.describeCurrent()}".`, "parse-unexpected-token");
4163
+ }
4164
+ this.next();
4165
+ const close = this.expect("punctuation", "]");
4166
+ return { ...literal2, position: open.position, end: close.end };
4167
+ }
4168
+ reservedNameAt(subject, offset = 0) {
4169
+ const token = this.peek(offset);
4170
+ const next = this.peek(offset + 1);
4171
+ const continues = next.kind === "punctuation" && (next.value === "," || next.value === ")" || next.value === ":") || next.kind === "operator" && (next.value === "?" || next.value === "=");
4172
+ if (token.kind !== "keyword" || !continues) {
4173
+ return null;
4174
+ }
4175
+ const message = `"${token.value}" is a reserved word and cannot name a ${subject}. Rename it \u2014 a property of the same name is still legal, so "value.${token.value}" keeps working.`;
4176
+ this.report("parse-reserved-name", message, token.position);
4177
+ return this.next();
4178
+ }
4130
4179
  expectName() {
4131
4180
  if (this.checkName()) {
4132
4181
  return this.next();
@@ -4214,7 +4263,8 @@ function parseParameter(stream) {
4214
4263
  }
4215
4264
  return { name: name2, annotation, isVararg: true, position: token.position };
4216
4265
  }
4217
- const name = stream.expect("identifier").value;
4266
+ const reserved = stream.reservedNameAt("parameter");
4267
+ const name = reserved === null ? stream.expect("identifier").value : reserved.value;
4218
4268
  return { name, annotation: parseNamedAnnotation(stream, "parameter"), isVararg: false, position: token.position };
4219
4269
  }
4220
4270
  function parseParameters(stream) {
@@ -4406,6 +4456,12 @@ function parsePrimary(stream) {
4406
4456
  stream.expect("punctuation", ")");
4407
4457
  return { kind: "group-expression", expression, position: token.position };
4408
4458
  }
4459
+ if (token.kind === "keyword" && isLuamKeyword(token.value)) {
4460
+ const message = `"${token.value}" is a reserved word and cannot be read as a value. Rename the declaration \u2014 a property of the same name is still legal, so "value.${token.value}" keeps working.`;
4461
+ stream.report("parse-reserved-name", message, token.position);
4462
+ stream.next();
4463
+ return { kind: "identifier", name: token.value, position: token.position };
4464
+ }
4409
4465
  throw stream.error(`Unexpected "${stream.describeCurrent()}" in expression.`, "parse-unexpected-token");
4410
4466
  }
4411
4467
  function parseArguments(stream) {
@@ -4440,6 +4496,9 @@ function parseSuffixed(stream) {
4440
4496
  continue;
4441
4497
  }
4442
4498
  if (token.kind === "punctuation" && token.value === "[") {
4499
+ if (!stream.indexContinues(token)) {
4500
+ return expression;
4501
+ }
4443
4502
  stream.next();
4444
4503
  const index = parseExpression(stream);
4445
4504
  stream.expect("punctuation", "]");
@@ -4622,7 +4681,11 @@ function isDeclarationStart(stream) {
4622
4681
  if (token.value === "class") {
4623
4682
  return isClassHeader(stream, offset);
4624
4683
  }
4625
- return token.value === "interface" ? stream.checkAhead(offset + 2, "punctuation", "{") || stream.checkAhead(offset + 2, "keyword", "extends") : stream.checkAhead(offset + 2, "punctuation", "{");
4684
+ if (token.value === "interface") {
4685
+ const after = skipTypeParameters(stream, offset + 2);
4686
+ return stream.checkAhead(after, "punctuation", "{") || stream.checkAhead(after, "keyword", "extends");
4687
+ }
4688
+ return stream.checkAhead(offset + 2, "punctuation", "{");
4626
4689
  }
4627
4690
  function skipDecoratorArguments(stream) {
4628
4691
  let depth = 0;
@@ -4692,6 +4755,14 @@ function parseBraceClassMethod(stream, token, decorators, isStatic) {
4692
4755
  function parseFieldAnnotation(stream) {
4693
4756
  return parseNamedAnnotation(stream, "field");
4694
4757
  }
4758
+ function parseFieldValue(stream) {
4759
+ stream.stopIndexAtNewline(true);
4760
+ try {
4761
+ return parseExpression(stream);
4762
+ } finally {
4763
+ stream.stopIndexAtNewline(false);
4764
+ }
4765
+ }
4695
4766
  function expectClassFieldBoundary(stream, token) {
4696
4767
  const current = stream.current();
4697
4768
  const delimiter = current.kind === "punctuation" && (current.value === "}" || current.value === ";" || current.value === ",");
@@ -4717,7 +4788,7 @@ function parseStaticModifier(stream) {
4717
4788
  function parseClassMember(stream) {
4718
4789
  const decorators = parseDecorators(stream);
4719
4790
  const isStatic = parseStaticModifier(stream);
4720
- const token = stream.expectName();
4791
+ const token = stream.expectMemberKey();
4721
4792
  if (stream.check("punctuation", "(")) {
4722
4793
  stream.report("parse-class-method-form", `Write class member "${token.value}" as "${token.value} = function (...) ... end".`, token.position);
4723
4794
  return parseBraceClassMethod(stream, token, decorators, isStatic);
@@ -4726,7 +4797,7 @@ function parseClassMember(stream) {
4726
4797
  return parseClassMethod(stream, token, decorators, isStatic);
4727
4798
  }
4728
4799
  const annotation = parseFieldAnnotation(stream);
4729
- const value = stream.match("operator", "=") ? parseExpression(stream) : null;
4800
+ const value = stream.match("operator", "=") ? parseFieldValue(stream) : null;
4730
4801
  expectClassFieldBoundary(stream, token);
4731
4802
  return { kind: "class-field", name: token.value, annotation, value, decorators, isStatic, position: token.position };
4732
4803
  }
@@ -4739,6 +4810,7 @@ function parseClassModifiers(stream, declaration) {
4739
4810
  }
4740
4811
  do {
4741
4812
  declaration.interfaces.push(stream.expect("identifier").value);
4813
+ declaration.interfaceArguments.push(parseTypeArguments(stream));
4742
4814
  } while (stream.match("punctuation", ","));
4743
4815
  }
4744
4816
  }
@@ -4754,6 +4826,7 @@ function parseClassDeclaration(stream, decorators) {
4754
4826
  superClass: null,
4755
4827
  superClassArguments: [],
4756
4828
  interfaces: [],
4829
+ interfaceArguments: [],
4757
4830
  members: [],
4758
4831
  decorators,
4759
4832
  position: position2
@@ -4780,7 +4853,7 @@ function parseClassDeclaration(stream, decorators) {
4780
4853
  return declaration;
4781
4854
  }
4782
4855
  function parseInterfaceMember(stream) {
4783
- const token = stream.expectName();
4856
+ const token = stream.expectMemberKey();
4784
4857
  if (stream.check("punctuation", "(")) {
4785
4858
  const parameters = parseParameters(stream);
4786
4859
  const returnAnnotation = parseOptionalAnnotation(stream);
@@ -4796,6 +4869,7 @@ function parseInterfaceDeclaration(stream) {
4796
4869
  const checkpoint = stream.checkpoint();
4797
4870
  const position2 = stream.next().position;
4798
4871
  const name = stream.expect("identifier").value;
4872
+ const typeParameters = parseTypeParameters(stream);
4799
4873
  const superInterfaces = [];
4800
4874
  const members = [];
4801
4875
  if (stream.match("keyword", "extends")) {
@@ -4818,7 +4892,15 @@ function parseInterfaceDeclaration(stream) {
4818
4892
  }
4819
4893
  }
4820
4894
  stream.expect("punctuation", "}");
4821
- const declaration = { kind: "interface-declaration", name, superInterfaces, members, position: position2 };
4895
+ const declaration = {
4896
+ kind: "interface-declaration",
4897
+ name,
4898
+ typeParameters: typeParameters.names,
4899
+ typeConstraints: typeParameters.constraints,
4900
+ superInterfaces,
4901
+ members,
4902
+ position: position2
4903
+ };
4822
4904
  stream.eraseFrom(checkpoint, "declaration");
4823
4905
  return declaration;
4824
4906
  }
@@ -4879,7 +4961,7 @@ function parseExpressionList(stream) {
4879
4961
  return values;
4880
4962
  }
4881
4963
  function parseDeclarator(stream) {
4882
- const token = stream.expect("identifier");
4964
+ const token = stream.reservedNameAt("local") ?? stream.expect("identifier");
4883
4965
  return { name: token.value, annotation: parseNamedAnnotation(stream, "local"), position: token.position };
4884
4966
  }
4885
4967
  function parseLocalStatement(stream, position2) {
@@ -4973,7 +5055,30 @@ function invalidStatement(stream, target, start) {
4973
5055
  const message = `${subject} is not a statement. Assign it with "=", pass it to a call, or remove the line.`;
4974
5056
  return stream.errorAt(message, "parse-invalid-statement", start.position, start.end);
4975
5057
  }
5058
+ function parseGlobalDeclaration(stream) {
5059
+ const marked = stream.checkAhead(1, "operator", "?") && stream.checkAhead(2, "punctuation", ":");
5060
+ if (!stream.check("identifier") || !marked && !stream.checkAhead(1, "punctuation", ":")) {
5061
+ return null;
5062
+ }
5063
+ const point = stream.speculate();
5064
+ try {
5065
+ const declaration = parseDeclarator(stream);
5066
+ if (declaration.annotation !== null && stream.match("operator", "=")) {
5067
+ return { kind: "global-statement", declaration, values: parseExpressionList(stream), position: declaration.position };
5068
+ }
5069
+ } catch (error) {
5070
+ if (!(error instanceof ParserError)) {
5071
+ throw error;
5072
+ }
5073
+ }
5074
+ stream.rewind(point);
5075
+ return null;
5076
+ }
4976
5077
  function parseExpressionStatement(stream) {
5078
+ const declaration = parseGlobalDeclaration(stream);
5079
+ if (declaration !== null) {
5080
+ return declaration;
5081
+ }
4977
5082
  const start = stream.current();
4978
5083
  const position2 = start.position;
4979
5084
  const targets = [parseSuffixed(stream)];
@@ -5001,7 +5106,8 @@ function parseKeywordStatement(stream, value) {
5001
5106
  if (stream.check("keyword", "function")) {
5002
5107
  return parseFunctionDeclaration(stream, true);
5003
5108
  }
5004
- return stream.check("keyword", "enum") ? parseEnumDeclaration(stream, true) : parseLocalStatement(stream, token.position);
5109
+ const isEnum = stream.check("keyword", "enum") && stream.checkAhead(1, "identifier");
5110
+ return isEnum ? parseEnumDeclaration(stream, true) : parseLocalStatement(stream, token.position);
5005
5111
  }
5006
5112
  if (value === "function") {
5007
5113
  return parseFunctionDeclaration(stream, false);
@@ -5266,10 +5372,21 @@ function isEmptyLiteral(type) {
5266
5372
  return type.kind === "record" && type.isLiteral === true && type.members.size === 0;
5267
5373
  }
5268
5374
  function widenInferred(type) {
5375
+ if (type.kind === "array") {
5376
+ return createArray(widenInferred(type.element));
5377
+ }
5378
+ if (type.kind === "union") {
5379
+ return createUnion(type.options.map(widenInferred));
5380
+ }
5269
5381
  if (type.kind !== "record" || type.isLiteral !== true) {
5270
5382
  return widenLiteral(type);
5271
5383
  }
5272
- return type.members.size === 0 ? TABLE_TYPE : createRecord(type.name, type.members, type.origin);
5384
+ if (type.members.size === 0) {
5385
+ return TABLE_TYPE;
5386
+ }
5387
+ const widened = new Map([...type.members].map(([name, member]) => [name, widenInferred(member)]));
5388
+ const record2 = createObjectType(widened);
5389
+ return record2.kind === "record" ? { ...record2, isInferred: true } : record2;
5273
5390
  }
5274
5391
  function createFunction(parameters, returnType, minimumArguments2, isVariadic = false, parameterNames, variadicType) {
5275
5392
  return {
@@ -5428,7 +5545,7 @@ function isFunctionAssignable(source, target, options) {
5428
5545
  return target.returnType.kind === "void" || isAssignable(source.returnType, target.returnType, options);
5429
5546
  }
5430
5547
  function isMapAssignable(source, target, options) {
5431
- if (source.kind === "table") {
5548
+ if (source.kind === "table" || isEmptyLiteral(source)) {
5432
5549
  return true;
5433
5550
  }
5434
5551
  if (source.kind === "array") {
@@ -5741,6 +5858,9 @@ var COMPILER_OPTION_FIELDS = [
5741
5858
  }),
5742
5859
  field("oop", BOOLEAN_TYPE, "Enables the MTA OOP API in the checker and the generated meta.xml.", { defaultValue: DEFAULT_COMPILER_OPTIONS.oop }),
5743
5860
  field("noUnusedLocals", BOOLEAN_TYPE, "Reports local declarations that are never read.", { defaultValue: DEFAULT_COMPILER_OPTIONS.noUnusedLocals }),
5861
+ field("noImplicitGlobals", BOOLEAN_TYPE, "Reports an assignment that creates a global the project never declares.", {
5862
+ defaultValue: DEFAULT_COMPILER_OPTIONS.noImplicitGlobals
5863
+ }),
5744
5864
  field("noUnusedParameters", BOOLEAN_TYPE, "Reports function and method parameters that are never read.", {
5745
5865
  defaultValue: DEFAULT_COMPILER_OPTIONS.noUnusedParameters
5746
5866
  }),
@@ -6802,6 +6922,7 @@ function readCompilerOptions(value) {
6802
6922
  strict: flag(source, "strict", DEFAULT_COMPILER_OPTIONS.strict),
6803
6923
  oop: flag(source, "oop", DEFAULT_COMPILER_OPTIONS.oop),
6804
6924
  noUnusedLocals: flag(source, "noUnusedLocals", DEFAULT_COMPILER_OPTIONS.noUnusedLocals),
6925
+ noImplicitGlobals: flag(source, "noImplicitGlobals", DEFAULT_COMPILER_OPTIONS.noImplicitGlobals),
6805
6926
  noUnusedParameters: flag(source, "noUnusedParameters", DEFAULT_COMPILER_OPTIONS.noUnusedParameters),
6806
6927
  warningsAsErrors: flag(source, "warningsAsErrors", DEFAULT_COMPILER_OPTIONS.warningsAsErrors)
6807
6928
  };
@@ -6978,7 +7099,7 @@ import { tmpdir } from "node:os";
6978
7099
  import { join as join2 } from "node:path";
6979
7100
 
6980
7101
  // src/cli/version.ts
6981
- var VERSION = true ? "0.19.11" : "0.0.0-dev";
7102
+ var VERSION = true ? "1.0.0" : "0.0.0-dev";
6982
7103
  var PROGRAM_NAME = "luam";
6983
7104
  var PROGRAM_DESCRIPTION = "luam \u2014 the Luam compiler for Multi Theft Auto resources.";
6984
7105
 
@@ -7042,7 +7163,7 @@ function runEditorCommand(command, args) {
7042
7163
  }
7043
7164
 
7044
7165
  // src/editor/editor-service.ts
7045
- var EXTENSION_ID = "thigasdevelopment.luam";
7166
+ var EXTENSION_ID = "luam.luam";
7046
7167
  var SUPPORTED_EDITORS = [
7047
7168
  { id: "vscode", name: "Visual Studio Code", command: "code" },
7048
7169
  { id: "vscode-insiders", name: "Visual Studio Code Insiders", command: "code-insiders" },
@@ -8862,12 +8983,13 @@ var TEST_DECLARATIONS = [
8862
8983
 
8863
8984
  // ../compiler/src/checker/ambient.ts
8864
8985
  var EVENT_NAME_PREFIX = "event:";
8865
- var EMPTY_AMBIENT = { classes: [], interfaces: [], enums: [], globals: [], events: [] };
8986
+ var EMPTY_AMBIENT = { classes: [], interfaces: [], enums: [], aliases: [], globals: [], events: [] };
8866
8987
  function ambientFromRegistry(registry) {
8867
8988
  return {
8868
8989
  classes: registry.allClasses(),
8869
8990
  interfaces: registry.allInterfaces(),
8870
8991
  enums: registry.allEnums().filter((info) => info.isLocal !== true),
8992
+ aliases: registry.allAliases(),
8871
8993
  globals: registry.allGlobals(),
8872
8994
  events: registry.allEvents()
8873
8995
  };
@@ -8885,6 +9007,7 @@ function ownDeclarations(registry, ambient) {
8885
9007
  classes: withoutNames(all.classes, ambient.classes),
8886
9008
  interfaces: withoutNames(all.interfaces, ambient.interfaces),
8887
9009
  enums: withoutNames(all.enums, ambient.enums),
9010
+ aliases: withoutNames(all.aliases, ambient.aliases),
8888
9011
  globals: withoutNames(all.globals, ambient.globals),
8889
9012
  events: withoutNames(all.events, ambient.events)
8890
9013
  };
@@ -8903,6 +9026,7 @@ function mergeAmbient(sources) {
8903
9026
  classes: mergeByName(sources.map((source) => source.classes)),
8904
9027
  interfaces: mergeByName(sources.map((source) => source.interfaces)),
8905
9028
  enums: mergeByName(sources.map((source) => source.enums)),
9029
+ aliases: mergeByName(sources.map((source) => source.aliases)),
8906
9030
  globals: mergeByName(sources.map((source) => source.globals)),
8907
9031
  events: mergeByName(sources.map((source) => source.events))
8908
9032
  };
@@ -8977,6 +9101,9 @@ function declareAll(catalog, environment, source) {
8977
9101
  function isAvailableIn(declared, environment) {
8978
9102
  return declared === "shared" || declared === environment;
8979
9103
  }
9104
+ function isVisibleIn(declared, environment) {
9105
+ return environment === "shared" || isAvailableIn(declared, environment);
9106
+ }
8980
9107
 
8981
9108
  // ../compiler/src/checker/api-types.ts
8982
9109
  var PRIMITIVES = {
@@ -9195,6 +9322,9 @@ var MAX_DEPTH = 32;
9195
9322
  function classSubstitutions(info, typeArguments) {
9196
9323
  return new Map(info.typeParameters.map((parameter, index) => [parameter, typeArguments[index] ?? ANY_TYPE]));
9197
9324
  }
9325
+ function parameterSubstitutions(typeParameters, typeArguments) {
9326
+ return new Map(typeParameters.map((parameter, index) => [parameter, typeArguments[index] ?? ANY_TYPE]));
9327
+ }
9198
9328
  function parentSubstitutions(registry, info, current) {
9199
9329
  const parent = info.superClass === null ? null : registry.lookupClass(info.superClass);
9200
9330
  if (parent === null) {
@@ -9222,7 +9352,15 @@ function substitutionsFor(registry, receiver, owner) {
9222
9352
  }
9223
9353
  return /* @__PURE__ */ new Map();
9224
9354
  }
9355
+ function interfaceSubstitutions(registry, receiver) {
9356
+ const contract = registry.lookupInterface(receiver.name);
9357
+ return contract === null ? null : parameterSubstitutions(contract.typeParameters, receiver.typeArguments ?? []);
9358
+ }
9225
9359
  function specializeMember(context, receiver, member, property) {
9360
+ const contract = interfaceSubstitutions(context.declarations, receiver);
9361
+ if (contract !== null) {
9362
+ return contract.size === 0 ? member : { ...member, type: substituteType(member.type, contract) };
9363
+ }
9226
9364
  const owner = context.declarations.lookupMemberOwner(receiver.name, property);
9227
9365
  if (owner === null || owner === receiver.name) {
9228
9366
  const own = context.declarations.lookupClass(receiver.name);
@@ -9307,6 +9445,11 @@ function reportConstraintViolations(context, owner, typeParameters, typeConstrai
9307
9445
  });
9308
9446
  }
9309
9447
  function checkTypeConstraints(context, name, typeArguments, position2) {
9448
+ const contract = context.declarations.lookupInterface(name);
9449
+ if (contract !== null) {
9450
+ reportConstraintViolations(context, `interface "${name}"`, contract.typeParameters, contract.typeConstraints, typeArguments, position2);
9451
+ return;
9452
+ }
9310
9453
  const info = context.declarations.lookupClass(name);
9311
9454
  if (info === null) {
9312
9455
  return;
@@ -12233,10 +12376,14 @@ var MTA_EXACT = {
12233
12376
  client: MTA_CLIENT_GLOBALS
12234
12377
  };
12235
12378
  function globalsFor(environment) {
12236
- return DECLARATIONS.flatMap((declaration) => {
12379
+ const resolved2 = /* @__PURE__ */ new Map();
12380
+ for (const declaration of DECLARATIONS) {
12237
12381
  const exact = findDeclaration(declaration.name, environment);
12238
- return exact === null ? [] : [exact];
12239
- });
12382
+ if (exact !== null && !resolved2.has(exact.name)) {
12383
+ resolved2.set(exact.name, exact);
12384
+ }
12385
+ }
12386
+ return [...resolved2.values()];
12240
12387
  }
12241
12388
  function findDeclaration(name, environment) {
12242
12389
  const declaration = BY_NAME.get(name);
@@ -12244,7 +12391,7 @@ function findDeclaration(name, environment) {
12244
12391
  return declaration ?? null;
12245
12392
  }
12246
12393
  if (!isAvailableIn(declaration.environment, environment)) {
12247
- return null;
12394
+ return environment === "shared" ? declaration : null;
12248
12395
  }
12249
12396
  if (declaration.source !== "mta") {
12250
12397
  return declaration;
@@ -14049,11 +14196,15 @@ var DeclarationRegistry = class {
14049
14196
  classes = /* @__PURE__ */ new Map();
14050
14197
  interfaces = /* @__PURE__ */ new Map();
14051
14198
  enums = /* @__PURE__ */ new Map();
14199
+ aliases = /* @__PURE__ */ new Map();
14052
14200
  globals = /* @__PURE__ */ new Map();
14053
14201
  events = /* @__PURE__ */ new Map();
14054
14202
  declareGlobal(info) {
14055
14203
  this.globals.set(info.name, info);
14056
14204
  }
14205
+ lookupGlobal(name) {
14206
+ return this.globals.get(name) ?? null;
14207
+ }
14057
14208
  allGlobals() {
14058
14209
  return [...this.globals.values()];
14059
14210
  }
@@ -14089,6 +14240,15 @@ var DeclarationRegistry = class {
14089
14240
  declareEnum(info) {
14090
14241
  this.enums.set(info.name, info);
14091
14242
  }
14243
+ declareAlias(info) {
14244
+ this.aliases.set(info.name, info);
14245
+ }
14246
+ lookupAlias(name) {
14247
+ return this.aliases.get(name) ?? null;
14248
+ }
14249
+ allAliases() {
14250
+ return [...this.aliases.values()];
14251
+ }
14092
14252
  lookupEnum(name) {
14093
14253
  return this.enums.get(name) ?? null;
14094
14254
  }
@@ -14229,6 +14389,7 @@ function buildRegistry() {
14229
14389
  superClass: declaration.parent,
14230
14390
  superArguments: [],
14231
14391
  interfaces: [],
14392
+ interfaceArguments: [],
14232
14393
  members,
14233
14394
  statics: /* @__PURE__ */ new Map(),
14234
14395
  position: MTA_POSITION
@@ -14435,6 +14596,11 @@ var CheckContext = class {
14435
14596
  ambientClasses = /* @__PURE__ */ new Set();
14436
14597
  ambientInterfaces = /* @__PURE__ */ new Set();
14437
14598
  ambientEnums = /* @__PURE__ */ new Set();
14599
+ ambientAliases = /* @__PURE__ */ new Set();
14600
+ ambientGlobals = /* @__PURE__ */ new Set();
14601
+ obligations = /* @__PURE__ */ new Map();
14602
+ blockDepth = 0;
14603
+ noImplicitGlobals = false;
14438
14604
  constructor(mode, environment, ambient = EMPTY_AMBIENT, project = EMPTY_PROJECT_DECLARATIONS, oop = false) {
14439
14605
  this.mode = mode;
14440
14606
  this.environment = environment;
@@ -14510,6 +14676,24 @@ var CheckContext = class {
14510
14676
  isAmbientEnum(name) {
14511
14677
  return this.ambientEnums.has(name);
14512
14678
  }
14679
+ isAmbientAlias(name) {
14680
+ return this.ambientAliases.has(name);
14681
+ }
14682
+ isAmbientGlobal(name) {
14683
+ return this.ambientGlobals.has(name);
14684
+ }
14685
+ openRecordObligation(obligation) {
14686
+ this.obligations.set(obligation.path, obligation);
14687
+ }
14688
+ recordObligation(path) {
14689
+ return this.obligations.get(path) ?? null;
14690
+ }
14691
+ closeRecordObligation(path) {
14692
+ this.obligations.delete(path);
14693
+ }
14694
+ recordObligationPaths() {
14695
+ return [...this.obligations.keys()];
14696
+ }
14513
14697
  noteExternalReference(name, position2) {
14514
14698
  if (!this.externalReferences.has(name)) {
14515
14699
  this.externalReferences.set(name, position2);
@@ -14679,19 +14863,28 @@ var CheckContext = class {
14679
14863
  assignability() {
14680
14864
  return { allowNil: this.allowNil, resolveNominal: (name) => this.nominalShape(name) };
14681
14865
  }
14682
- expectAssignable(source, target, position2, subject) {
14866
+ resolveValueAnnotation(annotation, subject) {
14867
+ const resolved2 = this.resolveAnnotation(annotation);
14868
+ if (resolved2.kind !== "tuple") {
14869
+ return resolved2;
14870
+ }
14871
+ const message = `A parenthesised list like "${typeToString(resolved2)}" is a return shape and cannot type ${subject}. Name one type instead.`;
14872
+ this.report("check-tuple-position", message, annotation.position);
14873
+ return firstValueOf(resolved2);
14874
+ }
14875
+ expectAssignable(source, target, position2, subject, printed = target) {
14683
14876
  if (isAssignable(source, target, this.assignability())) {
14684
14877
  return;
14685
14878
  }
14686
14879
  const received = isLiteralType(target) || target.kind === "union" ? source : widenLiteral(source);
14687
- const message = `${subject} expects "${typeToString(target)}" but received "${typeToString(received)}".`;
14880
+ const message = `${subject} expects "${typeToString(printed)}" but received "${typeToString(received)}".`;
14688
14881
  const hint = `${nilHint(source, target, this.mode)}${missingKeyHint(source, target, (name) => this.nominalShape(name))}`;
14689
14882
  this.report("check-type-mismatch", `${message}${hint}`, position2);
14690
14883
  }
14691
14884
  declareProject(project) {
14692
14885
  for (const declaration of project.globals) {
14693
14886
  this.projectEnvironments.set(declaration.name, declaration.environment);
14694
- if (isAvailableIn(declaration.environment, this.environment)) {
14887
+ if (isVisibleIn(declaration.environment, this.environment)) {
14695
14888
  const symbol = { name: declaration.name, type: descriptorToType(declaration.type), isLocal: false, position: PROJECT_POSITION };
14696
14889
  this.binder.declareGlobal(symbol);
14697
14890
  }
@@ -14712,7 +14905,14 @@ var CheckContext = class {
14712
14905
  this.declarations.declareEnum(info);
14713
14906
  this.binder.declareGlobal({ name: info.name, type: createNamed(info.name), isLocal: false, position: info.position });
14714
14907
  }
14908
+ for (const info of ambient.aliases) {
14909
+ this.ambientAliases.add(info.name);
14910
+ this.binder.declareAlias(info.name, info.type, info.typeParameters);
14911
+ this.declarations.declareAlias(info);
14912
+ }
14715
14913
  for (const info of ambient.globals) {
14914
+ this.ambientGlobals.add(info.name);
14915
+ this.declarations.declareGlobal(info);
14716
14916
  this.binder.declareGlobal({ name: info.name, type: info.type, isLocal: false, position: info.position });
14717
14917
  }
14718
14918
  for (const info of ambient.events) {
@@ -14732,18 +14932,20 @@ var CheckContext = class {
14732
14932
  return createMap(this.resolveAnnotation(key), this.resolveAnnotation(value));
14733
14933
  }
14734
14934
  resolveClassAnnotation(name, typeArguments, position2) {
14735
- const declared = this.declarations.lookupClass(name)?.typeParameters ?? [];
14935
+ const declaredInterface = this.declarations.lookupInterface(name);
14936
+ const owner = declaredInterface === null ? "Class" : "Interface";
14937
+ const declared = declaredInterface?.typeParameters ?? this.declarations.lookupClass(name)?.typeParameters ?? [];
14736
14938
  const resolved2 = typeArguments.map((argument) => this.resolveAnnotation(argument));
14737
14939
  if (declared.length === 0) {
14738
14940
  return createNamed(name);
14739
14941
  }
14740
14942
  if (resolved2.length !== declared.length) {
14741
14943
  const expected = declared.length === 1 ? "1 type argument" : `${declared.length} type arguments`;
14742
- this.report("check-generic-arity", `Class "${name}" expects ${expected} but received ${resolved2.length}.`, position2);
14944
+ this.report("check-generic-arity", `${owner} "${name}" expects ${expected} but received ${resolved2.length}.`, position2);
14743
14945
  }
14744
14946
  const specialized = createNamed(name, declared.map((unused, index) => resolved2[index] ?? ANY_TYPE));
14745
14947
  if (namedNesting(specialized) > MAX_GENERIC_DEPTH) {
14746
- const message = `Class "${name}" is nested more than ${MAX_GENERIC_DEPTH} levels deep here. Name the inner type with a "type" alias.`;
14948
+ const message = `${owner} "${name}" is nested more than ${MAX_GENERIC_DEPTH} levels deep here. Name the inner type with a "type" alias.`;
14747
14949
  this.report("check-generic-depth", message, position2);
14748
14950
  return createNamed(name);
14749
14951
  }
@@ -14789,6 +14991,7 @@ var ALLOWED = /* @__PURE__ */ new Set([
14789
14991
  var LABELS = {
14790
14992
  "local-statement": 'A "local" declaration',
14791
14993
  "assignment-statement": "An assignment",
14994
+ "global-statement": "A global declaration",
14792
14995
  "call-statement": "A call",
14793
14996
  "return-statement": 'A "return"',
14794
14997
  "break-statement": 'A "break"',
@@ -14848,6 +15051,7 @@ function statementExpressions(statement) {
14848
15051
  switch (statement.kind) {
14849
15052
  case "local-statement":
14850
15053
  case "return-statement":
15054
+ case "global-statement":
14851
15055
  return statement.values;
14852
15056
  case "assignment-statement":
14853
15057
  return [...statement.targets, ...statement.values];
@@ -14995,18 +15199,28 @@ function checkContract(context, info, contract, member) {
14995
15199
  const message = `${subject} expects "${typeToString(member.type)}" from interface "${contract}" but is "${typeToString(actual.type)}".`;
14996
15200
  context.report("check-unimplemented-interface", message, actual.position);
14997
15201
  }
15202
+ function contractName(name, typeArguments) {
15203
+ return typeArguments.length === 0 ? name : `${name}<${typeArguments.map(typeToString).join(", ")}>`;
15204
+ }
14998
15205
  function checkInterfaces(context, info) {
14999
- for (const name of info.interfaces) {
15206
+ info.interfaces.forEach((name, index) => {
15000
15207
  const contract = context.declarations.lookupInterface(name);
15001
15208
  if (contract === null) {
15002
15209
  context.noteExternalReference(name, info.position);
15003
15210
  context.report("check-unknown-interface", `Class "${info.name}" implements "${name}", which is not defined.`, info.position);
15004
- continue;
15211
+ return;
15005
15212
  }
15213
+ const typeArguments = info.interfaceArguments[index] ?? [];
15214
+ if (contract.typeParameters.length > 0 && typeArguments.length !== contract.typeParameters.length) {
15215
+ const expected = contract.typeParameters.length === 1 ? "1 type argument" : `${contract.typeParameters.length} type arguments`;
15216
+ context.report("check-generic-arity", `Interface "${name}" expects ${expected} but received ${typeArguments.length}.`, info.position);
15217
+ }
15218
+ const substitutions = parameterSubstitutions(contract.typeParameters, typeArguments);
15219
+ const label2 = contractName(name, typeArguments);
15006
15220
  for (const member of context.declarations.collectInterfaceContract(contract.name)) {
15007
- checkContract(context, info, name, member);
15221
+ checkContract(context, info, label2, substitutions.size === 0 ? member : { ...member, type: substituteType(member.type, substitutions) });
15008
15222
  }
15009
- }
15223
+ });
15010
15224
  }
15011
15225
  function checkOverrides(context, info, statement) {
15012
15226
  for (const member of statement.members) {
@@ -15615,6 +15829,7 @@ function statementExpressions2(statement) {
15615
15829
  switch (statement.kind) {
15616
15830
  case "local-statement":
15617
15831
  case "return-statement":
15832
+ case "global-statement":
15618
15833
  return statement.values;
15619
15834
  case "assignment-statement":
15620
15835
  return [...statement.targets, ...statement.values];
@@ -15672,6 +15887,9 @@ function addTargets(statement, paths) {
15672
15887
  if (statement.kind === "local-statement") {
15673
15888
  statement.declarations.forEach((declaration) => paths.add(declaration.name));
15674
15889
  }
15890
+ if (statement.kind === "global-statement") {
15891
+ paths.add(statement.declaration.name);
15892
+ }
15675
15893
  }
15676
15894
  function collectPaths(body, paths) {
15677
15895
  for (const statement of body) {
@@ -15811,7 +16029,9 @@ function contextualFunction(type) {
15811
16029
  // ../mta-types/src/generated/mta-events.ts
15812
16030
  var SHARED_EVENTS = [];
15813
16031
  var SERVER_EVENTS = [
16032
+ "onAccountCreate",
15814
16033
  "onAccountDataChange",
16034
+ "onAccountRemove",
15815
16035
  "onBan",
15816
16036
  "onChatMessage",
15817
16037
  "onColShapeHit",
@@ -15828,12 +16048,14 @@ var SERVER_EVENTS = [
15828
16048
  "onElementModelChange",
15829
16049
  "onElementStartSync",
15830
16050
  "onElementStopSync",
16051
+ "onExplosion",
15831
16052
  "onMarkerHit",
15832
16053
  "onMarkerLeave",
15833
16054
  "onPedDamage",
15834
16055
  "onPedVehicleEnter",
15835
16056
  "onPedVehicleExit",
15836
16057
  "onPedWasted",
16058
+ "onPedWeaponReload",
15837
16059
  "onPedWeaponSwitch",
15838
16060
  "onPickupHit",
15839
16061
  "onPickupLeave",
@@ -15842,12 +16064,16 @@ var SERVER_EVENTS = [
15842
16064
  "onPlayerACInfo",
15843
16065
  "onPlayerBan",
15844
16066
  "onPlayerChangeNick",
16067
+ "onPlayerChangesProtectedData",
16068
+ "onPlayerChangesWorldSpecialProperty",
15845
16069
  "onPlayerChat",
15846
16070
  "onPlayerClick",
15847
16071
  "onPlayerCommand",
15848
16072
  "onPlayerConnect",
15849
16073
  "onPlayerContact",
15850
16074
  "onPlayerDamage",
16075
+ "onPlayerDetonateSatchels",
16076
+ "onPlayerDiscordJoin",
15851
16077
  "onPlayerJoin",
15852
16078
  "onPlayerLogin",
15853
16079
  "onPlayerLogout",
@@ -15860,12 +16086,17 @@ var SERVER_EVENTS = [
15860
16086
  "onPlayerPickupLeave",
15861
16087
  "onPlayerPickupUse",
15862
16088
  "onPlayerPrivateMessage",
16089
+ "onPlayerProjectileCreation",
15863
16090
  "onPlayerQuit",
15864
16091
  "onPlayerResourceStart",
15865
16092
  "onPlayerScreenShot",
15866
16093
  "onPlayerSpawn",
15867
16094
  "onPlayerStealthKill",
15868
16095
  "onPlayerTarget",
16096
+ "onPlayerTeamChange",
16097
+ "onPlayerTeleport",
16098
+ "onPlayerTriggerEventThreshold",
16099
+ "onPlayerTriggerInvalidEvent",
15869
16100
  "onPlayerUnmute",
15870
16101
  "onPlayerVehicleEnter",
15871
16102
  "onPlayerVehicleExit",
@@ -15873,12 +16104,15 @@ var SERVER_EVENTS = [
15873
16104
  "onPlayerVoiceStop",
15874
16105
  "onPlayerWasted",
15875
16106
  "onPlayerWeaponFire",
16107
+ "onPlayerWeaponReload",
15876
16108
  "onPlayerWeaponSwitch",
15877
16109
  "onResourceLoadStateChange",
15878
16110
  "onResourcePreStart",
15879
16111
  "onResourceStart",
16112
+ "onResourceStateChange",
15880
16113
  "onResourceStop",
15881
16114
  "onSettingChange",
16115
+ "onShutdown",
15882
16116
  "onTrailerAttach",
15883
16117
  "onTrailerDetach",
15884
16118
  "onUnban",
@@ -15909,6 +16143,7 @@ var CLIENT_EVENTS = [
15909
16143
  "onClientColShapeHit",
15910
16144
  "onClientColShapeLeave",
15911
16145
  "onClientConsole",
16146
+ "onClientCoreCommand",
15912
16147
  "onClientCursorMove",
15913
16148
  "onClientDebugMessage",
15914
16149
  "onClientDoubleClick",
@@ -15951,6 +16186,7 @@ var CLIENT_EVENTS = [
15951
16186
  "onClientObjectMoveStart",
15952
16187
  "onClientObjectMoveStop",
15953
16188
  "onClientPaste",
16189
+ "onClientPedChoke",
15954
16190
  "onClientPedDamage",
15955
16191
  "onClientPedHeliKilled",
15956
16192
  "onClientPedHitByWaterCannon",
@@ -16025,6 +16261,17 @@ var MTA_EVENTS = {
16025
16261
 
16026
16262
  // ../mta-types/src/generated/events/mta-event-signatures-server-1.ts
16027
16263
  var MTA_EVENT_SIGNATURES_SERVER_1 = {
16264
+ onAccountCreate: fn(
16265
+ [
16266
+ named("Account")
16267
+ ],
16268
+ VOID,
16269
+ 1,
16270
+ false,
16271
+ [
16272
+ "theAccount"
16273
+ ]
16274
+ ),
16028
16275
  onAccountDataChange: fn(
16029
16276
  [
16030
16277
  named("Account"),
@@ -16040,6 +16287,17 @@ var MTA_EVENT_SIGNATURES_SERVER_1 = {
16040
16287
  "theValue"
16041
16288
  ]
16042
16289
  ),
16290
+ onAccountRemove: fn(
16291
+ [
16292
+ named("Account")
16293
+ ],
16294
+ VOID,
16295
+ 1,
16296
+ false,
16297
+ [
16298
+ "theAccount"
16299
+ ]
16300
+ ),
16043
16301
  onBan: fn(
16044
16302
  [
16045
16303
  named("Ban")
@@ -16054,7 +16312,7 @@ var MTA_EVENT_SIGNATURES_SERVER_1 = {
16054
16312
  onChatMessage: fn(
16055
16313
  [
16056
16314
  STRING,
16057
- ANY
16315
+ named("Element")
16058
16316
  ],
16059
16317
  VOID,
16060
16318
  2,
@@ -16106,16 +16364,22 @@ var MTA_EVENT_SIGNATURES_SERVER_1 = {
16106
16364
  STRING,
16107
16365
  NUMBER,
16108
16366
  STRING,
16367
+ NUMBER,
16368
+ NUMBER,
16369
+ NUMBER,
16109
16370
  NUMBER
16110
16371
  ],
16111
16372
  VOID,
16112
- 4,
16373
+ 7,
16113
16374
  false,
16114
16375
  [
16115
16376
  "message",
16116
16377
  "level",
16117
16378
  "file",
16118
- "line"
16379
+ "line",
16380
+ "r",
16381
+ "g",
16382
+ "b"
16119
16383
  ]
16120
16384
  ),
16121
16385
  onElementClicked: fn(
@@ -16212,7 +16476,11 @@ var MTA_EVENT_SIGNATURES_SERVER_1 = {
16212
16476
  "oldInterior",
16213
16477
  "newInterior"
16214
16478
  ]
16215
- ),
16479
+ )
16480
+ };
16481
+
16482
+ // ../mta-types/src/generated/events/mta-event-signatures-server-2.ts
16483
+ var MTA_EVENT_SIGNATURES_SERVER_2 = {
16216
16484
  onElementModelChange: fn(
16217
16485
  [
16218
16486
  NUMBER,
@@ -16247,11 +16515,24 @@ var MTA_EVENT_SIGNATURES_SERVER_1 = {
16247
16515
  [
16248
16516
  "oldSyncer"
16249
16517
  ]
16250
- )
16251
- };
16252
-
16253
- // ../mta-types/src/generated/events/mta-event-signatures-server-2.ts
16254
- var MTA_EVENT_SIGNATURES_SERVER_2 = {
16518
+ ),
16519
+ onExplosion: fn(
16520
+ [
16521
+ NUMBER,
16522
+ NUMBER,
16523
+ NUMBER,
16524
+ NUMBER
16525
+ ],
16526
+ VOID,
16527
+ 4,
16528
+ false,
16529
+ [
16530
+ "x",
16531
+ "y",
16532
+ "z",
16533
+ "theType"
16534
+ ]
16535
+ ),
16255
16536
  onMarkerHit: fn(
16256
16537
  [
16257
16538
  named("Element"),
@@ -16327,17 +16608,36 @@ var MTA_EVENT_SIGNATURES_SERVER_2 = {
16327
16608
  named("Element"),
16328
16609
  NUMBER,
16329
16610
  NUMBER,
16330
- BOOLEAN
16611
+ BOOLEAN,
16612
+ NUMBER,
16613
+ NUMBER
16331
16614
  ],
16332
16615
  VOID,
16333
- 5,
16616
+ 7,
16334
16617
  false,
16335
16618
  [
16336
16619
  "totalAmmo",
16337
16620
  "killer",
16338
16621
  "killerWeapon",
16339
16622
  "bodypart",
16340
- "stealth"
16623
+ "stealth",
16624
+ "animGroup",
16625
+ "animID"
16626
+ ]
16627
+ ),
16628
+ onPedWeaponReload: fn(
16629
+ [
16630
+ NUMBER,
16631
+ NUMBER,
16632
+ NUMBER
16633
+ ],
16634
+ VOID,
16635
+ 3,
16636
+ false,
16637
+ [
16638
+ "weapon",
16639
+ "clip",
16640
+ "ammo"
16341
16641
  ]
16342
16642
  ),
16343
16643
  onPedWeaponSwitch: fn(
@@ -16392,7 +16692,11 @@ var MTA_EVENT_SIGNATURES_SERVER_2 = {
16392
16692
  [
16393
16693
  "playerWhoUsed"
16394
16694
  ]
16395
- ),
16695
+ )
16696
+ };
16697
+
16698
+ // ../mta-types/src/generated/events/mta-event-signatures-server-3.ts
16699
+ var MTA_EVENT_SIGNATURES_SERVER_3 = {
16396
16700
  onPlayerACInfo: fn(
16397
16701
  [
16398
16702
  TABLE,
@@ -16438,6 +16742,34 @@ var MTA_EVENT_SIGNATURES_SERVER_2 = {
16438
16742
  "changedByUser"
16439
16743
  ]
16440
16744
  ),
16745
+ onPlayerChangesProtectedData: fn(
16746
+ [
16747
+ named("Element"),
16748
+ STRING,
16749
+ ANY
16750
+ ],
16751
+ VOID,
16752
+ 3,
16753
+ false,
16754
+ [
16755
+ "element",
16756
+ "key",
16757
+ "value"
16758
+ ]
16759
+ ),
16760
+ onPlayerChangesWorldSpecialProperty: fn(
16761
+ [
16762
+ STRING,
16763
+ BOOLEAN
16764
+ ],
16765
+ VOID,
16766
+ 2,
16767
+ false,
16768
+ [
16769
+ "property",
16770
+ "enabled"
16771
+ ]
16772
+ ),
16441
16773
  onPlayerChat: fn(
16442
16774
  [
16443
16775
  STRING,
@@ -16475,11 +16807,7 @@ var MTA_EVENT_SIGNATURES_SERVER_2 = {
16475
16807
  "screenPosX",
16476
16808
  "screenPosY"
16477
16809
  ]
16478
- )
16479
- };
16480
-
16481
- // ../mta-types/src/generated/events/mta-event-signatures-server-3.ts
16482
- var MTA_EVENT_SIGNATURES_SERVER_3 = {
16810
+ ),
16483
16811
  onPlayerCommand: fn(
16484
16812
  [
16485
16813
  STRING
@@ -16542,6 +16870,26 @@ var MTA_EVENT_SIGNATURES_SERVER_3 = {
16542
16870
  "loss"
16543
16871
  ]
16544
16872
  ),
16873
+ onPlayerDetonateSatchels: fn(
16874
+ [],
16875
+ VOID,
16876
+ 0,
16877
+ false,
16878
+ []
16879
+ ),
16880
+ onPlayerDiscordJoin: fn(
16881
+ [
16882
+ BOOLEAN,
16883
+ STRING
16884
+ ],
16885
+ VOID,
16886
+ 2,
16887
+ false,
16888
+ [
16889
+ "justConnected",
16890
+ "key"
16891
+ ]
16892
+ ),
16545
16893
  onPlayerJoin: fn(
16546
16894
  [],
16547
16895
  VOID,
@@ -16574,7 +16922,11 @@ var MTA_EVENT_SIGNATURES_SERVER_3 = {
16574
16922
  "thePreviousAccount",
16575
16923
  "theCurrentAccount"
16576
16924
  ]
16577
- ),
16925
+ )
16926
+ };
16927
+
16928
+ // ../mta-types/src/generated/events/mta-event-signatures-server-4.ts
16929
+ var MTA_EVENT_SIGNATURES_SERVER_4 = {
16578
16930
  onPlayerMarkerHit: fn(
16579
16931
  [
16580
16932
  named("Marker"),
@@ -16636,7 +16988,7 @@ var MTA_EVENT_SIGNATURES_SERVER_3 = {
16636
16988
  ),
16637
16989
  onPlayerPickupHit: fn(
16638
16990
  [
16639
- ANY
16991
+ named("Pickup")
16640
16992
  ],
16641
16993
  VOID,
16642
16994
  1,
@@ -16647,7 +16999,7 @@ var MTA_EVENT_SIGNATURES_SERVER_3 = {
16647
16999
  ),
16648
17000
  onPlayerPickupLeave: fn(
16649
17001
  [
16650
- ANY
17002
+ named("Pickup")
16651
17003
  ],
16652
17004
  VOID,
16653
17005
  1,
@@ -16658,7 +17010,7 @@ var MTA_EVENT_SIGNATURES_SERVER_3 = {
16658
17010
  ),
16659
17011
  onPlayerPickupUse: fn(
16660
17012
  [
16661
- ANY
17013
+ named("Pickup")
16662
17014
  ],
16663
17015
  VOID,
16664
17016
  1,
@@ -16670,14 +17022,49 @@ var MTA_EVENT_SIGNATURES_SERVER_3 = {
16670
17022
  onPlayerPrivateMessage: fn(
16671
17023
  [
16672
17024
  STRING,
16673
- named("Player")
17025
+ named("Player"),
17026
+ STRING
16674
17027
  ],
16675
17028
  VOID,
16676
- 2,
17029
+ 3,
16677
17030
  false,
16678
17031
  [
16679
- "message",
16680
- "recipient"
17032
+ "fullMessage",
17033
+ "recipient",
17034
+ "content"
17035
+ ]
17036
+ ),
17037
+ onPlayerProjectileCreation: fn(
17038
+ [
17039
+ NUMBER,
17040
+ NUMBER,
17041
+ NUMBER,
17042
+ NUMBER,
17043
+ NUMBER,
17044
+ named("Element"),
17045
+ NUMBER,
17046
+ NUMBER,
17047
+ NUMBER,
17048
+ NUMBER,
17049
+ NUMBER,
17050
+ NUMBER
17051
+ ],
17052
+ VOID,
17053
+ 12,
17054
+ false,
17055
+ [
17056
+ "weaponType",
17057
+ "x",
17058
+ "y",
17059
+ "z",
17060
+ "force",
17061
+ "target",
17062
+ "rotX",
17063
+ "rotY",
17064
+ "rotZ",
17065
+ "velX",
17066
+ "velY",
17067
+ "velZ"
16681
17068
  ]
16682
17069
  ),
16683
17070
  onPlayerQuit: fn(
@@ -16705,11 +17092,7 @@ var MTA_EVENT_SIGNATURES_SERVER_3 = {
16705
17092
  [
16706
17093
  "loadedResource"
16707
17094
  ]
16708
- )
16709
- };
16710
-
16711
- // ../mta-types/src/generated/events/mta-event-signatures-server-4.ts
16712
- var MTA_EVENT_SIGNATURES_SERVER_4 = {
17095
+ ),
16713
17096
  onPlayerScreenShot: fn(
16714
17097
  [
16715
17098
  named("Resource"),
@@ -16764,7 +17147,11 @@ var MTA_EVENT_SIGNATURES_SERVER_4 = {
16764
17147
  [
16765
17148
  "targetPlayer"
16766
17149
  ]
16767
- ),
17150
+ )
17151
+ };
17152
+
17153
+ // ../mta-types/src/generated/events/mta-event-signatures-server-5.ts
17154
+ var MTA_EVENT_SIGNATURES_SERVER_5 = {
16768
17155
  onPlayerTarget: fn(
16769
17156
  [
16770
17157
  named("Element")
@@ -16776,6 +17163,66 @@ var MTA_EVENT_SIGNATURES_SERVER_4 = {
16776
17163
  "targettedElement"
16777
17164
  ]
16778
17165
  ),
17166
+ onPlayerTeamChange: fn(
17167
+ [
17168
+ named("Team"),
17169
+ named("Team")
17170
+ ],
17171
+ VOID,
17172
+ 2,
17173
+ false,
17174
+ [
17175
+ "oldTeam",
17176
+ "newTeam"
17177
+ ]
17178
+ ),
17179
+ onPlayerTeleport: fn(
17180
+ [
17181
+ NUMBER,
17182
+ NUMBER,
17183
+ NUMBER,
17184
+ NUMBER,
17185
+ NUMBER,
17186
+ NUMBER
17187
+ ],
17188
+ VOID,
17189
+ 6,
17190
+ false,
17191
+ [
17192
+ "previousX",
17193
+ "previousY",
17194
+ "previousZ",
17195
+ "currentX",
17196
+ "currentY",
17197
+ "currentZ"
17198
+ ]
17199
+ ),
17200
+ onPlayerTriggerEventThreshold: fn(
17201
+ [
17202
+ STRING
17203
+ ],
17204
+ VOID,
17205
+ 1,
17206
+ false,
17207
+ [
17208
+ "eventName"
17209
+ ]
17210
+ ),
17211
+ onPlayerTriggerInvalidEvent: fn(
17212
+ [
17213
+ STRING,
17214
+ BOOLEAN,
17215
+ BOOLEAN
17216
+ ],
17217
+ VOID,
17218
+ 3,
17219
+ false,
17220
+ [
17221
+ "eventName",
17222
+ "isAdded",
17223
+ "isRemote"
17224
+ ]
17225
+ ),
16779
17226
  onPlayerUnmute: fn(
16780
17227
  [],
16781
17228
  VOID,
@@ -16835,17 +17282,21 @@ var MTA_EVENT_SIGNATURES_SERVER_4 = {
16835
17282
  named("Element"),
16836
17283
  NUMBER,
16837
17284
  NUMBER,
16838
- BOOLEAN
17285
+ BOOLEAN,
17286
+ NUMBER,
17287
+ NUMBER
16839
17288
  ],
16840
17289
  VOID,
16841
- 5,
17290
+ 7,
16842
17291
  false,
16843
17292
  [
16844
17293
  "totalAmmo",
16845
17294
  "killer",
16846
17295
  "killerWeapon",
16847
17296
  "bodypart",
16848
- "stealth"
17297
+ "stealth",
17298
+ "animGroup",
17299
+ "animID"
16849
17300
  ]
16850
17301
  ),
16851
17302
  onPlayerWeaponFire: fn(
@@ -16863,7 +17314,7 @@ var MTA_EVENT_SIGNATURES_SERVER_4 = {
16863
17314
  8,
16864
17315
  false,
16865
17316
  [
16866
- "weapon",
17317
+ "weaponID",
16867
17318
  "endX",
16868
17319
  "endY",
16869
17320
  "endZ",
@@ -16873,6 +17324,21 @@ var MTA_EVENT_SIGNATURES_SERVER_4 = {
16873
17324
  "startZ"
16874
17325
  ]
16875
17326
  ),
17327
+ onPlayerWeaponReload: fn(
17328
+ [
17329
+ NUMBER,
17330
+ NUMBER,
17331
+ NUMBER
17332
+ ],
17333
+ VOID,
17334
+ 3,
17335
+ false,
17336
+ [
17337
+ "weapon",
17338
+ "ammoInClip",
17339
+ "ammo"
17340
+ ]
17341
+ ),
16876
17342
  onPlayerWeaponSwitch: fn(
16877
17343
  [
16878
17344
  NUMBER,
@@ -16900,7 +17366,11 @@ var MTA_EVENT_SIGNATURES_SERVER_4 = {
16900
17366
  "oldState",
16901
17367
  "newState"
16902
17368
  ]
16903
- ),
17369
+ )
17370
+ };
17371
+
17372
+ // ../mta-types/src/generated/events/mta-event-signatures-server-6.ts
17373
+ var MTA_EVENT_SIGNATURES_SERVER_6 = {
16904
17374
  onResourcePreStart: fn(
16905
17375
  [
16906
17376
  named("Resource")
@@ -16922,11 +17392,22 @@ var MTA_EVENT_SIGNATURES_SERVER_4 = {
16922
17392
  [
16923
17393
  "startedResource"
16924
17394
  ]
16925
- )
16926
- };
16927
-
16928
- // ../mta-types/src/generated/events/mta-event-signatures-server-5.ts
16929
- var MTA_EVENT_SIGNATURES_SERVER_5 = {
17395
+ ),
17396
+ onResourceStateChange: fn(
17397
+ [
17398
+ named("Resource"),
17399
+ STRING,
17400
+ STRING
17401
+ ],
17402
+ VOID,
17403
+ 3,
17404
+ false,
17405
+ [
17406
+ "changedResource",
17407
+ "oldState",
17408
+ "newState"
17409
+ ]
17410
+ ),
16930
17411
  onResourceStop: fn(
16931
17412
  [
16932
17413
  named("Resource"),
@@ -16955,6 +17436,19 @@ var MTA_EVENT_SIGNATURES_SERVER_5 = {
16955
17436
  "newValue"
16956
17437
  ]
16957
17438
  ),
17439
+ onShutdown: fn(
17440
+ [
17441
+ named("Resource"),
17442
+ STRING
17443
+ ],
17444
+ VOID,
17445
+ 2,
17446
+ false,
17447
+ [
17448
+ "theResource",
17449
+ "reason"
17450
+ ]
17451
+ ),
16958
17452
  onTrailerAttach: fn(
16959
17453
  [
16960
17454
  named("Vehicle")
@@ -17034,11 +17528,17 @@ var MTA_EVENT_SIGNATURES_SERVER_5 = {
17034
17528
  ]
17035
17529
  ),
17036
17530
  onVehicleExplode: fn(
17037
- [],
17531
+ [
17532
+ BOOLEAN,
17533
+ named("Player")
17534
+ ],
17038
17535
  VOID,
17039
- 0,
17536
+ 2,
17040
17537
  false,
17041
- []
17538
+ [
17539
+ "withExplosion",
17540
+ "player"
17541
+ ]
17042
17542
  ),
17043
17543
  onVehicleRespawn: fn(
17044
17544
  [
@@ -17159,7 +17659,7 @@ var MTA_EVENT_SIGNATURES_CLIENT_1 = {
17159
17659
  false,
17160
17660
  [
17161
17661
  "URL",
17162
- "isMain"
17662
+ "isMainFrame"
17163
17663
  ]
17164
17664
  ),
17165
17665
  onClientBrowserNavigate: fn(
@@ -17325,6 +17825,17 @@ var MTA_EVENT_SIGNATURES_CLIENT_1 = {
17325
17825
 
17326
17826
  // ../mta-types/src/generated/events/mta-event-signatures-client-2.ts
17327
17827
  var MTA_EVENT_SIGNATURES_CLIENT_2 = {
17828
+ onClientCoreCommand: fn(
17829
+ [
17830
+ STRING
17831
+ ],
17832
+ VOID,
17833
+ 1,
17834
+ false,
17835
+ [
17836
+ "command"
17837
+ ]
17838
+ ),
17328
17839
  onClientCursorMove: fn(
17329
17840
  [
17330
17841
  NUMBER,
@@ -17537,18 +18048,18 @@ var MTA_EVENT_SIGNATURES_CLIENT_2 = {
17537
18048
  [
17538
18049
  "editBox"
17539
18050
  ]
17540
- ),
18051
+ )
18052
+ };
18053
+
18054
+ // ../mta-types/src/generated/events/mta-event-signatures-client-3.ts
18055
+ var MTA_EVENT_SIGNATURES_CLIENT_3 = {
17541
18056
  onClientGUIBlur: fn(
17542
18057
  [],
17543
18058
  VOID,
17544
18059
  0,
17545
18060
  false,
17546
18061
  []
17547
- )
17548
- };
17549
-
17550
- // ../mta-types/src/generated/events/mta-event-signatures-client-3.ts
17551
- var MTA_EVENT_SIGNATURES_CLIENT_3 = {
18062
+ ),
17552
18063
  onClientGUIChanged: fn(
17553
18064
  [
17554
18065
  named("Element")
@@ -17745,7 +18256,11 @@ var MTA_EVENT_SIGNATURES_CLIENT_3 = {
17745
18256
  "absoluteY",
17746
18257
  "leftGUI"
17747
18258
  ]
17748
- ),
18259
+ )
18260
+ };
18261
+
18262
+ // ../mta-types/src/generated/events/mta-event-signatures-client-4.ts
18263
+ var MTA_EVENT_SIGNATURES_CLIENT_4 = {
17749
18264
  onClientMouseLeave: fn(
17750
18265
  [
17751
18266
  NUMBER,
@@ -17760,11 +18275,7 @@ var MTA_EVENT_SIGNATURES_CLIENT_3 = {
17760
18275
  "absoluteY",
17761
18276
  "enteredGUI"
17762
18277
  ]
17763
- )
17764
- };
17765
-
17766
- // ../mta-types/src/generated/events/mta-event-signatures-client-4.ts
17767
- var MTA_EVENT_SIGNATURES_CLIENT_4 = {
18278
+ ),
17768
18279
  onClientMouseMove: fn(
17769
18280
  [
17770
18281
  NUMBER,
@@ -17849,6 +18360,19 @@ var MTA_EVENT_SIGNATURES_CLIENT_4 = {
17849
18360
  "clipboardText"
17850
18361
  ]
17851
18362
  ),
18363
+ onClientPedChoke: fn(
18364
+ [
18365
+ NUMBER,
18366
+ named("Ped")
18367
+ ],
18368
+ VOID,
18369
+ 2,
18370
+ false,
18371
+ [
18372
+ "weaponID",
18373
+ "responsiblePed"
18374
+ ]
18375
+ ),
17852
18376
  onClientPedDamage: fn(
17853
18377
  [
17854
18378
  named("Element"),
@@ -17946,9 +18470,13 @@ var MTA_EVENT_SIGNATURES_CLIENT_4 = {
17946
18470
  "killer",
17947
18471
  "weapon",
17948
18472
  "bodypart",
17949
- "loss"
18473
+ "lossOrStealth"
17950
18474
  ]
17951
- ),
18475
+ )
18476
+ };
18477
+
18478
+ // ../mta-types/src/generated/events/mta-event-signatures-client-5.ts
18479
+ var MTA_EVENT_SIGNATURES_CLIENT_5 = {
17952
18480
  onClientPedWeaponFire: fn(
17953
18481
  [
17954
18482
  NUMBER,
@@ -17984,11 +18512,7 @@ var MTA_EVENT_SIGNATURES_CLIENT_4 = {
17984
18512
  "thePlayer",
17985
18513
  "matchingDimension"
17986
18514
  ]
17987
- )
17988
- };
17989
-
17990
- // ../mta-types/src/generated/events/mta-event-signatures-client-5.ts
17991
- var MTA_EVENT_SIGNATURES_CLIENT_5 = {
18515
+ ),
17992
18516
  onClientPickupLeave: fn(
17993
18517
  [
17994
18518
  named("Player"),
@@ -18180,7 +18704,11 @@ var MTA_EVENT_SIGNATURES_CLIENT_5 = {
18180
18704
  [
18181
18705
  "stuntType"
18182
18706
  ]
18183
- ),
18707
+ )
18708
+ };
18709
+
18710
+ // ../mta-types/src/generated/events/mta-event-signatures-client-6.ts
18711
+ var MTA_EVENT_SIGNATURES_CLIENT_6 = {
18184
18712
  onClientPlayerTarget: fn(
18185
18713
  [
18186
18714
  named("Element")
@@ -18204,11 +18732,7 @@ var MTA_EVENT_SIGNATURES_CLIENT_5 = {
18204
18732
  "theVehicle",
18205
18733
  "seat"
18206
18734
  ]
18207
- )
18208
- };
18209
-
18210
- // ../mta-types/src/generated/events/mta-event-signatures-client-6.ts
18211
- var MTA_EVENT_SIGNATURES_CLIENT_6 = {
18735
+ ),
18212
18736
  onClientPlayerVehicleExit: fn(
18213
18737
  [
18214
18738
  named("Vehicle"),
@@ -18263,16 +18787,20 @@ var MTA_EVENT_SIGNATURES_CLIENT_6 = {
18263
18787
  named("Element"),
18264
18788
  NUMBER,
18265
18789
  NUMBER,
18266
- BOOLEAN
18790
+ BOOLEAN,
18791
+ NUMBER,
18792
+ NUMBER
18267
18793
  ],
18268
18794
  VOID,
18269
- 4,
18795
+ 6,
18270
18796
  false,
18271
18797
  [
18272
18798
  "killer",
18273
18799
  "weapon",
18274
18800
  "bodypart",
18275
- "stealth"
18801
+ "stealth",
18802
+ "animGroup",
18803
+ "animID"
18276
18804
  ]
18277
18805
  ),
18278
18806
  onClientPlayerWeaponFire: fn(
@@ -18395,7 +18923,11 @@ var MTA_EVENT_SIGNATURES_CLIENT_6 = {
18395
18923
  [
18396
18924
  "didClearRenderTargets"
18397
18925
  ]
18398
- ),
18926
+ )
18927
+ };
18928
+
18929
+ // ../mta-types/src/generated/events/mta-event-signatures-client-7.ts
18930
+ var MTA_EVENT_SIGNATURES_CLIENT_7 = {
18399
18931
  onClientSoundBeat: fn(
18400
18932
  [
18401
18933
  NUMBER
@@ -18428,11 +18960,7 @@ var MTA_EVENT_SIGNATURES_CLIENT_6 = {
18428
18960
  [
18429
18961
  "length"
18430
18962
  ]
18431
- )
18432
- };
18433
-
18434
- // ../mta-types/src/generated/events/mta-event-signatures-client-7.ts
18435
- var MTA_EVENT_SIGNATURES_CLIENT_7 = {
18963
+ ),
18436
18964
  onClientSoundStarted: fn(
18437
18965
  [
18438
18966
  STRING
@@ -18538,7 +19066,7 @@ var MTA_EVENT_SIGNATURES_CLIENT_7 = {
18538
19066
  [
18539
19067
  "theHitElement",
18540
19068
  "damageImpulseMag",
18541
- "bodypart",
19069
+ "bodyPart",
18542
19070
  "collisionX",
18543
19071
  "collisionY",
18544
19072
  "collisionZ",
@@ -18622,7 +19150,11 @@ var MTA_EVENT_SIGNATURES_CLIENT_7 = {
18622
19150
  0,
18623
19151
  false,
18624
19152
  []
18625
- ),
19153
+ )
19154
+ };
19155
+
19156
+ // ../mta-types/src/generated/events/mta-event-signatures-client-8.ts
19157
+ var MTA_EVENT_SIGNATURES_CLIENT_8 = {
18626
19158
  onClientVehicleStartEnter: fn(
18627
19159
  [
18628
19160
  named("Ped"),
@@ -18652,11 +19184,7 @@ var MTA_EVENT_SIGNATURES_CLIENT_7 = {
18652
19184
  "seat",
18653
19185
  "door"
18654
19186
  ]
18655
- )
18656
- };
18657
-
18658
- // ../mta-types/src/generated/events/mta-event-signatures-client-8.ts
18659
- var MTA_EVENT_SIGNATURES_CLIENT_8 = {
19187
+ ),
18660
19188
  onClientVehicleWeaponHit: fn(
18661
19189
  [
18662
19190
  NUMBER,
@@ -18737,7 +19265,8 @@ var MTA_EVENT_SIGNATURES = {
18737
19265
  ...MTA_EVENT_SIGNATURES_SERVER_2,
18738
19266
  ...MTA_EVENT_SIGNATURES_SERVER_3,
18739
19267
  ...MTA_EVENT_SIGNATURES_SERVER_4,
18740
- ...MTA_EVENT_SIGNATURES_SERVER_5
19268
+ ...MTA_EVENT_SIGNATURES_SERVER_5,
19269
+ ...MTA_EVENT_SIGNATURES_SERVER_6
18741
19270
  },
18742
19271
  client: {
18743
19272
  ...MTA_EVENT_SIGNATURES_CLIENT_1,
@@ -18772,21 +19301,42 @@ function eventHandler(name, environment) {
18772
19301
  return MTA_EVENT_SIGNATURES[environment][name] ?? null;
18773
19302
  }
18774
19303
 
18775
- // ../compiler/src/checker/environment-checks.ts
18776
- var EVENT_FUNCTIONS = /* @__PURE__ */ new Set(["addEventHandler", "removeEventHandler", "triggerEvent"]);
19304
+ // ../compiler/src/checker/environment-message.ts
18777
19305
  function scopeLabel(environment) {
18778
19306
  return environment === "shared" ? "shared" : `${environment}-only`;
18779
19307
  }
19308
+ function unavailableTail(environment) {
19309
+ return `is not available in a "${environment}" file.`;
19310
+ }
19311
+ function unusableTail(environment) {
19312
+ return `cannot be used in a "${environment}" file.`;
19313
+ }
19314
+ function reportEnvironment(context, code, message, position2) {
19315
+ if (context.environment === "shared") {
19316
+ return;
19317
+ }
19318
+ context.report(code, message, position2);
19319
+ }
19320
+
19321
+ // ../compiler/src/checker/environment-checks.ts
19322
+ var EVENT_FUNCTIONS = /* @__PURE__ */ new Set(["addEventHandler", "removeEventHandler", "triggerEvent"]);
19323
+ function reportProject(context, name, declared, position2) {
19324
+ const message = `"${name}" is declared by the project, is ${scopeLabel(declared)}, and ${unavailableTail(context.environment)}`;
19325
+ reportEnvironment(context, "check-environment-api", message, position2);
19326
+ }
19327
+ function reportApi(context, name, declared, position2) {
19328
+ const message = `API "${name}" is ${scopeLabel(declared)} and ${unavailableTail(context.environment)}`;
19329
+ reportEnvironment(context, "check-environment-api", message, position2);
19330
+ }
18780
19331
  function checkGlobalReference(context, name, position2) {
18781
19332
  if (name === "self") {
18782
- const message2 = 'A "self" is only bound inside a class method or a "function Name:method()"; here it reads a global that is "nil".';
18783
- context.report("check-invalid-self", message2, position2);
19333
+ const message = 'A "self" is only bound inside a class method or a "function Name:method()"; here it reads a global that is "nil".';
19334
+ context.report("check-invalid-self", message, position2);
18784
19335
  return;
18785
19336
  }
18786
19337
  const project = context.projectEnvironmentOf(name);
18787
19338
  if (project !== null) {
18788
- const message2 = `"${name}" is declared by the project, is ${scopeLabel(project)}, and is not available in a "${context.environment}" file.`;
18789
- context.report("check-environment-api", message2, position2);
19339
+ reportProject(context, name, project, position2);
18790
19340
  return;
18791
19341
  }
18792
19342
  const declared = declarationEnvironment(name);
@@ -18794,8 +19344,26 @@ function checkGlobalReference(context, name, position2) {
18794
19344
  context.noteExternalReference(name, position2);
18795
19345
  return;
18796
19346
  }
18797
- const message = `API "${name}" is ${scopeLabel(declared)} and is not available in a "${context.environment}" file.`;
18798
- context.report("check-environment-api", message, position2);
19347
+ reportApi(context, name, declared, position2);
19348
+ }
19349
+ function checkSharedReference(context, name, position2) {
19350
+ if (context.environment !== "shared" || context.moduleGlobals.has(name)) {
19351
+ return;
19352
+ }
19353
+ const project = context.projectEnvironmentOf(name);
19354
+ if (project !== null) {
19355
+ if (project !== "shared") {
19356
+ reportProject(context, name, project, position2);
19357
+ }
19358
+ return;
19359
+ }
19360
+ if (!context.binder.isBuiltinReference(name)) {
19361
+ return;
19362
+ }
19363
+ const declared = declarationEnvironment(name);
19364
+ if (declared !== null && declared !== "shared") {
19365
+ reportApi(context, name, declared, position2);
19366
+ }
18799
19367
  }
18800
19368
  function eventName(expression) {
18801
19369
  const argument = expression.args[0];
@@ -18814,8 +19382,8 @@ function checkEventUsage(context, expression) {
18814
19382
  if (name === null || custom?.environment === "shared" || custom?.environment === context.environment || declared === null || declared === context.environment) {
18815
19383
  return;
18816
19384
  }
18817
- const message = `Event "${name}" is ${scopeLabel(declared)} and cannot be used in a "${context.environment}" file.`;
18818
- context.report("check-environment-event", message, expression.position);
19385
+ const message = `Event "${name}" is ${scopeLabel(declared)} and ${unusableTail(context.environment)}`;
19386
+ reportEnvironment(context, "check-environment-event", message, expression.position);
18819
19387
  }
18820
19388
 
18821
19389
  // ../mta-types/src/event-call-semantics.ts
@@ -18996,6 +19564,136 @@ function withoutSelfParameter(signature2) {
18996
19564
  return createFunction(signature2.parameters.slice(1), signature2.returnType, minimum, signature2.isVariadic, names.slice(1), signature2.variadicType);
18997
19565
  }
18998
19566
 
19567
+ // ../compiler/src/checker/record-completion.ts
19568
+ function recordShapeOf(context, type) {
19569
+ if (type.kind === "record") {
19570
+ return type;
19571
+ }
19572
+ if (type.kind !== "named") {
19573
+ return null;
19574
+ }
19575
+ const shape = context.assignability().resolveNominal?.(type.name) ?? null;
19576
+ return shape === null ? null : { kind: "record", name: type.name, origin: null, members: shape.members };
19577
+ }
19578
+ function pendingKeys(context, source, target) {
19579
+ if (source.kind !== "record" || source.isLiteral !== true) {
19580
+ return null;
19581
+ }
19582
+ const shape = recordShapeOf(context, target);
19583
+ if (shape === null) {
19584
+ return null;
19585
+ }
19586
+ const missing2 = /* @__PURE__ */ new Map();
19587
+ const options = context.assignability();
19588
+ for (const [name, member] of shape.members) {
19589
+ const written = source.members.get(name);
19590
+ if (written === void 0) {
19591
+ if (member.kind !== "optional") {
19592
+ missing2.set(name, member);
19593
+ }
19594
+ continue;
19595
+ }
19596
+ if (!isAssignable(written, member, options)) {
19597
+ return null;
19598
+ }
19599
+ }
19600
+ for (const name of source.members.keys()) {
19601
+ if (!shape.members.has(name)) {
19602
+ return null;
19603
+ }
19604
+ }
19605
+ return missing2.size === 0 ? null : missing2;
19606
+ }
19607
+ function deferRecordCompletion(context, target, source, declared, subject, position2) {
19608
+ const path = pathOf2(target);
19609
+ if (path === null) {
19610
+ return false;
19611
+ }
19612
+ const missing2 = pendingKeys(context, source, declared);
19613
+ if (missing2 === null) {
19614
+ return false;
19615
+ }
19616
+ context.openRecordObligation({
19617
+ path,
19618
+ subject,
19619
+ source,
19620
+ target: declared,
19621
+ missing: missing2,
19622
+ discharged: 0,
19623
+ depth: context.blockDepth,
19624
+ line: position2.line,
19625
+ position: position2
19626
+ });
19627
+ return true;
19628
+ }
19629
+ function reportIncompleteRecord(context, obligation, position2) {
19630
+ if (obligation.discharged === 0) {
19631
+ context.closeRecordObligation(obligation.path);
19632
+ context.expectAssignable(obligation.source, obligation.target, obligation.position, obligation.subject);
19633
+ return;
19634
+ }
19635
+ const keys = [...obligation.missing.keys()].map((key) => `"${key}"`);
19636
+ const label2 = keys.length === 1 ? `Key ${keys[0]} is` : `Keys ${keys.join(", ")} are`;
19637
+ const built = `The table built on line ${obligation.line} is used before it is complete.`;
19638
+ const message = `${obligation.subject} expects "${typeToString(obligation.target)}". ${label2} never assigned. ${built}`;
19639
+ context.report("check-incomplete-record", message, position2);
19640
+ context.closeRecordObligation(obligation.path);
19641
+ }
19642
+ function dischargeRecordKey(context, target, valueType, position2) {
19643
+ if (target.kind !== "member-expression") {
19644
+ return false;
19645
+ }
19646
+ const path = pathOf2(target.object);
19647
+ const obligation = path === null ? null : context.recordObligation(path);
19648
+ if (obligation === null || obligation.depth !== context.blockDepth) {
19649
+ return false;
19650
+ }
19651
+ const expected = obligation.missing.get(target.property);
19652
+ if (expected === void 0) {
19653
+ return false;
19654
+ }
19655
+ context.expectAssignable(valueType, expected, position2, `Key "${target.property}"`);
19656
+ obligation.missing.delete(target.property);
19657
+ obligation.discharged += 1;
19658
+ if (obligation.missing.size === 0) {
19659
+ context.closeRecordObligation(obligation.path);
19660
+ }
19661
+ return true;
19662
+ }
19663
+ function extendInferredRecord(context, target, valueType) {
19664
+ if (target.kind !== "member-expression" || target.object.kind !== "identifier") {
19665
+ return false;
19666
+ }
19667
+ const symbol = context.binder.lookup(target.object.name);
19668
+ if (symbol === null || symbol.type.kind !== "record" || symbol.type.isInferred !== true || symbol.type.members.has(target.property)) {
19669
+ return false;
19670
+ }
19671
+ const members = new Map(symbol.type.members);
19672
+ members.set(target.property, widenInferred(valueType));
19673
+ const extended = createObjectType(members);
19674
+ symbol.type = extended.kind === "record" ? { ...extended, isInferred: true } : extended;
19675
+ return true;
19676
+ }
19677
+ function escapesRecordObligation(context, expression) {
19678
+ const path = pathOf2(expression);
19679
+ const obligation = path === null ? null : context.recordObligation(path);
19680
+ if (obligation !== null) {
19681
+ reportIncompleteRecord(context, obligation, expression.position);
19682
+ }
19683
+ }
19684
+ function settleRecordObligations(context, opened) {
19685
+ for (const path of context.recordObligationPaths()) {
19686
+ if (opened.has(path)) {
19687
+ continue;
19688
+ }
19689
+ const obligation = context.recordObligation(path);
19690
+ if (obligation === null) {
19691
+ continue;
19692
+ }
19693
+ reportIncompleteRecord(context, obligation, obligation.position);
19694
+ }
19695
+ }
19696
+
18999
19697
  // ../compiler/src/checker/resource-exports.ts
19000
19698
  var RESOURCE_LOOKUP = "getResourceFromName";
19001
19699
  var EXPORTS_TABLE = "exports";
@@ -19205,9 +19903,6 @@ function isElementType(name) {
19205
19903
 
19206
19904
  // ../compiler/src/checker/oop-members.ts
19207
19905
  var OOP_HINT = 'Set "compiler = { oop = true }" in .luam.manifest to enable the MTA OOP API.';
19208
- function scopeLabel2(environment) {
19209
- return environment === "shared" ? "shared" : `${environment}-only`;
19210
- }
19211
19906
  function isMtaElementName(declarations, className) {
19212
19907
  if (!isElementType(className)) {
19213
19908
  return false;
@@ -19225,6 +19920,14 @@ function reportDisabled(context, className, name, position2) {
19225
19920
  const subject = `"${className}.${name}" is part of the MTA OOP API, which this project does not enable.`;
19226
19921
  context.report("check-oop-disabled", `${subject} Call "${member.procedural}" instead. ${OOP_HINT}`, position2);
19227
19922
  }
19923
+ function acceptsMember(context, className, name, member, position2) {
19924
+ if (member.environment === void 0 || isAvailableIn(member.environment, context.environment)) {
19925
+ return true;
19926
+ }
19927
+ const subject = `"${className}.${name}" wraps "${member.procedural}", which is ${scopeLabel(member.environment)}`;
19928
+ reportEnvironment(context, "check-environment-api", `${subject} and ${unavailableTail(context.environment)}`, position2);
19929
+ return context.environment === "shared";
19930
+ }
19228
19931
  function isMtaClassReference(context, className) {
19229
19932
  return isMtaClass(className) && context.binder.lookup(className) === null && context.declarations.lookupClass(className) === null && context.declarations.lookupInterface(className) === null;
19230
19933
  }
@@ -19240,12 +19943,7 @@ function resolveMtaStaticMember(context, className, name, position2) {
19240
19943
  reportDisabled(context, className, name, position2);
19241
19944
  return null;
19242
19945
  }
19243
- if (member.environment !== void 0 && !isAvailableIn(member.environment, context.environment)) {
19244
- const subject = `"${className}.${name}" wraps "${member.procedural}", which is ${scopeLabel2(member.environment)}`;
19245
- context.report("check-environment-api", `${subject} and is not available in a "${context.environment}" file.`, position2);
19246
- return null;
19247
- }
19248
- return member;
19946
+ return acceptsMember(context, className, name, member, position2) ? member : null;
19249
19947
  }
19250
19948
  function resolveMtaConstructor(context, className, position2) {
19251
19949
  const constructor = mtaConstructor(className);
@@ -19260,9 +19958,11 @@ function resolveMtaConstructor(context, className, position2) {
19260
19958
  return null;
19261
19959
  }
19262
19960
  if (!isAvailableIn(constructor.environment, context.environment)) {
19263
- const subject = `"${className}(...)" is ${scopeLabel2(constructor.environment)}`;
19264
- context.report("check-environment-api", `${subject} and is not available in a "${context.environment}" file.`, position2);
19265
- return null;
19961
+ const subject = `"${className}(...)" is ${scopeLabel(constructor.environment)}`;
19962
+ reportEnvironment(context, "check-environment-api", `${subject} and ${unavailableTail(context.environment)}`, position2);
19963
+ if (context.environment !== "shared") {
19964
+ return null;
19965
+ }
19266
19966
  }
19267
19967
  return constructor.type;
19268
19968
  }
@@ -19282,12 +19982,7 @@ function resolveMtaMember(context, className, name, position2) {
19282
19982
  reportUnknown(context, className, name, position2);
19283
19983
  return null;
19284
19984
  }
19285
- if (member.environment !== void 0 && !isAvailableIn(member.environment, context.environment)) {
19286
- const subject = `"${className}.${name}" wraps "${member.procedural}", which is ${scopeLabel2(member.environment)}`;
19287
- context.report("check-environment-api", `${subject} and is not available in a "${context.environment}" file.`, position2);
19288
- return null;
19289
- }
19290
- return member;
19985
+ return acceptsMember(context, className, name, member, position2) ? member : null;
19291
19986
  }
19292
19987
 
19293
19988
  // ../compiler/src/checker/members.ts
@@ -19413,7 +20108,9 @@ function resolveNamedMember(context, receiver, expression) {
19413
20108
  if (contract === null) {
19414
20109
  return null;
19415
20110
  }
19416
- const members = new Map(context.declarations.collectMembers(name).map((member2) => [member2.name, member2]));
20111
+ const substitutions = parameterSubstitutions(contract.typeParameters, receiver.typeArguments ?? []);
20112
+ const collected = context.declarations.collectMembers(name).map((entry) => substitutions.size === 0 ? entry : { ...entry, type: substituteType(entry.type, substitutions) });
20113
+ const members = new Map(collected.map((entry) => [entry.name, entry]));
19417
20114
  return checkInterfaceMember(context, name, members, expression);
19418
20115
  }
19419
20116
  function reportUnknownMethod(context, receiver, callee, method, position2) {
@@ -19581,6 +20278,39 @@ function checkUnary(context, operator, operand, expression) {
19581
20278
  return context.record(expression, NUMBER_TYPE);
19582
20279
  }
19583
20280
 
20281
+ // ../compiler/src/checker/shadowing.ts
20282
+ var HELPER_TARGETS = new Map(
20283
+ NATIVE_EXTENSIONS.map((extension) => [
20284
+ extension.target,
20285
+ extension.style === "call" ? `${extension.receiver}.${extension.property}(...)` : `${extension.receiver}.${extension.property}`
20286
+ ])
20287
+ );
20288
+ var SUPPRESSION = 'Rename the declaration, or record the new signature in a ".d.luam" file so later calls are checked against it.';
20289
+ function reportShadowedGlobal(context, name, position2) {
20290
+ if (context.isDeclarationFile || !context.binder.isBuiltinReference(name)) {
20291
+ return;
20292
+ }
20293
+ const message = `"${name}" is an API this environment declares. Later calls are still checked against the declared signature, not this one. ${SUPPRESSION}`;
20294
+ context.warn("check-shadowed-api", message, position2);
20295
+ }
20296
+ function reportShadowedHelper(context, library, member, position2) {
20297
+ if (context.isDeclarationFile || !isLibrary(library) || findLibraryMember(library, member) === null) {
20298
+ return;
20299
+ }
20300
+ const target = `${library}.${member}`;
20301
+ const rewrite = HELPER_TARGETS.get(target);
20302
+ const lowered = rewrite === void 0 ? "" : ` The extension "${rewrite}" lowers to it.`;
20303
+ const message = `"${target}" is part of the standard library this build models.${lowered} Later calls are still checked against the declared signature, not this one. ${SUPPRESSION}`;
20304
+ context.warn("check-shadowed-helper", message, position2);
20305
+ }
20306
+ function reportImplicitGlobal(context, name, position2) {
20307
+ if (context.isDeclarationFile || !context.noImplicitGlobals) {
20308
+ return;
20309
+ }
20310
+ const message = `"${name}" is not declared anywhere this file can reach, so this assignment creates a global. Declare it with "local", annotate it as a global, or describe it in a ".d.luam" file.`;
20311
+ context.warn("check-implicit-global", message, position2);
20312
+ }
20313
+
19584
20314
  // ../compiler/src/checker/union-members.ts
19585
20315
  function isShapeOption(context, option) {
19586
20316
  if (option.kind === "record") {
@@ -19802,8 +20532,12 @@ function negatedFacts(context, condition) {
19802
20532
  // ../compiler/src/checker/control-flow.ts
19803
20533
  var ITERATOR_FUNCTIONS = /* @__PURE__ */ new Set(["pairs", "ipairs"]);
19804
20534
  function checkBlock(context, body) {
20535
+ const opened = new Set(context.recordObligationPaths());
19805
20536
  context.binder.pushScope();
20537
+ context.blockDepth += 1;
19806
20538
  checkStatements(context, body);
20539
+ context.blockDepth -= 1;
20540
+ settleRecordObligations(context, opened);
19807
20541
  const declared = context.binder.currentScopeNames();
19808
20542
  context.binder.popScope();
19809
20543
  for (const name of declared) {
@@ -19998,7 +20732,9 @@ function minimumArguments(context, parameters) {
19998
20732
  function buildFunctionType(context, parameters, returnAnnotation, contextual = null) {
19999
20733
  const isVariadic = parameters.some((parameter) => parameter.isVararg);
20000
20734
  const named2 = parameters.filter((parameter) => !parameter.isVararg);
20001
- const types = named2.map((parameter, index) => parameter.annotation === null ? contextual?.parameters[index] ?? ANY_TYPE : context.resolveAnnotation(parameter.annotation));
20735
+ const types = named2.map(
20736
+ (parameter, index) => parameter.annotation === null ? contextual?.parameters[index] ?? ANY_TYPE : context.resolveValueAnnotation(parameter.annotation, "a parameter")
20737
+ );
20002
20738
  const names = named2.map((parameter) => parameter.name);
20003
20739
  return createFunction(types, context.resolveAnnotation(returnAnnotation), minimumArguments(context, parameters), isVariadic, names);
20004
20740
  }
@@ -20043,7 +20779,11 @@ function checkFunctionBody(context, parameters, returnAnnotation, body, signatur
20043
20779
  parameterIndex += 1;
20044
20780
  }
20045
20781
  }
20782
+ const opened = new Set(context.recordObligationPaths());
20783
+ context.blockDepth += 1;
20046
20784
  checkStatements(context, body);
20785
+ context.blockDepth -= 1;
20786
+ settleRecordObligations(context, opened);
20047
20787
  const declared = context.currentReturnType();
20048
20788
  if (declared !== null && context.flowState.reachable && !toleratesFallthrough(declared)) {
20049
20789
  reportMissingReturn(context, declared, position2);
@@ -20072,9 +20812,11 @@ function checkLocal(context, statement) {
20072
20812
  context.binder.declare({ name: declaration.name, type: inferred, isLocal: true, position: declaration.position, origin: "local" });
20073
20813
  return;
20074
20814
  }
20075
- const declared = context.resolveAnnotation(declaration.annotation);
20076
- if (value !== void 0) {
20077
- context.expectAssignable(valueType, declared, value.position, `Variable "${declaration.name}"`);
20815
+ const declared = context.resolveValueAnnotation(declaration.annotation, "a local");
20816
+ const subject = `Variable "${declaration.name}"`;
20817
+ const deferred = value !== void 0 && deferRecordCompletion(context, { kind: "identifier", name: declaration.name, position: declaration.position }, valueType, declared, subject, value.position);
20818
+ if (value !== void 0 && !deferred) {
20819
+ context.expectAssignable(valueType, declared, value.position, subject);
20078
20820
  }
20079
20821
  context.binder.declare({ name: declaration.name, type: declared, isLocal: true, position: declaration.position, origin: "local" });
20080
20822
  if (value !== void 0) {
@@ -20093,6 +20835,13 @@ function checkCompoundOperand(context, operator, type, position2) {
20093
20835
  context.report("check-invalid-operand", `Operator "${operator}" cannot be applied to "${typeToString(type)}".`, position2);
20094
20836
  }
20095
20837
  }
20838
+ var DELETABLE_CONTAINERS = /* @__PURE__ */ new Set(["map", "array", "table"]);
20839
+ function deletesContainerKey(context, target, valueType) {
20840
+ if (valueType.kind !== "nil" || target.kind !== "index-expression" && target.kind !== "member-expression") {
20841
+ return false;
20842
+ }
20843
+ return DELETABLE_CONTAINERS.has(context.typeOf(target.object).kind);
20844
+ }
20096
20845
  function recordAssignedFact(context, path, valueType, declared) {
20097
20846
  if (path === null || valueType.kind === "any") {
20098
20847
  return;
@@ -20109,9 +20858,12 @@ function checkAssignment(context, statement) {
20109
20858
  if (assigned !== null) {
20110
20859
  context.forgetNarrowing(assigned);
20111
20860
  }
20112
- const targetType = checkExpression(context, target);
20113
20861
  const valueType = valueTypes[index] ?? NIL_TYPE;
20114
20862
  const value = valueAt(statement.values, valueTypes, index);
20863
+ if (value !== void 0 && extendInferredRecord(context, target, valueType)) {
20864
+ return;
20865
+ }
20866
+ const targetType = checkExpression(context, target);
20115
20867
  if (target.kind === "member-expression") {
20116
20868
  const object = context.typeOf(target.object);
20117
20869
  const frame = context.currentClassMethod();
@@ -20130,16 +20882,54 @@ function checkAssignment(context, statement) {
20130
20882
  return;
20131
20883
  }
20132
20884
  if (target.kind === "identifier" && context.binder.lookup(target.name) === null) {
20885
+ reportImplicitGlobal(context, target.name, target.position);
20133
20886
  context.declareModuleGlobal({ name: target.name, type: valueType, isLocal: false, position: target.position });
20134
20887
  return;
20135
20888
  }
20889
+ if (!context.insideFunction()) {
20890
+ reportShadowedAssignment(context, target);
20891
+ }
20136
20892
  const declared = target.kind === "identifier" ? context.binder.lookup(target.name)?.type ?? targetType : targetType;
20893
+ if (deletesContainerKey(context, target, valueType)) {
20894
+ return;
20895
+ }
20896
+ if (value !== void 0 && dischargeRecordKey(context, target, valueType, value.position)) {
20897
+ return;
20898
+ }
20899
+ const path = pathOf2(target);
20900
+ if (path !== null) {
20901
+ context.closeRecordObligation(path);
20902
+ }
20903
+ if (value !== void 0 && deferRecordCompletion(context, target, valueType, declared, "Assignment", value.position)) {
20904
+ return;
20905
+ }
20137
20906
  if (value !== void 0) {
20138
20907
  context.expectAssignable(valueType, declared, value.position, "Assignment");
20139
20908
  }
20140
20909
  recordAssignedFact(context, pathOf2(target), valueType, declared);
20141
20910
  });
20142
20911
  }
20912
+ function rootIdentifier(expression) {
20913
+ if (expression.kind === "identifier") {
20914
+ return expression.name;
20915
+ }
20916
+ return expression.kind === "member-expression" || expression.kind === "index-expression" ? rootIdentifier(expression.object) : null;
20917
+ }
20918
+ function reportShadowedAssignment(context, target) {
20919
+ if (target.kind !== "identifier") {
20920
+ const root = rootIdentifier(target);
20921
+ if (root !== null && context.binder.lookup(root) === null) {
20922
+ reportImplicitGlobal(context, root, target.position);
20923
+ }
20924
+ }
20925
+ if (target.kind === "identifier") {
20926
+ reportShadowedGlobal(context, target.name, target.position);
20927
+ return;
20928
+ }
20929
+ if (target.kind === "member-expression" && target.object.kind === "identifier") {
20930
+ reportShadowedHelper(context, target.object.name, target.property, target.position);
20931
+ }
20932
+ }
20143
20933
  function checkFunctionDeclaration(context, statement) {
20144
20934
  const built = buildFunctionType(context, statement.parameters, statement.returnAnnotation);
20145
20935
  const type = applyTypeParameters(context, built, statement.typeParameters, statement.typeConstraints);
@@ -20148,9 +20938,13 @@ function checkFunctionDeclaration(context, statement) {
20148
20938
  if (statement.isLocal) {
20149
20939
  context.binder.declare({ ...symbol, origin: "local" });
20150
20940
  } else {
20941
+ reportShadowedGlobal(context, statement.name.name, statement.position);
20151
20942
  context.declareModuleGlobal(symbol);
20152
20943
  }
20153
20944
  }
20945
+ if (!statement.isLocal && statement.name.kind !== "identifier") {
20946
+ reportShadowedAssignment(context, statement.name);
20947
+ }
20154
20948
  context.record(statement.name, type);
20155
20949
  checkFunctionBody(context, statement.parameters, statement.returnAnnotation, statement.body, type, statement.isMethod ? ANY_TYPE : null, statement.position);
20156
20950
  }
@@ -20203,7 +20997,34 @@ function checkDeclareStatement(context, statement) {
20203
20997
  }
20204
20998
  const type = context.resolveAnnotation(statement.annotation);
20205
20999
  context.declareModuleGlobal({ name: statement.name, type, isLocal: false, position: statement.position });
20206
- context.declarations.declareGlobal({ name: statement.name, type, position: statement.position });
21000
+ context.declarations.declareGlobal({ name: statement.name, type, isDeclared: true, position: statement.position });
21001
+ }
21002
+ function checkGlobalStatement(context, statement) {
21003
+ const declaration = statement.declaration;
21004
+ const declared = declaration.annotation === null ? ANY_TYPE : context.resolveValueAnnotation(declaration.annotation, "a global");
21005
+ const valueTypes = checkValueList(context, statement.values);
21006
+ const value = valueAt(statement.values, valueTypes, 0);
21007
+ if (context.insideFunction()) {
21008
+ const message = `A type on global "${declaration.name}" is only valid at the top level of a file. Assign it without the annotation here.`;
21009
+ context.report("check-global-annotation-scope", message, statement.position);
21010
+ return;
21011
+ }
21012
+ const existing = context.declarations.lookupGlobal(declaration.name);
21013
+ const contract = existing !== null && existing.isDeclared === true ? existing.type : declared;
21014
+ if (existing !== null && existing.isDeclared !== true) {
21015
+ context.report("check-duplicate-global", `Global "${declaration.name}" is already declared with a type.`, statement.position);
21016
+ }
21017
+ if (value !== void 0) {
21018
+ context.expectAssignable(valueTypes[0] ?? NIL_TYPE, contract, value.position, `Global "${declaration.name}"`);
21019
+ }
21020
+ context.forgetNarrowing(declaration.name);
21021
+ context.declareModuleGlobal({ name: declaration.name, type: contract, isLocal: false, position: declaration.position });
21022
+ if (existing === null) {
21023
+ context.declarations.declareGlobal({ name: declaration.name, type: contract, position: declaration.position });
21024
+ }
21025
+ if (value !== void 0) {
21026
+ recordAssignedFact(context, declaration.name, valueTypes[0] ?? NIL_TYPE, contract);
21027
+ }
20207
21028
  }
20208
21029
  function checkStatement(context, statement) {
20209
21030
  switch (statement.kind) {
@@ -20211,6 +21032,8 @@ function checkStatement(context, statement) {
20211
21032
  return checkLocal(context, statement);
20212
21033
  case "assignment-statement":
20213
21034
  return checkAssignment(context, statement);
21035
+ case "global-statement":
21036
+ return checkGlobalStatement(context, statement);
20214
21037
  case "call-statement":
20215
21038
  checkExpression(context, statement.expression);
20216
21039
  return;
@@ -20237,11 +21060,15 @@ function checkStatement(context, statement) {
20237
21060
  case "generic-for-statement":
20238
21061
  return checkGenericFor(context, statement);
20239
21062
  case "type-alias-statement": {
20240
- const resolved2 = context.resolveAnnotation(statement.annotation);
21063
+ const resolved2 = context.resolveValueAnnotation(statement.annotation, "a type alias");
20241
21064
  const shape = statement.annotation.kind === "type-object" || statement.annotation.kind === "type-intersection";
20242
21065
  const named2 = shape ? renameRecord(resolved2, statement.name) : resolved2;
21066
+ if (context.isAmbientAlias(statement.name)) {
21067
+ context.report("check-duplicate-type", `Type "${statement.name}" is already defined.`, statement.position);
21068
+ }
20243
21069
  context.noteTypeParameters(statement.typeParameters);
20244
21070
  context.binder.declareAlias(statement.name, named2, statement.typeParameters);
21071
+ context.declarations.declareAlias({ name: statement.name, typeParameters: statement.typeParameters, type: named2, position: statement.position });
20245
21072
  return;
20246
21073
  }
20247
21074
  case "declare-statement":
@@ -20279,6 +21106,19 @@ function templateLiteralText(segments) {
20279
21106
  return segments.map((segment) => segment.kind === "text" ? segment.value : `\${${segment.value}}`).join("");
20280
21107
  }
20281
21108
 
21109
+ // ../compiler/src/checker/value-distribution.ts
21110
+ function distributeValueTypes(types) {
21111
+ const distributed = [];
21112
+ types.forEach((type, index) => {
21113
+ if (index === types.length - 1) {
21114
+ distributed.push(...valuesOf(type));
21115
+ return;
21116
+ }
21117
+ distributed.push(firstValueOf(type));
21118
+ });
21119
+ return distributed;
21120
+ }
21121
+
20282
21122
  // ../compiler/src/checker/expressions.ts
20283
21123
  var NAME_PATH_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*(?:\.[A-Za-z_][A-Za-z0-9_]*)*$/;
20284
21124
  var EXTENSION_RESULTS = {
@@ -20322,7 +21162,8 @@ function checkMember(context, expression) {
20322
21162
  checkExpression(context, expression.object);
20323
21163
  return context.record(expression, library);
20324
21164
  }
20325
- const objectType = checkExpression(context, expression.object);
21165
+ const received = checkExpression(context, expression.object);
21166
+ const objectType = received.kind === "optional" ? received.element : received;
20326
21167
  if (objectType.kind === "record") {
20327
21168
  return context.record(expression, resolveRecordMember(context, objectType, expression));
20328
21169
  }
@@ -20345,26 +21186,44 @@ function checkMember(context, expression) {
20345
21186
  }
20346
21187
  return context.record(expression, extension === null ? ANY_TYPE : EXTENSION_RESULTS[extension.result]);
20347
21188
  }
21189
+ function spreadsUnknownArity(args, argumentTypes) {
21190
+ if (args.length === 0 || args.length !== argumentTypes.length) {
21191
+ return false;
21192
+ }
21193
+ return args[args.length - 1]?.kind === "call-expression" && argumentTypes[argumentTypes.length - 1]?.kind === "any";
21194
+ }
21195
+ function resolveKeyedMember(context, objectType, expression) {
21196
+ if (expression.index.kind !== "string-literal" || objectType.kind !== "record" && objectType.kind !== "named") {
21197
+ return null;
21198
+ }
21199
+ const access = { kind: "member-expression", object: expression.object, property: expression.index.value, position: expression.index.position };
21200
+ return objectType.kind === "record" ? resolveRecordMember(context, objectType, access) : resolveNamedMember(context, objectType, access);
21201
+ }
20348
21202
  function countArguments2(total) {
20349
21203
  return total === 1 ? "1 argument" : `${total} arguments`;
20350
21204
  }
20351
21205
  function checkSignature(context, args, declared, position2, owner = "This call", typeArguments = []) {
20352
21206
  const argumentTypes = checkValueList(context, args, declared.parameters);
20353
21207
  const signature2 = specializeCall(context, owner, declared, argumentTypes, typeArguments, position2);
20354
- if (argumentTypes.length < signature2.minimumArguments) {
21208
+ const spreads = spreadsUnknownArity(args, argumentTypes);
21209
+ const fixed = spreads ? argumentTypes.length - 1 : argumentTypes.length;
21210
+ if (!spreads && argumentTypes.length < signature2.minimumArguments) {
20355
21211
  const message = `This call expects at least ${countArguments2(signature2.minimumArguments)} but received ${argumentTypes.length}.`;
20356
21212
  context.report("check-argument-count", message, position2);
20357
21213
  }
20358
- if (!signature2.isVariadic && argumentTypes.length > signature2.parameters.length) {
21214
+ if (!signature2.isVariadic && fixed > signature2.parameters.length) {
20359
21215
  const message = `This call expects at most ${countArguments2(signature2.parameters.length)} but received ${argumentTypes.length}.`;
20360
21216
  context.report("check-argument-count", message, position2);
20361
21217
  }
20362
21218
  signature2.parameters.forEach((parameter, index) => {
20363
21219
  const argumentType = argumentTypes[index];
20364
21220
  const argument = args[index];
20365
- if (argumentType !== void 0 && argument !== void 0) {
20366
- context.expectAssignable(argumentType, parameter, argument.position, `Argument ${index + 1}`);
21221
+ if (argumentType === void 0 || argument === void 0) {
21222
+ return;
20367
21223
  }
21224
+ const optional = index >= signature2.minimumArguments && parameter.kind !== "optional";
21225
+ const expected = optional ? createOptional(parameter) : parameter;
21226
+ context.expectAssignable(argumentType, expected, argument.position, `Argument ${index + 1}`, parameter);
20368
21227
  });
20369
21228
  if (signature2.isVariadic && signature2.variadicType !== void 0) {
20370
21229
  for (let index = signature2.parameters.length; index < argumentTypes.length; index += 1) {
@@ -20377,6 +21236,20 @@ function checkSignature(context, args, declared, position2, owner = "This call",
20377
21236
  }
20378
21237
  return signature2.returnType;
20379
21238
  }
21239
+ function reportClassReceiver(context, name, method, position2) {
21240
+ if (context.declarations.lookupStaticMember(name, method) !== null) {
21241
+ const message2 = `Call the static member "${method}" as "${name}.${method}(...)". A class value has no "self" to pass.`;
21242
+ context.report("check-static-receiver", message2, position2);
21243
+ return;
21244
+ }
21245
+ if (context.declarations.lookupMember(name, method) === null) {
21246
+ const message2 = `Call the static member "${method}" as "${name}.${method}(...)". A class value has no "self" to pass.`;
21247
+ context.report("check-static-receiver", message2, position2);
21248
+ return;
21249
+ }
21250
+ const message = `The receiver here is the class "${name}" itself, and "${method}" is one of its instance members. Create an instance \u2014 "local value = new ${name}()" \u2014 and call "value:${method}(...)", or read the member from a value of that class. Where the class and its single instance share one name, give the instance its own name.`;
21251
+ context.report("check-class-receiver", message, position2);
21252
+ }
20380
21253
  function callOwner(expression) {
20381
21254
  const name = expression.method ?? (expression.callee.kind === "identifier" ? expression.callee.name : null);
20382
21255
  return name === null ? "This call" : `Function "${name}"`;
@@ -20448,9 +21321,7 @@ function checkCall(context, expression) {
20448
21321
  return context.record(expression, checkSignature(context, expression.args, constructor, expression.position));
20449
21322
  }
20450
21323
  if (expression.method !== null && expression.callee.kind === "identifier" && isUserClassReference(context, expression.callee.name)) {
20451
- const name = expression.callee.name;
20452
- const message = `Call the static member "${expression.method}" as "${name}.${expression.method}(...)". A class value has no "self" to pass.`;
20453
- context.report("check-static-receiver", message, expression.position);
21324
+ reportClassReceiver(context, expression.callee.name, expression.method, expression.position);
20454
21325
  checkValueList(context, expression.args);
20455
21326
  return context.record(expression, ANY_TYPE);
20456
21327
  }
@@ -20529,6 +21400,8 @@ function checkMultiValueExpression(context, expression, expected = null) {
20529
21400
  const symbol = context.binder.lookup(expression.name);
20530
21401
  if (symbol === null) {
20531
21402
  checkGlobalReference(context, expression.name, expression.position);
21403
+ } else {
21404
+ checkSharedReference(context, expression.name, expression.position);
20532
21405
  }
20533
21406
  if (symbol === null || symbol.isLocal !== true) {
20534
21407
  context.noteGlobalReference(expression.name);
@@ -20544,6 +21417,10 @@ function checkMultiValueExpression(context, expression, expected = null) {
20544
21417
  context.expectAssignable(indexType, objectType.key, expression.index.position, "Key");
20545
21418
  return context.record(expression, objectType.value);
20546
21419
  }
21420
+ const keyed = resolveKeyedMember(context, objectType, expression);
21421
+ if (keyed !== null) {
21422
+ return context.record(expression, keyed);
21423
+ }
20547
21424
  return context.record(expression, objectType.kind === "array" ? objectType.element : ANY_TYPE);
20548
21425
  }
20549
21426
  case "call-expression":
@@ -20573,16 +21450,12 @@ function checkExpression(context, expression, expected = null) {
20573
21450
  return firstValueOf(checkMultiValueExpression(context, expression, expected));
20574
21451
  }
20575
21452
  function checkValueList(context, values, expected = []) {
20576
- const types = [];
20577
- values.forEach((value, index) => {
21453
+ const types = values.map((value, index) => {
20578
21454
  const type = checkMultiValueExpression(context, value, expected[index] ?? null);
20579
- if (index === values.length - 1) {
20580
- types.push(...valuesOf(type));
20581
- return;
20582
- }
20583
- types.push(firstValueOf(type));
21455
+ escapesRecordObligation(context, value);
21456
+ return type;
20584
21457
  });
20585
- return types;
21458
+ return distributeValueTypes(types);
20586
21459
  }
20587
21460
 
20588
21461
  // ../compiler/src/checker/classes.ts
@@ -20591,7 +21464,7 @@ function fieldType(context, member) {
20591
21464
  if (member.annotation === null) {
20592
21465
  return valueType === null ? ANY_TYPE : widenInferred(valueType);
20593
21466
  }
20594
- const declared = context.resolveAnnotation(member.annotation);
21467
+ const declared = context.resolveValueAnnotation(member.annotation, "a field");
20595
21468
  if (valueType !== null && member.value !== null) {
20596
21469
  context.expectAssignable(valueType, declared, member.value.position, `Field "${member.name}"`);
20597
21470
  }
@@ -20685,6 +21558,7 @@ function declareBuilder(context, info, statement) {
20685
21558
  superClass: null,
20686
21559
  superArguments: [],
20687
21560
  interfaces: [],
21561
+ interfaceArguments: [],
20688
21562
  members,
20689
21563
  statics: /* @__PURE__ */ new Map(),
20690
21564
  position: statement.position
@@ -20712,8 +21586,9 @@ function checkMethodBody(context, info, member) {
20712
21586
  context.popClassMethod();
20713
21587
  }
20714
21588
  function assignSuperClass(context, info, statement) {
20715
- info.superClass = resolveSuperClass(context, statement);
20716
- info.hasUnresolvedParent = statement.superClass !== null && info.superClass === null;
21589
+ const resolved2 = resolveSuperClass(context, statement);
21590
+ info.superClass = resolved2 ?? statement.superClass;
21591
+ info.hasUnresolvedParent = statement.superClass !== null && resolved2 === null;
20717
21592
  }
20718
21593
  function resolveSuperClass(context, statement) {
20719
21594
  if (statement.superClass === null) {
@@ -20755,6 +21630,7 @@ function declareClassInfo(context, statement) {
20755
21630
  superClass: null,
20756
21631
  superArguments: [],
20757
21632
  interfaces: statement.interfaces,
21633
+ interfaceArguments: statement.interfaceArguments.map((args) => args.map((argument) => context.resolveAnnotation(argument))),
20758
21634
  members: /* @__PURE__ */ new Map(),
20759
21635
  statics: /* @__PURE__ */ new Map(),
20760
21636
  position: statement.position
@@ -20793,6 +21669,7 @@ function checkInterfaceDeclaration(context, statement) {
20793
21669
  context.report("check-duplicate-interface", `Interface "${statement.name}" is already defined.`, statement.position);
20794
21670
  return;
20795
21671
  }
21672
+ context.noteTypeParameters(statement.typeParameters);
20796
21673
  const members = /* @__PURE__ */ new Map();
20797
21674
  for (const name of new Set(statement.superInterfaces)) {
20798
21675
  const parent = context.declarations.lookupInterface(name);
@@ -20809,7 +21686,7 @@ function checkInterfaceDeclaration(context, statement) {
20809
21686
  context.report("check-duplicate-interface-parent", `Interface "${statement.name}" extends the same interface more than once.`, statement.position);
20810
21687
  }
20811
21688
  for (const member of statement.members) {
20812
- const type = member.kind === "interface-field" ? context.resolveAnnotation(member.annotation) : buildFunctionType(context, member.parameters, member.returnAnnotation);
21689
+ const type = member.kind === "interface-field" ? context.resolveValueAnnotation(member.annotation, "a member") : buildFunctionType(context, member.parameters, member.returnAnnotation);
20813
21690
  const info = { name: member.name, type, isMethod: member.kind === "interface-method", position: member.position };
20814
21691
  if (members.has(member.name)) {
20815
21692
  context.report("check-duplicate-interface-member", `Interface "${statement.name}" declares member "${member.name}" more than once.`, member.position);
@@ -20830,6 +21707,8 @@ function checkInterfaceDeclaration(context, statement) {
20830
21707
  }
20831
21708
  context.declarations.declareInterface({
20832
21709
  name: statement.name,
21710
+ typeParameters: statement.typeParameters,
21711
+ typeConstraints: statement.typeConstraints.map((constraint) => constraint === null ? null : context.resolveAnnotation(constraint)),
20833
21712
  superInterfaces: statement.superInterfaces,
20834
21713
  members,
20835
21714
  position: statement.position
@@ -20952,12 +21831,14 @@ function check(program2, mode, environment = DEFAULT_ENVIRONMENT, options = {})
20952
21831
  const ambient = options.ambient ?? EMPTY_AMBIENT;
20953
21832
  const project = options.project ?? EMPTY_PROJECT_DECLARATIONS;
20954
21833
  const context = new CheckContext(mode, environment, ambient, project, options.oop === true);
21834
+ context.noImplicitGlobals = options.noImplicitGlobals === true;
20955
21835
  context.isDeclarationFile = options.isDeclarationFile === true;
20956
21836
  context.contracts = options.contracts ?? [];
20957
21837
  const structure = context.isDeclarationFile ? checkDeclarationFile(program2.body) : checkJumps(program2.body);
20958
21838
  const directives = collectDirectives(program2.body, { isDeclarationFile: context.isDeclarationFile });
20959
21839
  predeclareModule(context, program2.body);
20960
21840
  checkStatements(context, program2.body);
21841
+ settleRecordObligations(context, /* @__PURE__ */ new Set());
20961
21842
  reportUnknownTypes(context);
20962
21843
  reportUnusedSymbols(context, options.noUnusedLocals === true, options.noUnusedParameters === true);
20963
21844
  const external = externalReferences(context);
@@ -21330,13 +22211,17 @@ function emitExpression(state, expression, limit = 0) {
21330
22211
  }
21331
22212
 
21332
22213
  // ../compiler/src/emitter/classes.ts
22214
+ var BARE_KEY = /^[A-Za-z_][A-Za-z0-9_]*$/;
22215
+ function emitMemberKey(name) {
22216
+ return BARE_KEY.test(name) ? name : `[${emitString(name)}]`;
22217
+ }
21333
22218
  function emitMethod(state, className, member) {
21334
22219
  const self = { name: "self", annotation: null, isVararg: false, position: member.position };
21335
22220
  if (member.generated !== void 0) {
21336
22221
  return emitGeneratedMethod(state, className, member);
21337
22222
  }
21338
22223
  const parameters = member.isStatic ? member.parameters : [self, ...member.parameters];
21339
- return withSymbol(state, `${className}${member.isStatic ? "." : ":"}${member.name}`, () => emitFunctionBody(state, parameters, member.body, `${member.name} = function`));
22224
+ return withSymbol(state, `${className}${member.isStatic ? "." : ":"}${member.name}`, () => emitFunctionBody(state, parameters, member.body, `${emitMemberKey(member.name)} = function`));
21340
22225
  }
21341
22226
  function emitGeneratedMethod(state, className, member) {
21342
22227
  const fields = member.generated?.fields ?? [];
@@ -21422,7 +22307,7 @@ function emitMembers(state, statement) {
21422
22307
  continue;
21423
22308
  }
21424
22309
  const value = member.value === null ? "nil" : emitExpression(state, member.value);
21425
- entries3.push(indentLine(state, `${markSource(state, member.position.line, statement.name)}${member.name} = ${value}`));
22310
+ entries3.push(indentLine(state, `${markSource(state, member.position.line, statement.name)}${emitMemberKey(member.name)} = ${value}`));
21426
22311
  }
21427
22312
  for (const generated of state.generatedMembers.get(statement) ?? []) {
21428
22313
  entries3.push(indentLine(state, `${markSource(state, generated.position.line, `${statement.name}:${generated.name}`)}${emitMethod(state, statement.name, generated)}`));
@@ -21615,6 +22500,8 @@ function emitStatement(state, statement) {
21615
22500
  return emitLocal(state, statement);
21616
22501
  case "assignment-statement":
21617
22502
  return emitAssignment(state, statement);
22503
+ case "global-statement":
22504
+ return `${statement.declaration.name} = ${statement.values.map((value) => emitExpression(state, value)).join(", ")}`;
21618
22505
  case "call-statement":
21619
22506
  return emitExpression(state, statement.expression);
21620
22507
  case "function-declaration":
@@ -21822,6 +22709,9 @@ function nestedBlocks(statement) {
21822
22709
  case "assignment-statement":
21823
22710
  fromExpressions([...statement.targets, ...statement.values], blocks);
21824
22711
  break;
22712
+ case "global-statement":
22713
+ fromExpressions(statement.values, blocks);
22714
+ break;
21825
22715
  case "call-statement":
21826
22716
  fromExpression(statement.expression, blocks);
21827
22717
  break;
@@ -22513,6 +23403,7 @@ function compile(source, options = {}) {
22513
23403
  isDeclarationFile,
22514
23404
  oop: settings.oop,
22515
23405
  noUnusedLocals: settings.noUnusedLocals,
23406
+ noImplicitGlobals: settings.noImplicitGlobals,
22516
23407
  noUnusedParameters: settings.noUnusedParameters
22517
23408
  });
22518
23409
  const diagnostics = sortDiagnostics([...parsed.diagnostics, ...resolved2.diagnostics, ...checked.diagnostics]);
@@ -22756,11 +23647,12 @@ function createDependencyGraph(nodes) {
22756
23647
 
22757
23648
  // ../compiler/src/project/ambient-scope.ts
22758
23649
  function optionsKey(options) {
22759
- return `${options.strict ? "strict" : ""}|${options.oop ? "oop" : ""}|${options.noUnusedLocals ? "nul" : ""}|${options.noUnusedParameters ? "nup" : ""}`;
23650
+ const flags = [options.strict ? "strict" : "", options.oop ? "oop" : "", options.noUnusedLocals ? "nul" : "", options.noUnusedParameters ? "nup" : ""];
23651
+ return `${flags.join("|")}|${options.noImplicitGlobals ? "nig" : ""}`;
22760
23652
  }
22761
23653
  function declaresNothing(declarations) {
22762
- const { classes, interfaces, enums, globals, events } = declarations;
22763
- return classes.length === 0 && interfaces.length === 0 && enums.length === 0 && globals.length === 0 && events.length === 0;
23654
+ const { classes, interfaces, enums, aliases, globals, events } = declarations;
23655
+ return classes.length === 0 && interfaces.length === 0 && enums.length === 0 && aliases.length === 0 && globals.length === 0 && events.length === 0;
22764
23656
  }
22765
23657
  function sharedEnums(collected) {
22766
23658
  const declared = new Set(collected.flatMap((entry) => entry.declarations.enums.map((enumeration) => enumeration.name)));