@neocompose/cli 0.89.11 → 0.89.12
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 +16 -0
- package/dist/neo-runtime.mjs +141 -55
- package/dist/test-worker.mjs +19 -8
- 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/declarations/declarations.md +3 -0
- package/skills/neocompose-cli/references/declarations/initializers.md +2 -0
- package/skills/neocompose-cli/references/neoscript/collections.md +2 -0
- package/skills/neocompose-cli/references/neoscript/delegates-and-listeners.md +6 -1
- package/skills/neocompose-cli/references/world/variants.md +4 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.89.12
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 6dc08d2: Preserve lexical value bindings and non-null narrowing when capturing variables in delegates, including nested closures and variables named after a class.
|
|
8
|
+
|
|
9
|
+
Validate simple member reads in declaration defaults, including missing members, nullable receivers, and inaccessible static members.
|
|
10
|
+
|
|
11
|
+
Rename interface members together with their implementations and overrides, preserving unrelated overloads.
|
|
12
|
+
|
|
13
|
+
Complete delegate parameters inside tuples and named constructor overloads, and restore member completion in switch guards.
|
|
14
|
+
|
|
15
|
+
- 444e57d: Keep generated child-override generic bindings in local exports when candidate preparation reuses a mutable source baseline.
|
|
16
|
+
|
|
17
|
+
Clone owned tuple elements with fresh identities so modifying a copied child does not change the original.
|
|
18
|
+
|
|
3
19
|
## 0.89.11
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
package/dist/neo-runtime.mjs
CHANGED
|
@@ -19377,7 +19377,7 @@ var init_registry = __esm({
|
|
|
19377
19377
|
"../packages/manifest/schema-contract/registry.mjs"() {
|
|
19378
19378
|
"use strict";
|
|
19379
19379
|
PROJECT_SCHEMA_CONTRACT = Object.freeze({
|
|
19380
|
-
cliVersion: "0.89.
|
|
19380
|
+
cliVersion: "0.89.12",
|
|
19381
19381
|
projectFileUploadBatchSize: 32,
|
|
19382
19382
|
documentRecords: {
|
|
19383
19383
|
member: {
|
|
@@ -54884,11 +54884,13 @@ function cloneClassValueGraph(receiver, expected, ctx) {
|
|
|
54884
54884
|
);
|
|
54885
54885
|
clonedRecord[key] = clonedChild.id;
|
|
54886
54886
|
}
|
|
54887
|
-
} else if (Array.isArray(sourceRow.value) && (isMemberEntryCollectionBase(sourceMember) || sourceTypeInfo?.type === 6 /* List */ || sourceTypeInfo?.type === 28 /* Set */)) {
|
|
54887
|
+
} else if (Array.isArray(sourceRow.value) && (isMemberEntryCollectionBase(sourceMember) || isMemberTupleBase(sourceMember) || sourceTypeInfo?.type === 30 /* Tuple */ || sourceTypeInfo?.type === 6 /* List */ || sourceTypeInfo?.type === 28 /* Set */)) {
|
|
54888
54888
|
const entryMember = isMemberEntryCollectionBase(sourceMember) ? evalMemberById(ctx.vm, sourceMember.entryMemberId) : null;
|
|
54889
54889
|
const entryTypeInfo = sourceTypeInfo?.type === 6 /* List */ || sourceTypeInfo?.type === 28 /* Set */ ? sourceTypeInfo.entryTypeInfo : void 0;
|
|
54890
|
-
|
|
54891
|
-
|
|
54890
|
+
const tuple = isMemberTupleBase(sourceMember) ? sourceMember : null;
|
|
54891
|
+
const tupleType = sourceTypeInfo?.type === 30 /* Tuple */ ? sourceTypeInfo : null;
|
|
54892
|
+
if (entryMember !== null || entryTypeInfo !== void 0 || tuple !== null || tupleType !== null) {
|
|
54893
|
+
clone.value = sourceRow.value.map((childId, index) => {
|
|
54892
54894
|
if (typeof childId !== "string") return childId;
|
|
54893
54895
|
const child2 = evalValueById(
|
|
54894
54896
|
ctx,
|
|
@@ -54897,11 +54899,17 @@ function cloneClassValueGraph(receiver, expected, ctx) {
|
|
|
54897
54899
|
ctx.__valueOverlay
|
|
54898
54900
|
);
|
|
54899
54901
|
if (child2 === null) return childId;
|
|
54902
|
+
const elementMember = tuple === null ? entryMember : evalMemberById(ctx.vm, tuple.elementMemberIds[index]);
|
|
54903
|
+
const elementType = tupleType === null ? entryTypeInfo : tupleType.elements[index]?.typeInfo;
|
|
54904
|
+
if (elementMember === null && elementType === void 0)
|
|
54905
|
+
throw new NSGetterRuntimeError(
|
|
54906
|
+
`Class.Clone tuple element ${index} has no type descriptor.`
|
|
54907
|
+
);
|
|
54900
54908
|
return cloneRow2(
|
|
54901
54909
|
child2,
|
|
54902
|
-
|
|
54910
|
+
elementMember,
|
|
54903
54911
|
child2.containerId === sourceRow.id ? id2 : void 0,
|
|
54904
|
-
|
|
54912
|
+
elementType
|
|
54905
54913
|
).id;
|
|
54906
54914
|
});
|
|
54907
54915
|
ctx.onUnattributableValueRead?.(containerEntriesRead(sourceRow.id));
|
|
@@ -75264,9 +75272,10 @@ var init_strict_resolver = __esm({
|
|
|
75264
75272
|
if (outerEntry === null) return null;
|
|
75265
75273
|
const existing = context.byOuterEntry.get(outerEntry);
|
|
75266
75274
|
if (existing !== void 0) return existing;
|
|
75275
|
+
const capturedType = context.outerScope.lookupNarrowedType(name, outerEntry) ?? outerEntry.type;
|
|
75267
75276
|
const parameter4 = variable(
|
|
75268
75277
|
`__capture_${context.serial}_${context.captures.length}__`,
|
|
75269
|
-
|
|
75278
|
+
capturedType,
|
|
75270
75279
|
void 0,
|
|
75271
75280
|
this.project
|
|
75272
75281
|
);
|
|
@@ -75274,7 +75283,7 @@ var init_strict_resolver = __esm({
|
|
|
75274
75283
|
...scopeVariable(
|
|
75275
75284
|
name,
|
|
75276
75285
|
parameter4,
|
|
75277
|
-
|
|
75286
|
+
capturedType,
|
|
75278
75287
|
"local" /* Local */,
|
|
75279
75288
|
"local" /* Local */,
|
|
75280
75289
|
outerEntry.writeRoot,
|
|
@@ -83014,7 +83023,9 @@ var init_strict_resolver = __esm({
|
|
|
83014
83023
|
return literal(symbol.type, null);
|
|
83015
83024
|
}
|
|
83016
83025
|
hasValueReceiver(name, scope) {
|
|
83017
|
-
return scope.lookup(name) !== null || this.
|
|
83026
|
+
return scope.lookup(name) !== null || this.delegateCaptureContexts.some(
|
|
83027
|
+
(context) => context.outerScope.lookup(name) !== null
|
|
83028
|
+
) || this.implicitMember(name) !== null;
|
|
83018
83029
|
}
|
|
83019
83030
|
implicitMember(name) {
|
|
83020
83031
|
if (this.context.implicitMemberAccess !== true) return null;
|
|
@@ -99500,7 +99511,8 @@ function validateExpression(expression, expected, scope, environment, uri, range
|
|
|
99500
99511
|
const sourceOnly = expected !== void 0 && (isNeoVariantTypeName(expected.name) || expected.name === "NeoAction" || expected.name === "ImageRef");
|
|
99501
99512
|
let receiver = expression;
|
|
99502
99513
|
while (receiver.kind === "member") receiver = receiver.receiver;
|
|
99503
|
-
const
|
|
99514
|
+
const executableMember = expression.kind === "member" && (receiver.kind !== "ident" || receiver.typeQualifier !== void 0);
|
|
99515
|
+
const computed = (environment.checkComputedInitializers || expected?.name === "NeoDelegate") && !sourceOnly && (executableMember || expression.kind === "member" && expected?.name !== "NeoDelegate" || [
|
|
99504
99516
|
"binary",
|
|
99505
99517
|
"unary",
|
|
99506
99518
|
"force",
|
|
@@ -99549,14 +99561,13 @@ function validateExpression(expression, expected, scope, environment, uri, range
|
|
|
99549
99561
|
void 0,
|
|
99550
99562
|
{ allowPendingRegistryEntries: true }
|
|
99551
99563
|
);
|
|
99552
|
-
|
|
99553
|
-
|
|
99554
|
-
expected
|
|
99555
|
-
|
|
99556
|
-
|
|
99557
|
-
environment.projectIndex
|
|
99558
|
-
)
|
|
99564
|
+
const storedMember = storedValue && expression.kind === "member" && !executableMember;
|
|
99565
|
+
const expectedType = expected === void 0 || storedMember ? void 0 : resolveNeoScriptType(
|
|
99566
|
+
semanticAst(expected, expression.pos),
|
|
99567
|
+
context,
|
|
99568
|
+
environment.projectIndex
|
|
99559
99569
|
);
|
|
99570
|
+
scopedResolver.validateInitializerExpression(expression, expectedType);
|
|
99560
99571
|
} catch (error) {
|
|
99561
99572
|
if (!(error instanceof CompileError)) throw error;
|
|
99562
99573
|
pushDiagnostic(
|
|
@@ -104061,6 +104072,7 @@ function validateProjectSourceTypes(documents) {
|
|
|
104061
104072
|
validateSetSpelling(documents, environment.typeKinds, diagnostics);
|
|
104062
104073
|
return {
|
|
104063
104074
|
diagnostics,
|
|
104075
|
+
memberRelations: environment.memberRelations,
|
|
104064
104076
|
overloadImplementations: overloadImplementations(environment)
|
|
104065
104077
|
};
|
|
104066
104078
|
}
|
|
@@ -104137,6 +104149,7 @@ function createEnvironment2(documents) {
|
|
|
104137
104149
|
}
|
|
104138
104150
|
return {
|
|
104139
104151
|
declarations,
|
|
104152
|
+
memberRelations: [],
|
|
104140
104153
|
classes,
|
|
104141
104154
|
interfaces,
|
|
104142
104155
|
memberOwners,
|
|
@@ -105317,11 +105330,12 @@ function validateMembers(environment, diagnostics) {
|
|
|
105317
105330
|
}
|
|
105318
105331
|
function validateInterfaceMemberConflicts(ref, environment, diagnostics) {
|
|
105319
105332
|
const inherited = /* @__PURE__ */ new Map();
|
|
105333
|
+
const substitution = identitySubstitution(ref);
|
|
105320
105334
|
for (const base of ref.declaration.baseTypes) {
|
|
105321
105335
|
const target = environment.interfaces.get(base.name);
|
|
105322
105336
|
if (!target) continue;
|
|
105323
105337
|
for (const candidate of interfaceMembers(
|
|
105324
|
-
|
|
105338
|
+
interfaceView(base, target, substitution),
|
|
105325
105339
|
environment
|
|
105326
105340
|
)) {
|
|
105327
105341
|
const key = candidate.member.name.toLowerCase();
|
|
@@ -105338,6 +105352,10 @@ function validateInterfaceMemberConflicts(ref, environment, diagnostics) {
|
|
|
105338
105352
|
"interface-inherited",
|
|
105339
105353
|
environment
|
|
105340
105354
|
) === null) {
|
|
105355
|
+
environment.memberRelations.push([
|
|
105356
|
+
interfaceMemberLocation(prior),
|
|
105357
|
+
interfaceMemberLocation(candidate)
|
|
105358
|
+
]);
|
|
105341
105359
|
continue;
|
|
105342
105360
|
}
|
|
105343
105361
|
diagnose(
|
|
@@ -105359,7 +105377,6 @@ function validateInterfaceMemberConflicts(ref, environment, diagnostics) {
|
|
|
105359
105377
|
);
|
|
105360
105378
|
}
|
|
105361
105379
|
}
|
|
105362
|
-
const substitution = identitySubstitution(ref);
|
|
105363
105380
|
for (const member of ref.declaration.members) {
|
|
105364
105381
|
const prior = inherited.get(member.name.toLowerCase());
|
|
105365
105382
|
if (!prior) continue;
|
|
@@ -105368,12 +105385,18 @@ function validateInterfaceMemberConflicts(ref, environment, diagnostics) {
|
|
|
105368
105385
|
}
|
|
105369
105386
|
const mismatch = memberCompatibility(
|
|
105370
105387
|
member,
|
|
105371
|
-
|
|
105388
|
+
substitution,
|
|
105372
105389
|
prior,
|
|
105373
105390
|
"interface-inherited",
|
|
105374
105391
|
environment
|
|
105375
105392
|
);
|
|
105376
|
-
if (!mismatch)
|
|
105393
|
+
if (!mismatch) {
|
|
105394
|
+
environment.memberRelations.push([
|
|
105395
|
+
interfaceMemberLocation(prior),
|
|
105396
|
+
{ uri: ref.uri, range: member.nameRange }
|
|
105397
|
+
]);
|
|
105398
|
+
continue;
|
|
105399
|
+
}
|
|
105377
105400
|
diagnose(
|
|
105378
105401
|
diagnostics,
|
|
105379
105402
|
ref.uri,
|
|
@@ -105405,7 +105428,13 @@ function validateAbstractInterfaceMembers(ref, environment, diagnostics) {
|
|
|
105405
105428
|
"interface-contract",
|
|
105406
105429
|
environment
|
|
105407
105430
|
);
|
|
105408
|
-
if (!mismatch)
|
|
105431
|
+
if (!mismatch) {
|
|
105432
|
+
environment.memberRelations.push([
|
|
105433
|
+
interfaceMemberLocation(contract),
|
|
105434
|
+
memberLocation(implementation)
|
|
105435
|
+
]);
|
|
105436
|
+
continue;
|
|
105437
|
+
}
|
|
105409
105438
|
diagnose(
|
|
105410
105439
|
diagnostics,
|
|
105411
105440
|
ref.uri,
|
|
@@ -106447,6 +106476,10 @@ function validateConcreteClass(ref, environment, diagnostics) {
|
|
|
106447
106476
|
environment
|
|
106448
106477
|
) : null;
|
|
106449
106478
|
if (implementation && !implementation.member.modifiers.includes("abstract") && !implementation.member.modifiers.includes("static") && mismatch === null) {
|
|
106479
|
+
environment.memberRelations.push([
|
|
106480
|
+
interfaceMemberLocation(required2),
|
|
106481
|
+
memberLocation(implementation)
|
|
106482
|
+
]);
|
|
106450
106483
|
continue;
|
|
106451
106484
|
}
|
|
106452
106485
|
diagnose(
|
|
@@ -107561,6 +107594,7 @@ function analyzeNeoProjectSources(inputs, parsedDocuments = /* @__PURE__ */ new
|
|
|
107561
107594
|
compiledBodies: bodyCompilation.bodies,
|
|
107562
107595
|
bodyContexts: bodyCompilation.contexts,
|
|
107563
107596
|
overloadImplementations: typeValidation.overloadImplementations,
|
|
107597
|
+
memberRelations: typeValidation.memberRelations,
|
|
107564
107598
|
diagnostics
|
|
107565
107599
|
};
|
|
107566
107600
|
}
|
|
@@ -149329,9 +149363,8 @@ function materializeVariantChildOverrideBindingMembers(args) {
|
|
|
149329
149363
|
classId
|
|
149330
149364
|
);
|
|
149331
149365
|
args.serverMintedBindingMemberIds?.add(member.id);
|
|
149332
|
-
if (
|
|
149333
|
-
|
|
149334
|
-
else args.document.members.push(member);
|
|
149366
|
+
if (minted.size === 0) args.document.members = [...args.document.members];
|
|
149367
|
+
args.document.members.push(member);
|
|
149335
149368
|
args.prepared.push({
|
|
149336
149369
|
recordKind: "member",
|
|
149337
149370
|
recordId: member.id,
|
|
@@ -149354,6 +149387,7 @@ function materializeStaticSeedBindingMembers(args) {
|
|
|
149354
149387
|
if (ids.size !== bindings.length) {
|
|
149355
149388
|
throw new Error("Schema commit contains duplicate generic binding seeds.");
|
|
149356
149389
|
}
|
|
149390
|
+
if (bindings.length > 0) args.document.members = [...args.document.members];
|
|
149357
149391
|
for (const binding of bindings) {
|
|
149358
149392
|
const expectedBindingId = worldAnimationChildOverrideBindingMemberId(
|
|
149359
149393
|
binding.classId
|
|
@@ -149378,9 +149412,7 @@ function materializeStaticSeedBindingMembers(args) {
|
|
|
149378
149412
|
binding.classId
|
|
149379
149413
|
);
|
|
149380
149414
|
args.serverMintedBindingMemberIds?.add(member.id);
|
|
149381
|
-
|
|
149382
|
-
args.document.members = [...args.document.members, member];
|
|
149383
|
-
else args.document.members.push(member);
|
|
149415
|
+
args.document.members.push(member);
|
|
149384
149416
|
args.prepared.push({
|
|
149385
149417
|
recordKind: "member",
|
|
149386
149418
|
recordId: member.id,
|
|
@@ -151663,7 +151695,6 @@ var init_project_version_schema_commit = __esm({
|
|
|
151663
151695
|
"../src/database/project-version-schema-commit.ts"() {
|
|
151664
151696
|
"use strict";
|
|
151665
151697
|
init_members();
|
|
151666
|
-
init_immutable_json2();
|
|
151667
151698
|
init_commit_preparation_pass_cache();
|
|
151668
151699
|
init_compiled_construction_types();
|
|
151669
151700
|
init_member_kinds();
|
|
@@ -189603,7 +189634,7 @@ function scriptFeatureIndex(snapshot) {
|
|
|
189603
189634
|
typeAnnotations,
|
|
189604
189635
|
tokens,
|
|
189605
189636
|
tokenIndexes,
|
|
189606
|
-
enclosingOpener:
|
|
189637
|
+
enclosingOpener: receiverEnclosingOpeners(tokens),
|
|
189607
189638
|
objectInitializers
|
|
189608
189639
|
};
|
|
189609
189640
|
SCRIPT_FEATURE_INDEX.set(snapshot, index);
|
|
@@ -192574,7 +192605,7 @@ function flowProbe(snapshot) {
|
|
|
192574
192605
|
const tokens = scriptFeatureIndex(snapshot).tokens;
|
|
192575
192606
|
const overloaded = overloadedFunctionNames(snapshot.project);
|
|
192576
192607
|
if (!tokens.some(
|
|
192577
|
-
(token) => token.text === "is" || token.text === "switch" || overloaded.has(token.text)
|
|
192608
|
+
(token) => token.text === "is" || token.text === "=>" || token.text === "switch" || overloaded.has(token.text)
|
|
192578
192609
|
) && !hasGenericCall(snapshot))
|
|
192579
192610
|
return result;
|
|
192580
192611
|
const text = snapshot.source.text;
|
|
@@ -193921,6 +193952,8 @@ function expressionTokensBefore(tokens, endExclusive) {
|
|
|
193921
193952
|
start = name;
|
|
193922
193953
|
continue;
|
|
193923
193954
|
}
|
|
193955
|
+
if (depth === 0 && token.text === "when" && start < endExclusive - 1 && ![".", "?.", "!", "[", "<"].includes(tokens[start + 1]?.text ?? "") && followsSwitchPattern(tokens, start))
|
|
193956
|
+
break;
|
|
193924
193957
|
if (depth === 0 && (token.kind === "punctuation" && [";", "{", "}", ",", ":", "?"].includes(token.text) || // Only `?.` and `!` continue a receiver; every other operator
|
|
193925
193958
|
// (`+=`, `==`, `<`, …) ends it.
|
|
193926
193959
|
token.kind === "operator" && token.text !== "?." && token.text !== "!" || token.kind === "keyword" && ["return", "throw", "if", "else"].includes(token.text))) {
|
|
@@ -193929,6 +193962,24 @@ function expressionTokensBefore(tokens, endExclusive) {
|
|
|
193929
193962
|
}
|
|
193930
193963
|
return tokens.slice(start + 1, endExclusive);
|
|
193931
193964
|
}
|
|
193965
|
+
function receiverEnclosingOpeners(tokens) {
|
|
193966
|
+
let index = RECEIVER_ENCLOSING_OPENERS.get(tokens);
|
|
193967
|
+
if (!index) {
|
|
193968
|
+
index = enclosingOpenerIndex(tokens);
|
|
193969
|
+
RECEIVER_ENCLOSING_OPENERS.set(tokens, index);
|
|
193970
|
+
}
|
|
193971
|
+
return index;
|
|
193972
|
+
}
|
|
193973
|
+
function followsSwitchPattern(tokens, index) {
|
|
193974
|
+
const opener = receiverEnclosingOpeners(tokens)[index] ?? -1;
|
|
193975
|
+
if (tokens[opener]?.text !== "{" || tokens[opener - 1]?.text !== "switch")
|
|
193976
|
+
return false;
|
|
193977
|
+
const previous = tokens[index - 1];
|
|
193978
|
+
if (!previous) return false;
|
|
193979
|
+
if (previous.text === "when")
|
|
193980
|
+
return ["{", ","].includes(tokens[index - 2]?.text ?? "");
|
|
193981
|
+
return previous.kind === "identifier" || previous.kind === "integer" || previous.kind === "float" || previous.kind === "type" || previous.kind === "string" || [")", "]", ">", "true", "false", "null"].includes(previous.text);
|
|
193982
|
+
}
|
|
193932
193983
|
function genericCallNameIndex(tokens, close) {
|
|
193933
193984
|
if (!["(", ".", "{"].includes(tokens[close + 1]?.text ?? "")) return -1;
|
|
193934
193985
|
let depth = 0;
|
|
@@ -194082,7 +194133,7 @@ function isTypeAnnotationReference(snapshot, reference2) {
|
|
|
194082
194133
|
function isConstructorTypeReference(snapshot, reference2) {
|
|
194083
194134
|
return scriptFeatureIndex(snapshot).calls.get(reference2.start)?.kind === "constructor";
|
|
194084
194135
|
}
|
|
194085
|
-
var SCRIPT_FEATURE_INDEX, assumedLambdaInputs, LIST_OPENERS, LIST_CLOSERS, TUPLE_LABEL_DECLARATIONS, NAMED_ARGUMENT_LABELS, NO_EXPECTED_VALUE, CONSTRUCTIONS, ANNOTATION_TYPE_NAMES, FLOW_PROBES, PATTERN_DECLARATIONS, OVERLOADED_FUNCTION_NAMES, GENERIC_CALL_NAMES, LOCAL_SCOPE_INDEX, NAMED_ITEM_INDEX, COLLECTION_FUNCTION_DOCUMENTATION, LOCAL_SYMBOL_CACHE, CALL_COMMIT_CHARACTERS, GENERIC_CALL_COMMIT_CHARACTERS, SETTER_VALUE_ID_SUFFIX, LAMBDA_BODY_INDEX;
|
|
194136
|
+
var SCRIPT_FEATURE_INDEX, assumedLambdaInputs, LIST_OPENERS, LIST_CLOSERS, TUPLE_LABEL_DECLARATIONS, NAMED_ARGUMENT_LABELS, NO_EXPECTED_VALUE, CONSTRUCTIONS, ANNOTATION_TYPE_NAMES, FLOW_PROBES, PATTERN_DECLARATIONS, OVERLOADED_FUNCTION_NAMES, GENERIC_CALL_NAMES, LOCAL_SCOPE_INDEX, NAMED_ITEM_INDEX, COLLECTION_FUNCTION_DOCUMENTATION, LOCAL_SYMBOL_CACHE, CALL_COMMIT_CHARACTERS, GENERIC_CALL_COMMIT_CHARACTERS, SETTER_VALUE_ID_SUFFIX, RECEIVER_ENCLOSING_OPENERS, LAMBDA_BODY_INDEX;
|
|
194086
194137
|
var init_analyzer = __esm({
|
|
194087
194138
|
"../packages/neoscript-language/src/analyzer.ts"() {
|
|
194088
194139
|
"use strict";
|
|
@@ -194162,6 +194213,7 @@ var init_analyzer = __esm({
|
|
|
194162
194213
|
CALL_COMMIT_CHARACTERS = ["("];
|
|
194163
194214
|
GENERIC_CALL_COMMIT_CHARACTERS = ["<", "("];
|
|
194164
194215
|
SETTER_VALUE_ID_SUFFIX = ":setter-value";
|
|
194216
|
+
RECEIVER_ENCLOSING_OPENERS = /* @__PURE__ */ new WeakMap();
|
|
194165
194217
|
LAMBDA_BODY_INDEX = /* @__PURE__ */ new WeakMap();
|
|
194166
194218
|
}
|
|
194167
194219
|
});
|
|
@@ -199770,19 +199822,22 @@ function projectReferenceFamily(analysis, target, index = buildProjectSymbolInde
|
|
|
199770
199822
|
}
|
|
199771
199823
|
if (target.kind !== "member" || !target.ownerName) return [target];
|
|
199772
199824
|
const classes = /* @__PURE__ */ new Map();
|
|
199773
|
-
|
|
199825
|
+
const declarations = /* @__PURE__ */ new Map();
|
|
199826
|
+
for (const [uri, document] of analysis.documents) {
|
|
199774
199827
|
for (const declaration of document.declarations) {
|
|
199775
|
-
if (declaration.kind
|
|
199776
|
-
|
|
199828
|
+
if (declaration.kind !== "class") continue;
|
|
199829
|
+
classes.set(declaration.name, declaration);
|
|
199830
|
+
for (const member of declaration.members)
|
|
199831
|
+
declarations.set(locationKey3({ uri, range: member.nameRange }), member);
|
|
199777
199832
|
}
|
|
199778
199833
|
}
|
|
199779
199834
|
const joins = (member) => target.callable !== true || member?.kind === "function" && member.modifiers.some((modifier) => DISPATCH_MODIFIERS2.has(modifier));
|
|
199780
|
-
const declared = (symbol) =>
|
|
199781
|
-
|
|
199835
|
+
const declared = (symbol) => declarations.get(locationKey3(symbol.location));
|
|
199836
|
+
const members2 = analysis.symbols.filter(
|
|
199837
|
+
(symbol) => symbol.kind === "member" && symbol.name.toLowerCase() === target.name.toLowerCase()
|
|
199782
199838
|
);
|
|
199783
|
-
if (!joins(declared(target))) return [target];
|
|
199784
199839
|
const symbols = new Map(
|
|
199785
|
-
|
|
199840
|
+
members2.filter((symbol) => symbol.kind === "member" && joins(declared(symbol))).map((symbol) => [symbol.ownerName, symbol])
|
|
199786
199841
|
);
|
|
199787
199842
|
const roots = /* @__PURE__ */ new Map();
|
|
199788
199843
|
const root = (name) => {
|
|
@@ -199790,9 +199845,7 @@ function projectReferenceFamily(analysis, target, index = buildProjectSymbolInde
|
|
|
199790
199845
|
roots.set(name, null);
|
|
199791
199846
|
const declaration = classes.get(name);
|
|
199792
199847
|
const own = symbols.get(name);
|
|
199793
|
-
const member =
|
|
199794
|
-
(candidate) => candidate.name === target.name && joins(candidate)
|
|
199795
|
-
);
|
|
199848
|
+
const member = own ? declared(own) : void 0;
|
|
199796
199849
|
if (own && !member?.modifiers.includes("override")) {
|
|
199797
199850
|
roots.set(name, own);
|
|
199798
199851
|
return own;
|
|
@@ -199802,11 +199855,43 @@ function projectReferenceFamily(analysis, target, index = buildProjectSymbolInde
|
|
|
199802
199855
|
roots.set(name, resolved);
|
|
199803
199856
|
return resolved;
|
|
199804
199857
|
};
|
|
199805
|
-
const
|
|
199806
|
-
|
|
199807
|
-
return [...symbols.values()].filter(
|
|
199808
|
-
(symbol) => symbol.ownerName && root(symbol.ownerName) === selected
|
|
199858
|
+
const byLocation = new Map(
|
|
199859
|
+
members2.map((symbol) => [locationKey3(symbol.location), symbol])
|
|
199809
199860
|
);
|
|
199861
|
+
const edges = /* @__PURE__ */ new Map();
|
|
199862
|
+
const connect = (a, b) => {
|
|
199863
|
+
const left = locationKey3(a);
|
|
199864
|
+
const right = locationKey3(b);
|
|
199865
|
+
if (!byLocation.has(left) || !byLocation.has(right)) return;
|
|
199866
|
+
const add = (from, to) => {
|
|
199867
|
+
let values = edges.get(from);
|
|
199868
|
+
if (!values) edges.set(from, values = /* @__PURE__ */ new Set());
|
|
199869
|
+
values.add(to);
|
|
199870
|
+
};
|
|
199871
|
+
add(left, right);
|
|
199872
|
+
add(right, left);
|
|
199873
|
+
};
|
|
199874
|
+
for (const symbol of symbols.values()) {
|
|
199875
|
+
const selected = symbol.ownerName ? root(symbol.ownerName) : null;
|
|
199876
|
+
if (selected) connect(symbol.location, selected.location);
|
|
199877
|
+
}
|
|
199878
|
+
for (const [contract, implementation] of analysis.memberRelations)
|
|
199879
|
+
connect(contract, implementation);
|
|
199880
|
+
const visited = /* @__PURE__ */ new Set();
|
|
199881
|
+
const pending = [locationKey3(target.location)];
|
|
199882
|
+
const family = [];
|
|
199883
|
+
while (pending.length > 0) {
|
|
199884
|
+
const key = pending.pop();
|
|
199885
|
+
if (visited.has(key)) continue;
|
|
199886
|
+
visited.add(key);
|
|
199887
|
+
const symbol = byLocation.get(key);
|
|
199888
|
+
if (symbol) family.push(symbol);
|
|
199889
|
+
for (const next of edges.get(key) ?? []) pending.push(next);
|
|
199890
|
+
}
|
|
199891
|
+
return family.length > 0 ? family : [target];
|
|
199892
|
+
}
|
|
199893
|
+
function locationKey3(location3) {
|
|
199894
|
+
return `${location3.uri}:${location3.range.start.line}:${location3.range.start.character}`;
|
|
199810
199895
|
}
|
|
199811
199896
|
var DISPATCH_MODIFIERS2;
|
|
199812
199897
|
var init_project_source_reference_family = __esm({
|
|
@@ -200069,7 +200154,7 @@ function sameLocationInList(target, locations) {
|
|
|
200069
200154
|
(location3) => location3.uri === target.uri && location3.range.start.line === target.range.start.line && location3.range.start.character === target.range.start.character
|
|
200070
200155
|
);
|
|
200071
200156
|
}
|
|
200072
|
-
function
|
|
200157
|
+
function locationKey4(location3) {
|
|
200073
200158
|
const { start, end } = location3.range;
|
|
200074
200159
|
return JSON.stringify([
|
|
200075
200160
|
location3.uri,
|
|
@@ -200636,8 +200721,9 @@ var init_service = __esm({
|
|
|
200636
200721
|
if (!resolved) return [];
|
|
200637
200722
|
const declaration = resolved.symbol;
|
|
200638
200723
|
const family = projectReferenceFamily(analysis, declaration, index);
|
|
200724
|
+
const familyNames = new Set(family.map((member) => member.name));
|
|
200639
200725
|
const familyLocations = new Set(
|
|
200640
|
-
family.map((member) =>
|
|
200726
|
+
family.map((member) => locationKey4(member.location))
|
|
200641
200727
|
);
|
|
200642
200728
|
const familyIds = new Set(
|
|
200643
200729
|
family.flatMap((member) => member.id === null ? [] : [member.id])
|
|
@@ -200652,7 +200738,7 @@ var init_service = __esm({
|
|
|
200652
200738
|
for (let tokenIndex = 0; tokenIndex < tokens.length; tokenIndex++) {
|
|
200653
200739
|
const candidate = tokens[tokenIndex];
|
|
200654
200740
|
if (!isProjectNameToken(candidate)) continue;
|
|
200655
|
-
const matches = parameterName === null ? candidate.text
|
|
200741
|
+
const matches = parameterName === null ? familyNames.has(candidate.text) : candidate.text === declaration.name || candidate.text.toLowerCase() === parameterName && isNamedArgumentLabel(tokens, tokenIndex);
|
|
200656
200742
|
if (!matches) continue;
|
|
200657
200743
|
const candidateSymbol = projectSymbolAt(
|
|
200658
200744
|
analysis,
|
|
@@ -200660,11 +200746,11 @@ var init_service = __esm({
|
|
|
200660
200746
|
candidate.range.start,
|
|
200661
200747
|
index
|
|
200662
200748
|
)?.symbol;
|
|
200663
|
-
if (!candidateSymbol || !familyLocations.has(
|
|
200749
|
+
if (!candidateSymbol || !familyLocations.has(locationKey4(candidateSymbol.location))) {
|
|
200664
200750
|
continue;
|
|
200665
200751
|
}
|
|
200666
200752
|
const location3 = { uri: state.document.uri, range: candidate.range };
|
|
200667
|
-
if (!includeDeclaration && familyLocations.has(
|
|
200753
|
+
if (!includeDeclaration && familyLocations.has(locationKey4(location3))) {
|
|
200668
200754
|
continue;
|
|
200669
200755
|
}
|
|
200670
200756
|
locations.push(location3);
|
|
@@ -200675,11 +200761,11 @@ var init_service = __esm({
|
|
|
200675
200761
|
if (isProjectDocument(state.document, state.context)) continue;
|
|
200676
200762
|
const snapshot = this.scriptSnapshot(state);
|
|
200677
200763
|
for (const candidate of snapshot.parsed.references) {
|
|
200678
|
-
if (candidate.name
|
|
200764
|
+
if (!familyNames.has(candidate.name)) continue;
|
|
200679
200765
|
const symbolId = resolveReferenceSymbolId(snapshot, candidate);
|
|
200680
200766
|
if (symbolId === null) continue;
|
|
200681
200767
|
const matches = familyIds.has(symbolId) || definition(snapshot, candidate.range.start).some(
|
|
200682
|
-
(location3) => familyLocations.has(
|
|
200768
|
+
(location3) => familyLocations.has(locationKey4(location3))
|
|
200683
200769
|
);
|
|
200684
200770
|
if (!matches) continue;
|
|
200685
200771
|
locations.push({ uri: state.document.uri, range: candidate.range });
|
|
@@ -200687,7 +200773,7 @@ var init_service = __esm({
|
|
|
200687
200773
|
if (declaration.kind !== "parameter") continue;
|
|
200688
200774
|
for (const label of namedArgumentLabels(snapshot)) {
|
|
200689
200775
|
const parameter4 = label.parameter.selectionLocation;
|
|
200690
|
-
if (parameter4 && familyLocations.has(
|
|
200776
|
+
if (parameter4 && familyLocations.has(locationKey4(parameter4)))
|
|
200691
200777
|
locations.push({ uri: state.document.uri, range: label.range });
|
|
200692
200778
|
}
|
|
200693
200779
|
}
|
|
@@ -243072,7 +243158,7 @@ var releaseWorkspaceLock = () => void 0;
|
|
|
243072
243158
|
async function main() {
|
|
243073
243159
|
const args = parseArgs(process.argv.slice(2));
|
|
243074
243160
|
if (args.command === "--version") {
|
|
243075
|
-
console.log("0.89.
|
|
243161
|
+
console.log("0.89.12");
|
|
243076
243162
|
return;
|
|
243077
243163
|
}
|
|
243078
243164
|
if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {
|
package/dist/test-worker.mjs
CHANGED
|
@@ -41035,11 +41035,13 @@ function cloneClassValueGraph(receiver, expected, ctx) {
|
|
|
41035
41035
|
);
|
|
41036
41036
|
clonedRecord[key] = clonedChild.id;
|
|
41037
41037
|
}
|
|
41038
|
-
} else if (Array.isArray(sourceRow.value) && (isMemberEntryCollectionBase(sourceMember) || sourceTypeInfo?.type === 6 /* List */ || sourceTypeInfo?.type === 28 /* Set */)) {
|
|
41038
|
+
} else if (Array.isArray(sourceRow.value) && (isMemberEntryCollectionBase(sourceMember) || isMemberTupleBase(sourceMember) || sourceTypeInfo?.type === 30 /* Tuple */ || sourceTypeInfo?.type === 6 /* List */ || sourceTypeInfo?.type === 28 /* Set */)) {
|
|
41039
41039
|
const entryMember = isMemberEntryCollectionBase(sourceMember) ? evalMemberById(ctx.vm, sourceMember.entryMemberId) : null;
|
|
41040
41040
|
const entryTypeInfo = sourceTypeInfo?.type === 6 /* List */ || sourceTypeInfo?.type === 28 /* Set */ ? sourceTypeInfo.entryTypeInfo : void 0;
|
|
41041
|
-
|
|
41042
|
-
|
|
41041
|
+
const tuple = isMemberTupleBase(sourceMember) ? sourceMember : null;
|
|
41042
|
+
const tupleType = sourceTypeInfo?.type === 30 /* Tuple */ ? sourceTypeInfo : null;
|
|
41043
|
+
if (entryMember !== null || entryTypeInfo !== void 0 || tuple !== null || tupleType !== null) {
|
|
41044
|
+
clone.value = sourceRow.value.map((childId, index) => {
|
|
41043
41045
|
if (typeof childId !== "string") return childId;
|
|
41044
41046
|
const child = evalValueById(
|
|
41045
41047
|
ctx,
|
|
@@ -41048,11 +41050,17 @@ function cloneClassValueGraph(receiver, expected, ctx) {
|
|
|
41048
41050
|
ctx.__valueOverlay
|
|
41049
41051
|
);
|
|
41050
41052
|
if (child === null) return childId;
|
|
41053
|
+
const elementMember = tuple === null ? entryMember : evalMemberById(ctx.vm, tuple.elementMemberIds[index]);
|
|
41054
|
+
const elementType = tupleType === null ? entryTypeInfo : tupleType.elements[index]?.typeInfo;
|
|
41055
|
+
if (elementMember === null && elementType === void 0)
|
|
41056
|
+
throw new NSGetterRuntimeError(
|
|
41057
|
+
`Class.Clone tuple element ${index} has no type descriptor.`
|
|
41058
|
+
);
|
|
41051
41059
|
return cloneRow2(
|
|
41052
41060
|
child,
|
|
41053
|
-
|
|
41061
|
+
elementMember,
|
|
41054
41062
|
child.containerId === sourceRow.id ? id : void 0,
|
|
41055
|
-
|
|
41063
|
+
elementType
|
|
41056
41064
|
).id;
|
|
41057
41065
|
});
|
|
41058
41066
|
ctx.onUnattributableValueRead?.(containerEntriesRead(sourceRow.id));
|
|
@@ -59025,9 +59033,10 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
|
|
|
59025
59033
|
if (outerEntry === null) return null;
|
|
59026
59034
|
const existing = context.byOuterEntry.get(outerEntry);
|
|
59027
59035
|
if (existing !== void 0) return existing;
|
|
59036
|
+
const capturedType = context.outerScope.lookupNarrowedType(name, outerEntry) ?? outerEntry.type;
|
|
59028
59037
|
const parameter3 = variable(
|
|
59029
59038
|
`__capture_${context.serial}_${context.captures.length}__`,
|
|
59030
|
-
|
|
59039
|
+
capturedType,
|
|
59031
59040
|
void 0,
|
|
59032
59041
|
this.project
|
|
59033
59042
|
);
|
|
@@ -59035,7 +59044,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
|
|
|
59035
59044
|
...scopeVariable(
|
|
59036
59045
|
name,
|
|
59037
59046
|
parameter3,
|
|
59038
|
-
|
|
59047
|
+
capturedType,
|
|
59039
59048
|
"local" /* Local */,
|
|
59040
59049
|
"local" /* Local */,
|
|
59041
59050
|
outerEntry.writeRoot,
|
|
@@ -66775,7 +66784,9 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
|
|
|
66775
66784
|
return literal(symbol.type, null);
|
|
66776
66785
|
}
|
|
66777
66786
|
hasValueReceiver(name, scope) {
|
|
66778
|
-
return scope.lookup(name) !== null || this.
|
|
66787
|
+
return scope.lookup(name) !== null || this.delegateCaptureContexts.some(
|
|
66788
|
+
(context) => context.outerScope.lookup(name) !== null
|
|
66789
|
+
) || this.implicitMember(name) !== null;
|
|
66779
66790
|
}
|
|
66780
66791
|
implicitMember(name) {
|
|
66781
66792
|
if (this.context.implicitMemberAccess !== true) return null;
|
package/package.json
CHANGED
|
@@ -143,7 +143,7 @@ The marker near the top of `SKILL.md` must exactly match the package version,
|
|
|
143
143
|
and this quoted copy is checked too:
|
|
144
144
|
|
|
145
145
|
```html
|
|
146
|
-
<!-- reviewed-through-cli: 0.89.
|
|
146
|
+
<!-- reviewed-through-cli: 0.89.12 -->
|
|
147
147
|
```
|
|
148
148
|
|
|
149
149
|
Keep this skill on current behavior. Upgrade steps, rollout prerequisites,
|
|
@@ -43,6 +43,9 @@ Generic bindings and their nested collection descriptors follow the owning
|
|
|
43
43
|
declaration's identity. Deleting and recreating an idless declaration creates
|
|
44
44
|
fresh bindings; retaining its pulled IDs preserves them.
|
|
45
45
|
|
|
46
|
+
Editor rename follows an interface member through its compatible implementations
|
|
47
|
+
and overrides. Unrelated members and overloads keep their names.
|
|
48
|
+
|
|
46
49
|
## Modifiers
|
|
47
50
|
|
|
48
51
|
`public`, `protected`, `private`, `static`, `virtual`, `abstract`, `sealed`,
|
|
@@ -36,6 +36,8 @@ indentation, using the project's configured spaces or tabs.
|
|
|
36
36
|
The editor checks computed defaults with the same expression resolver as push.
|
|
37
37
|
Unknown names, missing members, invalid type arguments, and expression type
|
|
38
38
|
errors appear at the offending initializer expression, including nested defaults.
|
|
39
|
+
This includes simple member reads such as `value.Name`: nullable receivers and
|
|
40
|
+
private or protected access receive the same checks as executable bodies.
|
|
39
41
|
|
|
40
42
|
A default that isn't a closed literal stores as a computed initializer and
|
|
41
43
|
replays for omitted members in push, web, and SDK. A stored override stays
|
|
@@ -149,3 +149,5 @@ computed properties and callable signatures for cursors; store `List<T>` data
|
|
|
149
149
|
explicitly. Stored enumerable interface members accept authored class rows.
|
|
150
150
|
Runtime sequences are shown as unenumerated and are not expanded for previews.
|
|
151
151
|
`ToSet()` rejects enumerable/cursor interface elements.
|
|
152
|
+
|
|
153
|
+
`Clone()` also copies owned class values inside tuples. References inside the copied graph keep their targets.
|
|
@@ -11,7 +11,12 @@ List<Item> ready = this.Items.Where((item) => item.Count > 0);
|
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
- Lambdas may be returned, stored, or assigned to typed locals. They capture
|
|
14
|
-
surrounding locals and parameters by value when created.
|
|
14
|
+
surrounding locals and parameters by value when created. A non-null check
|
|
15
|
+
on a local remains valid inside its capture, even if the outer local is later
|
|
16
|
+
reassigned. This does not freeze mutable fields on captured objects.
|
|
17
|
+
A captured value can share a class name; member access uses the value.
|
|
18
|
+
- Editor completion uses the delegate parameter type inside tuple values and
|
|
19
|
+
named constructor arguments, including overloaded constructors.
|
|
15
20
|
- `(x) => x * 2` equals `(x) => { return x * 2; }`. In a void delegate the
|
|
16
21
|
expression must call or assign. Parenthesize a dictionary-literal body:
|
|
17
22
|
`() => ({ "a": 1 })`.
|
|
@@ -64,6 +64,10 @@ frame. For editing an existing clip, see [frame overrides](animation.md).
|
|
|
64
64
|
as instance overrides, and `ToVariant(Base)` removes the applied layer.
|
|
65
65
|
- On an object nested inside another instance's construction, `ToVariant`
|
|
66
66
|
applies in place and records nothing.
|
|
67
|
+
- Child overrides also answer omitted fields on children with their own
|
|
68
|
+
constructor recipes. The child keeps its identity and unanswered defaults.
|
|
69
|
+
Later instance writes remain pins until an answering variant transition clears
|
|
70
|
+
them. Structured partials change only the named components.
|
|
67
71
|
- Selections compare equal when class, variant, and bound lookup row match.
|
|
68
72
|
An unset optional selection differs from `Base`.
|
|
69
73
|
|