@neocompose/cli 0.5.3 → 0.6.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.
- package/CHANGELOG.md +20 -0
- package/dist/neo.mjs +875 -176
- package/package.json +1 -1
package/dist/neo.mjs
CHANGED
|
@@ -829,6 +829,7 @@ var init_document_contracts = __esm({
|
|
|
829
829
|
"isStatic",
|
|
830
830
|
"isVirtual",
|
|
831
831
|
"isAbstract",
|
|
832
|
+
"accessModifierKind",
|
|
832
833
|
"defaultValue",
|
|
833
834
|
"extendsMemberId",
|
|
834
835
|
"system",
|
|
@@ -1185,9 +1186,29 @@ function normalizeDocumentFields(recordKind, value) {
|
|
|
1185
1186
|
}
|
|
1186
1187
|
if (current === void 0) normalized[field] = null;
|
|
1187
1188
|
}
|
|
1189
|
+
if (recordKind === "member") {
|
|
1190
|
+
normalizeTypeInfoBindings(normalized.returnTypeInfo);
|
|
1191
|
+
if (Array.isArray(normalized.argumentTypes)) {
|
|
1192
|
+
for (const argument2 of normalized.argumentTypes) {
|
|
1193
|
+
normalizeTypeInfoBindings(argument2);
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1188
1197
|
omitRedundantDeclarationOrder(recordKind, normalized);
|
|
1189
1198
|
return normalized;
|
|
1190
1199
|
}
|
|
1200
|
+
function normalizeTypeInfoBindings(value) {
|
|
1201
|
+
if (!isRecord(value)) return;
|
|
1202
|
+
const bindings = value.typeArguments;
|
|
1203
|
+
if (bindings === null || isRecord(bindings) && Object.keys(bindings).length === 0) {
|
|
1204
|
+
delete value.typeArguments;
|
|
1205
|
+
} else if (isRecord(bindings)) {
|
|
1206
|
+
for (const binding of Object.values(bindings)) {
|
|
1207
|
+
normalizeTypeInfoBindings(binding);
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
normalizeTypeInfoBindings(value.entryTypeInfo);
|
|
1211
|
+
}
|
|
1191
1212
|
function memberDefaultApplies(field, type) {
|
|
1192
1213
|
if (field === "isVirtual" || field === "isAbstract" || field === "locked" || field === "required") {
|
|
1193
1214
|
return true;
|
|
@@ -1508,6 +1529,11 @@ function memberFromDocument(record3, members, owners, classNames, context) {
|
|
|
1508
1529
|
owner: owners.get(record3.recordId) ?? { kind: "loose" },
|
|
1509
1530
|
name: requiredString(data, "name", record3),
|
|
1510
1531
|
isStatic: booleanValue(data.isStatic, record3, "isStatic"),
|
|
1532
|
+
accessModifier: accessModifierValue(
|
|
1533
|
+
data.accessModifierKind,
|
|
1534
|
+
record3,
|
|
1535
|
+
"accessModifierKind"
|
|
1536
|
+
),
|
|
1511
1537
|
modifier,
|
|
1512
1538
|
locked: booleanValue(field("locked", false), record3, "locked"),
|
|
1513
1539
|
required: booleanValue(field("required", false), record3, "required"),
|
|
@@ -1750,7 +1776,8 @@ function memberToDocumentFields(member, baseData3) {
|
|
|
1750
1776
|
kind,
|
|
1751
1777
|
locked: member.locked,
|
|
1752
1778
|
required: member.required,
|
|
1753
|
-
isStatic: member.isStatic
|
|
1779
|
+
isStatic: member.isStatic,
|
|
1780
|
+
accessModifierKind: member.accessModifier
|
|
1754
1781
|
};
|
|
1755
1782
|
applyModifier(fields, member, baseData3);
|
|
1756
1783
|
if (member.defaultValue !== null) {
|
|
@@ -2350,6 +2377,16 @@ function optionalNumberOrNull(value, record3, path) {
|
|
|
2350
2377
|
if (value === void 0 || value === null) return null;
|
|
2351
2378
|
return requiredNumberValue(value, record3, path);
|
|
2352
2379
|
}
|
|
2380
|
+
function accessModifierValue(value, record3, path) {
|
|
2381
|
+
if (value !== "public" && value !== "protected" && value !== "private") {
|
|
2382
|
+
throw invalidDocument(
|
|
2383
|
+
record3,
|
|
2384
|
+
path,
|
|
2385
|
+
"must be public, protected, or private"
|
|
2386
|
+
);
|
|
2387
|
+
}
|
|
2388
|
+
return value;
|
|
2389
|
+
}
|
|
2353
2390
|
function requiredString(value, key, record3) {
|
|
2354
2391
|
return requiredStringValue(value[key], record3, key);
|
|
2355
2392
|
}
|
|
@@ -2606,6 +2643,11 @@ function interfaceFromDocument(record3, context) {
|
|
|
2606
2643
|
);
|
|
2607
2644
|
const memberId = requiredString(member, "id", record3);
|
|
2608
2645
|
const memberSource = nestedSource(source, "interfaceMember", memberId);
|
|
2646
|
+
const accessModifier = accessModifierValue(
|
|
2647
|
+
member.accessModifierKind,
|
|
2648
|
+
record3,
|
|
2649
|
+
`members.${name}.accessModifierKind`
|
|
2650
|
+
);
|
|
2609
2651
|
if (member.kind === "property") {
|
|
2610
2652
|
return {
|
|
2611
2653
|
id: memberId,
|
|
@@ -2621,6 +2663,7 @@ function interfaceFromDocument(record3, context) {
|
|
|
2621
2663
|
record3,
|
|
2622
2664
|
`members.${name}.settable`
|
|
2623
2665
|
),
|
|
2666
|
+
accessModifier,
|
|
2624
2667
|
source: memberSource
|
|
2625
2668
|
};
|
|
2626
2669
|
}
|
|
@@ -2644,6 +2687,7 @@ function interfaceFromDocument(record3, context) {
|
|
|
2644
2687
|
record3,
|
|
2645
2688
|
`members.${name}.deferred`
|
|
2646
2689
|
),
|
|
2690
|
+
accessModifier,
|
|
2647
2691
|
source: memberSource
|
|
2648
2692
|
};
|
|
2649
2693
|
}
|
|
@@ -2663,7 +2707,8 @@ function interfaceToDocument(neoInterface) {
|
|
|
2663
2707
|
id: member.id,
|
|
2664
2708
|
kind: "property",
|
|
2665
2709
|
typeInfo: manifestTypeToDocument(member.type),
|
|
2666
|
-
settable: member.settable
|
|
2710
|
+
settable: member.settable,
|
|
2711
|
+
accessModifierKind: member.accessModifier
|
|
2667
2712
|
};
|
|
2668
2713
|
} else {
|
|
2669
2714
|
members[member.name] = {
|
|
@@ -2674,7 +2719,8 @@ function interfaceToDocument(neoInterface) {
|
|
|
2674
2719
|
name: argument2.name,
|
|
2675
2720
|
...manifestTypeToDocument(argument2.type)
|
|
2676
2721
|
})),
|
|
2677
|
-
deferred: member.deferred
|
|
2722
|
+
deferred: member.deferred,
|
|
2723
|
+
accessModifierKind: member.accessModifier
|
|
2678
2724
|
};
|
|
2679
2725
|
}
|
|
2680
2726
|
}
|
|
@@ -3460,6 +3506,9 @@ var init_language_spec = __esm({
|
|
|
3460
3506
|
"interface",
|
|
3461
3507
|
"native",
|
|
3462
3508
|
"override",
|
|
3509
|
+
"private",
|
|
3510
|
+
"protected",
|
|
3511
|
+
"public",
|
|
3463
3512
|
"return",
|
|
3464
3513
|
"sealed",
|
|
3465
3514
|
"static",
|
|
@@ -3759,6 +3808,66 @@ function createProjectIndex(project) {
|
|
|
3759
3808
|
indexesByListMemberId
|
|
3760
3809
|
};
|
|
3761
3810
|
}
|
|
3811
|
+
function memberAccessFailure(args) {
|
|
3812
|
+
const access = args.symbol.accessModifier;
|
|
3813
|
+
if (access === void 0) return null;
|
|
3814
|
+
if (access === "public") return null;
|
|
3815
|
+
const declaringTypeId = args.symbol.inheritedFrom?.typeId ?? args.owner.id;
|
|
3816
|
+
const declaringTypeName = args.symbol.inheritedFrom?.typeName ?? args.owner.name;
|
|
3817
|
+
const accessing = args.context.declaringType ?? args.context.thisClass;
|
|
3818
|
+
const accessingTypeId = accessing?.kind === "named" ? accessing.typeId : void 0;
|
|
3819
|
+
if (access === "private") {
|
|
3820
|
+
if (accessingTypeId === declaringTypeId) return null;
|
|
3821
|
+
return { kind: "private", declaringTypeName };
|
|
3822
|
+
}
|
|
3823
|
+
if (args.owner.kind === "interface") {
|
|
3824
|
+
if (accessingTypeId !== void 0 && classFamilyImplementsInterface(
|
|
3825
|
+
args.project,
|
|
3826
|
+
accessingTypeId,
|
|
3827
|
+
declaringTypeId
|
|
3828
|
+
)) {
|
|
3829
|
+
return null;
|
|
3830
|
+
}
|
|
3831
|
+
return { kind: "interfaceProtected", interfaceName: declaringTypeName };
|
|
3832
|
+
}
|
|
3833
|
+
if (accessingTypeId !== void 0 && typeExtendsInclusive(args.project, accessingTypeId, declaringTypeId)) {
|
|
3834
|
+
return null;
|
|
3835
|
+
}
|
|
3836
|
+
return { kind: "protected", declaringTypeName };
|
|
3837
|
+
}
|
|
3838
|
+
function typeExtendsInclusive(project, typeId, ancestorTypeId) {
|
|
3839
|
+
const visited = /* @__PURE__ */ new Set();
|
|
3840
|
+
const queue = [typeId];
|
|
3841
|
+
while (queue.length > 0) {
|
|
3842
|
+
const current = queue.shift();
|
|
3843
|
+
if (current === ancestorTypeId) return true;
|
|
3844
|
+
if (visited.has(current)) continue;
|
|
3845
|
+
visited.add(current);
|
|
3846
|
+
const type = project.typeById.get(current);
|
|
3847
|
+
for (const baseTypeId of type?.baseTypeIds ?? []) queue.push(baseTypeId);
|
|
3848
|
+
}
|
|
3849
|
+
return false;
|
|
3850
|
+
}
|
|
3851
|
+
function classFamilyImplementsInterface(project, classTypeId, interfaceTypeId) {
|
|
3852
|
+
const visitedClasses = /* @__PURE__ */ new Set();
|
|
3853
|
+
const classQueue = [classTypeId];
|
|
3854
|
+
while (classQueue.length > 0) {
|
|
3855
|
+
const current = classQueue.shift();
|
|
3856
|
+
if (visitedClasses.has(current)) continue;
|
|
3857
|
+
visitedClasses.add(current);
|
|
3858
|
+
const type = project.typeById.get(current);
|
|
3859
|
+
if (type === void 0) continue;
|
|
3860
|
+
for (const interfaceId of type.interfaceTypeIds ?? []) {
|
|
3861
|
+
if (typeExtendsInclusive(project, interfaceId, interfaceTypeId)) {
|
|
3862
|
+
return true;
|
|
3863
|
+
}
|
|
3864
|
+
}
|
|
3865
|
+
for (const baseTypeId of type.baseTypeIds ?? []) {
|
|
3866
|
+
classQueue.push(baseTypeId);
|
|
3867
|
+
}
|
|
3868
|
+
}
|
|
3869
|
+
return false;
|
|
3870
|
+
}
|
|
3762
3871
|
function withNullability(type, nullable) {
|
|
3763
3872
|
return { ...type, nullable };
|
|
3764
3873
|
}
|
|
@@ -4437,11 +4546,23 @@ function completionItemsForResolution(snapshot, resolved, word) {
|
|
|
4437
4546
|
return resolved.staticType.members.filter((member) => member.kind === "enumMember").map((member) => symbolCompletion(member, word, snapshot));
|
|
4438
4547
|
}
|
|
4439
4548
|
if (resolved.staticType) {
|
|
4440
|
-
|
|
4441
|
-
|
|
4442
|
-
|
|
4443
|
-
(
|
|
4444
|
-
|
|
4549
|
+
const staticType = resolved.staticType;
|
|
4550
|
+
return staticType.members.filter(
|
|
4551
|
+
(member) => member.static === true && isMemberCompletionAccessible(snapshot, staticType, member)
|
|
4552
|
+
).map((member) => symbolCompletion(member, word, snapshot));
|
|
4553
|
+
}
|
|
4554
|
+
const owner = resolved.type.kind === "named" ? snapshot.project.typeById.get(resolved.type.typeId) : void 0;
|
|
4555
|
+
return membersForType(snapshot, resolved.type).filter(
|
|
4556
|
+
(symbol) => owner === void 0 || isMemberCompletionAccessible(snapshot, owner, symbol)
|
|
4557
|
+
).map((symbol) => symbolCompletion(symbol, word, snapshot));
|
|
4558
|
+
}
|
|
4559
|
+
function isMemberCompletionAccessible(snapshot, owner, symbol) {
|
|
4560
|
+
return memberAccessFailure({
|
|
4561
|
+
project: snapshot.project,
|
|
4562
|
+
context: snapshot.context,
|
|
4563
|
+
owner,
|
|
4564
|
+
symbol
|
|
4565
|
+
}) === null;
|
|
4445
4566
|
}
|
|
4446
4567
|
function membersForType(snapshot, type) {
|
|
4447
4568
|
if (type.kind === "named") {
|
|
@@ -9788,6 +9909,7 @@ var init_strict_resolver = __esm({
|
|
|
9788
9909
|
pos
|
|
9789
9910
|
);
|
|
9790
9911
|
}
|
|
9912
|
+
this.assertMemberAccessible(staticType, member, pos);
|
|
9791
9913
|
if (member.static !== true) {
|
|
9792
9914
|
throw new CompileError(
|
|
9793
9915
|
`Member '${staticType.name}.${name}' requires an instance receiver.`,
|
|
@@ -9940,6 +10062,7 @@ var init_strict_resolver = __esm({
|
|
|
9940
10062
|
pos
|
|
9941
10063
|
);
|
|
9942
10064
|
}
|
|
10065
|
+
this.assertMemberAccessible(type, member, pos);
|
|
9943
10066
|
if (member.static === true) {
|
|
9944
10067
|
throw new CompileError(
|
|
9945
10068
|
`Static member '${type.name}.${name}' must be accessed through the type name, not an instance.`,
|
|
@@ -10261,6 +10384,7 @@ var init_strict_resolver = __esm({
|
|
|
10261
10384
|
pos
|
|
10262
10385
|
);
|
|
10263
10386
|
}
|
|
10387
|
+
this.assertMemberAccessible(staticType, member, pos);
|
|
10264
10388
|
if (member.static !== true) {
|
|
10265
10389
|
throw new CompileError(
|
|
10266
10390
|
`Member '${staticType.name}.${callee.name}' requires an instance receiver.`,
|
|
@@ -10297,6 +10421,7 @@ var init_strict_resolver = __esm({
|
|
|
10297
10421
|
(candidate) => (candidate.kind === "function" || candidate.kind === "method") && candidate.name === callee.name
|
|
10298
10422
|
);
|
|
10299
10423
|
if (member) {
|
|
10424
|
+
if (type !== void 0) this.assertMemberAccessible(type, member, pos);
|
|
10300
10425
|
if (member.static === true) {
|
|
10301
10426
|
throw new CompileError(
|
|
10302
10427
|
`Static member '${type?.name}.${callee.name}' must be accessed through the type name, not an instance.`,
|
|
@@ -10847,6 +10972,7 @@ var init_strict_resolver = __esm({
|
|
|
10847
10972
|
(candidate) => (candidate.kind === "function" || candidate.kind === "method") && candidate.name === memberName
|
|
10848
10973
|
);
|
|
10849
10974
|
if (!symbol2) return null;
|
|
10975
|
+
this.assertMemberAccessible(staticType, symbol2, expression.pos);
|
|
10850
10976
|
if (symbol2.static !== true) {
|
|
10851
10977
|
throw new CompileError(
|
|
10852
10978
|
`Member '${staticType.name}.${memberName}' requires an instance receiver.`,
|
|
@@ -10888,6 +11014,9 @@ var init_strict_resolver = __esm({
|
|
|
10888
11014
|
(candidate) => (candidate.kind === "function" || candidate.kind === "method") && candidate.name === memberName
|
|
10889
11015
|
);
|
|
10890
11016
|
if (!symbol) return null;
|
|
11017
|
+
if (type !== void 0) {
|
|
11018
|
+
this.assertMemberAccessible(type, symbol, expression.pos);
|
|
11019
|
+
}
|
|
10891
11020
|
if (symbol.static === true) {
|
|
10892
11021
|
throw new CompileError(
|
|
10893
11022
|
`Static member '${type?.name}.${memberName}' must be accessed through the type name, not an instance.`,
|
|
@@ -11265,6 +11394,36 @@ var init_strict_resolver = __esm({
|
|
|
11265
11394
|
describe(type) {
|
|
11266
11395
|
return formatType(type, this.project);
|
|
11267
11396
|
}
|
|
11397
|
+
/**
|
|
11398
|
+
* Enforces C#-style member accessibility on a resolved member. Runs after
|
|
11399
|
+
* the member is found so hover/definition still resolve while the strict
|
|
11400
|
+
* compile carries the diagnostic.
|
|
11401
|
+
*/
|
|
11402
|
+
assertMemberAccessible(owner, symbol, pos) {
|
|
11403
|
+
const failure = memberAccessFailure({
|
|
11404
|
+
project: this.project,
|
|
11405
|
+
context: this.context,
|
|
11406
|
+
owner,
|
|
11407
|
+
symbol
|
|
11408
|
+
});
|
|
11409
|
+
if (failure === null) return;
|
|
11410
|
+
if (failure.kind === "private") {
|
|
11411
|
+
throw new CompileError(
|
|
11412
|
+
`'${symbol.name}' is private to ${failure.declaringTypeName}.`,
|
|
11413
|
+
pos
|
|
11414
|
+
);
|
|
11415
|
+
}
|
|
11416
|
+
if (failure.kind === "interfaceProtected") {
|
|
11417
|
+
throw new CompileError(
|
|
11418
|
+
`'${symbol.name}' is protected; through an ${failure.interfaceName} reference it is accessible only from classes that implement ${failure.interfaceName} and their derived classes.`,
|
|
11419
|
+
pos
|
|
11420
|
+
);
|
|
11421
|
+
}
|
|
11422
|
+
throw new CompileError(
|
|
11423
|
+
`'${symbol.name}' is protected; accessible only from ${failure.declaringTypeName} and derived classes.`,
|
|
11424
|
+
pos
|
|
11425
|
+
);
|
|
11426
|
+
}
|
|
11268
11427
|
symbolValue(symbol) {
|
|
11269
11428
|
if (symbol.kind === "root" || symbol.kind === "parameter" || symbol.kind === "value") {
|
|
11270
11429
|
return {
|
|
@@ -11287,6 +11446,13 @@ var init_strict_resolver = __esm({
|
|
|
11287
11446
|
if (this.context.staticMember === true && symbol.static !== true) {
|
|
11288
11447
|
return null;
|
|
11289
11448
|
}
|
|
11449
|
+
const accessFailure = memberAccessFailure({
|
|
11450
|
+
project: this.project,
|
|
11451
|
+
context: this.context,
|
|
11452
|
+
owner,
|
|
11453
|
+
symbol
|
|
11454
|
+
});
|
|
11455
|
+
if (accessFailure !== null) return null;
|
|
11290
11456
|
return { owner, symbol };
|
|
11291
11457
|
}
|
|
11292
11458
|
nextCallSite(pos) {
|
|
@@ -12335,12 +12501,165 @@ var init_parity_contract = __esm({
|
|
|
12335
12501
|
});
|
|
12336
12502
|
|
|
12337
12503
|
// ../packages/neoscript-language/src/project-source-ast.ts
|
|
12504
|
+
function isNeoSourceAccessModifier(value) {
|
|
12505
|
+
return value === "public" || value === "protected" || value === "private";
|
|
12506
|
+
}
|
|
12507
|
+
function effectiveSourceAccessModifier(modifiers, ownerKind) {
|
|
12508
|
+
const explicit = modifiers.find(isNeoSourceAccessModifier);
|
|
12509
|
+
if (explicit !== void 0) return explicit;
|
|
12510
|
+
return ownerKind === "interface" ? "public" : "private";
|
|
12511
|
+
}
|
|
12338
12512
|
var init_project_source_ast = __esm({
|
|
12339
12513
|
"../packages/neoscript-language/src/project-source-ast.ts"() {
|
|
12340
12514
|
"use strict";
|
|
12341
12515
|
}
|
|
12342
12516
|
});
|
|
12343
12517
|
|
|
12518
|
+
// ../packages/neoscript-language/src/project-source-tokens.ts
|
|
12519
|
+
function rangeContains(range2, position) {
|
|
12520
|
+
return positionCompare(range2.start, position) <= 0 && positionCompare(position, range2.end) <= 0;
|
|
12521
|
+
}
|
|
12522
|
+
function rangeSize(range2) {
|
|
12523
|
+
return (range2.end.line - range2.start.line) * 1e6 + range2.end.character - range2.start.character;
|
|
12524
|
+
}
|
|
12525
|
+
function documentPrefix(text, position) {
|
|
12526
|
+
const lines = text.split("\n");
|
|
12527
|
+
return [
|
|
12528
|
+
...lines.slice(0, position.line),
|
|
12529
|
+
(lines[position.line] ?? "").slice(0, position.character)
|
|
12530
|
+
].join("\n");
|
|
12531
|
+
}
|
|
12532
|
+
function projectTokenAt(document, position) {
|
|
12533
|
+
const offset = new SourceText(document.text).offsetAt(position);
|
|
12534
|
+
const tokens = projectTokens(document);
|
|
12535
|
+
const containing = tokens.find(
|
|
12536
|
+
(token) => token.start <= offset && offset < token.end
|
|
12537
|
+
);
|
|
12538
|
+
if (containing?.kind === "identifier") return containing;
|
|
12539
|
+
const touching = tokens.find(
|
|
12540
|
+
(token) => token.kind === "identifier" && token.end === offset
|
|
12541
|
+
);
|
|
12542
|
+
return touching ?? containing;
|
|
12543
|
+
}
|
|
12544
|
+
function projectTokens(document) {
|
|
12545
|
+
const cached = PROJECT_TOKEN_CACHE.get(document);
|
|
12546
|
+
if (cached) return cached;
|
|
12547
|
+
const source = new SourceText(document.text);
|
|
12548
|
+
const tokens = lex(document.text).tokens.flatMap(
|
|
12549
|
+
(token) => {
|
|
12550
|
+
if (token.kind !== "string" || !token.raw.startsWith('"""')) {
|
|
12551
|
+
return [token];
|
|
12552
|
+
}
|
|
12553
|
+
const result = [];
|
|
12554
|
+
const contentEnd = token.raw.endsWith('"""') ? token.end - 3 : token.end;
|
|
12555
|
+
let segmentStart = token.start;
|
|
12556
|
+
let cursor = token.start + 3;
|
|
12557
|
+
while (cursor < contentEnd) {
|
|
12558
|
+
if (document.text[cursor] !== "{" || document.text[cursor + 1] === "{") {
|
|
12559
|
+
cursor++;
|
|
12560
|
+
continue;
|
|
12561
|
+
}
|
|
12562
|
+
const close = tripleInterpolationEnd(
|
|
12563
|
+
document.text,
|
|
12564
|
+
cursor + 1,
|
|
12565
|
+
contentEnd
|
|
12566
|
+
);
|
|
12567
|
+
if (close === null) break;
|
|
12568
|
+
if (segmentStart < cursor + 1) {
|
|
12569
|
+
result.push(
|
|
12570
|
+
projectToken(
|
|
12571
|
+
"string",
|
|
12572
|
+
document.text,
|
|
12573
|
+
source,
|
|
12574
|
+
segmentStart,
|
|
12575
|
+
cursor + 1
|
|
12576
|
+
)
|
|
12577
|
+
);
|
|
12578
|
+
}
|
|
12579
|
+
const expressionStart = cursor + 1;
|
|
12580
|
+
const expression = document.text.slice(expressionStart, close);
|
|
12581
|
+
for (const nested of lex(expression).tokens) {
|
|
12582
|
+
if (nested.kind === "eof") continue;
|
|
12583
|
+
const start = expressionStart + nested.start;
|
|
12584
|
+
const end = expressionStart + nested.end;
|
|
12585
|
+
result.push({
|
|
12586
|
+
...nested,
|
|
12587
|
+
start,
|
|
12588
|
+
end,
|
|
12589
|
+
raw: document.text.slice(start, end),
|
|
12590
|
+
range: source.range(start, end)
|
|
12591
|
+
});
|
|
12592
|
+
}
|
|
12593
|
+
segmentStart = close;
|
|
12594
|
+
cursor = close + 1;
|
|
12595
|
+
}
|
|
12596
|
+
if (segmentStart < token.end) {
|
|
12597
|
+
result.push(
|
|
12598
|
+
projectToken(
|
|
12599
|
+
"string",
|
|
12600
|
+
document.text,
|
|
12601
|
+
source,
|
|
12602
|
+
segmentStart,
|
|
12603
|
+
token.end
|
|
12604
|
+
)
|
|
12605
|
+
);
|
|
12606
|
+
}
|
|
12607
|
+
return result;
|
|
12608
|
+
}
|
|
12609
|
+
);
|
|
12610
|
+
PROJECT_TOKEN_CACHE.set(document, tokens);
|
|
12611
|
+
return tokens;
|
|
12612
|
+
}
|
|
12613
|
+
function projectToken(kind, text, source, start, end) {
|
|
12614
|
+
const raw = text.slice(start, end);
|
|
12615
|
+
return { kind, text: raw, raw, start, end, range: source.range(start, end) };
|
|
12616
|
+
}
|
|
12617
|
+
function tripleInterpolationEnd(text, start, limit) {
|
|
12618
|
+
let depth = 0;
|
|
12619
|
+
let cursor = start;
|
|
12620
|
+
while (cursor < limit) {
|
|
12621
|
+
const char = text[cursor];
|
|
12622
|
+
const next = text[cursor + 1];
|
|
12623
|
+
if (char === '"') {
|
|
12624
|
+
cursor++;
|
|
12625
|
+
while (cursor < limit) {
|
|
12626
|
+
if (text[cursor] === "\\") cursor += 2;
|
|
12627
|
+
else if (text[cursor] === '"') {
|
|
12628
|
+
cursor++;
|
|
12629
|
+
break;
|
|
12630
|
+
} else cursor++;
|
|
12631
|
+
}
|
|
12632
|
+
continue;
|
|
12633
|
+
}
|
|
12634
|
+
if (char === "/" && next === "/") {
|
|
12635
|
+
while (cursor < limit && text[cursor] !== "\n") cursor++;
|
|
12636
|
+
continue;
|
|
12637
|
+
}
|
|
12638
|
+
if (char === "{") depth++;
|
|
12639
|
+
else if (char === "}") {
|
|
12640
|
+
if (depth === 0) return cursor;
|
|
12641
|
+
depth--;
|
|
12642
|
+
}
|
|
12643
|
+
cursor++;
|
|
12644
|
+
}
|
|
12645
|
+
return null;
|
|
12646
|
+
}
|
|
12647
|
+
function rangesEqual(left, right) {
|
|
12648
|
+
return positionCompare(left.start, right.start) === 0 && positionCompare(left.end, right.end) === 0;
|
|
12649
|
+
}
|
|
12650
|
+
function positionCompare(left, right) {
|
|
12651
|
+
return left.line === right.line ? left.character - right.character : left.line - right.line;
|
|
12652
|
+
}
|
|
12653
|
+
var PROJECT_TOKEN_CACHE;
|
|
12654
|
+
var init_project_source_tokens = __esm({
|
|
12655
|
+
"../packages/neoscript-language/src/project-source-tokens.ts"() {
|
|
12656
|
+
"use strict";
|
|
12657
|
+
init_lexer();
|
|
12658
|
+
init_source_text();
|
|
12659
|
+
PROJECT_TOKEN_CACHE = /* @__PURE__ */ new WeakMap();
|
|
12660
|
+
}
|
|
12661
|
+
});
|
|
12662
|
+
|
|
12344
12663
|
// ../packages/neoscript-language/src/project-source-parser.ts
|
|
12345
12664
|
function parseNeoProjectSource(sourceValue, kind) {
|
|
12346
12665
|
const lexed = lex(sourceValue);
|
|
@@ -12657,6 +12976,7 @@ function validateDeclarationSemantics(declarations, diagnostics) {
|
|
|
12657
12976
|
message: `Member '${member.name}' repeats the '${modifier}' modifier.`
|
|
12658
12977
|
});
|
|
12659
12978
|
}
|
|
12979
|
+
validateMemberAccessModifiers(declaration, member, diagnostics);
|
|
12660
12980
|
if (member.kind !== "function") continue;
|
|
12661
12981
|
if (declaration.kind === "interface") {
|
|
12662
12982
|
if (member.body) {
|
|
@@ -12702,6 +13022,61 @@ function validateDeclarationSemantics(declarations, diagnostics) {
|
|
|
12702
13022
|
}
|
|
12703
13023
|
}
|
|
12704
13024
|
}
|
|
13025
|
+
function validateMemberAccessModifiers(declaration, member, diagnostics) {
|
|
13026
|
+
const accessModifiers = [
|
|
13027
|
+
...new Set(member.modifiers.filter(isNeoSourceAccessModifier))
|
|
13028
|
+
];
|
|
13029
|
+
if (accessModifiers.length > 1) {
|
|
13030
|
+
diagnostics.push({
|
|
13031
|
+
range: member.nameRange,
|
|
13032
|
+
severity: "error",
|
|
13033
|
+
source: "neo-project",
|
|
13034
|
+
code: "conflicting-access-modifiers",
|
|
13035
|
+
message: `Member '${member.name}' declares more than one access modifier (${accessModifiers.join(", ")}); a member accepts at most one.`
|
|
13036
|
+
});
|
|
13037
|
+
return;
|
|
13038
|
+
}
|
|
13039
|
+
const accessModifier = accessModifiers[0];
|
|
13040
|
+
if (accessModifier === void 0) return;
|
|
13041
|
+
if (declaration.kind === "interface" && accessModifier === "private") {
|
|
13042
|
+
diagnostics.push({
|
|
13043
|
+
range: member.nameRange,
|
|
13044
|
+
severity: "error",
|
|
13045
|
+
source: "neo-project",
|
|
13046
|
+
code: "private-interface-member",
|
|
13047
|
+
message: `Interface member '${member.name}' cannot be private; private interface members are not yet supported. Use public or protected.`
|
|
13048
|
+
});
|
|
13049
|
+
return;
|
|
13050
|
+
}
|
|
13051
|
+
if (accessModifier !== "private") return;
|
|
13052
|
+
if (member.modifiers.includes("virtual")) {
|
|
13053
|
+
diagnostics.push({
|
|
13054
|
+
range: member.nameRange,
|
|
13055
|
+
severity: "error",
|
|
13056
|
+
source: "neo-project",
|
|
13057
|
+
code: "private-virtual-member",
|
|
13058
|
+
message: `Member '${member.name}' cannot be both private and virtual; a private member is never overridable.`
|
|
13059
|
+
});
|
|
13060
|
+
}
|
|
13061
|
+
if (member.modifiers.includes("abstract")) {
|
|
13062
|
+
diagnostics.push({
|
|
13063
|
+
range: member.nameRange,
|
|
13064
|
+
severity: "error",
|
|
13065
|
+
source: "neo-project",
|
|
13066
|
+
code: "private-abstract-member",
|
|
13067
|
+
message: `Member '${member.name}' cannot be both private and abstract; an abstract member exists to be implemented by descendants.`
|
|
13068
|
+
});
|
|
13069
|
+
}
|
|
13070
|
+
if (member.modifiers.includes("override")) {
|
|
13071
|
+
diagnostics.push({
|
|
13072
|
+
range: member.nameRange,
|
|
13073
|
+
severity: "error",
|
|
13074
|
+
source: "neo-project",
|
|
13075
|
+
code: "private-override-member",
|
|
13076
|
+
message: `Member '${member.name}' cannot be both private and override; an override keeps the accessibility of the member it overrides, and a private member cannot be overridden.`
|
|
13077
|
+
});
|
|
13078
|
+
}
|
|
13079
|
+
}
|
|
12705
13080
|
function isNameToken(token) {
|
|
12706
13081
|
return token !== void 0 && (token.kind === "identifier" || token.kind === "type" || token.kind === "keyword");
|
|
12707
13082
|
}
|
|
@@ -12737,12 +13112,16 @@ var init_project_source_parser = __esm({
|
|
|
12737
13112
|
"use strict";
|
|
12738
13113
|
init_lexer();
|
|
12739
13114
|
init_neoflow_graph_parser();
|
|
13115
|
+
init_project_source_ast();
|
|
12740
13116
|
init_source_text();
|
|
12741
13117
|
MODIFIERS = /* @__PURE__ */ new Set([
|
|
12742
13118
|
"abstract",
|
|
12743
13119
|
"async",
|
|
12744
13120
|
"native",
|
|
12745
13121
|
"override",
|
|
13122
|
+
"private",
|
|
13123
|
+
"protected",
|
|
13124
|
+
"public",
|
|
12746
13125
|
"sealed",
|
|
12747
13126
|
"static",
|
|
12748
13127
|
"virtual"
|
|
@@ -12780,6 +13159,14 @@ var init_project_source_parser = __esm({
|
|
|
12780
13159
|
const annotations = this.parseAnnotations();
|
|
12781
13160
|
const modifiers = this.parseModifiers();
|
|
12782
13161
|
if (this.at("class")) {
|
|
13162
|
+
const accessModifier = modifiers.find(isNeoSourceAccessModifier);
|
|
13163
|
+
if (accessModifier !== void 0) {
|
|
13164
|
+
throw this.failure(
|
|
13165
|
+
"source-class-access-modifier",
|
|
13166
|
+
`Access modifier '${accessModifier}' is valid only on class and interface member declarations, not on a class declaration.`,
|
|
13167
|
+
start
|
|
13168
|
+
);
|
|
13169
|
+
}
|
|
12783
13170
|
return this.parseClass(start, annotations, modifiers);
|
|
12784
13171
|
}
|
|
12785
13172
|
if (this.at("interface")) {
|
|
@@ -13380,6 +13767,7 @@ var init_project_schema_contract_generated = __esm({
|
|
|
13380
13767
|
"isStatic",
|
|
13381
13768
|
"isVirtual",
|
|
13382
13769
|
"isAbstract",
|
|
13770
|
+
"accessModifierKind",
|
|
13383
13771
|
"defaultValue",
|
|
13384
13772
|
"extendsMemberId",
|
|
13385
13773
|
"system",
|
|
@@ -17191,6 +17579,10 @@ function sourceMemberSymbol(member, owner, typeIds, source) {
|
|
|
17191
17579
|
type,
|
|
17192
17580
|
static: staticMember,
|
|
17193
17581
|
abstract: member.modifiers.includes("abstract"),
|
|
17582
|
+
accessModifier: effectiveSourceAccessModifier(
|
|
17583
|
+
member.modifiers,
|
|
17584
|
+
owner.declaration.kind
|
|
17585
|
+
),
|
|
17194
17586
|
location: location(owner.uri, member.range),
|
|
17195
17587
|
selectionLocation: location(owner.uri, member.nameRange)
|
|
17196
17588
|
};
|
|
@@ -17525,6 +17917,7 @@ var init_project_source_script_compiler = __esm({
|
|
|
17525
17917
|
"use strict";
|
|
17526
17918
|
init_compiler();
|
|
17527
17919
|
init_language_spec();
|
|
17920
|
+
init_project_source_ast();
|
|
17528
17921
|
init_project();
|
|
17529
17922
|
init_project_root();
|
|
17530
17923
|
init_source_text();
|
|
@@ -18081,6 +18474,7 @@ function validateMembers(environment, diagnostics) {
|
|
|
18081
18474
|
}
|
|
18082
18475
|
for (const modifier of member.modifiers) {
|
|
18083
18476
|
if (modifier === "async" && member.kind === "function") continue;
|
|
18477
|
+
if (isNeoSourceAccessModifier(modifier)) continue;
|
|
18084
18478
|
diagnose(
|
|
18085
18479
|
diagnostics,
|
|
18086
18480
|
ref.uri,
|
|
@@ -18734,6 +19128,7 @@ var init_project_source_type_checker = __esm({
|
|
|
18734
19128
|
"../packages/neoscript-language/src/project-source-type-checker.ts"() {
|
|
18735
19129
|
"use strict";
|
|
18736
19130
|
init_language_spec();
|
|
19131
|
+
init_project_source_ast();
|
|
18737
19132
|
BUILTIN_ARITY = /* @__PURE__ */ new Map([
|
|
18738
19133
|
["List", 1],
|
|
18739
19134
|
["Set", 1],
|
|
@@ -18792,7 +19187,13 @@ function analyzeNeoProjectSources(inputs) {
|
|
|
18792
19187
|
const symbols = [];
|
|
18793
19188
|
for (const [uri, document] of documents) {
|
|
18794
19189
|
for (const declaration of document.declarations) {
|
|
18795
|
-
collectDeclarationSymbols(
|
|
19190
|
+
collectDeclarationSymbols(
|
|
19191
|
+
uri,
|
|
19192
|
+
document,
|
|
19193
|
+
declaration,
|
|
19194
|
+
symbols,
|
|
19195
|
+
diagnostics
|
|
19196
|
+
);
|
|
18796
19197
|
}
|
|
18797
19198
|
}
|
|
18798
19199
|
validateSymbolUniqueness(symbols, diagnostics);
|
|
@@ -18802,7 +19203,7 @@ function analyzeNeoProjectSources(inputs) {
|
|
|
18802
19203
|
diagnostics.push(...compileProjectSourceBodies(documents).diagnostics);
|
|
18803
19204
|
return { documents, symbols, diagnostics };
|
|
18804
19205
|
}
|
|
18805
|
-
function collectDeclarationSymbols(uri, declaration, symbols, diagnostics) {
|
|
19206
|
+
function collectDeclarationSymbols(uri, document, declaration, symbols, diagnostics) {
|
|
18806
19207
|
const declarationKind = declaration.kind;
|
|
18807
19208
|
collectSymbol(
|
|
18808
19209
|
uri,
|
|
@@ -18812,7 +19213,9 @@ function collectDeclarationSymbols(uri, declaration, symbols, diagnostics) {
|
|
|
18812
19213
|
declaration.annotations,
|
|
18813
19214
|
void 0,
|
|
18814
19215
|
symbols,
|
|
18815
|
-
diagnostics
|
|
19216
|
+
diagnostics,
|
|
19217
|
+
void 0,
|
|
19218
|
+
declaration.kind === "global" ? declaration.type.name : void 0
|
|
18816
19219
|
);
|
|
18817
19220
|
if (declaration.kind === "enum") {
|
|
18818
19221
|
for (const option of declaration.options) {
|
|
@@ -18829,7 +19232,10 @@ function collectDeclarationSymbols(uri, declaration, symbols, diagnostics) {
|
|
|
18829
19232
|
}
|
|
18830
19233
|
return;
|
|
18831
19234
|
}
|
|
18832
|
-
if (declaration.kind === "global")
|
|
19235
|
+
if (declaration.kind === "global") {
|
|
19236
|
+
collectGlobalChildSymbols(uri, document, declaration, symbols, diagnostics);
|
|
19237
|
+
return;
|
|
19238
|
+
}
|
|
18833
19239
|
if (declaration.kind === "class") {
|
|
18834
19240
|
for (const parameter3 of declaration.genericParameters) {
|
|
18835
19241
|
collectSymbol(
|
|
@@ -18886,6 +19292,104 @@ function collectDeclarationSymbols(uri, declaration, symbols, diagnostics) {
|
|
|
18886
19292
|
}
|
|
18887
19293
|
}
|
|
18888
19294
|
}
|
|
19295
|
+
function collectGlobalChildSymbols(uri, document, declaration, symbols, diagnostics) {
|
|
19296
|
+
if (declaration.type.name === "Root") return;
|
|
19297
|
+
const initializer = declaration.initializer;
|
|
19298
|
+
const tokens = lex(document.sourceText).tokens.filter(
|
|
19299
|
+
(token) => token.kind !== "comment" && token.kind !== "eof" && rangeWithin(initializer.range, token.range)
|
|
19300
|
+
);
|
|
19301
|
+
let braceDepth = 0;
|
|
19302
|
+
let groupDepth = 0;
|
|
19303
|
+
let pendingAnnotations = [];
|
|
19304
|
+
for (let index = 0; index < tokens.length; index++) {
|
|
19305
|
+
const token = tokens[index];
|
|
19306
|
+
if (token.text === "{") {
|
|
19307
|
+
braceDepth++;
|
|
19308
|
+
continue;
|
|
19309
|
+
}
|
|
19310
|
+
if (token.text === "}") {
|
|
19311
|
+
braceDepth--;
|
|
19312
|
+
continue;
|
|
19313
|
+
}
|
|
19314
|
+
if (braceDepth !== 1) continue;
|
|
19315
|
+
if (token.text === "(" || token.text === "[") {
|
|
19316
|
+
groupDepth++;
|
|
19317
|
+
continue;
|
|
19318
|
+
}
|
|
19319
|
+
if (token.text === ")" || token.text === "]") {
|
|
19320
|
+
groupDepth--;
|
|
19321
|
+
continue;
|
|
19322
|
+
}
|
|
19323
|
+
if (groupDepth !== 0) continue;
|
|
19324
|
+
if (token.text === ";") {
|
|
19325
|
+
pendingAnnotations = [];
|
|
19326
|
+
continue;
|
|
19327
|
+
}
|
|
19328
|
+
if (token.text === "@") {
|
|
19329
|
+
const annotation2 = scanAnnotation(tokens, index);
|
|
19330
|
+
if (annotation2) {
|
|
19331
|
+
pendingAnnotations.push(annotation2.annotation);
|
|
19332
|
+
index = annotation2.endIndex;
|
|
19333
|
+
}
|
|
19334
|
+
continue;
|
|
19335
|
+
}
|
|
19336
|
+
const name = tokens[index + 1];
|
|
19337
|
+
if ((token.kind === "type" || token.kind === "identifier") && name?.kind === "identifier" && tokens[index + 2]?.text === "=" && tokens[index + 3]?.text !== "=" && // A pending annotation or statement boundary precedes a declaration;
|
|
19338
|
+
// `key: value` fields and expression member accesses never do.
|
|
19339
|
+
tokens[index - 1]?.text !== "." && tokens[index - 1]?.text !== ":") {
|
|
19340
|
+
collectSymbol(
|
|
19341
|
+
uri,
|
|
19342
|
+
"graphChild",
|
|
19343
|
+
name.text,
|
|
19344
|
+
name.range,
|
|
19345
|
+
pendingAnnotations,
|
|
19346
|
+
declaration.name,
|
|
19347
|
+
symbols,
|
|
19348
|
+
diagnostics,
|
|
19349
|
+
void 0,
|
|
19350
|
+
token.text
|
|
19351
|
+
);
|
|
19352
|
+
pendingAnnotations = [];
|
|
19353
|
+
index += 2;
|
|
19354
|
+
}
|
|
19355
|
+
}
|
|
19356
|
+
}
|
|
19357
|
+
function scanAnnotation(tokens, atIndex) {
|
|
19358
|
+
const marker = tokens[atIndex];
|
|
19359
|
+
const name = tokens[atIndex + 1];
|
|
19360
|
+
if (!name || name.kind !== "identifier" && name.kind !== "keyword") {
|
|
19361
|
+
return null;
|
|
19362
|
+
}
|
|
19363
|
+
const argumentsList2 = [];
|
|
19364
|
+
let endIndex = atIndex + 1;
|
|
19365
|
+
let endRange = name.range;
|
|
19366
|
+
if (tokens[atIndex + 2]?.text === "(") {
|
|
19367
|
+
let depth = 0;
|
|
19368
|
+
for (let index = atIndex + 2; index < tokens.length; index++) {
|
|
19369
|
+
const token = tokens[index];
|
|
19370
|
+
if (token.text === "(") depth++;
|
|
19371
|
+
else if (token.text === ")" && --depth === 0) {
|
|
19372
|
+
endIndex = index;
|
|
19373
|
+
endRange = token.range;
|
|
19374
|
+
break;
|
|
19375
|
+
} else if (depth === 1 && token.kind === "string") {
|
|
19376
|
+
argumentsList2.push({ text: token.raw, range: token.range });
|
|
19377
|
+
}
|
|
19378
|
+
}
|
|
19379
|
+
}
|
|
19380
|
+
return {
|
|
19381
|
+
annotation: {
|
|
19382
|
+
name: name.text,
|
|
19383
|
+
nameRange: name.range,
|
|
19384
|
+
arguments: argumentsList2,
|
|
19385
|
+
range: { start: marker.range.start, end: endRange.end }
|
|
19386
|
+
},
|
|
19387
|
+
endIndex
|
|
19388
|
+
};
|
|
19389
|
+
}
|
|
19390
|
+
function rangeWithin(outer, inner) {
|
|
19391
|
+
return positionCompare(outer.start, inner.start) <= 0 && positionCompare(inner.end, outer.end) <= 0;
|
|
19392
|
+
}
|
|
18889
19393
|
function collectFlowSymbols(uri, content, ownerName, scopeRange, symbols, diagnostics) {
|
|
18890
19394
|
for (const binding of content.bindings) {
|
|
18891
19395
|
collectSymbol(
|
|
@@ -19177,6 +19681,8 @@ var init_project_source_analysis = __esm({
|
|
|
19177
19681
|
"../packages/neoscript-language/src/project-source-analysis.ts"() {
|
|
19178
19682
|
"use strict";
|
|
19179
19683
|
init_language_spec();
|
|
19684
|
+
init_lexer();
|
|
19685
|
+
init_project_source_tokens();
|
|
19180
19686
|
init_project_source_parser();
|
|
19181
19687
|
init_project_source_semantics();
|
|
19182
19688
|
init_project_source_script_compiler();
|
|
@@ -21242,151 +21748,6 @@ var init_project_schema_manifest = __esm({
|
|
|
21242
21748
|
}
|
|
21243
21749
|
});
|
|
21244
21750
|
|
|
21245
|
-
// ../packages/neoscript-language/src/project-source-tokens.ts
|
|
21246
|
-
function rangeContains(range2, position) {
|
|
21247
|
-
return positionCompare(range2.start, position) <= 0 && positionCompare(position, range2.end) <= 0;
|
|
21248
|
-
}
|
|
21249
|
-
function rangeSize(range2) {
|
|
21250
|
-
return (range2.end.line - range2.start.line) * 1e6 + range2.end.character - range2.start.character;
|
|
21251
|
-
}
|
|
21252
|
-
function documentPrefix(text, position) {
|
|
21253
|
-
const lines = text.split("\n");
|
|
21254
|
-
return [
|
|
21255
|
-
...lines.slice(0, position.line),
|
|
21256
|
-
(lines[position.line] ?? "").slice(0, position.character)
|
|
21257
|
-
].join("\n");
|
|
21258
|
-
}
|
|
21259
|
-
function projectTokenAt(document, position) {
|
|
21260
|
-
const offset = new SourceText(document.text).offsetAt(position);
|
|
21261
|
-
const tokens = projectTokens(document);
|
|
21262
|
-
const containing = tokens.find(
|
|
21263
|
-
(token) => token.start <= offset && offset < token.end
|
|
21264
|
-
);
|
|
21265
|
-
if (containing?.kind === "identifier") return containing;
|
|
21266
|
-
const touching = tokens.find(
|
|
21267
|
-
(token) => token.kind === "identifier" && token.end === offset
|
|
21268
|
-
);
|
|
21269
|
-
return touching ?? containing;
|
|
21270
|
-
}
|
|
21271
|
-
function projectTokens(document) {
|
|
21272
|
-
const cached = PROJECT_TOKEN_CACHE.get(document);
|
|
21273
|
-
if (cached) return cached;
|
|
21274
|
-
const source = new SourceText(document.text);
|
|
21275
|
-
const tokens = lex(document.text).tokens.flatMap(
|
|
21276
|
-
(token) => {
|
|
21277
|
-
if (token.kind !== "string" || !token.raw.startsWith('"""')) {
|
|
21278
|
-
return [token];
|
|
21279
|
-
}
|
|
21280
|
-
const result = [];
|
|
21281
|
-
const contentEnd = token.raw.endsWith('"""') ? token.end - 3 : token.end;
|
|
21282
|
-
let segmentStart = token.start;
|
|
21283
|
-
let cursor = token.start + 3;
|
|
21284
|
-
while (cursor < contentEnd) {
|
|
21285
|
-
if (document.text[cursor] !== "{" || document.text[cursor + 1] === "{") {
|
|
21286
|
-
cursor++;
|
|
21287
|
-
continue;
|
|
21288
|
-
}
|
|
21289
|
-
const close = tripleInterpolationEnd(
|
|
21290
|
-
document.text,
|
|
21291
|
-
cursor + 1,
|
|
21292
|
-
contentEnd
|
|
21293
|
-
);
|
|
21294
|
-
if (close === null) break;
|
|
21295
|
-
if (segmentStart < cursor + 1) {
|
|
21296
|
-
result.push(
|
|
21297
|
-
projectToken(
|
|
21298
|
-
"string",
|
|
21299
|
-
document.text,
|
|
21300
|
-
source,
|
|
21301
|
-
segmentStart,
|
|
21302
|
-
cursor + 1
|
|
21303
|
-
)
|
|
21304
|
-
);
|
|
21305
|
-
}
|
|
21306
|
-
const expressionStart = cursor + 1;
|
|
21307
|
-
const expression = document.text.slice(expressionStart, close);
|
|
21308
|
-
for (const nested of lex(expression).tokens) {
|
|
21309
|
-
if (nested.kind === "eof") continue;
|
|
21310
|
-
const start = expressionStart + nested.start;
|
|
21311
|
-
const end = expressionStart + nested.end;
|
|
21312
|
-
result.push({
|
|
21313
|
-
...nested,
|
|
21314
|
-
start,
|
|
21315
|
-
end,
|
|
21316
|
-
raw: document.text.slice(start, end),
|
|
21317
|
-
range: source.range(start, end)
|
|
21318
|
-
});
|
|
21319
|
-
}
|
|
21320
|
-
segmentStart = close;
|
|
21321
|
-
cursor = close + 1;
|
|
21322
|
-
}
|
|
21323
|
-
if (segmentStart < token.end) {
|
|
21324
|
-
result.push(
|
|
21325
|
-
projectToken(
|
|
21326
|
-
"string",
|
|
21327
|
-
document.text,
|
|
21328
|
-
source,
|
|
21329
|
-
segmentStart,
|
|
21330
|
-
token.end
|
|
21331
|
-
)
|
|
21332
|
-
);
|
|
21333
|
-
}
|
|
21334
|
-
return result;
|
|
21335
|
-
}
|
|
21336
|
-
);
|
|
21337
|
-
PROJECT_TOKEN_CACHE.set(document, tokens);
|
|
21338
|
-
return tokens;
|
|
21339
|
-
}
|
|
21340
|
-
function projectToken(kind, text, source, start, end) {
|
|
21341
|
-
const raw = text.slice(start, end);
|
|
21342
|
-
return { kind, text: raw, raw, start, end, range: source.range(start, end) };
|
|
21343
|
-
}
|
|
21344
|
-
function tripleInterpolationEnd(text, start, limit) {
|
|
21345
|
-
let depth = 0;
|
|
21346
|
-
let cursor = start;
|
|
21347
|
-
while (cursor < limit) {
|
|
21348
|
-
const char = text[cursor];
|
|
21349
|
-
const next = text[cursor + 1];
|
|
21350
|
-
if (char === '"') {
|
|
21351
|
-
cursor++;
|
|
21352
|
-
while (cursor < limit) {
|
|
21353
|
-
if (text[cursor] === "\\") cursor += 2;
|
|
21354
|
-
else if (text[cursor] === '"') {
|
|
21355
|
-
cursor++;
|
|
21356
|
-
break;
|
|
21357
|
-
} else cursor++;
|
|
21358
|
-
}
|
|
21359
|
-
continue;
|
|
21360
|
-
}
|
|
21361
|
-
if (char === "/" && next === "/") {
|
|
21362
|
-
while (cursor < limit && text[cursor] !== "\n") cursor++;
|
|
21363
|
-
continue;
|
|
21364
|
-
}
|
|
21365
|
-
if (char === "{") depth++;
|
|
21366
|
-
else if (char === "}") {
|
|
21367
|
-
if (depth === 0) return cursor;
|
|
21368
|
-
depth--;
|
|
21369
|
-
}
|
|
21370
|
-
cursor++;
|
|
21371
|
-
}
|
|
21372
|
-
return null;
|
|
21373
|
-
}
|
|
21374
|
-
function rangesEqual(left, right) {
|
|
21375
|
-
return positionCompare(left.start, right.start) === 0 && positionCompare(left.end, right.end) === 0;
|
|
21376
|
-
}
|
|
21377
|
-
function positionCompare(left, right) {
|
|
21378
|
-
return left.line === right.line ? left.character - right.character : left.line - right.line;
|
|
21379
|
-
}
|
|
21380
|
-
var PROJECT_TOKEN_CACHE;
|
|
21381
|
-
var init_project_source_tokens = __esm({
|
|
21382
|
-
"../packages/neoscript-language/src/project-source-tokens.ts"() {
|
|
21383
|
-
"use strict";
|
|
21384
|
-
init_lexer();
|
|
21385
|
-
init_source_text();
|
|
21386
|
-
PROJECT_TOKEN_CACHE = /* @__PURE__ */ new WeakMap();
|
|
21387
|
-
}
|
|
21388
|
-
});
|
|
21389
|
-
|
|
21390
21751
|
// ../packages/neoscript-language/src/quick-fixes.ts
|
|
21391
21752
|
function quickFixFor(document, diagnostic) {
|
|
21392
21753
|
if (diagnostic.code === "missing-semicolon") {
|
|
@@ -21703,11 +22064,17 @@ function projectMemberCompletions(analysis, document, position) {
|
|
|
21703
22064
|
if (!owner || owner.kind !== "identifier") return null;
|
|
21704
22065
|
const resolvedOwner = projectSymbolAt(analysis, document, owner.range.start);
|
|
21705
22066
|
if (!resolvedOwner) return null;
|
|
22067
|
+
const ownerNames = /* @__PURE__ */ new Set();
|
|
21706
22068
|
const typeName = projectSymbolTypeName(resolvedOwner.symbol);
|
|
21707
|
-
if (
|
|
21708
|
-
|
|
21709
|
-
(
|
|
22069
|
+
if (typeName) ownerNames.add(typeName);
|
|
22070
|
+
if (resolvedOwner.symbol.kind === "global") {
|
|
22071
|
+
ownerNames.add(resolvedOwner.symbol.name);
|
|
22072
|
+
}
|
|
22073
|
+
if (ownerNames.size === 0) return null;
|
|
22074
|
+
const members = analysis.symbols.filter(
|
|
22075
|
+
(symbol) => (symbol.kind === "member" || symbol.kind === "graphChild") && symbol.ownerName !== void 0 && ownerNames.has(symbol.ownerName)
|
|
21710
22076
|
);
|
|
22077
|
+
return members.length > 0 ? members : null;
|
|
21711
22078
|
}
|
|
21712
22079
|
function projectConstructorArgumentCompletions(analysis, document, position) {
|
|
21713
22080
|
const tokens = lex(document.text).tokens.filter(
|
|
@@ -21799,6 +22166,15 @@ function graphConstructorNamedArguments(typeName) {
|
|
|
21799
22166
|
{ name: "reason", type: "string" },
|
|
21800
22167
|
{ name: "duration", type: "decimal?" }
|
|
21801
22168
|
];
|
|
22169
|
+
case "Vector2":
|
|
22170
|
+
case "Vector2Int":
|
|
22171
|
+
case "Vector3":
|
|
22172
|
+
case "Vector3Int":
|
|
22173
|
+
case "Color":
|
|
22174
|
+
return graphConstructorParameters(typeName).map((parameter3) => ({
|
|
22175
|
+
name: parameter3.name,
|
|
22176
|
+
type: parameter3.type
|
|
22177
|
+
}));
|
|
21802
22178
|
default:
|
|
21803
22179
|
return null;
|
|
21804
22180
|
}
|
|
@@ -22234,6 +22610,19 @@ function indexedProjectSymbolAt(analysis, document, position, index) {
|
|
|
22234
22610
|
return { token, symbol: visibleCandidates[0] };
|
|
22235
22611
|
}
|
|
22236
22612
|
if (visibleCandidates.length === 0) return null;
|
|
22613
|
+
const sourceTokens = projectTokens(document);
|
|
22614
|
+
const tokenIndex = sourceTokens.findIndex(
|
|
22615
|
+
(candidate) => candidate.start === token.start && candidate.end === token.end
|
|
22616
|
+
);
|
|
22617
|
+
if (sourceTokens[tokenIndex + 1]?.text === "=" && sourceTokens[tokenIndex + 2]?.text !== "=") {
|
|
22618
|
+
const constructed = constructionMemberSymbol(
|
|
22619
|
+
analysis,
|
|
22620
|
+
document,
|
|
22621
|
+
token,
|
|
22622
|
+
visibleCandidates
|
|
22623
|
+
);
|
|
22624
|
+
if (constructed) return { token, symbol: constructed };
|
|
22625
|
+
}
|
|
22237
22626
|
const source = analysis.documents.get(document.uri);
|
|
22238
22627
|
const owner = source ? declarationContaining(source, token.range.start)?.name : void 0;
|
|
22239
22628
|
if (owner) {
|
|
@@ -22242,10 +22631,6 @@ function indexedProjectSymbolAt(analysis, document, position, index) {
|
|
|
22242
22631
|
);
|
|
22243
22632
|
if (owned.length === 1) return { token, symbol: owned[0] };
|
|
22244
22633
|
}
|
|
22245
|
-
const sourceTokens = projectTokens(document);
|
|
22246
|
-
const tokenIndex = sourceTokens.findIndex(
|
|
22247
|
-
(candidate) => candidate.start === token.start && candidate.end === token.end
|
|
22248
|
-
);
|
|
22249
22634
|
const dotOwner = sourceTokens[tokenIndex - 1]?.text === "." ? sourceTokens[tokenIndex - 2] : void 0;
|
|
22250
22635
|
if (dotOwner) {
|
|
22251
22636
|
const resolvedOwner = indexedProjectSymbolAt(
|
|
@@ -22254,15 +22639,39 @@ function indexedProjectSymbolAt(analysis, document, position, index) {
|
|
|
22254
22639
|
dotOwner.range.start,
|
|
22255
22640
|
index
|
|
22256
22641
|
);
|
|
22257
|
-
const
|
|
22642
|
+
const ownerNames = /* @__PURE__ */ new Set();
|
|
22643
|
+
if (resolvedOwner) {
|
|
22644
|
+
const typeName = projectSymbolTypeName(resolvedOwner.symbol);
|
|
22645
|
+
if (typeName) ownerNames.add(typeName);
|
|
22646
|
+
if (resolvedOwner.symbol.kind === "global") {
|
|
22647
|
+
ownerNames.add(resolvedOwner.symbol.name);
|
|
22648
|
+
}
|
|
22649
|
+
} else {
|
|
22650
|
+
ownerNames.add(dotOwner.text);
|
|
22651
|
+
}
|
|
22258
22652
|
const qualified = visibleCandidates.filter(
|
|
22259
|
-
(symbol) => symbol.ownerName
|
|
22653
|
+
(symbol) => symbol.ownerName !== void 0 && ownerNames.has(symbol.ownerName)
|
|
22260
22654
|
);
|
|
22261
22655
|
if (qualified.length === 1) return { token, symbol: qualified[0] };
|
|
22262
22656
|
}
|
|
22263
22657
|
const projectLevel = visibleCandidates.filter((symbol) => !symbol.ownerName);
|
|
22264
22658
|
return projectLevel.length === 1 ? { token, symbol: projectLevel[0] } : null;
|
|
22265
22659
|
}
|
|
22660
|
+
function constructionMemberSymbol(analysis, document, token, candidates) {
|
|
22661
|
+
const site = constructionSiteAt(analysis, document, token.range.start);
|
|
22662
|
+
let current = site?.enclosingTypeName ?? null;
|
|
22663
|
+
const visited = /* @__PURE__ */ new Set();
|
|
22664
|
+
while (current !== null && !visited.has(current)) {
|
|
22665
|
+
visited.add(current);
|
|
22666
|
+
const owned = candidates.find(
|
|
22667
|
+
(symbol) => symbol.kind === "member" && symbol.ownerName === current
|
|
22668
|
+
);
|
|
22669
|
+
if (owned) return owned;
|
|
22670
|
+
const declaration = findTypeDeclaration(analysis, current);
|
|
22671
|
+
current = declaration?.kind === "class" ? resolvableBaseClassName(analysis, declaration) : null;
|
|
22672
|
+
}
|
|
22673
|
+
return null;
|
|
22674
|
+
}
|
|
22266
22675
|
function projectSymbolTypeName(symbol) {
|
|
22267
22676
|
switch (symbol.kind) {
|
|
22268
22677
|
case "class":
|
|
@@ -22360,24 +22769,222 @@ function signatureResult(name, parameters, activeParameter) {
|
|
|
22360
22769
|
};
|
|
22361
22770
|
}
|
|
22362
22771
|
function contextualConstructorType(analysis, document, position) {
|
|
22772
|
+
return constructionSiteAt(analysis, document, position)?.expectedTypeName ?? null;
|
|
22773
|
+
}
|
|
22774
|
+
function initializerRootAt(analysis, document, position) {
|
|
22363
22775
|
const source = analysis.documents.get(document.uri);
|
|
22364
22776
|
if (!source) return null;
|
|
22365
22777
|
for (const declaration of source.declarations) {
|
|
22366
22778
|
if (declaration.kind === "global") {
|
|
22367
22779
|
if (rangeContains(declaration.initializer.range, position)) {
|
|
22368
|
-
return
|
|
22780
|
+
return {
|
|
22781
|
+
type: declaration.type,
|
|
22782
|
+
range: declaration.initializer.range
|
|
22783
|
+
};
|
|
22369
22784
|
}
|
|
22370
22785
|
continue;
|
|
22371
22786
|
}
|
|
22372
22787
|
if (declaration.kind === "enum") continue;
|
|
22373
22788
|
for (const member of declaration.members) {
|
|
22374
22789
|
if (member.kind === "field" && member.initializer && rangeContains(member.initializer.range, position)) {
|
|
22375
|
-
return member.type.
|
|
22790
|
+
return { type: member.type, range: member.initializer.range };
|
|
22376
22791
|
}
|
|
22377
22792
|
}
|
|
22378
22793
|
}
|
|
22379
22794
|
return null;
|
|
22380
22795
|
}
|
|
22796
|
+
function constructionSiteAt(analysis, document, position) {
|
|
22797
|
+
const root = initializerRootAt(analysis, document, position);
|
|
22798
|
+
if (!root) return null;
|
|
22799
|
+
const tokens = projectTokens(document).filter(
|
|
22800
|
+
(token) => token.kind !== "comment" && token.kind !== "eof" && rangeContains(root.range, token.range.start) && positionCompare(token.range.start, position) < 0
|
|
22801
|
+
);
|
|
22802
|
+
const stack = [];
|
|
22803
|
+
const expectedType = () => {
|
|
22804
|
+
const frame = stack.at(-1);
|
|
22805
|
+
if (!frame) return root.type;
|
|
22806
|
+
switch (frame.kind) {
|
|
22807
|
+
case "object":
|
|
22808
|
+
case "dictionary":
|
|
22809
|
+
return frame.slotType;
|
|
22810
|
+
case "list":
|
|
22811
|
+
return frame.elementType;
|
|
22812
|
+
case "call":
|
|
22813
|
+
return constructorArgumentType(analysis, frame);
|
|
22814
|
+
case "opaque":
|
|
22815
|
+
return null;
|
|
22816
|
+
}
|
|
22817
|
+
};
|
|
22818
|
+
let sawNew = false;
|
|
22819
|
+
let pendingNewTypeName = null;
|
|
22820
|
+
let closedConstructorTypeName = null;
|
|
22821
|
+
for (let index = 0; index < tokens.length; index++) {
|
|
22822
|
+
const token = tokens[index];
|
|
22823
|
+
if (token.text === "@") {
|
|
22824
|
+
if ((tokens[index + 1]?.kind === "identifier" || tokens[index + 1]?.kind === "keyword") && tokens[index + 2]?.text === "(") {
|
|
22825
|
+
let depth = 0;
|
|
22826
|
+
index += 2;
|
|
22827
|
+
for (; index < tokens.length; index++) {
|
|
22828
|
+
if (tokens[index].text === "(") depth++;
|
|
22829
|
+
else if (tokens[index].text === ")" && --depth === 0) break;
|
|
22830
|
+
}
|
|
22831
|
+
} else if (tokens[index + 1]?.kind === "identifier") {
|
|
22832
|
+
index += 1;
|
|
22833
|
+
}
|
|
22834
|
+
continue;
|
|
22835
|
+
}
|
|
22836
|
+
if (token.text === "new") {
|
|
22837
|
+
sawNew = true;
|
|
22838
|
+
pendingNewTypeName = expectedType()?.name ?? null;
|
|
22839
|
+
closedConstructorTypeName = null;
|
|
22840
|
+
continue;
|
|
22841
|
+
}
|
|
22842
|
+
if (sawNew && (token.kind === "identifier" || token.kind === "type")) {
|
|
22843
|
+
pendingNewTypeName = token.text;
|
|
22844
|
+
continue;
|
|
22845
|
+
}
|
|
22846
|
+
if (sawNew && token.text === "<") {
|
|
22847
|
+
let depth = 0;
|
|
22848
|
+
for (; index < tokens.length; index++) {
|
|
22849
|
+
if (tokens[index].text === "<") depth++;
|
|
22850
|
+
else if (tokens[index].text === ">" && --depth === 0) break;
|
|
22851
|
+
}
|
|
22852
|
+
continue;
|
|
22853
|
+
}
|
|
22854
|
+
if (token.text === "{") {
|
|
22855
|
+
if (sawNew || closedConstructorTypeName !== null) {
|
|
22856
|
+
stack.push({
|
|
22857
|
+
kind: "object",
|
|
22858
|
+
typeName: pendingNewTypeName ?? closedConstructorTypeName,
|
|
22859
|
+
slotType: null
|
|
22860
|
+
});
|
|
22861
|
+
sawNew = false;
|
|
22862
|
+
pendingNewTypeName = null;
|
|
22863
|
+
} else {
|
|
22864
|
+
const expected = expectedType();
|
|
22865
|
+
if (expected?.name === "Dictionary") {
|
|
22866
|
+
stack.push({
|
|
22867
|
+
kind: "dictionary",
|
|
22868
|
+
valueType: expected.typeArguments[1] ?? null,
|
|
22869
|
+
slotType: null
|
|
22870
|
+
});
|
|
22871
|
+
} else {
|
|
22872
|
+
stack.push({ kind: "opaque" });
|
|
22873
|
+
}
|
|
22874
|
+
}
|
|
22875
|
+
closedConstructorTypeName = null;
|
|
22876
|
+
continue;
|
|
22877
|
+
}
|
|
22878
|
+
if (token.text === "(") {
|
|
22879
|
+
if (sawNew) {
|
|
22880
|
+
stack.push({
|
|
22881
|
+
kind: "call",
|
|
22882
|
+
typeName: pendingNewTypeName,
|
|
22883
|
+
argumentIndex: 0,
|
|
22884
|
+
argumentName: null
|
|
22885
|
+
});
|
|
22886
|
+
sawNew = false;
|
|
22887
|
+
pendingNewTypeName = null;
|
|
22888
|
+
} else {
|
|
22889
|
+
stack.push({ kind: "opaque" });
|
|
22890
|
+
}
|
|
22891
|
+
closedConstructorTypeName = null;
|
|
22892
|
+
continue;
|
|
22893
|
+
}
|
|
22894
|
+
if (token.text === "[") {
|
|
22895
|
+
stack.push({
|
|
22896
|
+
kind: "list",
|
|
22897
|
+
elementType: collectionElementType2(expectedType())
|
|
22898
|
+
});
|
|
22899
|
+
closedConstructorTypeName = null;
|
|
22900
|
+
continue;
|
|
22901
|
+
}
|
|
22902
|
+
if (token.text === ")") {
|
|
22903
|
+
const frame2 = stack.pop();
|
|
22904
|
+
closedConstructorTypeName = frame2?.kind === "call" ? frame2.typeName : null;
|
|
22905
|
+
continue;
|
|
22906
|
+
}
|
|
22907
|
+
if (token.text === "}" || token.text === "]") {
|
|
22908
|
+
stack.pop();
|
|
22909
|
+
closedConstructorTypeName = null;
|
|
22910
|
+
continue;
|
|
22911
|
+
}
|
|
22912
|
+
closedConstructorTypeName = null;
|
|
22913
|
+
const frame = stack.at(-1);
|
|
22914
|
+
if (!frame) continue;
|
|
22915
|
+
if (frame.kind === "object") {
|
|
22916
|
+
if (token.text === "=" && tokens[index + 1]?.text !== "=") {
|
|
22917
|
+
const nameToken = tokens[index - 1];
|
|
22918
|
+
frame.slotType = nameToken && (nameToken.kind === "identifier" || nameToken.kind === "type") ? declaredFieldType(analysis, frame.typeName, nameToken.text) : null;
|
|
22919
|
+
} else if (token.text === ",") {
|
|
22920
|
+
frame.slotType = null;
|
|
22921
|
+
}
|
|
22922
|
+
} else if (frame.kind === "dictionary") {
|
|
22923
|
+
if (token.text === ":") frame.slotType = frame.valueType;
|
|
22924
|
+
else if (token.text === ",") frame.slotType = null;
|
|
22925
|
+
} else if (frame.kind === "call") {
|
|
22926
|
+
if (token.text === ",") {
|
|
22927
|
+
frame.argumentIndex++;
|
|
22928
|
+
frame.argumentName = null;
|
|
22929
|
+
} else if (token.text === ":") {
|
|
22930
|
+
const nameToken = tokens[index - 1];
|
|
22931
|
+
frame.argumentName = nameToken?.kind === "identifier" ? nameToken.text : null;
|
|
22932
|
+
}
|
|
22933
|
+
}
|
|
22934
|
+
}
|
|
22935
|
+
const enclosing = [...stack].reverse().find(
|
|
22936
|
+
(frame) => frame.kind === "object"
|
|
22937
|
+
);
|
|
22938
|
+
return {
|
|
22939
|
+
expectedTypeName: expectedType()?.name ?? null,
|
|
22940
|
+
enclosingTypeName: enclosing?.typeName ?? null
|
|
22941
|
+
};
|
|
22942
|
+
}
|
|
22943
|
+
function collectionElementType2(type) {
|
|
22944
|
+
if (!type) return null;
|
|
22945
|
+
if (type.name === "List" || type.name === "Set") {
|
|
22946
|
+
return type.typeArguments[0] ?? null;
|
|
22947
|
+
}
|
|
22948
|
+
return null;
|
|
22949
|
+
}
|
|
22950
|
+
function constructorArgumentType(analysis, frame) {
|
|
22951
|
+
if (!frame.typeName) return null;
|
|
22952
|
+
const declaration = findTypeDeclaration(analysis, frame.typeName);
|
|
22953
|
+
if (!declaration || declaration.kind === "global" || declaration.kind === "enum") {
|
|
22954
|
+
return null;
|
|
22955
|
+
}
|
|
22956
|
+
const fields = declaration.members.filter(
|
|
22957
|
+
(member) => member.kind === "field" && !member.modifiers.includes("static")
|
|
22958
|
+
);
|
|
22959
|
+
if (frame.argumentName !== null) {
|
|
22960
|
+
return fields.find((field) => field.name === frame.argumentName)?.type ?? null;
|
|
22961
|
+
}
|
|
22962
|
+
return fields[frame.argumentIndex]?.type ?? null;
|
|
22963
|
+
}
|
|
22964
|
+
function declaredFieldType(analysis, typeName, fieldName) {
|
|
22965
|
+
let current = typeName;
|
|
22966
|
+
const visited = /* @__PURE__ */ new Set();
|
|
22967
|
+
while (current !== null && !visited.has(current)) {
|
|
22968
|
+
visited.add(current);
|
|
22969
|
+
const declaration = findTypeDeclaration(analysis, current);
|
|
22970
|
+
if (!declaration || declaration.kind === "global" || declaration.kind === "enum") {
|
|
22971
|
+
return null;
|
|
22972
|
+
}
|
|
22973
|
+
const member = declaration.members.find(
|
|
22974
|
+
(candidate) => candidate.kind === "field" && candidate.name === fieldName
|
|
22975
|
+
);
|
|
22976
|
+
if (member) return member.type;
|
|
22977
|
+
current = declaration.kind === "class" ? resolvableBaseClassName(analysis, declaration) : null;
|
|
22978
|
+
}
|
|
22979
|
+
return null;
|
|
22980
|
+
}
|
|
22981
|
+
function resolvableBaseClassName(analysis, declaration) {
|
|
22982
|
+
for (const base of declaration.baseTypes) {
|
|
22983
|
+
const resolved = findTypeDeclaration(analysis, base.name);
|
|
22984
|
+
if (resolved?.kind === "class") return base.name;
|
|
22985
|
+
}
|
|
22986
|
+
return null;
|
|
22987
|
+
}
|
|
22381
22988
|
function findTypeDeclaration(analysis, name) {
|
|
22382
22989
|
for (const document of analysis.documents.values()) {
|
|
22383
22990
|
const declaration = document.declarations.find(
|
|
@@ -22448,6 +23055,35 @@ function graphConstructorParameters(typeName) {
|
|
|
22448
23055
|
{ type: "string", name: "reason" },
|
|
22449
23056
|
{ type: "decimal?", name: "duration" }
|
|
22450
23057
|
];
|
|
23058
|
+
case "Vector2":
|
|
23059
|
+
return [
|
|
23060
|
+
{ type: "float", name: "x" },
|
|
23061
|
+
{ type: "float", name: "y" }
|
|
23062
|
+
];
|
|
23063
|
+
case "Vector2Int":
|
|
23064
|
+
return [
|
|
23065
|
+
{ type: "int", name: "x" },
|
|
23066
|
+
{ type: "int", name: "y" }
|
|
23067
|
+
];
|
|
23068
|
+
case "Vector3":
|
|
23069
|
+
return [
|
|
23070
|
+
{ type: "float", name: "x" },
|
|
23071
|
+
{ type: "float", name: "y" },
|
|
23072
|
+
{ type: "float", name: "z" }
|
|
23073
|
+
];
|
|
23074
|
+
case "Vector3Int":
|
|
23075
|
+
return [
|
|
23076
|
+
{ type: "int", name: "x" },
|
|
23077
|
+
{ type: "int", name: "y" },
|
|
23078
|
+
{ type: "int", name: "z" }
|
|
23079
|
+
];
|
|
23080
|
+
case "Color":
|
|
23081
|
+
return [
|
|
23082
|
+
{ type: "float", name: "r" },
|
|
23083
|
+
{ type: "float", name: "g" },
|
|
23084
|
+
{ type: "float", name: "b" },
|
|
23085
|
+
{ type: "float", name: "a" }
|
|
23086
|
+
];
|
|
22451
23087
|
default:
|
|
22452
23088
|
return [];
|
|
22453
23089
|
}
|
|
@@ -23910,6 +24546,11 @@ function assertMember2(value, path) {
|
|
|
23910
24546
|
assertMemberOwner(member.owner, `${path}.owner`);
|
|
23911
24547
|
nonEmptyString(member.name, `${path}.name`);
|
|
23912
24548
|
booleanAt(member.isStatic, `${path}.isStatic`);
|
|
24549
|
+
stringIn(
|
|
24550
|
+
member.accessModifier,
|
|
24551
|
+
/* @__PURE__ */ new Set(["public", "protected", "private"]),
|
|
24552
|
+
`${path}.accessModifier`
|
|
24553
|
+
);
|
|
23913
24554
|
stringIn(
|
|
23914
24555
|
member.modifier,
|
|
23915
24556
|
/* @__PURE__ */ new Set([
|
|
@@ -24340,12 +24981,14 @@ function assertInterfaceMember(value, path) {
|
|
|
24340
24981
|
"name",
|
|
24341
24982
|
"type",
|
|
24342
24983
|
"settable",
|
|
24984
|
+
"accessModifier",
|
|
24343
24985
|
"source"
|
|
24344
24986
|
]);
|
|
24345
24987
|
nonEmptyString(member.id, `${path}.id`);
|
|
24346
24988
|
nonEmptyString(member.name, `${path}.name`);
|
|
24347
24989
|
assertType2(member.type, `${path}.type`);
|
|
24348
24990
|
booleanAt(member.settable, `${path}.settable`);
|
|
24991
|
+
assertInterfaceMemberAccessModifier(member.accessModifier, path);
|
|
24349
24992
|
assertSourceIdentity(member.source, `${path}.source`, "interfaceMember");
|
|
24350
24993
|
return;
|
|
24351
24994
|
}
|
|
@@ -24357,16 +25000,21 @@ function assertInterfaceMember(value, path) {
|
|
|
24357
25000
|
"returnType",
|
|
24358
25001
|
"arguments",
|
|
24359
25002
|
"deferred",
|
|
25003
|
+
"accessModifier",
|
|
24360
25004
|
"source"
|
|
24361
25005
|
]);
|
|
24362
25006
|
nonEmptyString(member.id, `${path}.id`);
|
|
24363
25007
|
nonEmptyString(member.name, `${path}.name`);
|
|
24364
25008
|
assertFunctionSignature(member, path);
|
|
25009
|
+
assertInterfaceMemberAccessModifier(member.accessModifier, path);
|
|
24365
25010
|
assertSourceIdentity(member.source, `${path}.source`, "interfaceMember");
|
|
24366
25011
|
return;
|
|
24367
25012
|
}
|
|
24368
25013
|
invalid(`${path}.kind`, "must be property or function.");
|
|
24369
25014
|
}
|
|
25015
|
+
function assertInterfaceMemberAccessModifier(value, path) {
|
|
25016
|
+
stringIn(value, /* @__PURE__ */ new Set(["public", "protected"]), `${path}.accessModifier`);
|
|
25017
|
+
}
|
|
24370
25018
|
function assertEnum2(value, path) {
|
|
24371
25019
|
const neoEnum = objectAt(value, path, [
|
|
24372
25020
|
"id",
|
|
@@ -25112,6 +25760,7 @@ var init_validate = __esm({
|
|
|
25112
25760
|
"owner",
|
|
25113
25761
|
"name",
|
|
25114
25762
|
"isStatic",
|
|
25763
|
+
"accessModifier",
|
|
25115
25764
|
"modifier",
|
|
25116
25765
|
"locked",
|
|
25117
25766
|
"required",
|
|
@@ -26923,6 +27572,10 @@ function memberCommon(context, ownerClass, declaration, id2, owner, base) {
|
|
|
26923
27572
|
owner,
|
|
26924
27573
|
name: declaration.name,
|
|
26925
27574
|
isStatic: declaration.modifiers.includes("static"),
|
|
27575
|
+
// Non-class placements (collection entries, generic arguments, loose
|
|
27576
|
+
// members) have no receiver type to scope visibility to; they are
|
|
27577
|
+
// structurally public. Class schema entries apply the C# omission default.
|
|
27578
|
+
accessModifier: owner.kind === "classMember" ? effectiveSourceAccessModifier(declaration.modifiers, "class") : "public",
|
|
26926
27579
|
modifier: memberModifier2(declaration.modifiers, base?.modifier),
|
|
26927
27580
|
locked: hasAnnotation(declaration.annotations, "locked"),
|
|
26928
27581
|
required: declaration.kind === "field" ? !declaration.type.nullable : base?.required ?? false,
|
|
@@ -27140,6 +27793,10 @@ function lowerInterface(context, declaration) {
|
|
|
27140
27793
|
`${declaration.name}.${member.name}`
|
|
27141
27794
|
);
|
|
27142
27795
|
const source = sourceIdentity2(member, "interfaceMember", member.name);
|
|
27796
|
+
const accessModifier = effectiveSourceAccessModifier(
|
|
27797
|
+
member.modifiers,
|
|
27798
|
+
"interface"
|
|
27799
|
+
);
|
|
27143
27800
|
if (member.kind === "function") {
|
|
27144
27801
|
return {
|
|
27145
27802
|
id: memberId,
|
|
@@ -27153,6 +27810,7 @@ function lowerInterface(context, declaration) {
|
|
|
27153
27810
|
selectionSpan: span(parameter3)
|
|
27154
27811
|
})),
|
|
27155
27812
|
deferred: member.modifiers.includes("async"),
|
|
27813
|
+
accessModifier,
|
|
27156
27814
|
source
|
|
27157
27815
|
};
|
|
27158
27816
|
}
|
|
@@ -27162,6 +27820,7 @@ function lowerInterface(context, declaration) {
|
|
|
27162
27820
|
name: member.name,
|
|
27163
27821
|
type: lowerType(context, member.type),
|
|
27164
27822
|
settable: /\bset\s*;/.test(member.body ?? ""),
|
|
27823
|
+
accessModifier,
|
|
27165
27824
|
source
|
|
27166
27825
|
};
|
|
27167
27826
|
});
|
|
@@ -28660,11 +29319,12 @@ function emitInterface(context, value) {
|
|
|
28660
29319
|
(interfaceId) => required(context.interfaces, interfaceId, "interface").name
|
|
28661
29320
|
);
|
|
28662
29321
|
const members = value.members.map((member) => {
|
|
29322
|
+
const access = member.accessModifier === "public" ? "" : `${member.accessModifier} `;
|
|
28663
29323
|
if (member.kind === "property") {
|
|
28664
|
-
return `${id(member.id)}${renderType(context, member.type)} ${member.name} { get;${member.settable ? " set;" : ""} }`;
|
|
29324
|
+
return `${id(member.id)}${access}${renderType(context, member.type)} ${member.name} { get;${member.settable ? " set;" : ""} }`;
|
|
28665
29325
|
}
|
|
28666
29326
|
const deferred = member.deferred ? "async " : "";
|
|
28667
|
-
return `${id(member.id)}${deferred}${renderReturnType(context, member.returnType)} ${member.name}(${member.arguments.map(
|
|
29327
|
+
return `${id(member.id)}${access}${deferred}${renderReturnType(context, member.returnType)} ${member.name}(${member.arguments.map(
|
|
28668
29328
|
(argument2) => `${renderType(context, argument2.type)} ${argument2.name}`
|
|
28669
29329
|
).join(", ")});`;
|
|
28670
29330
|
});
|
|
@@ -28729,9 +29389,10 @@ ${body ? `${signature} ${body}` : abstractContract ? `${signature};` : `native $
|
|
|
28729
29389
|
${prefix}${type} ${member.name}${initializer === null ? ";" : ` = ${initializer};`}`;
|
|
28730
29390
|
}
|
|
28731
29391
|
function memberModifier3(member) {
|
|
29392
|
+
const accessPrefix = `${member.accessModifier} `;
|
|
28732
29393
|
const staticPrefix = member.isStatic ? "static " : "";
|
|
28733
29394
|
const modifier = member.modifier === "plain" ? "" : member.modifier === "abstractOverride" ? "abstract override " : member.modifier === "sealedOverride" ? "override " : `${member.modifier} `;
|
|
28734
|
-
return `${staticPrefix}${modifier}`;
|
|
29395
|
+
return `${accessPrefix}${staticPrefix}${modifier}`;
|
|
28735
29396
|
}
|
|
28736
29397
|
function renderExtendsGenericBindings(context, schemaClass2, base) {
|
|
28737
29398
|
if (base.genericParameters.length === 0) return "";
|
|
@@ -32801,6 +33462,11 @@ var init_neoscript = __esm({
|
|
|
32801
33462
|
});
|
|
32802
33463
|
|
|
32803
33464
|
// ../src/models/members/member-kinds.ts
|
|
33465
|
+
function isMemberAccessModifierKind(value) {
|
|
33466
|
+
if (value === "public") return true;
|
|
33467
|
+
if (value === "protected") return true;
|
|
33468
|
+
return value === "private";
|
|
33469
|
+
}
|
|
32804
33470
|
function isValidCallableIdentifier(value) {
|
|
32805
33471
|
if (typeof value !== "string") return false;
|
|
32806
33472
|
if (!FunctionMemberNamePattern.test(value)) return false;
|
|
@@ -33244,6 +33910,7 @@ function isMemberBase(value) {
|
|
|
33244
33910
|
if (typeof v.locked !== "boolean") return false;
|
|
33245
33911
|
if (typeof v.required !== "boolean") return false;
|
|
33246
33912
|
if (typeof v.isStatic !== "boolean") return false;
|
|
33913
|
+
if (!isMemberAccessModifierKind(v.accessModifierKind)) return false;
|
|
33247
33914
|
if (v.isVirtual !== void 0 && typeof v.isVirtual !== "boolean") {
|
|
33248
33915
|
return false;
|
|
33249
33916
|
}
|
|
@@ -33299,6 +33966,7 @@ function isMemberOverrideBase(value) {
|
|
|
33299
33966
|
if (v.locked !== void 0 && typeof v.locked !== "boolean") return false;
|
|
33300
33967
|
if (v.required !== void 0 && typeof v.required !== "boolean") return false;
|
|
33301
33968
|
if (v.isStatic !== void 0 && v.isStatic !== false) return false;
|
|
33969
|
+
if (!isMemberAccessModifierKind(v.accessModifierKind)) return false;
|
|
33302
33970
|
if (v.isVirtual !== void 0 && typeof v.isVirtual !== "boolean") {
|
|
33303
33971
|
return false;
|
|
33304
33972
|
}
|
|
@@ -33806,6 +34474,9 @@ function substituteMember(member, env, members) {
|
|
|
33806
34474
|
...binding,
|
|
33807
34475
|
name: resolved.name,
|
|
33808
34476
|
locked: resolved.locked,
|
|
34477
|
+
// Accessibility is a slot-owned declaration field — a binding member's
|
|
34478
|
+
// modifier must not change the declaring slot's visibility.
|
|
34479
|
+
accessModifierKind: resolved.accessModifierKind,
|
|
33809
34480
|
system: resolved.system ?? void 0
|
|
33810
34481
|
};
|
|
33811
34482
|
const slotId = getOptionalString(member, "id");
|
|
@@ -35112,6 +35783,7 @@ function isNeoInterfaceMember(value) {
|
|
|
35112
35783
|
if (value === null) return false;
|
|
35113
35784
|
const member = value;
|
|
35114
35785
|
if (typeof member.id !== "string" || member.id.length === 0) return false;
|
|
35786
|
+
if (!isMemberAccessModifierKind(member.accessModifierKind)) return false;
|
|
35115
35787
|
if (member.kind === "property") {
|
|
35116
35788
|
if (!isNSTypeInfo(member.typeInfo)) return false;
|
|
35117
35789
|
if (containsForbiddenMemberTypeInfo(member.typeInfo)) return false;
|
|
@@ -44476,6 +45148,29 @@ function migrateMemberStaticOwnership(data) {
|
|
|
44476
45148
|
if (Object.prototype.hasOwnProperty.call(data, "isStatic")) return data;
|
|
44477
45149
|
return { ...data, isStatic: false };
|
|
44478
45150
|
}
|
|
45151
|
+
function migrateMemberAccessModifier(data) {
|
|
45152
|
+
if (!isRecord5(data)) return data;
|
|
45153
|
+
if (Object.prototype.hasOwnProperty.call(data, "accessModifierKind")) {
|
|
45154
|
+
return data;
|
|
45155
|
+
}
|
|
45156
|
+
return { ...data, accessModifierKind: "public" };
|
|
45157
|
+
}
|
|
45158
|
+
function migrateInterfaceMemberAccessModifiers(data) {
|
|
45159
|
+
if (!isRecord5(data)) return data;
|
|
45160
|
+
const members = data.members;
|
|
45161
|
+
if (!isRecord5(members)) return data;
|
|
45162
|
+
let nextMembers = members;
|
|
45163
|
+
for (const [memberKey, member] of Object.entries(members)) {
|
|
45164
|
+
if (!isRecord5(member)) continue;
|
|
45165
|
+
if (Object.prototype.hasOwnProperty.call(member, "accessModifierKind")) {
|
|
45166
|
+
continue;
|
|
45167
|
+
}
|
|
45168
|
+
if (nextMembers === members) nextMembers = { ...members };
|
|
45169
|
+
nextMembers[memberKey] = { ...member, accessModifierKind: "public" };
|
|
45170
|
+
}
|
|
45171
|
+
if (nextMembers === members) return data;
|
|
45172
|
+
return { ...data, members: nextMembers };
|
|
45173
|
+
}
|
|
44479
45174
|
function migrateProjectRecordData(args) {
|
|
44480
45175
|
const currentVersion = CURRENT_PROJECT_RECORD_DATA_SCHEMA_VERSION[args.recordKind];
|
|
44481
45176
|
if (args.dataSchemaVersion > currentVersion) {
|
|
@@ -44659,12 +45354,12 @@ var init_project_record_migrations = __esm({
|
|
|
44659
45354
|
init_neoscript_call_receiver_migration();
|
|
44660
45355
|
CURRENT_PROJECT_RECORD_DATA_SCHEMA_VERSION = {
|
|
44661
45356
|
[ProjectRecordKind.Project]: 1,
|
|
44662
|
-
[ProjectRecordKind.Member]:
|
|
45357
|
+
[ProjectRecordKind.Member]: 5,
|
|
44663
45358
|
[ProjectRecordKind.Value]: 1,
|
|
44664
45359
|
[ProjectRecordKind.Class]: 1,
|
|
44665
45360
|
[ProjectRecordKind.InternalRecordRelation]: 1,
|
|
44666
45361
|
[ProjectRecordKind.Enum]: 4,
|
|
44667
|
-
[ProjectRecordKind.Interface]:
|
|
45362
|
+
[ProjectRecordKind.Interface]: 3,
|
|
44668
45363
|
[ProjectRecordKind.Dialogue]: 5,
|
|
44669
45364
|
[ProjectRecordKind.DialogueNode]: 4,
|
|
44670
45365
|
[ProjectRecordKind.DialogueGroup]: 4,
|
|
@@ -44682,7 +45377,8 @@ var init_project_record_migrations = __esm({
|
|
|
44682
45377
|
[ProjectRecordKind.Member]: {
|
|
44683
45378
|
1: migrateGeneralFunctionCallIR,
|
|
44684
45379
|
2: migrateMemberStaticOwnership,
|
|
44685
|
-
3: migrateExplicitCallReceiverIR
|
|
45380
|
+
3: migrateExplicitCallReceiverIR,
|
|
45381
|
+
4: migrateMemberAccessModifier
|
|
44686
45382
|
},
|
|
44687
45383
|
[ProjectRecordKind.Value]: {},
|
|
44688
45384
|
[ProjectRecordKind.Class]: {},
|
|
@@ -44690,7 +45386,9 @@ var init_project_record_migrations = __esm({
|
|
|
44690
45386
|
[ProjectRecordKind.Enum]: {
|
|
44691
45387
|
1: migrateEnumOptionKeyOrder
|
|
44692
45388
|
},
|
|
44693
|
-
[ProjectRecordKind.Interface]: {
|
|
45389
|
+
[ProjectRecordKind.Interface]: {
|
|
45390
|
+
2: migrateInterfaceMemberAccessModifiers
|
|
45391
|
+
},
|
|
44694
45392
|
[ProjectRecordKind.Dialogue]: {
|
|
44695
45393
|
1: migrateDialoguePrimaryLinkedValues,
|
|
44696
45394
|
2: migrateGeneralFunctionCallIR,
|
|
@@ -53057,7 +53755,8 @@ function constructClassValue(info, scope, ctx) {
|
|
|
53057
53755
|
classId,
|
|
53058
53756
|
locked: false,
|
|
53059
53757
|
required: true,
|
|
53060
|
-
isStatic: false
|
|
53758
|
+
isStatic: false,
|
|
53759
|
+
accessModifierKind: "public"
|
|
53061
53760
|
};
|
|
53062
53761
|
const createdValues = [];
|
|
53063
53762
|
const storageKeyDeclarations = /* @__PURE__ */ new Map();
|