@neocompose/cli 0.53.2 → 0.53.3
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
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.53.3] - 2026-09-19
|
|
4
|
+
|
|
5
|
+
- Executable object initializers can set immutable stored members during construction. Later mutation and readonly-member restrictions still apply.
|
|
6
|
+
- Evaluator effect results encode assigned lists and dictionaries as entry rows while preserving collection aliases during execution.
|
|
7
|
+
|
|
3
8
|
## [0.53.2] - 2026-09-19
|
|
4
9
|
|
|
5
10
|
- `Reference(Symbol)` and `Reference(LocalValue)` inside a constructed instance's initializer block compile. The stored initializer now carries `Reference<T>(id: "…")`, which the strict resolver accepts, so a list entry created with `new Stop(hour: 7) { MerchantRef = Reference(TestMerchant) }`, a member-default template, and the replay after a class change all push instead of failing with `Unknown function 'Reference'`. A local that carries no `@id` yet is refused by name.
|
package/dist/neo.mjs
CHANGED
|
@@ -7456,7 +7456,7 @@ var init_strict_resolver = __esm({
|
|
|
7456
7456
|
}
|
|
7457
7457
|
return resolved.pointer.value;
|
|
7458
7458
|
}
|
|
7459
|
-
resolveAssignment(statement, scope) {
|
|
7459
|
+
resolveAssignment(statement, scope, assignmentContext = "ordinary") {
|
|
7460
7460
|
if (!isAssignmentTarget(statement.target)) {
|
|
7461
7461
|
throw new CompileError(
|
|
7462
7462
|
"Assignment target must be a variable, member, or indexed value.",
|
|
@@ -7494,9 +7494,27 @@ var init_strict_resolver = __esm({
|
|
|
7494
7494
|
statement.pos
|
|
7495
7495
|
);
|
|
7496
7496
|
}
|
|
7497
|
-
if (
|
|
7497
|
+
if (target.symbol?.readonlyDeclaration === true) {
|
|
7498
7498
|
throw new CompileError(
|
|
7499
|
-
|
|
7499
|
+
`Member '${target.symbol.name}' is readonly and can only be changed through its class default.`,
|
|
7500
|
+
statement.pos
|
|
7501
|
+
);
|
|
7502
|
+
}
|
|
7503
|
+
if (writability === void 0) {
|
|
7504
|
+
throw new CompileError(
|
|
7505
|
+
`Cannot assign to a read-only ${this.describe(target.type)} value.`,
|
|
7506
|
+
statement.pos
|
|
7507
|
+
);
|
|
7508
|
+
}
|
|
7509
|
+
if (writability === "readOnly" /* ReadOnly */) {
|
|
7510
|
+
throw new CompileError(
|
|
7511
|
+
`Cannot assign to a read-only ${this.describe(target.type)} value.`,
|
|
7512
|
+
statement.pos
|
|
7513
|
+
);
|
|
7514
|
+
}
|
|
7515
|
+
if (writability === "immutable" /* Immutable */ && assignmentContext !== "initializer") {
|
|
7516
|
+
throw new CompileError(
|
|
7517
|
+
"Cannot assign because the target's effective storage is immutable.",
|
|
7500
7518
|
statement.pos
|
|
7501
7519
|
);
|
|
7502
7520
|
}
|
|
@@ -9281,16 +9299,22 @@ var init_strict_resolver = __esm({
|
|
|
9281
9299
|
const registryEntry = this.resolveRegistryEntry(receiver, name, pos);
|
|
9282
9300
|
if (registryEntry) return registryEntry;
|
|
9283
9301
|
if (receiver.indexSurface) {
|
|
9284
|
-
const
|
|
9285
|
-
|
|
9302
|
+
const surface = receiver.indexSurface;
|
|
9303
|
+
const declared = this.indexesFor(surface).find(
|
|
9304
|
+
(candidate) => candidate.name === name
|
|
9286
9305
|
);
|
|
9287
|
-
if (!
|
|
9306
|
+
if (!declared) {
|
|
9288
9307
|
throw new CompileError(
|
|
9289
9308
|
`List index surface has no declared index '${name}'.`,
|
|
9290
9309
|
pos
|
|
9291
9310
|
);
|
|
9292
9311
|
}
|
|
9293
|
-
const
|
|
9312
|
+
const index = {
|
|
9313
|
+
...declared,
|
|
9314
|
+
keyType: this.boundIndexKeyType(declared, surface.elementType),
|
|
9315
|
+
valueType: surface.elementType
|
|
9316
|
+
};
|
|
9317
|
+
const viewValueType = index.unique ? { ...index.valueType, nullable: true } : {
|
|
9294
9318
|
kind: "list",
|
|
9295
9319
|
elementType: { ...index.valueType, nullable: false },
|
|
9296
9320
|
readOnly: true
|
|
@@ -9309,10 +9333,7 @@ var init_strict_resolver = __esm({
|
|
|
9309
9333
|
indexCollectionPointer: receiver.pointer
|
|
9310
9334
|
};
|
|
9311
9335
|
}
|
|
9312
|
-
|
|
9313
|
-
if (receiver.type.kind === "list" && name === "Index" && receiverListMemberId && (this.context.project.listIndexes ?? []).some(
|
|
9314
|
-
(candidate) => candidate.listMemberId === receiverListMemberId
|
|
9315
|
-
)) {
|
|
9336
|
+
if (receiver.type.kind === "list" && name === "Index" && this.indexesFor(receiver.type).length > 0) {
|
|
9316
9337
|
return {
|
|
9317
9338
|
pointer: receiver.pointer,
|
|
9318
9339
|
type: { kind: "primitive", name: "unknown" },
|
|
@@ -9462,6 +9483,23 @@ var init_strict_resolver = __esm({
|
|
|
9462
9483
|
pos
|
|
9463
9484
|
);
|
|
9464
9485
|
}
|
|
9486
|
+
boundIndexKeyType(index, entryType) {
|
|
9487
|
+
const entry = neoScriptMemberLookupType(entryType);
|
|
9488
|
+
if (entry.kind !== "named") return index.keyType;
|
|
9489
|
+
const declaring = this.project.typeById.get(entry.typeId);
|
|
9490
|
+
if (!declaring) return index.keyType;
|
|
9491
|
+
const key = declaring.members.find((member) => member.name === index.name);
|
|
9492
|
+
return substituteTypeParameters(
|
|
9493
|
+
key?.type ?? index.keyType,
|
|
9494
|
+
entry,
|
|
9495
|
+
declaring
|
|
9496
|
+
);
|
|
9497
|
+
}
|
|
9498
|
+
/** The indexes declared on a schema-backed List, keyed by its member. */
|
|
9499
|
+
indexesFor(type) {
|
|
9500
|
+
if (type.listMemberId === void 0) return [];
|
|
9501
|
+
return this.project.indexesByListMemberId.get(type.listMemberId) ?? [];
|
|
9502
|
+
}
|
|
9465
9503
|
/**
|
|
9466
9504
|
* P42 §2.3. `Images.<Name>` / `AudioClips.<Name>`.
|
|
9467
9505
|
*
|
|
@@ -10341,7 +10379,8 @@ var init_strict_resolver = __esm({
|
|
|
10341
10379
|
receiver: { kind: "ident", name, pos: entry.pos }
|
|
10342
10380
|
}
|
|
10343
10381
|
},
|
|
10344
|
-
initializerScope
|
|
10382
|
+
initializerScope,
|
|
10383
|
+
"initializer"
|
|
10345
10384
|
);
|
|
10346
10385
|
if (assignment.type !== "assign" /* Assign */) {
|
|
10347
10386
|
throw new CompileError(
|
|
@@ -16354,6 +16393,28 @@ function effectiveSourceAccessModifier(modifiers, ownerKind) {
|
|
|
16354
16393
|
if (explicit !== void 0) return explicit;
|
|
16355
16394
|
return ownerKind === "interface" ? "public" : "private";
|
|
16356
16395
|
}
|
|
16396
|
+
function sourceMemberKeyArgument(annotation2) {
|
|
16397
|
+
const positional = annotation2.arguments[0];
|
|
16398
|
+
const argument2 = annotation2.arguments.find((entry) => entry.name === "member") ?? (positional !== void 0 && positional.name === void 0 ? positional : void 0);
|
|
16399
|
+
if (argument2 === void 0) return null;
|
|
16400
|
+
const text = argument2.text.trim();
|
|
16401
|
+
return {
|
|
16402
|
+
key: /^[A-Za-z_][A-Za-z0-9_]*$/.test(text) ? text : null,
|
|
16403
|
+
range: argument2.range
|
|
16404
|
+
};
|
|
16405
|
+
}
|
|
16406
|
+
function* sourceListIndexAnnotations(annotations) {
|
|
16407
|
+
for (const annotation2 of annotations) {
|
|
16408
|
+
if (annotation2.name !== "index") continue;
|
|
16409
|
+
const key = sourceMemberKeyArgument(annotation2)?.key;
|
|
16410
|
+
if (!key) continue;
|
|
16411
|
+
yield {
|
|
16412
|
+
key,
|
|
16413
|
+
unique: annotation2.arguments.find((argument2) => argument2.name === "kind")?.text.trim() === ".Unique",
|
|
16414
|
+
annotation: annotation2
|
|
16415
|
+
};
|
|
16416
|
+
}
|
|
16417
|
+
}
|
|
16357
16418
|
var init_project_source_ast = __esm({
|
|
16358
16419
|
"../packages/neoscript-language/src/project-source-ast.ts"() {
|
|
16359
16420
|
"use strict";
|
|
@@ -22751,7 +22812,7 @@ function validateMember(uri, member, ownerName, documentKind, ownerScope, enviro
|
|
|
22751
22812
|
);
|
|
22752
22813
|
validateTypeAnnotations(uri, member.type, environment, diagnostics);
|
|
22753
22814
|
if (documentKind !== "flow") {
|
|
22754
|
-
validateListAnnotations(uri, member, environment, diagnostics);
|
|
22815
|
+
validateListAnnotations(uri, member, ownerName, environment, diagnostics);
|
|
22755
22816
|
}
|
|
22756
22817
|
const scope = new Map(ownerScope);
|
|
22757
22818
|
if (member.kind === "function") {
|
|
@@ -23965,14 +24026,21 @@ function anchorPosition(anchor, offset) {
|
|
|
23965
24026
|
return { line: anchor.start.line + line, character };
|
|
23966
24027
|
}
|
|
23967
24028
|
function sourceClassFieldByName(declaration, name, environment, initialBindings = /* @__PURE__ */ new Map()) {
|
|
24029
|
+
const resolved = sourceClassMemberByName(
|
|
24030
|
+
declaration,
|
|
24031
|
+
name,
|
|
24032
|
+
environment,
|
|
24033
|
+
initialBindings
|
|
24034
|
+
);
|
|
24035
|
+
return resolved?.member.kind === "field" ? resolved : void 0;
|
|
24036
|
+
}
|
|
24037
|
+
function sourceClassMemberByName(declaration, name, environment, initialBindings = /* @__PURE__ */ new Map()) {
|
|
23968
24038
|
const visited = /* @__PURE__ */ new Set();
|
|
23969
24039
|
let current = declaration;
|
|
23970
24040
|
let bindings = initialBindings;
|
|
23971
24041
|
while (current !== void 0 && !visited.has(current.name)) {
|
|
23972
24042
|
visited.add(current.name);
|
|
23973
|
-
const member = current.members.find(
|
|
23974
|
-
(candidate) => candidate.kind === "field" && candidate.name === name
|
|
23975
|
-
);
|
|
24043
|
+
const member = current.members.find((candidate) => candidate.name === name);
|
|
23976
24044
|
if (member !== void 0) return { member, bindings };
|
|
23977
24045
|
const base = current.baseTypes.find(
|
|
23978
24046
|
(candidate) => environment.types.has(candidate.name)
|
|
@@ -24202,20 +24270,17 @@ function semanticMemberType(member, environment, bindings = /* @__PURE__ */ new
|
|
|
24202
24270
|
if (type.name !== "List") return type;
|
|
24203
24271
|
const entryType = type.arguments?.[0];
|
|
24204
24272
|
if (!entryType) return type;
|
|
24205
|
-
const entryClass = environment.types.get(entryType.name);
|
|
24206
|
-
if (!entryClass) return type;
|
|
24207
24273
|
const indexes2 = /* @__PURE__ */ new Map();
|
|
24208
|
-
for (const
|
|
24209
|
-
|
|
24210
|
-
const key = memberKeyArgument(annotation2)?.key;
|
|
24211
|
-
if (!key) continue;
|
|
24212
|
-
const field = resolveEntryField(entryClass, key, environment);
|
|
24274
|
+
for (const index of sourceListIndexAnnotations(member.annotations)) {
|
|
24275
|
+
const field = sourceClassMemberForType(entryType, index.key, environment);
|
|
24213
24276
|
if (!field) continue;
|
|
24214
|
-
const
|
|
24215
|
-
|
|
24216
|
-
indexes2.set(key, {
|
|
24277
|
+
const valueType = index.unique ? { ...entryType, nullable: true } : { name: "List", arguments: [{ ...entryType, nullable: false }] };
|
|
24278
|
+
indexes2.set(index.key, {
|
|
24217
24279
|
name: "Dictionary",
|
|
24218
|
-
arguments: [
|
|
24280
|
+
arguments: [
|
|
24281
|
+
substituteSemanticType(semanticType(field.member.type), field.bindings),
|
|
24282
|
+
valueType
|
|
24283
|
+
]
|
|
24219
24284
|
});
|
|
24220
24285
|
}
|
|
24221
24286
|
return indexes2.size === 0 ? type : { ...type, listIndexes: indexes2 };
|
|
@@ -24449,15 +24514,18 @@ function contextualAnnotationEnum(annotations, name, field) {
|
|
|
24449
24514
|
const value = annotations.find((annotation2) => annotation2.name === name)?.arguments.find((argument2) => argument2.name === field)?.text.trim();
|
|
24450
24515
|
return value?.startsWith(".") ? value.slice(1) : null;
|
|
24451
24516
|
}
|
|
24452
|
-
function validateListAnnotations(uri, member, environment, diagnostics) {
|
|
24517
|
+
function validateListAnnotations(uri, member, ownerName, environment, diagnostics) {
|
|
24453
24518
|
const declared = member.annotations.filter(
|
|
24454
24519
|
(annotation2) => annotation2.name === "index" || annotation2.name === "column"
|
|
24455
24520
|
);
|
|
24456
24521
|
if (declared.length === 0) return;
|
|
24457
|
-
const
|
|
24522
|
+
const entryType = listEntryType(
|
|
24523
|
+
member.type,
|
|
24524
|
+
environment.types.get(ownerName)
|
|
24525
|
+
);
|
|
24458
24526
|
const seen = /* @__PURE__ */ new Set();
|
|
24459
24527
|
for (const annotation2 of declared) {
|
|
24460
|
-
const target =
|
|
24528
|
+
const target = sourceMemberKeyArgument(annotation2);
|
|
24461
24529
|
if (target === null) {
|
|
24462
24530
|
pushDiagnostic(
|
|
24463
24531
|
diagnostics,
|
|
@@ -24492,20 +24560,25 @@ function validateListAnnotations(uri, member, environment, diagnostics) {
|
|
|
24492
24560
|
if (annotation2.name === "column" && target.key === LIST_COLUMN_INHERITANCE_KEY) {
|
|
24493
24561
|
continue;
|
|
24494
24562
|
}
|
|
24495
|
-
if (
|
|
24496
|
-
|
|
24497
|
-
|
|
24563
|
+
if (entryType === null) continue;
|
|
24564
|
+
if (!environment.types.has(entryType.name)) continue;
|
|
24565
|
+
const field = sourceClassMemberForType(entryType, target.key, environment);
|
|
24566
|
+
if (field === void 0) {
|
|
24498
24567
|
pushDiagnostic(
|
|
24499
24568
|
diagnostics,
|
|
24500
24569
|
uri,
|
|
24501
24570
|
target.range,
|
|
24502
24571
|
"unresolved-list-annotation-member",
|
|
24503
|
-
`@${annotation2.name}(member: ${target.key}) on '${member.name}' does not resolve on list entry class '${
|
|
24572
|
+
`@${annotation2.name}(member: ${target.key}) on '${member.name}' does not resolve on list entry class '${entryType.name}'.`
|
|
24504
24573
|
);
|
|
24505
24574
|
continue;
|
|
24506
24575
|
}
|
|
24507
24576
|
if (annotation2.name !== "index") continue;
|
|
24508
|
-
const domainError = indexKeyDomainError(
|
|
24577
|
+
const domainError = indexKeyDomainError(
|
|
24578
|
+
field.member,
|
|
24579
|
+
substituteSemanticType(semanticType(field.member.type), field.bindings),
|
|
24580
|
+
environment
|
|
24581
|
+
);
|
|
24509
24582
|
if (domainError !== null) {
|
|
24510
24583
|
pushDiagnostic(
|
|
24511
24584
|
diagnostics,
|
|
@@ -24517,46 +24590,45 @@ function validateListAnnotations(uri, member, environment, diagnostics) {
|
|
|
24517
24590
|
}
|
|
24518
24591
|
}
|
|
24519
24592
|
}
|
|
24520
|
-
function
|
|
24521
|
-
const positional = annotation2.arguments[0];
|
|
24522
|
-
const argument2 = annotation2.arguments.find((entry) => entry.name === "member") ?? (positional !== void 0 && positional.name === void 0 ? positional : void 0);
|
|
24523
|
-
if (argument2 === void 0) return null;
|
|
24524
|
-
const text = argument2.text.trim();
|
|
24525
|
-
return {
|
|
24526
|
-
key: IDENTIFIER_PATTERN.test(text) ? text : null,
|
|
24527
|
-
range: argument2.range
|
|
24528
|
-
};
|
|
24529
|
-
}
|
|
24530
|
-
function listEntryClass(type, environment) {
|
|
24593
|
+
function listEntryType(type, owner) {
|
|
24531
24594
|
if (type.name !== "List" && type.name !== "Set") return null;
|
|
24532
|
-
|
|
24533
|
-
if (entry === void 0) return null;
|
|
24534
|
-
return environment.types.get(entry.name) ?? null;
|
|
24535
|
-
}
|
|
24536
|
-
function resolveEntryField(entryClass, key, environment) {
|
|
24595
|
+
let entry = type.typeArguments[0];
|
|
24537
24596
|
const visited = /* @__PURE__ */ new Set();
|
|
24538
|
-
|
|
24539
|
-
|
|
24540
|
-
|
|
24541
|
-
|
|
24542
|
-
|
|
24543
|
-
|
|
24597
|
+
while (entry !== void 0) {
|
|
24598
|
+
const name = entry.name;
|
|
24599
|
+
const parameter4 = owner?.genericParameters.find(
|
|
24600
|
+
(candidate) => candidate.name === name
|
|
24601
|
+
);
|
|
24602
|
+
if (!parameter4) return semanticType(entry);
|
|
24603
|
+
if (visited.has(parameter4.name)) return null;
|
|
24604
|
+
visited.add(parameter4.name);
|
|
24605
|
+
entry = parameter4.constraint;
|
|
24544
24606
|
}
|
|
24545
24607
|
return null;
|
|
24546
24608
|
}
|
|
24547
|
-
function
|
|
24609
|
+
function sourceClassMemberForType(type, name, environment) {
|
|
24610
|
+
const declaration = environment.types.get(type.name);
|
|
24611
|
+
if (!declaration) return void 0;
|
|
24612
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
24613
|
+
for (const [index, parameter4] of declaration.genericParameters.entries()) {
|
|
24614
|
+
const argument2 = type.arguments?.[index];
|
|
24615
|
+
if (argument2) bindings.set(parameter4.name, argument2);
|
|
24616
|
+
}
|
|
24617
|
+
return sourceClassMemberByName(declaration, name, environment, bindings);
|
|
24618
|
+
}
|
|
24619
|
+
function indexKeyDomainError(field, type, environment) {
|
|
24548
24620
|
if (field.kind !== "field") {
|
|
24549
24621
|
return `'${field.name}' is a ${field.kind}, and index keys require a stored field`;
|
|
24550
24622
|
}
|
|
24551
|
-
if (
|
|
24623
|
+
if (type.name === "string") {
|
|
24552
24624
|
return annotationEnumOption(field.annotations, "settings", "format") === "Plain" ? null : `'${field.name}' is localized, and String index keys must be plain`;
|
|
24553
24625
|
}
|
|
24554
|
-
if (environment.enums.has(
|
|
24555
|
-
const entry =
|
|
24556
|
-
if (
|
|
24626
|
+
if (environment.enums.has(type.name)) return null;
|
|
24627
|
+
const entry = type.arguments?.[0];
|
|
24628
|
+
if (type.name === "List" && entry !== void 0 && environment.enums.has(entry.name) && annotationEnumOption(field.annotations, "settings", "selection") === "Multi") {
|
|
24557
24629
|
return `'${field.name}' is a multi-select Enum, and index keys require a single-select Enum`;
|
|
24558
24630
|
}
|
|
24559
|
-
return `'${field.name}' is a ${
|
|
24631
|
+
return `'${field.name}' is a ${type.name} field, and index keys require a plain String or a single-select Enum`;
|
|
24560
24632
|
}
|
|
24561
24633
|
function annotationEnumOption(annotations, name, field) {
|
|
24562
24634
|
const value = annotations.find((annotation2) => annotation2.name === name)?.arguments.find((argument2) => argument2.name === field)?.text.trim();
|
|
@@ -24711,10 +24783,11 @@ function classDerivesFromName(name, ancestorName, environment, seen = /* @__PURE
|
|
|
24711
24783
|
return classDerivesFromName(base.name, ancestorName, environment, seen);
|
|
24712
24784
|
});
|
|
24713
24785
|
}
|
|
24714
|
-
var NEO_VARIANT_FOLDER_SETTING, primitiveType,
|
|
24786
|
+
var NEO_VARIANT_FOLDER_SETTING, primitiveType, LIST_COLUMN_INHERITANCE_KEY, SEMANTIC_PRIMITIVE_TYPE_NAMES;
|
|
24715
24787
|
var init_project_source_semantics = __esm({
|
|
24716
24788
|
"../packages/neoscript-language/src/project-source-semantics.ts"() {
|
|
24717
24789
|
"use strict";
|
|
24790
|
+
init_project_source_ast();
|
|
24718
24791
|
init_project_local_values();
|
|
24719
24792
|
init_language_spec();
|
|
24720
24793
|
init_project_schema_contract_generated();
|
|
@@ -24727,7 +24800,6 @@ var init_project_source_semantics = __esm({
|
|
|
24727
24800
|
init_project_root();
|
|
24728
24801
|
NEO_VARIANT_FOLDER_SETTING = "folder";
|
|
24729
24802
|
primitiveType = (name) => ({ name });
|
|
24730
|
-
IDENTIFIER_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
24731
24803
|
LIST_COLUMN_INHERITANCE_KEY = "__other__";
|
|
24732
24804
|
SEMANTIC_PRIMITIVE_TYPE_NAMES = /* @__PURE__ */ new Set([
|
|
24733
24805
|
"bool",
|
|
@@ -25326,8 +25398,29 @@ function buildProjectGraph(documents) {
|
|
|
25326
25398
|
writable: false
|
|
25327
25399
|
});
|
|
25328
25400
|
}
|
|
25401
|
+
const listIndexes2 = [];
|
|
25402
|
+
for (const { member, symbol, uri } of memberInfo.values()) {
|
|
25403
|
+
if (symbol.type.kind !== "list") continue;
|
|
25404
|
+
const entryType = symbol.type.elementType;
|
|
25405
|
+
const entrySchema = neoScriptMemberLookupType(entryType);
|
|
25406
|
+
if (entrySchema.kind !== "named") continue;
|
|
25407
|
+
const entryMembers = effectiveMembers.get(entrySchema.typeId);
|
|
25408
|
+
for (const index of sourceListIndexAnnotations(member.annotations)) {
|
|
25409
|
+
const key = entryMembers?.find((field) => field.name === index.key);
|
|
25410
|
+
if (key === void 0) continue;
|
|
25411
|
+
listIndexes2.push({
|
|
25412
|
+
id: `${symbol.id}:index:${key.name}`,
|
|
25413
|
+
listMemberId: symbol.id,
|
|
25414
|
+
name: key.name,
|
|
25415
|
+
keyType: key.type,
|
|
25416
|
+
valueType: entryType,
|
|
25417
|
+
unique: index.unique,
|
|
25418
|
+
location: location(uri, index.annotation.range)
|
|
25419
|
+
});
|
|
25420
|
+
}
|
|
25421
|
+
}
|
|
25329
25422
|
return {
|
|
25330
|
-
project: { version: 1, types, globals, roots },
|
|
25423
|
+
project: { version: 1, types, globals, roots, listIndexes: listIndexes2 },
|
|
25331
25424
|
declarationsByName,
|
|
25332
25425
|
typeIdsByName: typeIds,
|
|
25333
25426
|
memberInfo
|
|
@@ -25338,7 +25431,8 @@ function sourceMemberSymbol(member, owner, typeIds, source) {
|
|
|
25338
25431
|
member.annotations,
|
|
25339
25432
|
`member:${owner.id}:${member.name}`
|
|
25340
25433
|
);
|
|
25341
|
-
const
|
|
25434
|
+
const declaredType = sourceTypeRef(member.type, owner, typeIds);
|
|
25435
|
+
const type = declaredType.kind === "list" ? { ...declaredType, listMemberId: id2 } : declaredType;
|
|
25342
25436
|
const staticMember = member.modifiers.includes("static");
|
|
25343
25437
|
const readonlyDeclaration = member.modifiers.includes("readonly");
|
|
25344
25438
|
const common = {
|
|
@@ -71294,6 +71388,33 @@ function exportInitializerCollections(created, writes, ctx) {
|
|
|
71294
71388
|
});
|
|
71295
71389
|
return [...exported, ...extra];
|
|
71296
71390
|
}
|
|
71391
|
+
function prepareSessionValueExport(ctx, checkpoint, writes) {
|
|
71392
|
+
const created = createdSessionValuesSince(ctx, checkpoint);
|
|
71393
|
+
if (created.length === 0) return;
|
|
71394
|
+
const invocationWrites = ctx.__executionState?.writes ?? writes;
|
|
71395
|
+
const exported = exportInitializerCollections(
|
|
71396
|
+
created,
|
|
71397
|
+
invocationWrites === writes || writes.length === 0 ? invocationWrites : [...invocationWrites, ...writes],
|
|
71398
|
+
ctx
|
|
71399
|
+
);
|
|
71400
|
+
if (exported === created) return;
|
|
71401
|
+
const replacements = /* @__PURE__ */ new Map();
|
|
71402
|
+
for (const row of exported) {
|
|
71403
|
+
const existing = ctx.__runtimeSessionValues?.get(row.id);
|
|
71404
|
+
if (existing === void 0) registerRuntimeSessionValue(ctx, row);
|
|
71405
|
+
else if (existing !== row) replacements.set(row.id, row);
|
|
71406
|
+
}
|
|
71407
|
+
return replacements;
|
|
71408
|
+
}
|
|
71409
|
+
function exportedSessionValuesSince(ctx, checkpoint, replacements) {
|
|
71410
|
+
const created = createdSessionValuesSince(ctx, checkpoint);
|
|
71411
|
+
if (replacements !== void 0) {
|
|
71412
|
+
for (const [index, row] of created.entries()) {
|
|
71413
|
+
created[index] = replacements.get(row.id) ?? row;
|
|
71414
|
+
}
|
|
71415
|
+
}
|
|
71416
|
+
return created;
|
|
71417
|
+
}
|
|
71297
71418
|
function evaluateNSGetter(getter, ctx) {
|
|
71298
71419
|
return evaluateNSGetterWithEffects(getter, ctx).value;
|
|
71299
71420
|
}
|
|
@@ -71358,19 +71479,20 @@ function evaluateNSGetterWithEffects(getter, ctx, argumentValues = [], options =
|
|
|
71358
71479
|
const rootIndex = created.findIndex(
|
|
71359
71480
|
(row) => row.value === result.value
|
|
71360
71481
|
);
|
|
71361
|
-
const
|
|
71482
|
+
const exported2 = exportInitializerCollections(
|
|
71362
71483
|
created,
|
|
71363
71484
|
writes,
|
|
71364
71485
|
runtimeCtx
|
|
71365
71486
|
);
|
|
71366
|
-
if (
|
|
71367
|
-
for (const row of
|
|
71487
|
+
if (exported2 !== created) {
|
|
71488
|
+
for (const row of exported2)
|
|
71368
71489
|
registerRuntimeSessionValue(runtimeCtx, row);
|
|
71369
71490
|
invalidateEvaluatorIndexes(runtimeCtx, null);
|
|
71370
71491
|
}
|
|
71371
|
-
const exportedRoot =
|
|
71492
|
+
const exportedRoot = exported2[rootIndex];
|
|
71372
71493
|
if (exportedRoot !== void 0) result.value = exportedRoot.value;
|
|
71373
71494
|
}
|
|
71495
|
+
const exported = !options.exportInitializerValues && options.sessionValueExport !== "defer" ? prepareSessionValueExport(runtimeCtx, creationCheckpoint, writes) : void 0;
|
|
71374
71496
|
finalizeConstructorAllocations(
|
|
71375
71497
|
runtimeCtx,
|
|
71376
71498
|
result.value,
|
|
@@ -71378,9 +71500,10 @@ function evaluateNSGetterWithEffects(getter, ctx, argumentValues = [], options =
|
|
|
71378
71500
|
getter.typeInfo
|
|
71379
71501
|
);
|
|
71380
71502
|
result.value = preserveReadOnlyReturnIdentity(result.value, runtimeCtx);
|
|
71381
|
-
const createdSessionValues =
|
|
71503
|
+
const createdSessionValues = exportedSessionValuesSince(
|
|
71382
71504
|
runtimeCtx,
|
|
71383
|
-
creationCheckpoint
|
|
71505
|
+
creationCheckpoint,
|
|
71506
|
+
exported
|
|
71384
71507
|
);
|
|
71385
71508
|
return createdSessionValues.length === 0 ? { value: result.value, writes } : { value: result.value, writes, createdSessionValues };
|
|
71386
71509
|
}
|
|
@@ -71399,6 +71522,7 @@ function evaluateNSVoidBody(action, ctx) {
|
|
|
71399
71522
|
consumeBudget(runtimeCtx, "workUnits", 1, "work unit");
|
|
71400
71523
|
const creationCheckpoint = sessionCreationCheckpoint(runtimeCtx);
|
|
71401
71524
|
const scope = createTopLevelScope(runtimeCtx);
|
|
71525
|
+
let exported;
|
|
71402
71526
|
try {
|
|
71403
71527
|
const result = evalInstructions(action.instructions, scope, runtimeCtx, {
|
|
71404
71528
|
allowFallthroughReturn: true,
|
|
@@ -71412,14 +71536,20 @@ function evaluateNSVoidBody(action, ctx) {
|
|
|
71412
71536
|
}
|
|
71413
71537
|
}
|
|
71414
71538
|
rejectEscapedLoopTransfer(result, "NeoScript action");
|
|
71539
|
+
exported = prepareSessionValueExport(
|
|
71540
|
+
runtimeCtx,
|
|
71541
|
+
creationCheckpoint,
|
|
71542
|
+
writes
|
|
71543
|
+
);
|
|
71415
71544
|
finalizeConstructorAllocations(runtimeCtx, void 0, ownsInvocationState);
|
|
71416
71545
|
} catch (error) {
|
|
71417
71546
|
finalizeConstructorAllocations(runtimeCtx, void 0, ownsInvocationState);
|
|
71418
71547
|
throw error;
|
|
71419
71548
|
}
|
|
71420
|
-
const createdSessionValues =
|
|
71549
|
+
const createdSessionValues = exportedSessionValuesSince(
|
|
71421
71550
|
runtimeCtx,
|
|
71422
|
-
creationCheckpoint
|
|
71551
|
+
creationCheckpoint,
|
|
71552
|
+
exported
|
|
71423
71553
|
);
|
|
71424
71554
|
return createdSessionValues.length === 0 ? { writes } : { writes, createdSessionValues };
|
|
71425
71555
|
}
|
|
@@ -71431,6 +71561,7 @@ function evaluateNSFunction(action, ctx, args) {
|
|
|
71431
71561
|
const creationCheckpoint = sessionCreationCheckpoint(runtimeCtx);
|
|
71432
71562
|
const runtimeArgs = remapRuntimeArguments(args, runtimeCtx);
|
|
71433
71563
|
let value;
|
|
71564
|
+
let exported;
|
|
71434
71565
|
try {
|
|
71435
71566
|
value = executeCompiledFunction(
|
|
71436
71567
|
action,
|
|
@@ -71438,6 +71569,11 @@ function evaluateNSFunction(action, ctx, args) {
|
|
|
71438
71569
|
runtimeArgs,
|
|
71439
71570
|
action.typeInfo.type === 0 /* Null */
|
|
71440
71571
|
);
|
|
71572
|
+
exported = prepareSessionValueExport(
|
|
71573
|
+
runtimeCtx,
|
|
71574
|
+
creationCheckpoint,
|
|
71575
|
+
writes
|
|
71576
|
+
);
|
|
71441
71577
|
finalizeConstructorAllocations(
|
|
71442
71578
|
runtimeCtx,
|
|
71443
71579
|
value,
|
|
@@ -71448,9 +71584,10 @@ function evaluateNSFunction(action, ctx, args) {
|
|
|
71448
71584
|
finalizeConstructorAllocations(runtimeCtx, void 0, ownsInvocationState);
|
|
71449
71585
|
throw error;
|
|
71450
71586
|
}
|
|
71451
|
-
const createdSessionValues =
|
|
71587
|
+
const createdSessionValues = exportedSessionValuesSince(
|
|
71452
71588
|
runtimeCtx,
|
|
71453
|
-
creationCheckpoint
|
|
71589
|
+
creationCheckpoint,
|
|
71590
|
+
exported
|
|
71454
71591
|
);
|
|
71455
71592
|
return createdSessionValues.length === 0 ? { value, writes } : { value, writes, createdSessionValues };
|
|
71456
71593
|
}
|
|
@@ -74686,10 +74823,15 @@ function dispatchNSGetterById(memberId, receiver, ctx) {
|
|
|
74686
74823
|
}
|
|
74687
74824
|
const innerStack = new Set(stack);
|
|
74688
74825
|
innerStack.add(memberId);
|
|
74689
|
-
return
|
|
74690
|
-
|
|
74691
|
-
|
|
74692
|
-
|
|
74826
|
+
return evaluateNSGetterWithEffects(
|
|
74827
|
+
getter,
|
|
74828
|
+
{
|
|
74829
|
+
...bindThisValue(ctx, receiver),
|
|
74830
|
+
__getterCallStack: innerStack
|
|
74831
|
+
},
|
|
74832
|
+
[],
|
|
74833
|
+
{ sessionValueExport: "defer" }
|
|
74834
|
+
).value;
|
|
74693
74835
|
}
|
|
74694
74836
|
function resolveCompiledGetter(memberId, ctx) {
|
|
74695
74837
|
const cache = evaluatorResolutionCache(ctx).compiledGetterByMemberId;
|
|
@@ -78015,7 +78157,10 @@ function evaluateInitializerInContext(init, member, ctx, createdValues, argument
|
|
|
78015
78157
|
compiled,
|
|
78016
78158
|
initializerCtx,
|
|
78017
78159
|
argumentValues,
|
|
78018
|
-
{
|
|
78160
|
+
{
|
|
78161
|
+
initializerResult: { member, genericEnv },
|
|
78162
|
+
sessionValueExport: "defer"
|
|
78163
|
+
}
|
|
78019
78164
|
);
|
|
78020
78165
|
} finally {
|
|
78021
78166
|
closeFrame();
|
|
@@ -79953,15 +80098,22 @@ function cloneClassValueGraph(receiver, expectedClassId, ctx) {
|
|
|
79953
80098
|
}
|
|
79954
80099
|
const active = /* @__PURE__ */ new Set();
|
|
79955
80100
|
const clonedBySourceId = /* @__PURE__ */ new Map();
|
|
79956
|
-
const constructorArgumentReferenceCounts = /* @__PURE__ */ new Map();
|
|
79957
80101
|
ctx.onUnattributableValueRead?.(`class-clone:${sourceId3}`);
|
|
79958
|
-
|
|
79959
|
-
|
|
79960
|
-
|
|
79961
|
-
|
|
79962
|
-
|
|
79963
|
-
)
|
|
80102
|
+
const constructorArgumentCandidates = evaluatorValues(ctx);
|
|
80103
|
+
let constructorArgumentReferenceCounts = null;
|
|
80104
|
+
function constructorArgumentReferenceCount(valueId) {
|
|
80105
|
+
if (constructorArgumentReferenceCounts === null) {
|
|
80106
|
+
constructorArgumentReferenceCounts = /* @__PURE__ */ new Map();
|
|
80107
|
+
for (const candidate of constructorArgumentCandidates) {
|
|
80108
|
+
for (const argument2 of ownedConstructorArgumentValues(candidate, ctx)) {
|
|
80109
|
+
constructorArgumentReferenceCounts.set(
|
|
80110
|
+
argument2.id,
|
|
80111
|
+
(constructorArgumentReferenceCounts.get(argument2.id) ?? 0) + 1
|
|
80112
|
+
);
|
|
80113
|
+
}
|
|
80114
|
+
}
|
|
79964
80115
|
}
|
|
80116
|
+
return constructorArgumentReferenceCounts.get(valueId) ?? 0;
|
|
79965
80117
|
}
|
|
79966
80118
|
function cloneInitializerRow(sourceRow, sourceMember, id2, clonedContainerId, sourceTypeInfo) {
|
|
79967
80119
|
if (sourceMember === null) {
|
|
@@ -80154,7 +80306,6 @@ function cloneClassValueGraph(receiver, expectedClassId, ctx) {
|
|
|
80154
80306
|
constructorArgs[argument2.parameterId] = alreadyCloned.id;
|
|
80155
80307
|
continue;
|
|
80156
80308
|
}
|
|
80157
|
-
if (constructorArgumentReferenceCounts.get(argument2.id) !== 1) continue;
|
|
80158
80309
|
const argumentRow = evalValueById(
|
|
80159
80310
|
ctx,
|
|
80160
80311
|
argument2.id,
|
|
@@ -80165,6 +80316,7 @@ function cloneClassValueGraph(receiver, expectedClassId, ctx) {
|
|
|
80165
80316
|
if (activeStaticBindingRoot(argument2.id, ctx) !== null || memberForValueRow(argumentRow, ctx) !== null) {
|
|
80166
80317
|
continue;
|
|
80167
80318
|
}
|
|
80319
|
+
if (constructorArgumentReferenceCount(argument2.id) !== 1) continue;
|
|
80168
80320
|
constructorArgs[argument2.parameterId] = cloneRow2(
|
|
80169
80321
|
argumentRow,
|
|
80170
80322
|
null,
|
|
@@ -83106,7 +83258,7 @@ function rewriteExpandedRow(node, expansion) {
|
|
|
83106
83258
|
const rewrite = (id2) => expansion.nodesByExpandedId.get(id2)?.virtualId ?? id2;
|
|
83107
83259
|
const row = cloneRow(node.expandedRow);
|
|
83108
83260
|
row.id = node.virtualId;
|
|
83109
|
-
if (isMemberClassBase(node.member) || isMemberDictionaryBase(node.member)) {
|
|
83261
|
+
if (row.value !== null && (isMemberClassBase(node.member) || isMemberDictionaryBase(node.member))) {
|
|
83110
83262
|
row.value = Object.fromEntries(
|
|
83111
83263
|
Object.entries(stringRecord2(row.value)).map(([key, childId]) => [
|
|
83112
83264
|
key,
|
|
@@ -109271,7 +109423,7 @@ function inheritedMember(context, memberId) {
|
|
|
109271
109423
|
function lowerListIndexes(ownerClass, declaration) {
|
|
109272
109424
|
const declared = /* @__PURE__ */ new Set();
|
|
109273
109425
|
return declaration.annotations.filter((entry) => entry.name === "index").map((entry) => {
|
|
109274
|
-
const schemaKey =
|
|
109426
|
+
const schemaKey = memberKeyArgument(entry, ownerClass, declaration);
|
|
109275
109427
|
if (declared.has(schemaKey)) {
|
|
109276
109428
|
throw new Error(
|
|
109277
109429
|
`@index(member: ${schemaKey}) is declared more than once on ${ownerClass.name}.${declaration.name}.`
|
|
@@ -109287,7 +109439,7 @@ function lowerListIndexes(ownerClass, declaration) {
|
|
|
109287
109439
|
function lowerListColumns(ownerClass, declaration) {
|
|
109288
109440
|
const declared = /* @__PURE__ */ new Set();
|
|
109289
109441
|
return declaration.annotations.filter((entry) => entry.name === "column").map((entry) => {
|
|
109290
|
-
const memberKey =
|
|
109442
|
+
const memberKey = memberKeyArgument(entry, ownerClass, declaration);
|
|
109291
109443
|
if (declared.has(memberKey)) {
|
|
109292
109444
|
throw new Error(
|
|
109293
109445
|
`@column(member: ${memberKey}) is declared more than once on ${ownerClass.name}.${declaration.name}.`
|
|
@@ -109306,7 +109458,7 @@ function lowerListColumns(ownerClass, declaration) {
|
|
|
109306
109458
|
};
|
|
109307
109459
|
});
|
|
109308
109460
|
}
|
|
109309
|
-
function
|
|
109461
|
+
function memberKeyArgument(value, ownerClass, declaration) {
|
|
109310
109462
|
const positional = value.arguments[0];
|
|
109311
109463
|
const raw = argument(value, "member") ?? (positional !== void 0 && positional.name === void 0 ? positional.expression : null);
|
|
109312
109464
|
if (raw === null) {
|
|
@@ -138565,7 +138717,7 @@ var init_registry2 = __esm({
|
|
|
138565
138717
|
"schema-contract/registry.mjs"() {
|
|
138566
138718
|
"use strict";
|
|
138567
138719
|
PROJECT_SCHEMA_CONTRACT = Object.freeze({
|
|
138568
|
-
cliVersion: "0.53.
|
|
138720
|
+
cliVersion: "0.53.3",
|
|
138569
138721
|
projectFileUploadBatchSize: 32,
|
|
138570
138722
|
documentRecords: {
|
|
138571
138723
|
member: {
|
|
@@ -146386,7 +146538,7 @@ There is no --keep-current: preserving current semantic state defines flatten.
|
|
|
146386
146538
|
async function main() {
|
|
146387
146539
|
const args = parseArgs(process.argv.slice(2));
|
|
146388
146540
|
if (args.command === "--version") {
|
|
146389
|
-
console.log("0.53.
|
|
146541
|
+
console.log("0.53.3");
|
|
146390
146542
|
return;
|
|
146391
146543
|
}
|
|
146392
146544
|
if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {
|
package/package.json
CHANGED
|
@@ -97,7 +97,7 @@ wrappers.
|
|
|
97
97
|
The marker near the top of `SKILL.md` must exactly match the package version:
|
|
98
98
|
|
|
99
99
|
```html
|
|
100
|
-
<!-- reviewed-through-cli: 0.53.
|
|
100
|
+
<!-- reviewed-through-cli: 0.53.3 -->
|
|
101
101
|
```
|
|
102
102
|
|
|
103
103
|
The quoted version above is checked too, so this instruction cannot go stale
|
|
@@ -334,3 +334,5 @@ class PlacedItem<
|
|
|
334
334
|
public TData Data = item.DefaultData.Clone();
|
|
335
335
|
}
|
|
336
336
|
```
|
|
337
|
+
|
|
338
|
+
Executable object initializer blocks can set immutable stored members on the newly constructed instance, including nested `new` expressions. Ordinary assignments after construction remain subject to storage restrictions. `readonly` declarations still change only through class defaults.
|