@thigasdevelopment/luam 0.19.0 → 0.19.1
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.
- package/README.md +3 -3
- package/lua/class.lua +1 -1
- package/luam.mjs +211 -89
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -275,12 +275,12 @@ VSCodium and Windsurf. The language server itself is editor-agnostic and speaks
|
|
|
275
275
|
|
|
276
276
|
## Known limitations
|
|
277
277
|
|
|
278
|
-
- **Narrowing
|
|
279
|
-
|
|
278
|
+
- **Narrowing follows a path, not an alias.** `if self.value ~= nil then` refines
|
|
279
|
+
the field inside the block; storing the test in a variable does not carry it.
|
|
280
280
|
- **A class is a type everywhere, a value from its declaration** — `extends` may
|
|
281
281
|
name a parent written further down, a top-level `new` may not.
|
|
282
282
|
- **The MTA catalog can lag a release** — a newer function stays `any`.
|
|
283
|
-
- **No
|
|
283
|
+
- **No declared metamethods or generic classes.**
|
|
284
284
|
- **The editor re-checks by declaration** — a declaration change re-analyzes every
|
|
285
285
|
file that can see it, an edit inside a function body only its own file.
|
|
286
286
|
- **An export is named, never verified** against the side that calls it.
|
package/lua/class.lua
CHANGED
package/luam.mjs
CHANGED
|
@@ -4521,7 +4521,7 @@ function parseDecorators(stream) {
|
|
|
4521
4521
|
}
|
|
4522
4522
|
return decorators;
|
|
4523
4523
|
}
|
|
4524
|
-
function parseClassMethod(stream, token, decorators) {
|
|
4524
|
+
function parseClassMethod(stream, token, decorators, isStatic) {
|
|
4525
4525
|
stream.expect("operator", "=");
|
|
4526
4526
|
const expression = parseFunctionExpression(stream);
|
|
4527
4527
|
return {
|
|
@@ -4529,6 +4529,7 @@ function parseClassMethod(stream, token, decorators) {
|
|
|
4529
4529
|
name: token.value,
|
|
4530
4530
|
isConstructor: token.value === "constructor",
|
|
4531
4531
|
isSynthetic: false,
|
|
4532
|
+
isStatic,
|
|
4532
4533
|
parameters: expression.parameters,
|
|
4533
4534
|
returnAnnotation: expression.returnAnnotation,
|
|
4534
4535
|
body: expression.body,
|
|
@@ -4536,7 +4537,7 @@ function parseClassMethod(stream, token, decorators) {
|
|
|
4536
4537
|
position: token.position
|
|
4537
4538
|
};
|
|
4538
4539
|
}
|
|
4539
|
-
function parseBraceClassMethod(stream, token, decorators) {
|
|
4540
|
+
function parseBraceClassMethod(stream, token, decorators, isStatic) {
|
|
4540
4541
|
const parameters = parseParameters(stream);
|
|
4541
4542
|
const returnAnnotation = parseOptionalAnnotation(stream);
|
|
4542
4543
|
const body = parseBraceBlock(stream);
|
|
@@ -4545,6 +4546,7 @@ function parseBraceClassMethod(stream, token, decorators) {
|
|
|
4545
4546
|
name: token.value,
|
|
4546
4547
|
isConstructor: token.value === "constructor",
|
|
4547
4548
|
isSynthetic: false,
|
|
4549
|
+
isStatic,
|
|
4548
4550
|
parameters,
|
|
4549
4551
|
returnAnnotation,
|
|
4550
4552
|
body,
|
|
@@ -4563,20 +4565,35 @@ function expectClassFieldBoundary(stream, token) {
|
|
|
4563
4565
|
}
|
|
4564
4566
|
throw stream.error(`Expected a line break or separator after class member "${token.value}".`, "parse-unexpected-token");
|
|
4565
4567
|
}
|
|
4568
|
+
var STATIC_MODIFIER = "static";
|
|
4569
|
+
function parseStaticModifier(stream) {
|
|
4570
|
+
if (!stream.check("identifier", STATIC_MODIFIER)) {
|
|
4571
|
+
return false;
|
|
4572
|
+
}
|
|
4573
|
+
const modifier = stream.current();
|
|
4574
|
+
if (!stream.checkName(1) || stream.peek(1).position.line !== modifier.position.line) {
|
|
4575
|
+
return false;
|
|
4576
|
+
}
|
|
4577
|
+
const checkpoint = stream.checkpoint();
|
|
4578
|
+
stream.next();
|
|
4579
|
+
stream.eraseToCurrent(checkpoint);
|
|
4580
|
+
return true;
|
|
4581
|
+
}
|
|
4566
4582
|
function parseClassMember(stream) {
|
|
4567
4583
|
const decorators = parseDecorators(stream);
|
|
4584
|
+
const isStatic = parseStaticModifier(stream);
|
|
4568
4585
|
const token = stream.expectName();
|
|
4569
4586
|
if (stream.check("punctuation", "(")) {
|
|
4570
4587
|
stream.report("parse-class-method-form", `Write class member "${token.value}" as "${token.value} = function (...) ... end".`, token.position);
|
|
4571
|
-
return parseBraceClassMethod(stream, token, decorators);
|
|
4588
|
+
return parseBraceClassMethod(stream, token, decorators, isStatic);
|
|
4572
4589
|
}
|
|
4573
4590
|
if (stream.check("operator", "=") && stream.checkAhead(1, "keyword", "function")) {
|
|
4574
|
-
return parseClassMethod(stream, token, decorators);
|
|
4591
|
+
return parseClassMethod(stream, token, decorators, isStatic);
|
|
4575
4592
|
}
|
|
4576
4593
|
const annotation = parseFieldAnnotation(stream);
|
|
4577
4594
|
const value = stream.match("operator", "=") ? parseExpression(stream) : null;
|
|
4578
4595
|
expectClassFieldBoundary(stream, token);
|
|
4579
|
-
return { kind: "class-field", name: token.value, annotation, value, decorators, position: token.position };
|
|
4596
|
+
return { kind: "class-field", name: token.value, annotation, value, decorators, isStatic, position: token.position };
|
|
4580
4597
|
}
|
|
4581
4598
|
function parseClassModifiers(stream, declaration) {
|
|
4582
4599
|
while (stream.check("keyword") && CLASS_MODIFIERS.has(stream.current().value)) {
|
|
@@ -6584,7 +6601,7 @@ import { tmpdir } from "node:os";
|
|
|
6584
6601
|
import { join as join2 } from "node:path";
|
|
6585
6602
|
|
|
6586
6603
|
// src/cli/version.ts
|
|
6587
|
-
var VERSION = true ? "0.19.
|
|
6604
|
+
var VERSION = true ? "0.19.1" : "0.0.0-dev";
|
|
6588
6605
|
var PROGRAM_NAME = "luam";
|
|
6589
6606
|
var PROGRAM_DESCRIPTION = "luam \u2014 the Luam compiler for Multi Theft Auto resources.";
|
|
6590
6607
|
|
|
@@ -8455,8 +8472,8 @@ var MTA_AUDIO_CLIENT = {
|
|
|
8455
8472
|
isSoundPaused: fn([named("Element")], BOOLEAN, 1),
|
|
8456
8473
|
playSFX: fn([STRING, NUMBER, NUMBER, BOOLEAN], named("Element"), 3),
|
|
8457
8474
|
playSFX3D: fn([STRING, NUMBER, NUMBER, NUMBER, NUMBER, NUMBER, BOOLEAN], named("Element"), 6),
|
|
8458
|
-
playSound: fn([STRING, BOOLEAN, BOOLEAN], named("
|
|
8459
|
-
playSound3D: fn([STRING, NUMBER, NUMBER, NUMBER, BOOLEAN, BOOLEAN], named("
|
|
8475
|
+
playSound: fn([STRING, BOOLEAN, BOOLEAN], named("Sound"), 1),
|
|
8476
|
+
playSound3D: fn([STRING, NUMBER, NUMBER, NUMBER, BOOLEAN, BOOLEAN], named("Sound3D"), 4),
|
|
8460
8477
|
playSoundFrontEnd: fn([NUMBER], BOOLEAN, 1),
|
|
8461
8478
|
setRadioChannel: fn([NUMBER], BOOLEAN, 1),
|
|
8462
8479
|
setSoundEffectEnabled: fn(
|
|
@@ -8521,7 +8538,7 @@ var MTA_BLIP_CLIENT = {
|
|
|
8521
8538
|
var MTA_BROWSER_CLIENT = {
|
|
8522
8539
|
canBrowserNavigateBack: fn([named("Browser")], BOOLEAN, 1),
|
|
8523
8540
|
canBrowserNavigateForward: fn([named("Browser")], BOOLEAN, 1),
|
|
8524
|
-
createBrowser: fn([NUMBER, NUMBER, BOOLEAN, BOOLEAN], named("
|
|
8541
|
+
createBrowser: fn([NUMBER, NUMBER, BOOLEAN, BOOLEAN], named("Browser"), 3),
|
|
8525
8542
|
executeBrowserJavascript: fn([named("Browser"), STRING], BOOLEAN, 2),
|
|
8526
8543
|
focusBrowser: fn([named("Browser")], BOOLEAN, 1),
|
|
8527
8544
|
getBrowserProperty: fn([named("Browser"), STRING], BOOLEAN, 2),
|
|
@@ -8611,10 +8628,10 @@ var MTA_DISCORD_CLIENT = {
|
|
|
8611
8628
|
// ../mta-types/src/generated/api/mta-drawing-client.ts
|
|
8612
8629
|
var MTA_DRAWING_CLIENT = {
|
|
8613
8630
|
dxConvertPixels: fn([STRING, STRING, NUMBER], STRING, 2),
|
|
8614
|
-
dxCreateFont: fn([STRING, NUMBER, BOOLEAN, STRING], named("
|
|
8615
|
-
dxCreateRenderTarget: fn([NUMBER, NUMBER, BOOLEAN], named("
|
|
8616
|
-
dxCreateScreenSource: fn([NUMBER, NUMBER], named("
|
|
8617
|
-
dxCreateShader: fn([STRING, NUMBER, NUMBER, BOOLEAN, STRING], tupleOf([named("
|
|
8631
|
+
dxCreateFont: fn([STRING, NUMBER, BOOLEAN, STRING], named("DxFont"), 1),
|
|
8632
|
+
dxCreateRenderTarget: fn([NUMBER, NUMBER, BOOLEAN], named("DxRenderTarget"), 2),
|
|
8633
|
+
dxCreateScreenSource: fn([NUMBER, NUMBER], named("DxScreenSource"), 2),
|
|
8634
|
+
dxCreateShader: fn([STRING, NUMBER, NUMBER, BOOLEAN, STRING], tupleOf([named("DxShader"), STRING]), 1),
|
|
8618
8635
|
dxCreateTexture: fn(
|
|
8619
8636
|
[
|
|
8620
8637
|
STRING,
|
|
@@ -9232,22 +9249,22 @@ var MTA_GUI_CLIENT = {
|
|
|
9232
9249
|
guiComboBoxSetOpen: fn([named("Element"), BOOLEAN], BOOLEAN, 2),
|
|
9233
9250
|
guiComboBoxSetSelected: fn([named("Element"), NUMBER], BOOLEAN, 2),
|
|
9234
9251
|
guiCreateBrowser: fn([NUMBER, NUMBER, NUMBER, NUMBER, BOOLEAN, BOOLEAN, BOOLEAN, named("GuiElement")], named("GuiBrowser"), 6),
|
|
9235
|
-
guiCreateButton: fn([NUMBER, NUMBER, NUMBER, NUMBER, STRING, BOOLEAN, named("GuiElement")], named("
|
|
9236
|
-
guiCreateCheckBox: fn([NUMBER, NUMBER, NUMBER, NUMBER, STRING, BOOLEAN, BOOLEAN, named("GuiElement")], named("
|
|
9237
|
-
guiCreateComboBox: fn([NUMBER, NUMBER, NUMBER, NUMBER, STRING, BOOLEAN, named("GuiElement")], named("
|
|
9238
|
-
guiCreateEdit: fn([NUMBER, NUMBER, NUMBER, NUMBER, STRING, BOOLEAN, named("GuiElement")], named("
|
|
9239
|
-
guiCreateFont: fn([STRING, NUMBER], named("
|
|
9240
|
-
guiCreateGridList: fn([NUMBER, NUMBER, NUMBER, NUMBER, BOOLEAN, named("GuiElement")], named("
|
|
9241
|
-
guiCreateLabel: fn([NUMBER, NUMBER, NUMBER, NUMBER, STRING, BOOLEAN, named("GuiElement")], named("
|
|
9252
|
+
guiCreateButton: fn([NUMBER, NUMBER, NUMBER, NUMBER, STRING, BOOLEAN, named("GuiElement")], named("GuiButton"), 5),
|
|
9253
|
+
guiCreateCheckBox: fn([NUMBER, NUMBER, NUMBER, NUMBER, STRING, BOOLEAN, BOOLEAN, named("GuiElement")], named("GuiCheckbox"), 6),
|
|
9254
|
+
guiCreateComboBox: fn([NUMBER, NUMBER, NUMBER, NUMBER, STRING, BOOLEAN, named("GuiElement")], named("GuiCombobox"), 5),
|
|
9255
|
+
guiCreateEdit: fn([NUMBER, NUMBER, NUMBER, NUMBER, STRING, BOOLEAN, named("GuiElement")], named("GuiEdit"), 5),
|
|
9256
|
+
guiCreateFont: fn([STRING, NUMBER], named("GuiFont"), 1),
|
|
9257
|
+
guiCreateGridList: fn([NUMBER, NUMBER, NUMBER, NUMBER, BOOLEAN, named("GuiElement")], named("GuiGridList"), 4),
|
|
9258
|
+
guiCreateLabel: fn([NUMBER, NUMBER, NUMBER, NUMBER, STRING, BOOLEAN, named("GuiElement")], named("GuiLabel"), 5),
|
|
9242
9259
|
guiCreateMemo: fn([NUMBER, NUMBER, NUMBER, NUMBER, STRING, BOOLEAN, named("GuiElement")], named("GuiMemo"), 5),
|
|
9243
9260
|
guiCreateProgressBar: fn([NUMBER, NUMBER, NUMBER, NUMBER, BOOLEAN, named("GuiElement")], named("Element"), 4),
|
|
9244
|
-
guiCreateRadioButton: fn([NUMBER, NUMBER, NUMBER, NUMBER, STRING, BOOLEAN, named("GuiElement")], named("
|
|
9261
|
+
guiCreateRadioButton: fn([NUMBER, NUMBER, NUMBER, NUMBER, STRING, BOOLEAN, named("GuiElement")], named("GuiRadioButton"), 5),
|
|
9245
9262
|
guiCreateScrollBar: fn([NUMBER, NUMBER, NUMBER, NUMBER, BOOLEAN, BOOLEAN, named("GuiElement")], named("GuiElement"), 5),
|
|
9246
9263
|
guiCreateScrollPane: fn([NUMBER, NUMBER, NUMBER, NUMBER, BOOLEAN, named("GuiElement")], named("Element"), 4),
|
|
9247
|
-
guiCreateStaticImage: fn([NUMBER, NUMBER, NUMBER, NUMBER, STRING, BOOLEAN, named("GuiElement")], named("
|
|
9248
|
-
guiCreateTab: fn([STRING, named("GuiElement")], named("
|
|
9249
|
-
guiCreateTabPanel: fn([NUMBER, NUMBER, NUMBER, NUMBER, BOOLEAN, named("GuiElement")], named("
|
|
9250
|
-
guiCreateWindow: fn([NUMBER, NUMBER, NUMBER, NUMBER, STRING, BOOLEAN], named("
|
|
9264
|
+
guiCreateStaticImage: fn([NUMBER, NUMBER, NUMBER, NUMBER, STRING, BOOLEAN, named("GuiElement")], named("GuiStaticImage"), 5),
|
|
9265
|
+
guiCreateTab: fn([STRING, named("GuiElement")], named("GuiTab"), 2),
|
|
9266
|
+
guiCreateTabPanel: fn([NUMBER, NUMBER, NUMBER, NUMBER, BOOLEAN, named("GuiElement")], named("GuiTabPanel"), 4),
|
|
9267
|
+
guiCreateWindow: fn([NUMBER, NUMBER, NUMBER, NUMBER, STRING, BOOLEAN], named("GuiWindow"), 5),
|
|
9251
9268
|
guiDeleteTab: fn([named("Element"), named("Element")], BOOLEAN, 2),
|
|
9252
9269
|
guiEditGetCaretIndex: fn([named("Element")], NUMBER, 1),
|
|
9253
9270
|
guiEditGetMaxLength: fn([named("GuiEdit")], NUMBER, 1),
|
|
@@ -11590,7 +11607,7 @@ var MTA_OOP_1 = [
|
|
|
11590
11607
|
),
|
|
11591
11608
|
oopClass(
|
|
11592
11609
|
"DxFont",
|
|
11593
|
-
|
|
11610
|
+
"Element",
|
|
11594
11611
|
[
|
|
11595
11612
|
oopMethod("getHeight", "client", "dxGetFontHeight", fn([NUMBER, ANY], NUMBER, 0)),
|
|
11596
11613
|
oopMethod("getSize", "client", "dxGetTextSize", fn([STRING, NUMBER, NUMBER, NUMBER, ANY, BOOLEAN, BOOLEAN], tupleOf([NUMBER, NUMBER]), 1)),
|
|
@@ -11601,14 +11618,14 @@ var MTA_OOP_1 = [
|
|
|
11601
11618
|
),
|
|
11602
11619
|
oopClass(
|
|
11603
11620
|
"DxRenderTarget",
|
|
11604
|
-
|
|
11621
|
+
"Element",
|
|
11605
11622
|
[],
|
|
11606
11623
|
[],
|
|
11607
11624
|
oopConstructor("client", fn([NUMBER, NUMBER, BOOLEAN], named("DxRenderTarget"), 2), "dxCreateRenderTarget")
|
|
11608
11625
|
),
|
|
11609
11626
|
oopClass(
|
|
11610
11627
|
"DxScreenSource",
|
|
11611
|
-
|
|
11628
|
+
"Element",
|
|
11612
11629
|
[
|
|
11613
11630
|
oopMethod("update", "client", "dxUpdateScreenSource", fn([BOOLEAN], BOOLEAN, 0))
|
|
11614
11631
|
],
|
|
@@ -11621,14 +11638,14 @@ var MTA_OOP_1 = [
|
|
|
11621
11638
|
var MTA_OOP_2 = [
|
|
11622
11639
|
oopClass(
|
|
11623
11640
|
"DxShader",
|
|
11624
|
-
|
|
11641
|
+
"Element",
|
|
11625
11642
|
[],
|
|
11626
11643
|
[],
|
|
11627
11644
|
oopConstructor("client", fn([STRING, NUMBER, NUMBER, BOOLEAN, STRING], named("DxShader"), 1), "dxCreateShader")
|
|
11628
11645
|
),
|
|
11629
11646
|
oopClass(
|
|
11630
11647
|
"DxTexture",
|
|
11631
|
-
|
|
11648
|
+
"Element",
|
|
11632
11649
|
[
|
|
11633
11650
|
oopMethod("getPixels", "client", "dxGetTexturePixels", fn([ANY, ANY, NUMBER, NUMBER, NUMBER, ANY], STRING, 1)),
|
|
11634
11651
|
oopMethod("setEdge", "client", "dxSetTextureEdge", fn([STRING, NUMBER], BOOLEAN, 1)),
|
|
@@ -11917,7 +11934,7 @@ var MTA_OOP_3 = [
|
|
|
11917
11934
|
),
|
|
11918
11935
|
oopClass(
|
|
11919
11936
|
"GuiButton",
|
|
11920
|
-
|
|
11937
|
+
"GuiElement",
|
|
11921
11938
|
[],
|
|
11922
11939
|
[],
|
|
11923
11940
|
oopConstructor("client", fn([NUMBER, NUMBER, NUMBER, NUMBER, STRING, BOOLEAN, named("Element")], named("GuiButton"), 6), "guiCreateButton")
|
|
@@ -11974,7 +11991,7 @@ var MTA_OOP_3 = [
|
|
|
11974
11991
|
),
|
|
11975
11992
|
oopClass(
|
|
11976
11993
|
"GuiElement",
|
|
11977
|
-
|
|
11994
|
+
"Element",
|
|
11978
11995
|
[
|
|
11979
11996
|
oopProperty("alpha", "client", "guiGetAlpha", NUMBER),
|
|
11980
11997
|
oopMethod("blur", "client", "guiBlur", fn([], BOOLEAN, 0)),
|
|
@@ -12027,7 +12044,7 @@ var MTA_OOP_3 = [
|
|
|
12027
12044
|
),
|
|
12028
12045
|
oopClass(
|
|
12029
12046
|
"GuiFont",
|
|
12030
|
-
|
|
12047
|
+
"Element",
|
|
12031
12048
|
[],
|
|
12032
12049
|
[],
|
|
12033
12050
|
oopConstructor("client", fn([STRING, NUMBER], named("GuiFont"), 1), "guiCreateFont")
|
|
@@ -12115,7 +12132,7 @@ var MTA_OOP_3 = [
|
|
|
12115
12132
|
),
|
|
12116
12133
|
oopClass(
|
|
12117
12134
|
"GuiRadioButton",
|
|
12118
|
-
|
|
12135
|
+
"GuiElement",
|
|
12119
12136
|
[
|
|
12120
12137
|
oopMethod("getSelected", "client", "guiRadioButtonGetSelected", fn([], BOOLEAN, 0)),
|
|
12121
12138
|
oopProperty("selected", "client", "guiRadioButtonGetSelected", BOOLEAN),
|
|
@@ -12176,7 +12193,7 @@ var MTA_OOP_4 = [
|
|
|
12176
12193
|
),
|
|
12177
12194
|
oopClass(
|
|
12178
12195
|
"Light",
|
|
12179
|
-
|
|
12196
|
+
"Element",
|
|
12180
12197
|
[
|
|
12181
12198
|
oopProperty("color", "client", "getLightColor", tupleOf([NUMBER, NUMBER, NUMBER])),
|
|
12182
12199
|
oopProperty("direction", "client", "getLightDirection", tupleOf([NUMBER, NUMBER, NUMBER])),
|
|
@@ -13186,6 +13203,34 @@ var DeclarationRegistry = class {
|
|
|
13186
13203
|
}
|
|
13187
13204
|
return null;
|
|
13188
13205
|
}
|
|
13206
|
+
lookupStaticMember(name, member) {
|
|
13207
|
+
const visited = /* @__PURE__ */ new Set();
|
|
13208
|
+
let current = this.lookupClass(name);
|
|
13209
|
+
while (current !== null && !visited.has(current.name)) {
|
|
13210
|
+
const found = current.statics.get(member);
|
|
13211
|
+
if (found !== void 0) {
|
|
13212
|
+
return found;
|
|
13213
|
+
}
|
|
13214
|
+
visited.add(current.name);
|
|
13215
|
+
current = current.superClass === null ? null : this.lookupClass(current.superClass);
|
|
13216
|
+
}
|
|
13217
|
+
return null;
|
|
13218
|
+
}
|
|
13219
|
+
collectStatics(name) {
|
|
13220
|
+
const collected = /* @__PURE__ */ new Map();
|
|
13221
|
+
const visited = /* @__PURE__ */ new Set();
|
|
13222
|
+
let current = this.lookupClass(name);
|
|
13223
|
+
while (current !== null && !visited.has(current.name)) {
|
|
13224
|
+
for (const [member, info] of current.statics) {
|
|
13225
|
+
if (!collected.has(member)) {
|
|
13226
|
+
collected.set(member, info);
|
|
13227
|
+
}
|
|
13228
|
+
}
|
|
13229
|
+
visited.add(current.name);
|
|
13230
|
+
current = current.superClass === null ? null : this.lookupClass(current.superClass);
|
|
13231
|
+
}
|
|
13232
|
+
return [...collected.values()];
|
|
13233
|
+
}
|
|
13189
13234
|
lookupMember(name, member) {
|
|
13190
13235
|
const visited = /* @__PURE__ */ new Set();
|
|
13191
13236
|
const found = this.lookupClassMember(name, member, visited);
|
|
@@ -13217,7 +13262,7 @@ function buildRegistry() {
|
|
|
13217
13262
|
procedural: member.procedural
|
|
13218
13263
|
});
|
|
13219
13264
|
}
|
|
13220
|
-
registry.declareClass({ name: declaration.name, superClass: declaration.parent, interfaces: [], members, position: MTA_POSITION });
|
|
13265
|
+
registry.declareClass({ name: declaration.name, superClass: declaration.parent, interfaces: [], members, statics: /* @__PURE__ */ new Map(), position: MTA_POSITION });
|
|
13221
13266
|
}
|
|
13222
13267
|
return registry;
|
|
13223
13268
|
}
|
|
@@ -13424,6 +13469,7 @@ var CheckContext = class {
|
|
|
13424
13469
|
externalReferences = /* @__PURE__ */ new Map();
|
|
13425
13470
|
unknownTypes = /* @__PURE__ */ new Map();
|
|
13426
13471
|
calledMembers = /* @__PURE__ */ new Set();
|
|
13472
|
+
staticAccess = /* @__PURE__ */ new Set();
|
|
13427
13473
|
typeParameters = /* @__PURE__ */ new Set();
|
|
13428
13474
|
generatedMembers = /* @__PURE__ */ new Map();
|
|
13429
13475
|
mode;
|
|
@@ -13490,20 +13536,20 @@ var CheckContext = class {
|
|
|
13490
13536
|
this.predeclared.delete(name);
|
|
13491
13537
|
return info;
|
|
13492
13538
|
}
|
|
13493
|
-
|
|
13494
|
-
return this.predeclared.has(name);
|
|
13495
|
-
}
|
|
13496
|
-
awaitsDeclaration(name) {
|
|
13539
|
+
pendingDeclarationOf(name) {
|
|
13497
13540
|
const seen = /* @__PURE__ */ new Set();
|
|
13498
13541
|
let current = this.declarations.lookupClass(name);
|
|
13499
13542
|
while (current !== null && !seen.has(current.name)) {
|
|
13500
13543
|
if (this.predeclared.has(current.name)) {
|
|
13501
|
-
return
|
|
13544
|
+
return current.name;
|
|
13502
13545
|
}
|
|
13503
13546
|
seen.add(current.name);
|
|
13504
13547
|
current = current.superClass === null ? null : this.declarations.lookupClass(current.superClass);
|
|
13505
13548
|
}
|
|
13506
|
-
return
|
|
13549
|
+
return null;
|
|
13550
|
+
}
|
|
13551
|
+
awaitsDeclaration(name) {
|
|
13552
|
+
return this.pendingDeclarationOf(name) !== null;
|
|
13507
13553
|
}
|
|
13508
13554
|
insideFunction() {
|
|
13509
13555
|
return this.returnStack.length > 0;
|
|
@@ -14163,6 +14209,7 @@ function accessorMethod(field2, decorator, name) {
|
|
|
14163
14209
|
name,
|
|
14164
14210
|
isConstructor: false,
|
|
14165
14211
|
isSynthetic: true,
|
|
14212
|
+
isStatic: false,
|
|
14166
14213
|
parameters: decorator === "Getter" ? [] : [value],
|
|
14167
14214
|
returnAnnotation: decorator === "Getter" ? field2.annotation : voidAnnotation,
|
|
14168
14215
|
body,
|
|
@@ -14171,7 +14218,7 @@ function accessorMethod(field2, decorator, name) {
|
|
|
14171
14218
|
};
|
|
14172
14219
|
}
|
|
14173
14220
|
function generatedMethod(field2, name, parameters, returnAnnotation, kind, fields) {
|
|
14174
|
-
return { kind: "class-method", name, isConstructor: false, isSynthetic: true, parameters, returnAnnotation, body: [], decorators: [], generated: { kind, fields }, position: field2.position };
|
|
14221
|
+
return { kind: "class-method", name, isConstructor: false, isSynthetic: true, isStatic: false, parameters, returnAnnotation, body: [], decorators: [], generated: { kind, fields }, position: field2.position };
|
|
14175
14222
|
}
|
|
14176
14223
|
function typeName(name, node) {
|
|
14177
14224
|
return { kind: "type-name", name, typeArguments: [], position: node.position };
|
|
@@ -17731,11 +17778,11 @@ var ELEMENT_TYPES = [
|
|
|
17731
17778
|
{ name: "Camera", parent: "Element" },
|
|
17732
17779
|
{ name: "ColShape", parent: "Element" },
|
|
17733
17780
|
{ name: "Connection", parent: null },
|
|
17734
|
-
{ name: "DxFont", parent:
|
|
17735
|
-
{ name: "DxRenderTarget", parent:
|
|
17736
|
-
{ name: "DxScreenSource", parent:
|
|
17737
|
-
{ name: "DxShader", parent:
|
|
17738
|
-
{ name: "DxTexture", parent:
|
|
17781
|
+
{ name: "DxFont", parent: "Element" },
|
|
17782
|
+
{ name: "DxRenderTarget", parent: "Element" },
|
|
17783
|
+
{ name: "DxScreenSource", parent: "Element" },
|
|
17784
|
+
{ name: "DxShader", parent: "Element" },
|
|
17785
|
+
{ name: "DxTexture", parent: "Element" },
|
|
17739
17786
|
{ name: "Effect", parent: "Element" },
|
|
17740
17787
|
{ name: "Element", parent: null },
|
|
17741
17788
|
{ name: "Engine", parent: null },
|
|
@@ -17744,21 +17791,21 @@ var ELEMENT_TYPES = [
|
|
|
17744
17791
|
{ name: "EngineTXD", parent: null },
|
|
17745
17792
|
{ name: "File", parent: null },
|
|
17746
17793
|
{ name: "GuiBrowser", parent: "GuiElement" },
|
|
17747
|
-
{ name: "GuiButton", parent:
|
|
17794
|
+
{ name: "GuiButton", parent: "GuiElement" },
|
|
17748
17795
|
{ name: "GuiCheckbox", parent: "GuiElement" },
|
|
17749
17796
|
{ name: "GuiCombobox", parent: "GuiElement" },
|
|
17750
17797
|
{ name: "GuiEdit", parent: "GuiElement" },
|
|
17751
|
-
{ name: "GuiElement", parent:
|
|
17752
|
-
{ name: "GuiFont", parent:
|
|
17798
|
+
{ name: "GuiElement", parent: "Element" },
|
|
17799
|
+
{ name: "GuiFont", parent: "Element" },
|
|
17753
17800
|
{ name: "GuiGridList", parent: "GuiElement" },
|
|
17754
17801
|
{ name: "GuiLabel", parent: "GuiElement" },
|
|
17755
17802
|
{ name: "GuiMemo", parent: "GuiElement" },
|
|
17756
|
-
{ name: "GuiRadioButton", parent:
|
|
17803
|
+
{ name: "GuiRadioButton", parent: "GuiElement" },
|
|
17757
17804
|
{ name: "GuiStaticImage", parent: "GuiElement" },
|
|
17758
17805
|
{ name: "GuiTab", parent: "GuiElement" },
|
|
17759
17806
|
{ name: "GuiTabPanel", parent: "GuiElement" },
|
|
17760
17807
|
{ name: "GuiWindow", parent: "GuiElement" },
|
|
17761
|
-
{ name: "Light", parent:
|
|
17808
|
+
{ name: "Light", parent: "Element" },
|
|
17762
17809
|
{ name: "Marker", parent: "Element" },
|
|
17763
17810
|
{ name: "Material", parent: "Element" },
|
|
17764
17811
|
{ name: "Object", parent: "Element" },
|
|
@@ -17914,6 +17961,28 @@ function checkInterfaceMember(context, name, members, expression) {
|
|
|
17914
17961
|
context.report("check-unknown-member", `Interface "${name}" has no member "${expression.property}". Declared members: ${keys}.`, expression.position);
|
|
17915
17962
|
return ANY_TYPE;
|
|
17916
17963
|
}
|
|
17964
|
+
function isUserClassReference(context, name) {
|
|
17965
|
+
const symbol = context.binder.lookup(name);
|
|
17966
|
+
return symbol !== null && !symbol.isLocal && context.declarations.lookupClass(name) !== null;
|
|
17967
|
+
}
|
|
17968
|
+
function resolveStaticMember(context, className, expression) {
|
|
17969
|
+
const member = context.declarations.lookupStaticMember(className, expression.property);
|
|
17970
|
+
if (member !== null) {
|
|
17971
|
+
if (member.deprecated === true) {
|
|
17972
|
+
context.warn("check-deprecated-use", `Member "${expression.property}" is deprecated.`, expression.position);
|
|
17973
|
+
}
|
|
17974
|
+
context.staticAccess.add(expression);
|
|
17975
|
+
return member.type;
|
|
17976
|
+
}
|
|
17977
|
+
if (context.awaitsDeclaration(className)) {
|
|
17978
|
+
context.staticAccess.add(expression);
|
|
17979
|
+
return ANY_TYPE;
|
|
17980
|
+
}
|
|
17981
|
+
const instance = context.declarations.lookupMember(className, expression.property);
|
|
17982
|
+
const hint = instance === null ? "" : ` It is an instance member, so read it from a value of "${className}".`;
|
|
17983
|
+
context.report("check-unknown-member", `Class "${className}" has no static member "${expression.property}".${hint}`, expression.position);
|
|
17984
|
+
return ANY_TYPE;
|
|
17985
|
+
}
|
|
17917
17986
|
function resolveNamedMember(context, name, expression) {
|
|
17918
17987
|
const enumeration = context.declarations.lookupEnum(name);
|
|
17919
17988
|
if (enumeration !== null) {
|
|
@@ -17929,6 +17998,12 @@ function resolveNamedMember(context, name, expression) {
|
|
|
17929
17998
|
if (isMtaElement(context, name)) {
|
|
17930
17999
|
return resolveMtaMember(context, name, expression.property, expression.position)?.type ?? ANY_TYPE;
|
|
17931
18000
|
}
|
|
18001
|
+
const staticMember = context.declarations.lookupStaticMember(name, expression.property);
|
|
18002
|
+
if (staticMember !== null) {
|
|
18003
|
+
const message = `"${expression.property}" is a static member of class "${name}". Read it as "${name}.${expression.property}".`;
|
|
18004
|
+
context.report("check-static-receiver", message, expression.position);
|
|
18005
|
+
return staticMember.type;
|
|
18006
|
+
}
|
|
17932
18007
|
if (context.awaitsDeclaration(name)) {
|
|
17933
18008
|
return ANY_TYPE;
|
|
17934
18009
|
}
|
|
@@ -17961,9 +18036,10 @@ function checkNewExpression(context, expression) {
|
|
|
17961
18036
|
context.report("check-unknown-class", `Class "${expression.className}" is not defined.`, expression.position);
|
|
17962
18037
|
return ANY_TYPE;
|
|
17963
18038
|
}
|
|
17964
|
-
|
|
17965
|
-
|
|
17966
|
-
|
|
18039
|
+
const pending = context.insideFunction() ? null : context.pendingDeclarationOf(expression.className);
|
|
18040
|
+
if (pending !== null) {
|
|
18041
|
+
const subject = pending === expression.className ? `Class "${pending}"` : `Class "${expression.className}" extends "${pending}", which`;
|
|
18042
|
+
context.report("check-class-before-declaration", `${subject} is declared further down this file, so it does not exist yet at this point.`, expression.position);
|
|
17967
18043
|
}
|
|
17968
18044
|
const constructor = context.declarations.lookupMember(expression.className, "constructor");
|
|
17969
18045
|
if (constructor !== null && constructor.type.kind === "function") {
|
|
@@ -18681,6 +18757,10 @@ function checkMember(context, expression) {
|
|
|
18681
18757
|
checkExpression(context, expression.object);
|
|
18682
18758
|
return context.record(expression, narrowed);
|
|
18683
18759
|
}
|
|
18760
|
+
if (expression.object.kind === "identifier" && isUserClassReference(context, expression.object.name)) {
|
|
18761
|
+
context.references.add(expression.object.name);
|
|
18762
|
+
return context.record(expression, resolveStaticMember(context, expression.object.name, expression));
|
|
18763
|
+
}
|
|
18684
18764
|
if (expression.object.kind === "identifier" && isMtaClassReference(context, expression.object.name)) {
|
|
18685
18765
|
context.references.add(expression.object.name);
|
|
18686
18766
|
return context.record(expression, resolveMtaStaticMember(context, expression.object.name, expression.property, expression.position)?.type ?? ANY_TYPE);
|
|
@@ -18804,6 +18884,13 @@ function checkCall(context, expression) {
|
|
|
18804
18884
|
}
|
|
18805
18885
|
return context.record(expression, checkSignature(context, expression.args, constructor, expression.position));
|
|
18806
18886
|
}
|
|
18887
|
+
if (expression.method !== null && expression.callee.kind === "identifier" && isUserClassReference(context, expression.callee.name)) {
|
|
18888
|
+
const name = expression.callee.name;
|
|
18889
|
+
const message = `Call the static member "${expression.method}" as "${name}.${expression.method}(...)". A class value has no "self" to pass.`;
|
|
18890
|
+
context.report("check-static-receiver", message, expression.position);
|
|
18891
|
+
checkValueList(context, expression.args);
|
|
18892
|
+
return context.record(expression, ANY_TYPE);
|
|
18893
|
+
}
|
|
18807
18894
|
if (expression.method === null) {
|
|
18808
18895
|
context.calledMembers.add(expression.callee);
|
|
18809
18896
|
}
|
|
@@ -18960,6 +19047,26 @@ function syntheticMethodType(context, member, fieldTypes) {
|
|
|
18960
19047
|
}
|
|
18961
19048
|
return buildFunctionType(context, member.parameters, member.returnAnnotation);
|
|
18962
19049
|
}
|
|
19050
|
+
function checkMemberSpaces(context, info, statement) {
|
|
19051
|
+
for (const member of statement.members) {
|
|
19052
|
+
if (member.isStatic && info.members.has(member.name)) {
|
|
19053
|
+
context.report("check-duplicate-class-member", `Class "${info.name}" declares "${member.name}" as both a static and an instance member.`, member.position);
|
|
19054
|
+
}
|
|
19055
|
+
if (!member.isStatic || info.superClass === null) {
|
|
19056
|
+
continue;
|
|
19057
|
+
}
|
|
19058
|
+
const inherited = context.declarations.lookupStaticMember(info.superClass, member.name);
|
|
19059
|
+
const declared = info.statics.get(member.name);
|
|
19060
|
+
if (inherited === void 0 || inherited === null || declared === void 0) {
|
|
19061
|
+
continue;
|
|
19062
|
+
}
|
|
19063
|
+
const options = { allowNil: context.allowNil };
|
|
19064
|
+
if (!isAssignable(declared.type, inherited.type, options) || !isAssignable(inherited.type, declared.type, options)) {
|
|
19065
|
+
const message = `Static member "${member.name}" must match "${typeToString(inherited.type)}" declared by class "${info.superClass}".`;
|
|
19066
|
+
context.report("check-invalid-override", message, member.position);
|
|
19067
|
+
}
|
|
19068
|
+
}
|
|
19069
|
+
}
|
|
18963
19070
|
function registerMembers(context, info, statement) {
|
|
18964
19071
|
const fieldTypes = /* @__PURE__ */ new Map();
|
|
18965
19072
|
for (const member of statement.members) {
|
|
@@ -18972,7 +19079,8 @@ function registerMembers(context, info, statement) {
|
|
|
18972
19079
|
for (const member of [...statement.members, ...generated]) {
|
|
18973
19080
|
const type = member.kind === "class-field" ? fieldTypes.get(member) ?? ANY_TYPE : member.isSynthetic ? syntheticMethodType(context, member, fieldTypes) : buildFunctionType(context, member.parameters, member.returnAnnotation);
|
|
18974
19081
|
const decorators = member.decorators.map((decorator) => decorator.name);
|
|
18975
|
-
info.members
|
|
19082
|
+
const space = member.isStatic ? info.statics : info.members;
|
|
19083
|
+
space.set(member.name, {
|
|
18976
19084
|
name: member.name,
|
|
18977
19085
|
type,
|
|
18978
19086
|
isMethod: member.kind === "class-method",
|
|
@@ -18981,6 +19089,7 @@ function registerMembers(context, info, statement) {
|
|
|
18981
19089
|
deprecated: decorators.includes("Deprecated")
|
|
18982
19090
|
});
|
|
18983
19091
|
}
|
|
19092
|
+
checkMemberSpaces(context, info, statement);
|
|
18984
19093
|
return generated;
|
|
18985
19094
|
}
|
|
18986
19095
|
function declareBuilder(context, info, statement) {
|
|
@@ -18997,7 +19106,7 @@ function declareBuilder(context, info, statement) {
|
|
|
18997
19106
|
}
|
|
18998
19107
|
}
|
|
18999
19108
|
members.set("build", { name: "build", type: { kind: "function", parameters: [], minimumArguments: 0, isVariadic: false, returnType: createNamed(statement.name) }, isMethod: true, position: statement.position });
|
|
19000
|
-
context.declarations.declareClass({ name, superClass: null, interfaces: [], members, position: statement.position });
|
|
19109
|
+
context.declarations.declareClass({ name, superClass: null, interfaces: [], members, statics: /* @__PURE__ */ new Map(), position: statement.position });
|
|
19001
19110
|
context.declareModuleGlobal({ name, type: createNamed(name), isLocal: false, position: statement.position });
|
|
19002
19111
|
}
|
|
19003
19112
|
function checkMethodBody(context, info, member) {
|
|
@@ -19005,10 +19114,14 @@ function checkMethodBody(context, info, member) {
|
|
|
19005
19114
|
if (explicitSelf !== void 0) {
|
|
19006
19115
|
context.report("check-explicit-self-parameter", 'Class methods receive "self" automatically; remove it from the parameter list.', explicitSelf.position);
|
|
19007
19116
|
}
|
|
19008
|
-
const signature = info.members.get(member.name)?.type;
|
|
19117
|
+
const signature = (member.isStatic ? info.statics : info.members).get(member.name)?.type;
|
|
19009
19118
|
if (signature?.kind !== "function") {
|
|
19010
19119
|
return;
|
|
19011
19120
|
}
|
|
19121
|
+
if (member.isStatic) {
|
|
19122
|
+
checkFunctionBody(context, member.parameters, member.returnAnnotation, member.body, signature, null);
|
|
19123
|
+
return;
|
|
19124
|
+
}
|
|
19012
19125
|
context.pushClassMethod({ className: info.name, methodName: member.name });
|
|
19013
19126
|
checkFunctionBody(context, member.parameters, member.returnAnnotation, member.body, signature, createNamed(info.name));
|
|
19014
19127
|
context.popClassMethod();
|
|
@@ -19047,6 +19160,7 @@ function declareClassInfo(context, statement) {
|
|
|
19047
19160
|
superClass: null,
|
|
19048
19161
|
interfaces: statement.interfaces,
|
|
19049
19162
|
members: /* @__PURE__ */ new Map(),
|
|
19163
|
+
statics: /* @__PURE__ */ new Map(),
|
|
19050
19164
|
position: statement.position
|
|
19051
19165
|
};
|
|
19052
19166
|
context.declarations.declareClass(info);
|
|
@@ -19246,6 +19360,7 @@ function check(program2, mode, environment = DEFAULT_ENVIRONMENT, options = {})
|
|
|
19246
19360
|
diagnostics: sortDiagnostics([...structure, ...directives.diagnostics, ...context.diagnostics]),
|
|
19247
19361
|
types: context.types,
|
|
19248
19362
|
references: context.references,
|
|
19363
|
+
staticAccess: context.staticAccess,
|
|
19249
19364
|
declarations: context.declarations,
|
|
19250
19365
|
aliases: context.binder.resolvedAliases(),
|
|
19251
19366
|
declaredGlobals: context.declaredGlobals,
|
|
@@ -19362,8 +19477,8 @@ function finalizeEmission(code, markers, sourceLineOffset = 0) {
|
|
|
19362
19477
|
|
|
19363
19478
|
// ../compiler/src/emitter/state.ts
|
|
19364
19479
|
var INDENT2 = " ";
|
|
19365
|
-
function createEmitState(types, references, generatedMembers) {
|
|
19366
|
-
return { types, references, generatedMembers, helpers: /* @__PURE__ */ new Set(), indent: 0, markers: [], symbol: void 0, loopWrap: false };
|
|
19480
|
+
function createEmitState(types, references, generatedMembers, staticAccess = /* @__PURE__ */ new Set()) {
|
|
19481
|
+
return { types, references, staticAccess, generatedMembers, helpers: /* @__PURE__ */ new Set(), indent: 0, markers: [], symbol: void 0, loopWrap: false };
|
|
19367
19482
|
}
|
|
19368
19483
|
function requireHelper(state, helper) {
|
|
19369
19484
|
if (helper !== null) {
|
|
@@ -19515,6 +19630,10 @@ function emitTable(state, expression) {
|
|
|
19515
19630
|
return `{ ${fields.join(", ")} }`;
|
|
19516
19631
|
}
|
|
19517
19632
|
function emitMember(state, expression) {
|
|
19633
|
+
if (state.staticAccess.has(expression) && expression.object.kind === "identifier") {
|
|
19634
|
+
requireHelper(state, "class");
|
|
19635
|
+
return `getClass(${emitString(expression.object.name)}).${expression.property}`;
|
|
19636
|
+
}
|
|
19518
19637
|
const extension = resolvePropertyExtension(typeOf(state, expression.object), expression.property);
|
|
19519
19638
|
const object = emitExpression(state, expression.object, UNARY_PRECEDENCE);
|
|
19520
19639
|
if (extension === null) {
|
|
@@ -19609,7 +19728,8 @@ function emitMethod(state, className, member) {
|
|
|
19609
19728
|
if (member.generated !== void 0) {
|
|
19610
19729
|
return emitGeneratedMethod(state, className, member);
|
|
19611
19730
|
}
|
|
19612
|
-
|
|
19731
|
+
const parameters = member.isStatic ? member.parameters : [self, ...member.parameters];
|
|
19732
|
+
return withSymbol(state, `${className}${member.isStatic ? "." : ":"}${member.name}`, () => emitFunctionBody(state, parameters, member.body, `${member.name} = function`));
|
|
19613
19733
|
}
|
|
19614
19734
|
function emitGeneratedMethod(state, className, member) {
|
|
19615
19735
|
const fields = member.generated?.fields ?? [];
|
|
@@ -19681,7 +19801,7 @@ function emitMembers(state, statement) {
|
|
|
19681
19801
|
state.indent += 1;
|
|
19682
19802
|
for (const member of statement.members) {
|
|
19683
19803
|
if (member.kind === "class-method") {
|
|
19684
|
-
entries2.push(indentLine(state, `${markSource(state, member.position.line, `${statement.name}
|
|
19804
|
+
entries2.push(indentLine(state, `${markSource(state, member.position.line, `${statement.name}${member.isStatic ? "." : ":"}${member.name}`)}${emitMethod(state, statement.name, member)}`));
|
|
19685
19805
|
continue;
|
|
19686
19806
|
}
|
|
19687
19807
|
if (member.decorators.some((decorator) => decorator.name === "Lazy")) {
|
|
@@ -19923,8 +20043,8 @@ function emitBlock(state, statements) {
|
|
|
19923
20043
|
}
|
|
19924
20044
|
return lines;
|
|
19925
20045
|
}
|
|
19926
|
-
function emit2(program2, types, references, generatedMembers = /* @__PURE__ */ new Map(), sourceLineOffset = 0) {
|
|
19927
|
-
const state = createEmitState(types, references, generatedMembers);
|
|
20046
|
+
function emit2(program2, types, references, generatedMembers = /* @__PURE__ */ new Map(), sourceLineOffset = 0, staticAccess = /* @__PURE__ */ new Set()) {
|
|
20047
|
+
const state = createEmitState(types, references, generatedMembers, staticAccess);
|
|
19928
20048
|
const lines = emitBlock(state, program2.body);
|
|
19929
20049
|
const markedCode = lines.length === 0 ? "" : `${lines.join("\n")}
|
|
19930
20050
|
`;
|
|
@@ -20176,7 +20296,7 @@ function erasedEdit(source, span) {
|
|
|
20176
20296
|
}
|
|
20177
20297
|
function canonicalEdit(input, statement, span) {
|
|
20178
20298
|
const { source } = input;
|
|
20179
|
-
const emitted = emit2({ ...input.program, body: [statement] }, input.types, input.references, input.generatedMembers, statement.position.line - 1);
|
|
20299
|
+
const emitted = emit2({ ...input.program, body: [statement] }, input.types, input.references, input.generatedMembers, statement.position.line - 1, input.staticAccess);
|
|
20180
20300
|
const trimmed = span.end < source.length && emitted.code.endsWith("\n") ? emitted.code.slice(0, -1) : emitted.code;
|
|
20181
20301
|
if (trimmed.length === 0) {
|
|
20182
20302
|
return erasedEdit(source, span);
|
|
@@ -20211,15 +20331,16 @@ function builderClassText(input, statement) {
|
|
|
20211
20331
|
}
|
|
20212
20332
|
|
|
20213
20333
|
// ../compiler/src/emitter/preserve-guards.ts
|
|
20214
|
-
|
|
20334
|
+
var NO_STATIC_ACCESS = /* @__PURE__ */ new Set();
|
|
20335
|
+
function isPreservableExpression(expression, types, statics = NO_STATIC_ACCESS) {
|
|
20215
20336
|
switch (expression.kind) {
|
|
20216
20337
|
case "template-literal":
|
|
20217
20338
|
case "new-expression":
|
|
20218
20339
|
return false;
|
|
20219
20340
|
case "member-expression":
|
|
20220
|
-
return resolvePropertyExtension(types.get(expression.object) ?? null, expression.property) === null && isPreservableExpression(expression.object, types);
|
|
20341
|
+
return !statics.has(expression) && resolvePropertyExtension(types.get(expression.object) ?? null, expression.property) === null && isPreservableExpression(expression.object, types, statics);
|
|
20221
20342
|
case "index-expression":
|
|
20222
|
-
return isPreservableExpression(expression.object, types) && isPreservableExpression(expression.index, types);
|
|
20343
|
+
return isPreservableExpression(expression.object, types, statics) && isPreservableExpression(expression.index, types, statics);
|
|
20223
20344
|
case "call-expression":
|
|
20224
20345
|
if (expression.method === null && expression.callee.kind === "identifier" && expression.callee.name === "super") {
|
|
20225
20346
|
return false;
|
|
@@ -20227,43 +20348,43 @@ function isPreservableExpression(expression, types) {
|
|
|
20227
20348
|
if (expression.callee.kind === "member-expression" && resolveCallExtension(types.get(expression.callee.object) ?? null, expression.callee.property) !== null) {
|
|
20228
20349
|
return false;
|
|
20229
20350
|
}
|
|
20230
|
-
return isPreservableExpression(expression.callee, types) && expression.args.every((argument) => isPreservableExpression(argument, types));
|
|
20351
|
+
return isPreservableExpression(expression.callee, types, statics) && expression.args.every((argument) => isPreservableExpression(argument, types, statics));
|
|
20231
20352
|
case "table-expression":
|
|
20232
20353
|
return expression.fields.every(
|
|
20233
|
-
(field2) => (field2.key === null || isPreservableExpression(field2.key, types)) && isPreservableExpression(field2.value, types)
|
|
20354
|
+
(field2) => (field2.key === null || isPreservableExpression(field2.key, types, statics)) && isPreservableExpression(field2.value, types, statics)
|
|
20234
20355
|
);
|
|
20235
20356
|
case "binary-expression":
|
|
20236
|
-
return isPreservableExpression(expression.left, types) && isPreservableExpression(expression.right, types);
|
|
20357
|
+
return isPreservableExpression(expression.left, types, statics) && isPreservableExpression(expression.right, types, statics);
|
|
20237
20358
|
case "unary-expression":
|
|
20238
|
-
return isPreservableExpression(expression.operand, types);
|
|
20359
|
+
return isPreservableExpression(expression.operand, types, statics);
|
|
20239
20360
|
case "group-expression":
|
|
20240
|
-
return isPreservableExpression(expression.expression, types);
|
|
20361
|
+
return isPreservableExpression(expression.expression, types, statics);
|
|
20241
20362
|
default:
|
|
20242
20363
|
return true;
|
|
20243
20364
|
}
|
|
20244
20365
|
}
|
|
20245
|
-
function every(expressions, types) {
|
|
20246
|
-
return expressions.every((expression) => isPreservableExpression(expression, types));
|
|
20366
|
+
function every(expressions, types, statics) {
|
|
20367
|
+
return expressions.every((expression) => isPreservableExpression(expression, types, statics));
|
|
20247
20368
|
}
|
|
20248
|
-
function isPreservableStatement(statement, types) {
|
|
20369
|
+
function isPreservableStatement(statement, types, statics = NO_STATIC_ACCESS) {
|
|
20249
20370
|
switch (statement.kind) {
|
|
20250
20371
|
case "local-statement":
|
|
20251
|
-
return every(statement.values, types);
|
|
20372
|
+
return every(statement.values, types, statics);
|
|
20252
20373
|
case "assignment-statement":
|
|
20253
|
-
return statement.operator === "=" && every(statement.targets, types) && every(statement.values, types);
|
|
20374
|
+
return statement.operator === "=" && every(statement.targets, types, statics) && every(statement.values, types, statics);
|
|
20254
20375
|
case "call-statement":
|
|
20255
|
-
return isPreservableExpression(statement.expression, types);
|
|
20376
|
+
return isPreservableExpression(statement.expression, types, statics);
|
|
20256
20377
|
case "return-statement":
|
|
20257
|
-
return every(statement.values, types);
|
|
20378
|
+
return every(statement.values, types, statics);
|
|
20258
20379
|
case "while-statement":
|
|
20259
20380
|
case "repeat-statement":
|
|
20260
|
-
return isPreservableExpression(statement.condition, types);
|
|
20381
|
+
return isPreservableExpression(statement.condition, types, statics);
|
|
20261
20382
|
case "if-statement":
|
|
20262
|
-
return statement.clauses.every((clause) => isPreservableExpression(clause.condition, types));
|
|
20383
|
+
return statement.clauses.every((clause) => isPreservableExpression(clause.condition, types, statics));
|
|
20263
20384
|
case "numeric-for-statement":
|
|
20264
|
-
return isPreservableExpression(statement.start, types) && isPreservableExpression(statement.limit, types) && (statement.step === null || isPreservableExpression(statement.step, types));
|
|
20385
|
+
return isPreservableExpression(statement.start, types, statics) && isPreservableExpression(statement.limit, types, statics) && (statement.step === null || isPreservableExpression(statement.step, types, statics));
|
|
20265
20386
|
case "generic-for-statement":
|
|
20266
|
-
return every(statement.iterators, types);
|
|
20387
|
+
return every(statement.iterators, types, statics);
|
|
20267
20388
|
case "break-statement":
|
|
20268
20389
|
case "declare-statement":
|
|
20269
20390
|
case "do-statement":
|
|
@@ -20391,7 +20512,7 @@ function classEdits(input, statement, spans) {
|
|
|
20391
20512
|
edits.push({ start: span.start, end, replacement: isLazyField(member) ? longComment(text) : blankSpan(text) });
|
|
20392
20513
|
continue;
|
|
20393
20514
|
}
|
|
20394
|
-
if (member.kind === "class-method") {
|
|
20515
|
+
if (member.kind === "class-method" && !member.isStatic) {
|
|
20395
20516
|
const self = selfEdit(source, member, span);
|
|
20396
20517
|
if (self === null) {
|
|
20397
20518
|
return null;
|
|
@@ -20505,7 +20626,7 @@ function surgery(collector, statement) {
|
|
|
20505
20626
|
const edits2 = classEdits(input, statement, { span, members: input.spans });
|
|
20506
20627
|
return edits2 === null ? null : { edits: edits2, wrapsBody: false };
|
|
20507
20628
|
}
|
|
20508
|
-
if (loopBody(statement) === null || !isPreservableStatement(statement, input.types)) {
|
|
20629
|
+
if (loopBody(statement) === null || !isPreservableStatement(statement, input.types, input.staticAccess)) {
|
|
20509
20630
|
return null;
|
|
20510
20631
|
}
|
|
20511
20632
|
const edits = loopEdits(input, statement);
|
|
@@ -20534,7 +20655,7 @@ function visit(collector, statement, wrapped) {
|
|
|
20534
20655
|
descend(collector, statement, false, surgical.wrapsBody);
|
|
20535
20656
|
return;
|
|
20536
20657
|
}
|
|
20537
|
-
if (isPreservableStatement(statement, collector.input.types) && keepsScaffolding(statement)) {
|
|
20658
|
+
if (isPreservableStatement(statement, collector.input.types, collector.input.staticAccess) && keepsScaffolding(statement)) {
|
|
20538
20659
|
const inherited = statement.kind === "do-statement" || statement.kind === "if-statement" ? wrapped : false;
|
|
20539
20660
|
descend(collector, statement, inherited, false);
|
|
20540
20661
|
return;
|
|
@@ -20687,7 +20808,7 @@ function compile(source, options = {}) {
|
|
|
20687
20808
|
return { ...shared, code: null, requiredHelpers: [], lines: [] };
|
|
20688
20809
|
}
|
|
20689
20810
|
const references = reachedNames(checked.references, options.projectReferences);
|
|
20690
|
-
const emitted = emit2(parsed.program, checked.types, references, checked.generatedMembers);
|
|
20811
|
+
const emitted = emit2(parsed.program, checked.types, references, checked.generatedMembers, 0, checked.staticAccess);
|
|
20691
20812
|
const preserved = emitPreservingSource({
|
|
20692
20813
|
source,
|
|
20693
20814
|
program: parsed.program,
|
|
@@ -20697,6 +20818,7 @@ function compile(source, options = {}) {
|
|
|
20697
20818
|
types: checked.types,
|
|
20698
20819
|
references,
|
|
20699
20820
|
generatedMembers: checked.generatedMembers,
|
|
20821
|
+
staticAccess: checked.staticAccess,
|
|
20700
20822
|
development: options.development === true
|
|
20701
20823
|
});
|
|
20702
20824
|
const required = new Set(emitted.requiredHelpers);
|