@neocompose/cli 0.84.1 → 0.84.2
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 +9 -0
- package/dist/neo-runtime.mjs +265 -73
- package/dist/test-worker.mjs +155 -33
- package/package.json +1 -1
- package/skills/neocompose-cli/SKILL.md +1 -1
- package/skills/neocompose-cli/references/cli-development.md +1 -1
- package/skills/neocompose-cli/references/neoscript.md +21 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.84.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 89cf02a: Allow runtime interface tests on generic values whose bounds admit implementing subtypes, including members accessed through open generic classes. Continue rejecting provably disjoint types.
|
|
8
|
+
- de01b14: Keep proven interface capabilities after negative guards that continue, break, return, or throw. Guarded receivers retain their class members, support interface member dispatch and assignment, and offer both sets of members in editor completion.
|
|
9
|
+
- 6a93d79: Report unknown class names in stored object initializers at the constructor type token, including nested arguments and collections. Refresh editor diagnostics when the class is created, renamed, or removed.
|
|
10
|
+
- c3c0b0c: Report construction-path initializer failures at their original source file and token instead of a downstream reference. Keep mapped diagnostics through deferred reference validation and omit duplicate reports from references to the same failure.
|
|
11
|
+
|
|
3
12
|
## 0.84.1
|
|
4
13
|
|
|
5
14
|
### Patch Changes
|
package/dist/neo-runtime.mjs
CHANGED
|
@@ -17587,7 +17587,7 @@ var init_registry = __esm({
|
|
|
17587
17587
|
"../packages/manifest/schema-contract/registry.mjs"() {
|
|
17588
17588
|
"use strict";
|
|
17589
17589
|
PROJECT_SCHEMA_CONTRACT = Object.freeze({
|
|
17590
|
-
cliVersion: "0.84.
|
|
17590
|
+
cliVersion: "0.84.2",
|
|
17591
17591
|
projectFileUploadBatchSize: 32,
|
|
17592
17592
|
documentRecords: {
|
|
17593
17593
|
member: {
|
|
@@ -21418,7 +21418,8 @@ var init_executable_parser = __esm({
|
|
|
21418
21418
|
}
|
|
21419
21419
|
if (isIdentifier(t) && t.text === NEOSCRIPT_CONSTRUCTOR_KEYWORD) {
|
|
21420
21420
|
this.next();
|
|
21421
|
-
const
|
|
21421
|
+
const classToken = isIdentifier(this.peek()) ? this.next() : null;
|
|
21422
|
+
const className = classToken?.text ?? null;
|
|
21422
21423
|
const typeArguments = [];
|
|
21423
21424
|
if (this.eat("operator", "<")) {
|
|
21424
21425
|
if (className === null) {
|
|
@@ -21452,6 +21453,7 @@ var init_executable_parser = __esm({
|
|
|
21452
21453
|
return {
|
|
21453
21454
|
kind: "new",
|
|
21454
21455
|
className,
|
|
21456
|
+
...classToken ? { classNamePos: at(classToken) } : {},
|
|
21455
21457
|
...typeArguments.length > 0 ? { typeArguments } : {},
|
|
21456
21458
|
args,
|
|
21457
21459
|
...hasArgumentList ? { hasArgumentList: true } : {},
|
|
@@ -31635,6 +31637,22 @@ function neoScriptMemberLookupType(type) {
|
|
|
31635
31637
|
}
|
|
31636
31638
|
return nullable2 && current.nullable !== true ? { ...current, nullable: true } : current;
|
|
31637
31639
|
}
|
|
31640
|
+
function neoScriptMemberReceiverType(type, memberName, project) {
|
|
31641
|
+
const primary = neoScriptMemberLookupType(type);
|
|
31642
|
+
if (primary.kind !== "named" || primary.narrowedInterfaces === void 0)
|
|
31643
|
+
return primary;
|
|
31644
|
+
const declaration = project.typeById.get(primary.typeId);
|
|
31645
|
+
if (declaration?.kind === "class" && (memberName === NEOSCRIPT_CLASS_ID_MEMBER || memberName === "Clone"))
|
|
31646
|
+
return primary;
|
|
31647
|
+
if (declaration?.members.some((member) => member.name === memberName))
|
|
31648
|
+
return primary;
|
|
31649
|
+
for (const bound of Object.values(primary.narrowedInterfaces)) {
|
|
31650
|
+
if (project.typeById.get(bound.typeId)?.members.some((member) => member.name === memberName)) {
|
|
31651
|
+
return { ...bound, nullable: primary.nullable === true };
|
|
31652
|
+
}
|
|
31653
|
+
}
|
|
31654
|
+
return primary;
|
|
31655
|
+
}
|
|
31638
31656
|
function isNeoScriptHandleReferenceTarget(target, isValueType) {
|
|
31639
31657
|
switch (target.kind) {
|
|
31640
31658
|
case "list":
|
|
@@ -31952,6 +31970,20 @@ function isNeoScriptTypeAssignable(source, target, project) {
|
|
|
31952
31970
|
if (isUnknownType(source) || isUnknownType(target)) return false;
|
|
31953
31971
|
if (isNullType(source)) return isNullableType2(target);
|
|
31954
31972
|
if (isNullableType2(source) && !isNullableType2(target)) return false;
|
|
31973
|
+
if (target.kind === "named" && target.narrowedInterfaces !== void 0) {
|
|
31974
|
+
for (const bound of Object.values(target.narrowedInterfaces)) {
|
|
31975
|
+
if (!isNeoScriptTypeAssignable(source, bound, project)) return false;
|
|
31976
|
+
}
|
|
31977
|
+
}
|
|
31978
|
+
if (source.kind === "named" && source.narrowedInterfaces !== void 0) {
|
|
31979
|
+
const direct = target.kind === "named" ? source.narrowedInterfaces[target.typeId] : void 0;
|
|
31980
|
+
if (direct !== void 0 && isNeoScriptTypeAssignable(direct, target, project))
|
|
31981
|
+
return true;
|
|
31982
|
+
for (const bound of Object.values(source.narrowedInterfaces)) {
|
|
31983
|
+
if (bound !== direct && isNeoScriptTypeAssignable(bound, target, project))
|
|
31984
|
+
return true;
|
|
31985
|
+
}
|
|
31986
|
+
}
|
|
31955
31987
|
if (source.kind === "primitive" && target.kind === "primitive") {
|
|
31956
31988
|
if (source.name === target.name) return true;
|
|
31957
31989
|
return source.name === "int" && (target.name === "float" || target.name === "decimal");
|
|
@@ -32036,9 +32068,40 @@ function isNeoScriptTypeAssignable(source, target, project) {
|
|
|
32036
32068
|
}
|
|
32037
32069
|
return false;
|
|
32038
32070
|
}
|
|
32071
|
+
function withoutNeoScriptInterfaceProofs(type) {
|
|
32072
|
+
if (type.kind !== "named" || type.narrowedInterfaces === void 0)
|
|
32073
|
+
return type;
|
|
32074
|
+
const { narrowedInterfaces: _proofs, ...declared } = type;
|
|
32075
|
+
return declared;
|
|
32076
|
+
}
|
|
32039
32077
|
function commonNeoScriptAssignableType(left, right, project) {
|
|
32040
32078
|
if (isNeoScriptTypeAssignable(left, right, project)) return right;
|
|
32041
32079
|
if (isNeoScriptTypeAssignable(right, left, project)) return left;
|
|
32080
|
+
if (left.kind === "named" && right.kind === "named" && (left.narrowedInterfaces !== void 0 || right.narrowedInterfaces !== void 0)) {
|
|
32081
|
+
const declaredLeft = withoutNeoScriptInterfaceProofs(left);
|
|
32082
|
+
const declaredRight = withoutNeoScriptInterfaceProofs(right);
|
|
32083
|
+
const common = commonNeoScriptAssignableType(
|
|
32084
|
+
declaredLeft,
|
|
32085
|
+
declaredRight,
|
|
32086
|
+
project
|
|
32087
|
+
);
|
|
32088
|
+
if (common?.kind !== "named") return null;
|
|
32089
|
+
const proofs = {};
|
|
32090
|
+
for (const [source, other] of [
|
|
32091
|
+
[left, right],
|
|
32092
|
+
[right, left]
|
|
32093
|
+
]) {
|
|
32094
|
+
for (const [id2, proof] of Object.entries(
|
|
32095
|
+
source.narrowedInterfaces ?? {}
|
|
32096
|
+
)) {
|
|
32097
|
+
if (proofs[id2] !== void 0) continue;
|
|
32098
|
+
const opposite = other.narrowedInterfaces?.[id2] ?? other;
|
|
32099
|
+
if (isNeoScriptTypeAssignable(opposite, proof, project))
|
|
32100
|
+
proofs[id2] = proof;
|
|
32101
|
+
}
|
|
32102
|
+
}
|
|
32103
|
+
return { ...common, narrowedInterfaces: proofs };
|
|
32104
|
+
}
|
|
32042
32105
|
return null;
|
|
32043
32106
|
}
|
|
32044
32107
|
function isNeoVariantTypeId(typeId, project) {
|
|
@@ -34302,17 +34365,22 @@ function mergeFactSets(sets) {
|
|
|
34302
34365
|
)
|
|
34303
34366
|
);
|
|
34304
34367
|
}
|
|
34305
|
-
function mergeNarrowingMaps(maps) {
|
|
34368
|
+
function mergeNarrowingMaps(maps, project) {
|
|
34306
34369
|
const first = maps[0];
|
|
34307
34370
|
if (!first) return /* @__PURE__ */ new Map();
|
|
34308
34371
|
const result = /* @__PURE__ */ new Map();
|
|
34309
34372
|
for (const [path, narrowed] of first) {
|
|
34310
|
-
|
|
34311
|
-
|
|
34312
|
-
|
|
34313
|
-
|
|
34314
|
-
|
|
34373
|
+
let common = narrowed.type;
|
|
34374
|
+
for (let index = 1; index < maps.length; index++) {
|
|
34375
|
+
const candidate = maps[index].get(path);
|
|
34376
|
+
if (candidate?.rootEntry !== narrowed.rootEntry) {
|
|
34377
|
+
common = null;
|
|
34378
|
+
break;
|
|
34379
|
+
}
|
|
34380
|
+
common = commonNeoScriptAssignableType(common, candidate.type, project);
|
|
34381
|
+
if (common === null) break;
|
|
34315
34382
|
}
|
|
34383
|
+
if (common !== null) result.set(path, { ...narrowed, type: common });
|
|
34316
34384
|
}
|
|
34317
34385
|
return result;
|
|
34318
34386
|
}
|
|
@@ -34341,6 +34409,16 @@ function typeRefsEqual(left, right) {
|
|
|
34341
34409
|
if (left.kind === "named" && right.kind === "named") {
|
|
34342
34410
|
const leftArgs = left.typeArguments ?? [];
|
|
34343
34411
|
const rightArgs = right.typeArguments ?? [];
|
|
34412
|
+
if (left.narrowedInterfaces !== right.narrowedInterfaces) {
|
|
34413
|
+
const leftBounds = Object.entries(left.narrowedInterfaces ?? {});
|
|
34414
|
+
const rightBounds = right.narrowedInterfaces ?? {};
|
|
34415
|
+
if (leftBounds.length !== Object.keys(rightBounds).length) return false;
|
|
34416
|
+
for (const [id2, leftBound] of leftBounds) {
|
|
34417
|
+
const rightBound = rightBounds[id2];
|
|
34418
|
+
if (rightBound === void 0 || !typeRefsEqual(leftBound, rightBound))
|
|
34419
|
+
return false;
|
|
34420
|
+
}
|
|
34421
|
+
}
|
|
34344
34422
|
return left.typeId === right.typeId && leftArgs.length === rightArgs.length && leftArgs.every((item, index) => {
|
|
34345
34423
|
const other = rightArgs[index];
|
|
34346
34424
|
return other !== void 0 && typeRefsEqual(item, other);
|
|
@@ -35320,6 +35398,10 @@ function typesOverlap(left, right, project) {
|
|
|
35320
35398
|
if (isUnknown(left) || isUnknown(right)) return true;
|
|
35321
35399
|
if (isNull(left)) return isNullable(right);
|
|
35322
35400
|
if (isNull(right)) return isNullable(left);
|
|
35401
|
+
left = neoScriptMemberLookupType(left);
|
|
35402
|
+
right = neoScriptMemberLookupType(right);
|
|
35403
|
+
if (left.kind === "typeParameter" || right.kind === "typeParameter")
|
|
35404
|
+
return true;
|
|
35323
35405
|
if (isNeoScriptTypeAssignable(left, right, project) || isNeoScriptTypeAssignable(right, left, project))
|
|
35324
35406
|
return true;
|
|
35325
35407
|
if (left.kind === "named" && right.kind === "named") {
|
|
@@ -36689,7 +36771,7 @@ var init_strict_resolver = __esm({
|
|
|
36689
36771
|
statement.init.pos
|
|
36690
36772
|
);
|
|
36691
36773
|
}
|
|
36692
|
-
const localType = declared ?? initial.type;
|
|
36774
|
+
const localType = declared ?? withoutNeoScriptInterfaceProofs(initial.type);
|
|
36693
36775
|
if (declared) {
|
|
36694
36776
|
this.requireAssignable(
|
|
36695
36777
|
initial.type,
|
|
@@ -36704,16 +36786,18 @@ var init_strict_resolver = __esm({
|
|
|
36704
36786
|
initial.pointer,
|
|
36705
36787
|
this.project
|
|
36706
36788
|
);
|
|
36707
|
-
|
|
36708
|
-
|
|
36709
|
-
|
|
36710
|
-
|
|
36711
|
-
|
|
36712
|
-
|
|
36713
|
-
|
|
36714
|
-
this.localWriteTargetRoot(initial, scope)
|
|
36715
|
-
)
|
|
36789
|
+
const entry = scopeVariable(
|
|
36790
|
+
statement.name,
|
|
36791
|
+
local,
|
|
36792
|
+
localType,
|
|
36793
|
+
"local" /* Local */,
|
|
36794
|
+
localOwnership(initial),
|
|
36795
|
+
this.localWriteTargetRoot(initial, scope)
|
|
36716
36796
|
);
|
|
36797
|
+
scope.define(entry);
|
|
36798
|
+
if (inferred && localType !== initial.type) {
|
|
36799
|
+
scope.narrow(statement.name, entry, initial.type);
|
|
36800
|
+
}
|
|
36717
36801
|
return { type: "variable" /* Variable */, variable: local };
|
|
36718
36802
|
}
|
|
36719
36803
|
case "if": {
|
|
@@ -36768,7 +36852,8 @@ var init_strict_resolver = __esm({
|
|
|
36768
36852
|
mergeBranchInvalidations(scope, branchExitOwnershipScopes);
|
|
36769
36853
|
if (branchExitNarrowings.length > 0) {
|
|
36770
36854
|
for (const [path, narrowed] of mergeNarrowingMaps(
|
|
36771
|
-
branchExitNarrowings
|
|
36855
|
+
branchExitNarrowings,
|
|
36856
|
+
this.project
|
|
36772
36857
|
)) {
|
|
36773
36858
|
const rootEntry = scope.lookup(pathRoot(path));
|
|
36774
36859
|
if (rootEntry === narrowed.rootEntry) {
|
|
@@ -37694,7 +37779,7 @@ var init_strict_resolver = __esm({
|
|
|
37694
37779
|
}
|
|
37695
37780
|
mergeLoopNarrowings(parent, exitPaths) {
|
|
37696
37781
|
if (exitPaths.length === 0) return;
|
|
37697
|
-
const merged = mergeNarrowingMaps(exitPaths);
|
|
37782
|
+
const merged = mergeNarrowingMaps(exitPaths, this.project);
|
|
37698
37783
|
for (const [path, narrowed] of parent.effectiveNarrowedPaths()) {
|
|
37699
37784
|
const common = merged.get(path);
|
|
37700
37785
|
if (parent.containsEntry(narrowed.rootEntry) && (common?.rootEntry !== narrowed.rootEntry || !typeRefsEqual(common.type, narrowed.type))) {
|
|
@@ -39447,8 +39532,13 @@ var init_strict_resolver = __esm({
|
|
|
39447
39532
|
expression.receiver,
|
|
39448
39533
|
scope
|
|
39449
39534
|
);
|
|
39450
|
-
|
|
39451
|
-
|
|
39535
|
+
const memberType2 = neoScriptMemberReceiverType(
|
|
39536
|
+
receiverExpression.type,
|
|
39537
|
+
expression.name,
|
|
39538
|
+
this.project
|
|
39539
|
+
);
|
|
39540
|
+
if (memberType2.kind !== "named") return null;
|
|
39541
|
+
owner = this.project.typeById.get(memberType2.typeId);
|
|
39452
39542
|
symbol = owner?.members.find(
|
|
39453
39543
|
(candidate) => candidate.name === expression.name && (candidate.kind === "function" || candidate.kind === "method")
|
|
39454
39544
|
);
|
|
@@ -39459,7 +39549,10 @@ var init_strict_resolver = __esm({
|
|
|
39459
39549
|
expression.pos
|
|
39460
39550
|
);
|
|
39461
39551
|
}
|
|
39462
|
-
receiver = {
|
|
39552
|
+
receiver = {
|
|
39553
|
+
kind: "instance",
|
|
39554
|
+
expression: { ...receiverExpression, type: memberType2 }
|
|
39555
|
+
};
|
|
39463
39556
|
}
|
|
39464
39557
|
} else {
|
|
39465
39558
|
return null;
|
|
@@ -39536,9 +39629,13 @@ var init_strict_resolver = __esm({
|
|
|
39536
39629
|
if (symbol === void 0 || symbol.static !== true) return null;
|
|
39537
39630
|
} else {
|
|
39538
39631
|
const receiver2 = this.resolveExpression(expression.receiver, scope);
|
|
39539
|
-
|
|
39540
|
-
|
|
39541
|
-
|
|
39632
|
+
receiverType = neoScriptMemberReceiverType(
|
|
39633
|
+
receiver2.type,
|
|
39634
|
+
expression.name,
|
|
39635
|
+
this.project
|
|
39636
|
+
);
|
|
39637
|
+
if (receiverType.kind !== "named") return null;
|
|
39638
|
+
owner = this.project.typeById.get(receiverType.typeId);
|
|
39542
39639
|
symbol = owner?.members.find(
|
|
39543
39640
|
(candidate) => candidate.name === expression.name && (candidate.kind === "function" || candidate.kind === "method")
|
|
39544
39641
|
);
|
|
@@ -39616,6 +39713,7 @@ var init_strict_resolver = __esm({
|
|
|
39616
39713
|
pos
|
|
39617
39714
|
);
|
|
39618
39715
|
}
|
|
39716
|
+
entryType = withoutNeoScriptInterfaceProofs(entryType);
|
|
39619
39717
|
for (const item of resolved) {
|
|
39620
39718
|
const common = commonNeoScriptAssignableType(
|
|
39621
39719
|
entryType,
|
|
@@ -39640,7 +39738,7 @@ var init_strict_resolver = __esm({
|
|
|
39640
39738
|
}
|
|
39641
39739
|
const type = {
|
|
39642
39740
|
kind: "list",
|
|
39643
|
-
elementType: entryType
|
|
39741
|
+
elementType: withoutNeoScriptInterfaceProofs(entryType)
|
|
39644
39742
|
};
|
|
39645
39743
|
const wire = toWireType(type, this.project);
|
|
39646
39744
|
if (wire.type !== 6 /* List */) {
|
|
@@ -39706,6 +39804,7 @@ var init_strict_resolver = __esm({
|
|
|
39706
39804
|
if (!keyType || !valueType) {
|
|
39707
39805
|
throw new CompileError("Dictionary literal type inference failed.", pos);
|
|
39708
39806
|
}
|
|
39807
|
+
valueType = withoutNeoScriptInterfaceProofs(valueType);
|
|
39709
39808
|
for (const entry of resolved) {
|
|
39710
39809
|
if (expectedDictionary) {
|
|
39711
39810
|
this.requireAssignable(
|
|
@@ -39732,7 +39831,7 @@ var init_strict_resolver = __esm({
|
|
|
39732
39831
|
const type = {
|
|
39733
39832
|
kind: "dictionary",
|
|
39734
39833
|
keyType,
|
|
39735
|
-
valueType
|
|
39834
|
+
valueType: withoutNeoScriptInterfaceProofs(valueType)
|
|
39736
39835
|
};
|
|
39737
39836
|
const wire = toWireType(type, this.project);
|
|
39738
39837
|
if (wire.type !== 5 /* Dictionary */) {
|
|
@@ -39988,8 +40087,19 @@ var init_strict_resolver = __esm({
|
|
|
39988
40087
|
const target = this.resolveType(fact.targetType);
|
|
39989
40088
|
const targetDefinition = target.kind === "named" ? this.project.typeById.get(target.typeId) : void 0;
|
|
39990
40089
|
const naturalDefinition = natural.type.kind === "named" ? this.project.typeById.get(natural.type.typeId) : void 0;
|
|
39991
|
-
|
|
39992
|
-
|
|
40090
|
+
let narrowed = { ...target, nullable: false };
|
|
40091
|
+
if (!fact.bindingName && natural.type.kind === "named" && (naturalDefinition?.kind === "class" || naturalDefinition?.kind === "interface") && target.kind === "named" && targetDefinition?.kind === "interface") {
|
|
40092
|
+
narrowed = { ...natural.type, nullable: false };
|
|
40093
|
+
if (!isNeoScriptTypeAssignable(narrowed, target, this.project)) {
|
|
40094
|
+
narrowed = {
|
|
40095
|
+
...narrowed,
|
|
40096
|
+
narrowedInterfaces: {
|
|
40097
|
+
...natural.type.narrowedInterfaces,
|
|
40098
|
+
[target.typeId]: target
|
|
40099
|
+
}
|
|
40100
|
+
};
|
|
40101
|
+
}
|
|
40102
|
+
}
|
|
39993
40103
|
if (mode === "all" && fact.path !== null && rootEntry !== null && place.type.kind !== "reference") {
|
|
39994
40104
|
targetScope.narrow(fact.path, rootEntry, narrowed);
|
|
39995
40105
|
}
|
|
@@ -40582,7 +40692,11 @@ var init_strict_resolver = __esm({
|
|
|
40582
40692
|
if (receiver.dialogues !== void 0) {
|
|
40583
40693
|
return this.resolveDialogueGroupRead(receiver, name, pos);
|
|
40584
40694
|
}
|
|
40585
|
-
const memberReceiverType =
|
|
40695
|
+
const memberReceiverType = neoScriptMemberReceiverType(
|
|
40696
|
+
receiver.type,
|
|
40697
|
+
name,
|
|
40698
|
+
this.project
|
|
40699
|
+
);
|
|
40586
40700
|
if (memberReceiverType.kind === "named") {
|
|
40587
40701
|
const type = this.project.typeById.get(memberReceiverType.typeId);
|
|
40588
40702
|
if (!type) {
|
|
@@ -41394,7 +41508,7 @@ var init_strict_resolver = __esm({
|
|
|
41394
41508
|
}
|
|
41395
41509
|
const type = {
|
|
41396
41510
|
kind: "list",
|
|
41397
|
-
elementType: entryType
|
|
41511
|
+
elementType: withoutNeoScriptInterfaceProofs(entryType)
|
|
41398
41512
|
};
|
|
41399
41513
|
const wire = toWireType(type, this.project);
|
|
41400
41514
|
if (wire.type !== 6 /* List */) {
|
|
@@ -41635,7 +41749,11 @@ var init_strict_resolver = __esm({
|
|
|
41635
41749
|
pos
|
|
41636
41750
|
);
|
|
41637
41751
|
}
|
|
41638
|
-
const memberReceiverType =
|
|
41752
|
+
const memberReceiverType = neoScriptMemberReceiverType(
|
|
41753
|
+
receiver.type,
|
|
41754
|
+
callee.name,
|
|
41755
|
+
this.project
|
|
41756
|
+
);
|
|
41639
41757
|
const namedType2 = memberReceiverType.kind === "named" ? this.project.typeById.get(memberReceiverType.typeId) : void 0;
|
|
41640
41758
|
const member = namedType2?.members.find(
|
|
41641
41759
|
(candidate) => (candidate.kind === "function" || candidate.kind === "method") && candidate.name === callee.name
|
|
@@ -44060,7 +44178,11 @@ var init_strict_resolver = __esm({
|
|
|
44060
44178
|
}
|
|
44061
44179
|
const receiver = receiverValue();
|
|
44062
44180
|
if (receiver.dialogues !== void 0) return null;
|
|
44063
|
-
const memberReceiverType =
|
|
44181
|
+
const memberReceiverType = neoScriptMemberReceiverType(
|
|
44182
|
+
receiver.type,
|
|
44183
|
+
memberName,
|
|
44184
|
+
this.project
|
|
44185
|
+
);
|
|
44064
44186
|
if (memberReceiverType.kind !== "named") return null;
|
|
44065
44187
|
const type = this.project.typeById.get(memberReceiverType.typeId);
|
|
44066
44188
|
const symbol = type?.members.find(
|
|
@@ -50978,7 +51100,29 @@ function validateExpression(expression, expected, scope, environment, uri, range
|
|
|
50978
51100
|
);
|
|
50979
51101
|
return;
|
|
50980
51102
|
}
|
|
50981
|
-
if (!declaration)
|
|
51103
|
+
if (!declaration) {
|
|
51104
|
+
if (expression.className !== null && !environment.projectIndex.typeByName.has(expression.className) && semanticTypeRef(
|
|
51105
|
+
{
|
|
51106
|
+
name: expression.className,
|
|
51107
|
+
...expression.typeArguments ? { arguments: expression.typeArguments.map(semanticAstType) } : {}
|
|
51108
|
+
},
|
|
51109
|
+
scope,
|
|
51110
|
+
environment
|
|
51111
|
+
) === void 0) {
|
|
51112
|
+
pushDiagnostic(
|
|
51113
|
+
diagnostics,
|
|
51114
|
+
uri,
|
|
51115
|
+
anchor ? anchorSpan(
|
|
51116
|
+
anchor,
|
|
51117
|
+
expression.classNamePos ?? expression.pos,
|
|
51118
|
+
expression.className.length
|
|
51119
|
+
) : range2,
|
|
51120
|
+
"unknown-construction-type",
|
|
51121
|
+
`Unknown class '${expression.className}'.`
|
|
51122
|
+
);
|
|
51123
|
+
}
|
|
51124
|
+
return;
|
|
51125
|
+
}
|
|
50982
51126
|
if (declaration.modifiers.includes("abstract")) {
|
|
50983
51127
|
pushDiagnostic(
|
|
50984
51128
|
diagnostics,
|
|
@@ -55341,7 +55485,7 @@ function sourceParameter(parameter4, owner, typeIds, id2, functionTypeParameters
|
|
|
55341
55485
|
};
|
|
55342
55486
|
}
|
|
55343
55487
|
function substituteInheritedSourceMember(member, baseInfo, resolvedBaseType) {
|
|
55344
|
-
if (baseInfo.declaration.kind !== "class" || resolvedBaseType.kind !== "named") {
|
|
55488
|
+
if (baseInfo.declaration.kind !== "class" && baseInfo.declaration.kind !== "interface" || resolvedBaseType.kind !== "named") {
|
|
55345
55489
|
return {
|
|
55346
55490
|
...member,
|
|
55347
55491
|
inheritedFrom: member.inheritedFrom ?? {
|
|
@@ -143486,13 +143630,6 @@ function drainValueReferenceObligationsV4(state, manifest, options) {
|
|
|
143486
143630
|
...composeReferenceSitePosition(move.site, options.sourceTextByUri)
|
|
143487
143631
|
});
|
|
143488
143632
|
}
|
|
143489
|
-
for (const recorded of options.registry.loweringFailures) {
|
|
143490
|
-
failures.push({
|
|
143491
|
-
message: recorded.message,
|
|
143492
|
-
...recorded.code === void 0 ? {} : { code: recorded.code },
|
|
143493
|
-
...composeReferenceSitePosition(recorded.site, options.sourceTextByUri)
|
|
143494
|
-
});
|
|
143495
|
-
}
|
|
143496
143633
|
for (const obligation of [
|
|
143497
143634
|
...collectionValueObligations(manifest),
|
|
143498
143635
|
...options.registry.referenceObligations
|
|
@@ -143530,7 +143667,17 @@ function drainValueReferenceObligationsV4(state, manifest, options) {
|
|
|
143530
143667
|
...composeReferenceSitePosition(obligation.site, options.sourceTextByUri)
|
|
143531
143668
|
});
|
|
143532
143669
|
}
|
|
143533
|
-
|
|
143670
|
+
const loweringFailures = options.registry.loweringFailures.map(
|
|
143671
|
+
(recorded) => recorded instanceof SchemaSourceError ? recorded : {
|
|
143672
|
+
message: recorded.message,
|
|
143673
|
+
...recorded.code === void 0 ? {} : { code: recorded.code },
|
|
143674
|
+
...composeReferenceSitePosition(
|
|
143675
|
+
recorded.site,
|
|
143676
|
+
options.sourceTextByUri
|
|
143677
|
+
)
|
|
143678
|
+
}
|
|
143679
|
+
);
|
|
143680
|
+
return [...loweringFailures, ...failures];
|
|
143534
143681
|
}
|
|
143535
143682
|
function withoutDeletedValues(state, deletedValueIds) {
|
|
143536
143683
|
if (deletedValueIds.size === 0) return state;
|
|
@@ -152062,6 +152209,7 @@ var INFERRED_GENERIC_CLASS_PREFIX, MEMBER_KIND_DICTIONARY2, MEMBER_KIND_LIST2, M
|
|
|
152062
152209
|
var init_value_sources = __esm({
|
|
152063
152210
|
"src/project-source/value-sources.ts"() {
|
|
152064
152211
|
"use strict";
|
|
152212
|
+
init_source_diagnostics();
|
|
152065
152213
|
init_immutable_json3();
|
|
152066
152214
|
init_lower_support();
|
|
152067
152215
|
init_record_fields();
|
|
@@ -157111,6 +157259,10 @@ function walkValueSegments(walk, startId, segments, path, subject, fail2) {
|
|
|
157111
157259
|
const resolved = walk.resolveVirtualPath?.(startId, segments);
|
|
157112
157260
|
if (resolved != null) return resolved;
|
|
157113
157261
|
} catch (error) {
|
|
157262
|
+
if (error instanceof SchemaSourceError) {
|
|
157263
|
+
walk.registry.loweringFailures.push(error);
|
|
157264
|
+
return null;
|
|
157265
|
+
}
|
|
157114
157266
|
fail2(
|
|
157115
157267
|
`${subject} ${path} could not resolve its construction: ${error instanceof Error ? error.message : String(error)}`
|
|
157116
157268
|
);
|
|
@@ -157185,6 +157337,7 @@ var ROOT_PROJECT_FIELDS2, ROOT_PATH_PENDING_PREFIX;
|
|
|
157185
157337
|
var init_root_source = __esm({
|
|
157186
157338
|
"src/project-source/root-source.ts"() {
|
|
157187
157339
|
"use strict";
|
|
157340
|
+
init_source_diagnostics();
|
|
157188
157341
|
init_project_root();
|
|
157189
157342
|
init_value_comparison();
|
|
157190
157343
|
init_members();
|
|
@@ -160362,30 +160515,47 @@ function computeStatus(workspace, options, conflictedFiles, parseErrors, parseWa
|
|
|
160362
160515
|
[...staticValues.records, ...memberDefaults.records, ...rootValues.records],
|
|
160363
160516
|
staticMemberValueIds
|
|
160364
160517
|
);
|
|
160518
|
+
const sourceTextByUri = new Map(
|
|
160519
|
+
sourceEntries.map((entry) => [entry.relPath, entry.source])
|
|
160520
|
+
);
|
|
160365
160521
|
let collectionBindings;
|
|
160366
160522
|
const resolveVirtualPath = (rootId, segments) => {
|
|
160367
|
-
if (collectionBindings
|
|
160368
|
-
|
|
160369
|
-
|
|
160370
|
-
|
|
160371
|
-
|
|
160372
|
-
|
|
160373
|
-
|
|
160374
|
-
|
|
160375
|
-
|
|
160376
|
-
|
|
160377
|
-
|
|
160378
|
-
|
|
160379
|
-
|
|
160380
|
-
|
|
160381
|
-
|
|
160523
|
+
if (collectionBindings instanceof SchemaSourceError)
|
|
160524
|
+
throw collectionBindings;
|
|
160525
|
+
try {
|
|
160526
|
+
if (collectionBindings === void 0) {
|
|
160527
|
+
const candidate = /* @__PURE__ */ new Map();
|
|
160528
|
+
for (const [key, record7] of Object.entries(rootPathResolutionState)) {
|
|
160529
|
+
if (record7.file !== void 0 && isSchemaRecordKindV4(record7.recordKind) && !documentsByKey.has(key))
|
|
160530
|
+
continue;
|
|
160531
|
+
candidate.set(key, { ...record7, deleted: false });
|
|
160532
|
+
}
|
|
160533
|
+
for (const row of valueLowerRegistry.pendingValues.values()) {
|
|
160534
|
+
candidate.set(`value:${row.id}`, {
|
|
160535
|
+
recordKind: "value",
|
|
160536
|
+
recordId: row.id,
|
|
160537
|
+
contentHash: "",
|
|
160538
|
+
deleted: false,
|
|
160539
|
+
data: { id: row.id, ...encodeStoredValueRowFields(row) }
|
|
160540
|
+
});
|
|
160541
|
+
}
|
|
160542
|
+
const document = readPulledProjectDocumentV4(candidate);
|
|
160543
|
+
compilePulledProjectDocumentForEvaluationV4(document);
|
|
160544
|
+
collectionBindings = new CollectionBindingMaterializer(document);
|
|
160382
160545
|
}
|
|
160383
|
-
const
|
|
160384
|
-
|
|
160385
|
-
|
|
160546
|
+
const resolved = collectionBindings.resolvePath(rootId, segments);
|
|
160547
|
+
return resolved;
|
|
160548
|
+
} catch (error) {
|
|
160549
|
+
const diagnostic = initializerRuntimeDiagnostic(
|
|
160550
|
+
error,
|
|
160551
|
+
valueLowerRegistry.initializerSites,
|
|
160552
|
+
sourceTextByUri,
|
|
160553
|
+
projectAnalysisV4
|
|
160554
|
+
);
|
|
160555
|
+
if (!hasAuthoredSourceFile(diagnostic.file)) throw error;
|
|
160556
|
+
if (collectionBindings === void 0) collectionBindings = diagnostic;
|
|
160557
|
+
throw diagnostic;
|
|
160386
160558
|
}
|
|
160387
|
-
const resolved = collectionBindings.resolvePath(rootId, segments);
|
|
160388
|
-
return resolved;
|
|
160389
160559
|
};
|
|
160390
160560
|
const resolvedCollectionPaths = resolveRootPathCollectionValuesV4({
|
|
160391
160561
|
manifest,
|
|
@@ -160568,7 +160738,7 @@ function computeStatus(workspace, options, conflictedFiles, parseErrors, parseWa
|
|
|
160568
160738
|
unavailableSlots: rootValues.unavailableSlots,
|
|
160569
160739
|
registry: valueLowerRegistry
|
|
160570
160740
|
});
|
|
160571
|
-
if (collectionBindings !== void 0) {
|
|
160741
|
+
if (collectionBindings !== void 0 && !(collectionBindings instanceof SchemaSourceError)) {
|
|
160572
160742
|
const bindings = collectionBindings;
|
|
160573
160743
|
const templateInitializer = (id2) => {
|
|
160574
160744
|
const sourceValueId = bindings.rowForValue(id2)?.sourceValueId;
|
|
@@ -160808,9 +160978,6 @@ function computeStatus(workspace, options, conflictedFiles, parseErrors, parseWa
|
|
|
160808
160978
|
changes.push(recordDeleteChange(recordState, recordFile));
|
|
160809
160979
|
}
|
|
160810
160980
|
appendCollectionEntryDeletes(workspace, reconstructed3, changes);
|
|
160811
|
-
const sourceTextByUri = new Map(
|
|
160812
|
-
sourceEntries.map((entry) => [entry.relPath, entry.source])
|
|
160813
|
-
);
|
|
160814
160981
|
const referenceFailures = drainValueReferenceObligationsV4(
|
|
160815
160982
|
prospectiveState,
|
|
160816
160983
|
manifest,
|
|
@@ -160833,6 +161000,10 @@ function computeStatus(workspace, options, conflictedFiles, parseErrors, parseWa
|
|
|
160833
161000
|
}
|
|
160834
161001
|
);
|
|
160835
161002
|
for (const failure of referenceFailures) {
|
|
161003
|
+
if (failure instanceof SchemaSourceError) {
|
|
161004
|
+
parseErrors.push(failure);
|
|
161005
|
+
continue;
|
|
161006
|
+
}
|
|
160836
161007
|
const message = failure.code === void 0 ? failure.message : `${failure.code}: ${failure.message}`;
|
|
160837
161008
|
parseErrors.push(
|
|
160838
161009
|
new SchemaSourceError(
|
|
@@ -160846,7 +161017,11 @@ function computeStatus(workspace, options, conflictedFiles, parseErrors, parseWa
|
|
|
160846
161017
|
}
|
|
160847
161018
|
reportPhase("record-diff-references", "Checking packed values\u2026");
|
|
160848
161019
|
if (referenceFailures.length > 0) {
|
|
160849
|
-
return refusedStatus(
|
|
161020
|
+
return refusedStatus(
|
|
161021
|
+
conflictedFiles,
|
|
161022
|
+
uniqueSourceErrors(parseErrors),
|
|
161023
|
+
parseWarnings
|
|
161024
|
+
);
|
|
160850
161025
|
}
|
|
160851
161026
|
if (valueLowerRegistry.initializerKeyPatches.size > 0) {
|
|
160852
161027
|
authoredValueSeeds = settleInitializerKeyCode({
|
|
@@ -167475,9 +167650,10 @@ function completionItemsForResolution(snapshot, resolved, word) {
|
|
|
167475
167650
|
}
|
|
167476
167651
|
const memberType2 = neoScriptMemberLookupType(resolved.type);
|
|
167477
167652
|
const owner = memberType2.kind === "named" ? snapshot.project.typeById.get(memberType2.typeId) : void 0;
|
|
167478
|
-
return membersForType(snapshot, resolved.type).filter(
|
|
167479
|
-
|
|
167480
|
-
|
|
167653
|
+
return membersForType(snapshot, resolved.type).filter((symbol) => {
|
|
167654
|
+
const declaration = symbol.inheritedFrom === void 0 ? owner : snapshot.project.typeById.get(symbol.inheritedFrom.typeId) ?? owner;
|
|
167655
|
+
return (resolved.symbol?.name !== "base" || isConcreteBaseMember(symbol)) && (declaration === void 0 || isMemberCompletionAccessible(snapshot, declaration, symbol));
|
|
167656
|
+
}).map((symbol) => symbolCompletion(symbol, word, snapshot));
|
|
167481
167657
|
}
|
|
167482
167658
|
function isConcreteBaseMember(symbol) {
|
|
167483
167659
|
return !symbol.id.startsWith("builtin:") && symbol.static !== true && symbol.abstract !== true && (symbol.kind === "function" || symbol.kind === "method" || symbol.computed === true);
|
|
@@ -167537,6 +167713,22 @@ function membersForType(snapshot, type) {
|
|
|
167537
167713
|
} : {}
|
|
167538
167714
|
};
|
|
167539
167715
|
});
|
|
167716
|
+
if (type.narrowedInterfaces) {
|
|
167717
|
+
const names = new Set(members.map((member) => member.name));
|
|
167718
|
+
for (const bound of Object.values(type.narrowedInterfaces)) {
|
|
167719
|
+
for (const member of membersForType(snapshot, bound)) {
|
|
167720
|
+
if (names.has(member.name)) continue;
|
|
167721
|
+
names.add(member.name);
|
|
167722
|
+
const owner = snapshot.project.typeById.get(bound.typeId);
|
|
167723
|
+
members.push(
|
|
167724
|
+
owner === void 0 || member.inheritedFrom !== void 0 ? member : {
|
|
167725
|
+
...member,
|
|
167726
|
+
inheritedFrom: { typeId: owner.id, typeName: owner.name }
|
|
167727
|
+
}
|
|
167728
|
+
);
|
|
167729
|
+
}
|
|
167730
|
+
}
|
|
167731
|
+
}
|
|
167540
167732
|
if (named.kind === "class") {
|
|
167541
167733
|
members = members.filter(
|
|
167542
167734
|
(member) => member.name !== NEOSCRIPT_CLASS_ID_MEMBER
|
|
@@ -215809,7 +216001,7 @@ var releaseWorkspaceLock = () => void 0;
|
|
|
215809
216001
|
async function main() {
|
|
215810
216002
|
const args = parseArgs(process.argv.slice(2));
|
|
215811
216003
|
if (args.command === "--version") {
|
|
215812
|
-
console.log("0.84.
|
|
216004
|
+
console.log("0.84.2");
|
|
215813
216005
|
return;
|
|
215814
216006
|
}
|
|
215815
216007
|
if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {
|
package/dist/test-worker.mjs
CHANGED
|
@@ -15965,6 +15965,22 @@ function neoScriptMemberLookupType(type) {
|
|
|
15965
15965
|
}
|
|
15966
15966
|
return nullable2 && current.nullable !== true ? { ...current, nullable: true } : current;
|
|
15967
15967
|
}
|
|
15968
|
+
function neoScriptMemberReceiverType(type, memberName, project) {
|
|
15969
|
+
const primary = neoScriptMemberLookupType(type);
|
|
15970
|
+
if (primary.kind !== "named" || primary.narrowedInterfaces === void 0)
|
|
15971
|
+
return primary;
|
|
15972
|
+
const declaration = project.typeById.get(primary.typeId);
|
|
15973
|
+
if (declaration?.kind === "class" && (memberName === NEOSCRIPT_CLASS_ID_MEMBER || memberName === "Clone"))
|
|
15974
|
+
return primary;
|
|
15975
|
+
if (declaration?.members.some((member) => member.name === memberName))
|
|
15976
|
+
return primary;
|
|
15977
|
+
for (const bound of Object.values(primary.narrowedInterfaces)) {
|
|
15978
|
+
if (project.typeById.get(bound.typeId)?.members.some((member) => member.name === memberName)) {
|
|
15979
|
+
return { ...bound, nullable: primary.nullable === true };
|
|
15980
|
+
}
|
|
15981
|
+
}
|
|
15982
|
+
return primary;
|
|
15983
|
+
}
|
|
15968
15984
|
function isNeoScriptHandleReferenceTarget(target, isValueType) {
|
|
15969
15985
|
switch (target.kind) {
|
|
15970
15986
|
case "list":
|
|
@@ -16288,6 +16304,20 @@ function isNeoScriptTypeAssignable(source, target, project) {
|
|
|
16288
16304
|
if (isUnknownType(source) || isUnknownType(target)) return false;
|
|
16289
16305
|
if (isNullType(source)) return isNullableType2(target);
|
|
16290
16306
|
if (isNullableType2(source) && !isNullableType2(target)) return false;
|
|
16307
|
+
if (target.kind === "named" && target.narrowedInterfaces !== void 0) {
|
|
16308
|
+
for (const bound of Object.values(target.narrowedInterfaces)) {
|
|
16309
|
+
if (!isNeoScriptTypeAssignable(source, bound, project)) return false;
|
|
16310
|
+
}
|
|
16311
|
+
}
|
|
16312
|
+
if (source.kind === "named" && source.narrowedInterfaces !== void 0) {
|
|
16313
|
+
const direct = target.kind === "named" ? source.narrowedInterfaces[target.typeId] : void 0;
|
|
16314
|
+
if (direct !== void 0 && isNeoScriptTypeAssignable(direct, target, project))
|
|
16315
|
+
return true;
|
|
16316
|
+
for (const bound of Object.values(source.narrowedInterfaces)) {
|
|
16317
|
+
if (bound !== direct && isNeoScriptTypeAssignable(bound, target, project))
|
|
16318
|
+
return true;
|
|
16319
|
+
}
|
|
16320
|
+
}
|
|
16291
16321
|
if (source.kind === "primitive" && target.kind === "primitive") {
|
|
16292
16322
|
if (source.name === target.name) return true;
|
|
16293
16323
|
return source.name === "int" && (target.name === "float" || target.name === "decimal");
|
|
@@ -16372,9 +16402,40 @@ function isNeoScriptTypeAssignable(source, target, project) {
|
|
|
16372
16402
|
}
|
|
16373
16403
|
return false;
|
|
16374
16404
|
}
|
|
16405
|
+
function withoutNeoScriptInterfaceProofs(type) {
|
|
16406
|
+
if (type.kind !== "named" || type.narrowedInterfaces === void 0)
|
|
16407
|
+
return type;
|
|
16408
|
+
const { narrowedInterfaces: _proofs, ...declared } = type;
|
|
16409
|
+
return declared;
|
|
16410
|
+
}
|
|
16375
16411
|
function commonNeoScriptAssignableType(left, right, project) {
|
|
16376
16412
|
if (isNeoScriptTypeAssignable(left, right, project)) return right;
|
|
16377
16413
|
if (isNeoScriptTypeAssignable(right, left, project)) return left;
|
|
16414
|
+
if (left.kind === "named" && right.kind === "named" && (left.narrowedInterfaces !== void 0 || right.narrowedInterfaces !== void 0)) {
|
|
16415
|
+
const declaredLeft = withoutNeoScriptInterfaceProofs(left);
|
|
16416
|
+
const declaredRight = withoutNeoScriptInterfaceProofs(right);
|
|
16417
|
+
const common = commonNeoScriptAssignableType(
|
|
16418
|
+
declaredLeft,
|
|
16419
|
+
declaredRight,
|
|
16420
|
+
project
|
|
16421
|
+
);
|
|
16422
|
+
if (common?.kind !== "named") return null;
|
|
16423
|
+
const proofs = {};
|
|
16424
|
+
for (const [source, other] of [
|
|
16425
|
+
[left, right],
|
|
16426
|
+
[right, left]
|
|
16427
|
+
]) {
|
|
16428
|
+
for (const [id, proof] of Object.entries(
|
|
16429
|
+
source.narrowedInterfaces ?? {}
|
|
16430
|
+
)) {
|
|
16431
|
+
if (proofs[id] !== void 0) continue;
|
|
16432
|
+
const opposite = other.narrowedInterfaces?.[id] ?? other;
|
|
16433
|
+
if (isNeoScriptTypeAssignable(opposite, proof, project))
|
|
16434
|
+
proofs[id] = proof;
|
|
16435
|
+
}
|
|
16436
|
+
}
|
|
16437
|
+
return { ...common, narrowedInterfaces: proofs };
|
|
16438
|
+
}
|
|
16378
16439
|
return null;
|
|
16379
16440
|
}
|
|
16380
16441
|
function isNeoVariantTypeId(typeId, project) {
|
|
@@ -35539,7 +35600,8 @@ var Parser = class _Parser {
|
|
|
35539
35600
|
}
|
|
35540
35601
|
if (isIdentifier(t) && t.text === NEOSCRIPT_CONSTRUCTOR_KEYWORD) {
|
|
35541
35602
|
this.next();
|
|
35542
|
-
const
|
|
35603
|
+
const classToken = isIdentifier(this.peek()) ? this.next() : null;
|
|
35604
|
+
const className = classToken?.text ?? null;
|
|
35543
35605
|
const typeArguments = [];
|
|
35544
35606
|
if (this.eat("operator", "<")) {
|
|
35545
35607
|
if (className === null) {
|
|
@@ -35573,6 +35635,7 @@ var Parser = class _Parser {
|
|
|
35573
35635
|
return {
|
|
35574
35636
|
kind: "new",
|
|
35575
35637
|
className,
|
|
35638
|
+
...classToken ? { classNamePos: at(classToken) } : {},
|
|
35576
35639
|
...typeArguments.length > 0 ? { typeArguments } : {},
|
|
35577
35640
|
args,
|
|
35578
35641
|
...hasArgumentList ? { hasArgumentList: true } : {},
|
|
@@ -44500,7 +44563,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
|
|
|
44500
44563
|
statement.init.pos
|
|
44501
44564
|
);
|
|
44502
44565
|
}
|
|
44503
|
-
const localType = declared ?? initial.type;
|
|
44566
|
+
const localType = declared ?? withoutNeoScriptInterfaceProofs(initial.type);
|
|
44504
44567
|
if (declared) {
|
|
44505
44568
|
this.requireAssignable(
|
|
44506
44569
|
initial.type,
|
|
@@ -44515,16 +44578,18 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
|
|
|
44515
44578
|
initial.pointer,
|
|
44516
44579
|
this.project
|
|
44517
44580
|
);
|
|
44518
|
-
|
|
44519
|
-
|
|
44520
|
-
|
|
44521
|
-
|
|
44522
|
-
|
|
44523
|
-
|
|
44524
|
-
|
|
44525
|
-
this.localWriteTargetRoot(initial, scope)
|
|
44526
|
-
)
|
|
44581
|
+
const entry = scopeVariable(
|
|
44582
|
+
statement.name,
|
|
44583
|
+
local,
|
|
44584
|
+
localType,
|
|
44585
|
+
"local" /* Local */,
|
|
44586
|
+
localOwnership(initial),
|
|
44587
|
+
this.localWriteTargetRoot(initial, scope)
|
|
44527
44588
|
);
|
|
44589
|
+
scope.define(entry);
|
|
44590
|
+
if (inferred && localType !== initial.type) {
|
|
44591
|
+
scope.narrow(statement.name, entry, initial.type);
|
|
44592
|
+
}
|
|
44528
44593
|
return { type: "variable" /* Variable */, variable: local };
|
|
44529
44594
|
}
|
|
44530
44595
|
case "if": {
|
|
@@ -44579,7 +44644,8 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
|
|
|
44579
44644
|
mergeBranchInvalidations(scope, branchExitOwnershipScopes);
|
|
44580
44645
|
if (branchExitNarrowings.length > 0) {
|
|
44581
44646
|
for (const [path, narrowed] of mergeNarrowingMaps(
|
|
44582
|
-
branchExitNarrowings
|
|
44647
|
+
branchExitNarrowings,
|
|
44648
|
+
this.project
|
|
44583
44649
|
)) {
|
|
44584
44650
|
const rootEntry = scope.lookup(pathRoot(path));
|
|
44585
44651
|
if (rootEntry === narrowed.rootEntry) {
|
|
@@ -45505,7 +45571,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
|
|
|
45505
45571
|
}
|
|
45506
45572
|
mergeLoopNarrowings(parent, exitPaths) {
|
|
45507
45573
|
if (exitPaths.length === 0) return;
|
|
45508
|
-
const merged = mergeNarrowingMaps(exitPaths);
|
|
45574
|
+
const merged = mergeNarrowingMaps(exitPaths, this.project);
|
|
45509
45575
|
for (const [path, narrowed] of parent.effectiveNarrowedPaths()) {
|
|
45510
45576
|
const common = merged.get(path);
|
|
45511
45577
|
if (parent.containsEntry(narrowed.rootEntry) && (common?.rootEntry !== narrowed.rootEntry || !typeRefsEqual(common.type, narrowed.type))) {
|
|
@@ -47258,8 +47324,13 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
|
|
|
47258
47324
|
expression.receiver,
|
|
47259
47325
|
scope
|
|
47260
47326
|
);
|
|
47261
|
-
|
|
47262
|
-
|
|
47327
|
+
const memberType2 = neoScriptMemberReceiverType(
|
|
47328
|
+
receiverExpression.type,
|
|
47329
|
+
expression.name,
|
|
47330
|
+
this.project
|
|
47331
|
+
);
|
|
47332
|
+
if (memberType2.kind !== "named") return null;
|
|
47333
|
+
owner = this.project.typeById.get(memberType2.typeId);
|
|
47263
47334
|
symbol = owner?.members.find(
|
|
47264
47335
|
(candidate) => candidate.name === expression.name && (candidate.kind === "function" || candidate.kind === "method")
|
|
47265
47336
|
);
|
|
@@ -47270,7 +47341,10 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
|
|
|
47270
47341
|
expression.pos
|
|
47271
47342
|
);
|
|
47272
47343
|
}
|
|
47273
|
-
receiver = {
|
|
47344
|
+
receiver = {
|
|
47345
|
+
kind: "instance",
|
|
47346
|
+
expression: { ...receiverExpression, type: memberType2 }
|
|
47347
|
+
};
|
|
47274
47348
|
}
|
|
47275
47349
|
} else {
|
|
47276
47350
|
return null;
|
|
@@ -47347,9 +47421,13 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
|
|
|
47347
47421
|
if (symbol === void 0 || symbol.static !== true) return null;
|
|
47348
47422
|
} else {
|
|
47349
47423
|
const receiver2 = this.resolveExpression(expression.receiver, scope);
|
|
47350
|
-
|
|
47351
|
-
|
|
47352
|
-
|
|
47424
|
+
receiverType = neoScriptMemberReceiverType(
|
|
47425
|
+
receiver2.type,
|
|
47426
|
+
expression.name,
|
|
47427
|
+
this.project
|
|
47428
|
+
);
|
|
47429
|
+
if (receiverType.kind !== "named") return null;
|
|
47430
|
+
owner = this.project.typeById.get(receiverType.typeId);
|
|
47353
47431
|
symbol = owner?.members.find(
|
|
47354
47432
|
(candidate) => candidate.name === expression.name && (candidate.kind === "function" || candidate.kind === "method")
|
|
47355
47433
|
);
|
|
@@ -47427,6 +47505,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
|
|
|
47427
47505
|
pos
|
|
47428
47506
|
);
|
|
47429
47507
|
}
|
|
47508
|
+
entryType = withoutNeoScriptInterfaceProofs(entryType);
|
|
47430
47509
|
for (const item of resolved) {
|
|
47431
47510
|
const common = commonNeoScriptAssignableType(
|
|
47432
47511
|
entryType,
|
|
@@ -47451,7 +47530,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
|
|
|
47451
47530
|
}
|
|
47452
47531
|
const type = {
|
|
47453
47532
|
kind: "list",
|
|
47454
|
-
elementType: entryType
|
|
47533
|
+
elementType: withoutNeoScriptInterfaceProofs(entryType)
|
|
47455
47534
|
};
|
|
47456
47535
|
const wire = toWireType(type, this.project);
|
|
47457
47536
|
if (wire.type !== 6 /* List */) {
|
|
@@ -47517,6 +47596,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
|
|
|
47517
47596
|
if (!keyType || !valueType) {
|
|
47518
47597
|
throw new CompileError("Dictionary literal type inference failed.", pos);
|
|
47519
47598
|
}
|
|
47599
|
+
valueType = withoutNeoScriptInterfaceProofs(valueType);
|
|
47520
47600
|
for (const entry of resolved) {
|
|
47521
47601
|
if (expectedDictionary) {
|
|
47522
47602
|
this.requireAssignable(
|
|
@@ -47543,7 +47623,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
|
|
|
47543
47623
|
const type = {
|
|
47544
47624
|
kind: "dictionary",
|
|
47545
47625
|
keyType,
|
|
47546
|
-
valueType
|
|
47626
|
+
valueType: withoutNeoScriptInterfaceProofs(valueType)
|
|
47547
47627
|
};
|
|
47548
47628
|
const wire = toWireType(type, this.project);
|
|
47549
47629
|
if (wire.type !== 5 /* Dictionary */) {
|
|
@@ -47799,8 +47879,19 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
|
|
|
47799
47879
|
const target = this.resolveType(fact.targetType);
|
|
47800
47880
|
const targetDefinition = target.kind === "named" ? this.project.typeById.get(target.typeId) : void 0;
|
|
47801
47881
|
const naturalDefinition = natural.type.kind === "named" ? this.project.typeById.get(natural.type.typeId) : void 0;
|
|
47802
|
-
|
|
47803
|
-
|
|
47882
|
+
let narrowed = { ...target, nullable: false };
|
|
47883
|
+
if (!fact.bindingName && natural.type.kind === "named" && (naturalDefinition?.kind === "class" || naturalDefinition?.kind === "interface") && target.kind === "named" && targetDefinition?.kind === "interface") {
|
|
47884
|
+
narrowed = { ...natural.type, nullable: false };
|
|
47885
|
+
if (!isNeoScriptTypeAssignable(narrowed, target, this.project)) {
|
|
47886
|
+
narrowed = {
|
|
47887
|
+
...narrowed,
|
|
47888
|
+
narrowedInterfaces: {
|
|
47889
|
+
...natural.type.narrowedInterfaces,
|
|
47890
|
+
[target.typeId]: target
|
|
47891
|
+
}
|
|
47892
|
+
};
|
|
47893
|
+
}
|
|
47894
|
+
}
|
|
47804
47895
|
if (mode === "all" && fact.path !== null && rootEntry !== null && place.type.kind !== "reference") {
|
|
47805
47896
|
targetScope.narrow(fact.path, rootEntry, narrowed);
|
|
47806
47897
|
}
|
|
@@ -48393,7 +48484,11 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
|
|
|
48393
48484
|
if (receiver.dialogues !== void 0) {
|
|
48394
48485
|
return this.resolveDialogueGroupRead(receiver, name, pos);
|
|
48395
48486
|
}
|
|
48396
|
-
const memberReceiverType =
|
|
48487
|
+
const memberReceiverType = neoScriptMemberReceiverType(
|
|
48488
|
+
receiver.type,
|
|
48489
|
+
name,
|
|
48490
|
+
this.project
|
|
48491
|
+
);
|
|
48397
48492
|
if (memberReceiverType.kind === "named") {
|
|
48398
48493
|
const type = this.project.typeById.get(memberReceiverType.typeId);
|
|
48399
48494
|
if (!type) {
|
|
@@ -49205,7 +49300,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
|
|
|
49205
49300
|
}
|
|
49206
49301
|
const type = {
|
|
49207
49302
|
kind: "list",
|
|
49208
|
-
elementType: entryType
|
|
49303
|
+
elementType: withoutNeoScriptInterfaceProofs(entryType)
|
|
49209
49304
|
};
|
|
49210
49305
|
const wire = toWireType(type, this.project);
|
|
49211
49306
|
if (wire.type !== 6 /* List */) {
|
|
@@ -49446,7 +49541,11 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
|
|
|
49446
49541
|
pos
|
|
49447
49542
|
);
|
|
49448
49543
|
}
|
|
49449
|
-
const memberReceiverType =
|
|
49544
|
+
const memberReceiverType = neoScriptMemberReceiverType(
|
|
49545
|
+
receiver.type,
|
|
49546
|
+
callee.name,
|
|
49547
|
+
this.project
|
|
49548
|
+
);
|
|
49450
49549
|
const namedType2 = memberReceiverType.kind === "named" ? this.project.typeById.get(memberReceiverType.typeId) : void 0;
|
|
49451
49550
|
const member = namedType2?.members.find(
|
|
49452
49551
|
(candidate) => (candidate.kind === "function" || candidate.kind === "method") && candidate.name === callee.name
|
|
@@ -51871,7 +51970,11 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
|
|
|
51871
51970
|
}
|
|
51872
51971
|
const receiver = receiverValue();
|
|
51873
51972
|
if (receiver.dialogues !== void 0) return null;
|
|
51874
|
-
const memberReceiverType =
|
|
51973
|
+
const memberReceiverType = neoScriptMemberReceiverType(
|
|
51974
|
+
receiver.type,
|
|
51975
|
+
memberName,
|
|
51976
|
+
this.project
|
|
51977
|
+
);
|
|
51875
51978
|
if (memberReceiverType.kind !== "named") return null;
|
|
51876
51979
|
const type = this.project.typeById.get(memberReceiverType.typeId);
|
|
51877
51980
|
const symbol = type?.members.find(
|
|
@@ -53032,17 +53135,22 @@ function mergeFactSets(sets) {
|
|
|
53032
53135
|
)
|
|
53033
53136
|
);
|
|
53034
53137
|
}
|
|
53035
|
-
function mergeNarrowingMaps(maps) {
|
|
53138
|
+
function mergeNarrowingMaps(maps, project) {
|
|
53036
53139
|
const first = maps[0];
|
|
53037
53140
|
if (!first) return /* @__PURE__ */ new Map();
|
|
53038
53141
|
const result = /* @__PURE__ */ new Map();
|
|
53039
53142
|
for (const [path, narrowed] of first) {
|
|
53040
|
-
|
|
53041
|
-
|
|
53042
|
-
|
|
53043
|
-
|
|
53044
|
-
|
|
53143
|
+
let common = narrowed.type;
|
|
53144
|
+
for (let index = 1; index < maps.length; index++) {
|
|
53145
|
+
const candidate = maps[index].get(path);
|
|
53146
|
+
if (candidate?.rootEntry !== narrowed.rootEntry) {
|
|
53147
|
+
common = null;
|
|
53148
|
+
break;
|
|
53149
|
+
}
|
|
53150
|
+
common = commonNeoScriptAssignableType(common, candidate.type, project);
|
|
53151
|
+
if (common === null) break;
|
|
53045
53152
|
}
|
|
53153
|
+
if (common !== null) result.set(path, { ...narrowed, type: common });
|
|
53046
53154
|
}
|
|
53047
53155
|
return result;
|
|
53048
53156
|
}
|
|
@@ -53071,6 +53179,16 @@ function typeRefsEqual(left, right) {
|
|
|
53071
53179
|
if (left.kind === "named" && right.kind === "named") {
|
|
53072
53180
|
const leftArgs = left.typeArguments ?? [];
|
|
53073
53181
|
const rightArgs = right.typeArguments ?? [];
|
|
53182
|
+
if (left.narrowedInterfaces !== right.narrowedInterfaces) {
|
|
53183
|
+
const leftBounds = Object.entries(left.narrowedInterfaces ?? {});
|
|
53184
|
+
const rightBounds = right.narrowedInterfaces ?? {};
|
|
53185
|
+
if (leftBounds.length !== Object.keys(rightBounds).length) return false;
|
|
53186
|
+
for (const [id, leftBound] of leftBounds) {
|
|
53187
|
+
const rightBound = rightBounds[id];
|
|
53188
|
+
if (rightBound === void 0 || !typeRefsEqual(leftBound, rightBound))
|
|
53189
|
+
return false;
|
|
53190
|
+
}
|
|
53191
|
+
}
|
|
53074
53192
|
return left.typeId === right.typeId && leftArgs.length === rightArgs.length && leftArgs.every((item, index) => {
|
|
53075
53193
|
const other = rightArgs[index];
|
|
53076
53194
|
return other !== void 0 && typeRefsEqual(item, other);
|
|
@@ -54050,6 +54168,10 @@ function typesOverlap(left, right, project) {
|
|
|
54050
54168
|
if (isUnknown(left) || isUnknown(right)) return true;
|
|
54051
54169
|
if (isNull(left)) return isNullable(right);
|
|
54052
54170
|
if (isNull(right)) return isNullable(left);
|
|
54171
|
+
left = neoScriptMemberLookupType(left);
|
|
54172
|
+
right = neoScriptMemberLookupType(right);
|
|
54173
|
+
if (left.kind === "typeParameter" || right.kind === "typeParameter")
|
|
54174
|
+
return true;
|
|
54053
54175
|
if (isNeoScriptTypeAssignable(left, right, project) || isNeoScriptTypeAssignable(right, left, project))
|
|
54054
54176
|
return true;
|
|
54055
54177
|
if (left.kind === "named" && right.kind === "named") {
|
package/package.json
CHANGED
|
@@ -129,7 +129,7 @@ wrappers.
|
|
|
129
129
|
The marker near the top of `SKILL.md` must exactly match the package version:
|
|
130
130
|
|
|
131
131
|
```html
|
|
132
|
-
<!-- reviewed-through-cli: 0.84.
|
|
132
|
+
<!-- reviewed-through-cli: 0.84.2 -->
|
|
133
133
|
```
|
|
134
134
|
|
|
135
135
|
The quoted version above is checked too, so this instruction cannot go stale
|
|
@@ -24,6 +24,15 @@ Keep computed getters, setters, functions, dialogue logic, group logic, and
|
|
|
24
24
|
constructors inline in their owning `.neo` or `.neoflow` declaration. Do not
|
|
25
25
|
create `Scripts/<Class>/<Member>.neo` sidecars.
|
|
26
26
|
|
|
27
|
+
Explicit constructions such as `new MissingClass(5)` require a declared type,
|
|
28
|
+
including inside stored object initializers, constructor arguments, and collections.
|
|
29
|
+
The editor reports an unresolved class at its type name and refreshes the diagnostic
|
|
30
|
+
when the declaration changes. Contextual `new(...)` still uses the expected type.
|
|
31
|
+
|
|
32
|
+
If resolving a stored reference encounters an invalid initializer elsewhere,
|
|
33
|
+
the diagnostic points to that initializer's authored file and position. Fix the
|
|
34
|
+
reported initializer; a valid downstream `Reference(...)` is not the error site.
|
|
35
|
+
|
|
27
36
|
Declare a setter's value type explicitly with the canonical form
|
|
28
37
|
`set(int value) { ... }`. Project analysis, candidate materialization, and
|
|
29
38
|
focused script commands all use the same accessor extraction. A property can have at most one getter and one setter. Concrete setters need a body (an empty body is a valid no-op); typed setters must use the property type and the parameter name `value`. Abstract and interface properties declare bodyless accessor contracts.
|
|
@@ -103,6 +112,18 @@ A generic receiver may call methods from its class or interface constraint,
|
|
|
103
112
|
including void calls used as statements. Generic arguments substitute through
|
|
104
113
|
the constraint; nullable receivers still require narrowing or null handling.
|
|
105
114
|
|
|
115
|
+
Runtime `is` tests on generic values check whether the bound can overlap the
|
|
116
|
+
tested type. A class bound need not implement an interface itself when a
|
|
117
|
+
subclass can implement it. A successful pattern binding exposes that interface's
|
|
118
|
+
members, including after `if (item.Data is not IReceiver receiver) continue;`.
|
|
119
|
+
Sealed classes without the interface and unrelated class bounds remain disjoint.
|
|
120
|
+
|
|
121
|
+
An interface guard also narrows the original receiver without a pattern binding.
|
|
122
|
+
After `if (item is not IReceiver) continue;`, `item` exposes both its declared
|
|
123
|
+
class members and `IReceiver` members. The same applies to guards that return,
|
|
124
|
+
throw, or break. Reassignment clears the proof, and paths that did not pass the
|
|
125
|
+
guard cannot use it.
|
|
126
|
+
|
|
106
127
|
Functions, natives and interface functions can declare their own type
|
|
107
128
|
parameters after the name, each with an optional constraint and default:
|
|
108
129
|
|