@neocompose/cli 0.5.1 → 0.5.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 +21 -0
- package/dist/neo.mjs +400 -41
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.5.3] - 2026-07-19
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- Emit row-backed instance-member defaults (class fields, ordered lists,
|
|
8
|
+
dictionaries) as inline constructed source instead of opaque `Reference(id)`
|
|
9
|
+
calls and raw value-row ID strings. Also resolve sprite/audio `@settings`
|
|
10
|
+
template references to their template symbol, file defaults to
|
|
11
|
+
`Images.X`/`AudioClips.X` registry symbols, and scalar enum default option
|
|
12
|
+
IDs to contextual `.Option` literals; resolve inherited class fields when
|
|
13
|
+
emitting nested value graphs; and stop indenting blank separator lines in
|
|
14
|
+
multi-line value emission.
|
|
15
|
+
|
|
16
|
+
## [0.5.2] - 2026-07-18
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- Stop `neo pull` from emitting inherited `@system` annotations on member
|
|
21
|
+
overrides and abstract implementations whose own records are not system
|
|
22
|
+
protected.
|
|
23
|
+
|
|
3
24
|
## [0.5.1] - 2026-07-18
|
|
4
25
|
|
|
5
26
|
### Fixed
|
package/dist/neo.mjs
CHANGED
|
@@ -1513,7 +1513,9 @@ function memberFromDocument(record3, members, owners, classNames, context) {
|
|
|
1513
1513
|
required: booleanValue(field("required", false), record3, "required"),
|
|
1514
1514
|
defaultValue,
|
|
1515
1515
|
overrideOf,
|
|
1516
|
-
|
|
1516
|
+
// System protection belongs to the declaration record. An override is
|
|
1517
|
+
// user-authored unless its own document explicitly marks it as system.
|
|
1518
|
+
system: systemFromDocument(data.system, record3, "system"),
|
|
1517
1519
|
storage: normalizedStorage(field("storage", null), record3),
|
|
1518
1520
|
storageKey: normalizedStorageKey(field("storageKey", null), record3)
|
|
1519
1521
|
};
|
|
@@ -26943,7 +26945,8 @@ function lowerFieldMember(context, ownerClass, declaration, id2, commonInput, ba
|
|
|
26943
26945
|
declaration.initializer,
|
|
26944
26946
|
declaration.type,
|
|
26945
26947
|
ownerClass,
|
|
26946
|
-
base
|
|
26948
|
+
base,
|
|
26949
|
+
id2
|
|
26947
26950
|
)
|
|
26948
26951
|
};
|
|
26949
26952
|
const settings = annotation(declaration.annotations, "settings");
|
|
@@ -26992,7 +26995,7 @@ function lowerFieldMember(context, ownerClass, declaration, id2, commonInput, ba
|
|
|
26992
26995
|
return {
|
|
26993
26996
|
...common,
|
|
26994
26997
|
kind: primitive3,
|
|
26995
|
-
templateId: referenceIdArgument(settings, "template") ?? (base?.kind === primitive3 ? base.templateId : null)
|
|
26998
|
+
templateId: referenceIdArgument(settings, "template") ?? templateSymbolArgument(context, settings, ownerClass, declaration) ?? (base?.kind === primitive3 ? base.templateId : null)
|
|
26996
26999
|
};
|
|
26997
27000
|
}
|
|
26998
27001
|
if (primitive3) return { ...common, kind: primitive3 };
|
|
@@ -27259,10 +27262,13 @@ function lowerType(context, type, ownerClass) {
|
|
|
27259
27262
|
if (type.name === "object") return { kind: "unknown", nullable };
|
|
27260
27263
|
throw new Error(`Unknown Neo type ${JSON.stringify(type.name)}.`);
|
|
27261
27264
|
}
|
|
27262
|
-
function lowerDefault(context, initializer, type, ownerClass, base) {
|
|
27265
|
+
function lowerDefault(context, initializer, type, ownerClass, base, memberId) {
|
|
27263
27266
|
if (initializer === null) {
|
|
27264
27267
|
return base?.defaultValue && "serverValueId" in base.defaultValue ? base.defaultValue : null;
|
|
27265
27268
|
}
|
|
27269
|
+
if (context.rowBackedDefaultMemberIds.has(memberId) && base?.defaultValue && !("serverValueId" in base.defaultValue)) {
|
|
27270
|
+
return base.defaultValue;
|
|
27271
|
+
}
|
|
27266
27272
|
const expression = parseExpression(initializer);
|
|
27267
27273
|
let value = lowerExpressionValue(context, expression, type, ownerClass);
|
|
27268
27274
|
if (value !== null && context.enumIdsByName.has(type.name) && !Array.isArray(value)) {
|
|
@@ -27399,16 +27405,25 @@ function lowerExpressionValue(context, expression, expected, ownerClass) {
|
|
|
27399
27405
|
const idArgument = expression.args[index >= 0 ? index : 0];
|
|
27400
27406
|
if (idArgument?.kind === "litString") return idArgument.value;
|
|
27401
27407
|
}
|
|
27402
|
-
if (expression.callee.kind === "member" && expression.callee.name === "Slice"
|
|
27403
|
-
const receiver = expression.callee.receiver;
|
|
27404
|
-
const index = receiver.argumentNames?.findIndex((name) => name === "id") ?? -1;
|
|
27405
|
-
const fileId = receiver.args[index >= 0 ? index : 0];
|
|
27408
|
+
if (expression.callee.kind === "member" && expression.callee.name === "Slice") {
|
|
27406
27409
|
const sliceIndex = expression.args[0];
|
|
27407
|
-
if (
|
|
27408
|
-
|
|
27409
|
-
|
|
27410
|
-
|
|
27411
|
-
|
|
27410
|
+
if (sliceIndex !== void 0 && sliceIndex.kind !== "litInt") {
|
|
27411
|
+
throw new Error("Sprite Slice defaults require an int literal.");
|
|
27412
|
+
}
|
|
27413
|
+
const receiver = expression.callee.receiver;
|
|
27414
|
+
if (receiver.kind === "call") {
|
|
27415
|
+
const index = receiver.argumentNames?.findIndex((name) => name === "id") ?? -1;
|
|
27416
|
+
const fileId2 = receiver.args[index >= 0 ? index : 0];
|
|
27417
|
+
if (fileId2?.kind === "litString") {
|
|
27418
|
+
return {
|
|
27419
|
+
fileId: fileId2.value,
|
|
27420
|
+
sliceIndex: sliceIndex?.value ?? 0
|
|
27421
|
+
};
|
|
27422
|
+
}
|
|
27423
|
+
}
|
|
27424
|
+
const fileId = projectFileIdForPath(context, receiver);
|
|
27425
|
+
if (fileId !== null) {
|
|
27426
|
+
return { fileId, sliceIndex: sliceIndex?.value ?? 0 };
|
|
27412
27427
|
}
|
|
27413
27428
|
}
|
|
27414
27429
|
throw new Error(
|
|
@@ -27416,6 +27431,8 @@ function lowerExpressionValue(context, expression, expected, ownerClass) {
|
|
|
27416
27431
|
);
|
|
27417
27432
|
}
|
|
27418
27433
|
case "member": {
|
|
27434
|
+
const fileId = projectFileIdForPath(context, expression);
|
|
27435
|
+
if (fileId !== null) return { fileId };
|
|
27419
27436
|
if (expression.name === "Slice" || expression.receiver.kind === "call") {
|
|
27420
27437
|
throw new Error(
|
|
27421
27438
|
"File defaults are lowered by the project-file compiler."
|
|
@@ -27429,6 +27446,17 @@ function lowerExpressionValue(context, expression, expected, ownerClass) {
|
|
|
27429
27446
|
);
|
|
27430
27447
|
}
|
|
27431
27448
|
}
|
|
27449
|
+
function projectFileIdForPath(context, expression) {
|
|
27450
|
+
const path = expressionMemberPath(expression);
|
|
27451
|
+
if (path === null) return null;
|
|
27452
|
+
return context.projectFileIdsBySymbol.get(path) ?? null;
|
|
27453
|
+
}
|
|
27454
|
+
function expressionMemberPath(expression) {
|
|
27455
|
+
if (expression.kind === "ident") return expression.name;
|
|
27456
|
+
if (expression.kind !== "member") return null;
|
|
27457
|
+
const receiver = expressionMemberPath(expression.receiver);
|
|
27458
|
+
return receiver === null ? null : `${receiver}.${expression.name}`;
|
|
27459
|
+
}
|
|
27432
27460
|
function manifestTypeForMember(context, member) {
|
|
27433
27461
|
const nullable = !member.required;
|
|
27434
27462
|
if (primitiveMemberKinds.has(member.kind)) {
|
|
@@ -27645,6 +27673,19 @@ function referenceIdArgument(value, name) {
|
|
|
27645
27673
|
const raw = argument(value, name);
|
|
27646
27674
|
return raw === null ? null : referenceId(raw);
|
|
27647
27675
|
}
|
|
27676
|
+
function templateSymbolArgument(context, settings, ownerClass, declaration) {
|
|
27677
|
+
const raw = argument(settings, "template");
|
|
27678
|
+
if (raw === null) return null;
|
|
27679
|
+
const expression = parseAnnotationExpression(raw);
|
|
27680
|
+
if (expression.kind !== "ident") return null;
|
|
27681
|
+
const templateId = context.templateIdsByName.get(expression.name);
|
|
27682
|
+
if (templateId === void 0) {
|
|
27683
|
+
throw new Error(
|
|
27684
|
+
`Member ${ownerClass.name}.${declaration.name} references unknown template ${JSON.stringify(expression.name)}.`
|
|
27685
|
+
);
|
|
27686
|
+
}
|
|
27687
|
+
return templateId;
|
|
27688
|
+
}
|
|
27648
27689
|
function referenceId(raw) {
|
|
27649
27690
|
try {
|
|
27650
27691
|
const expression = parseExpression(raw);
|
|
@@ -28175,7 +28216,24 @@ function lowerProjectSchemaV4(base, analysis, options = {}) {
|
|
|
28175
28216
|
enumOptionsByName,
|
|
28176
28217
|
loweredMembers: /* @__PURE__ */ new Map(),
|
|
28177
28218
|
placements: /* @__PURE__ */ new Map(),
|
|
28178
|
-
staticValueIdsBySymbol: options.staticValueIdsBySymbol ?? /* @__PURE__ */ new Map()
|
|
28219
|
+
staticValueIdsBySymbol: options.staticValueIdsBySymbol ?? /* @__PURE__ */ new Map(),
|
|
28220
|
+
templateIdsByName: new Map(
|
|
28221
|
+
analysis.configuration.globals.flatMap(
|
|
28222
|
+
(global) => global.type.name === "TextureTemplate" ? [
|
|
28223
|
+
[
|
|
28224
|
+
global.name,
|
|
28225
|
+
materializedId(global, "texture-template", global.name)
|
|
28226
|
+
]
|
|
28227
|
+
] : global.type.name === "AudioTemplate" ? [
|
|
28228
|
+
[
|
|
28229
|
+
global.name,
|
|
28230
|
+
materializedId(global, "audio-template", global.name)
|
|
28231
|
+
]
|
|
28232
|
+
] : []
|
|
28233
|
+
)
|
|
28234
|
+
),
|
|
28235
|
+
projectFileIdsBySymbol: options.projectFileIdsBySymbol ?? /* @__PURE__ */ new Map(),
|
|
28236
|
+
rowBackedDefaultMemberIds: options.rowBackedDefaultMemberIds ?? /* @__PURE__ */ new Set()
|
|
28179
28237
|
};
|
|
28180
28238
|
const classes = analysis.schema.classes.map(
|
|
28181
28239
|
(declaration) => lowerClass(context, declaration)
|
|
@@ -28324,7 +28382,14 @@ function emitProjectSourcesV4(manifest, options = {}) {
|
|
|
28324
28382
|
interfaces: new Map(manifest.interfaces.map((entry) => [entry.id, entry])),
|
|
28325
28383
|
enums: new Map(manifest.enums.map((entry) => [entry.id, entry])),
|
|
28326
28384
|
members: new Map(manifest.members.map((entry) => [entry.id, entry])),
|
|
28327
|
-
staticInitializers: options.staticInitializers ?? /* @__PURE__ */ new Map()
|
|
28385
|
+
staticInitializers: options.staticInitializers ?? /* @__PURE__ */ new Map(),
|
|
28386
|
+
defaultInitializers: options.defaultInitializers ?? /* @__PURE__ */ new Map(),
|
|
28387
|
+
fileSymbols: options.fileSymbols ?? /* @__PURE__ */ new Map(),
|
|
28388
|
+
templateNames: new Map(
|
|
28389
|
+
[...manifest.textureTemplates, ...manifest.audioTemplates].map(
|
|
28390
|
+
(template) => [template.id, template.name]
|
|
28391
|
+
)
|
|
28392
|
+
)
|
|
28328
28393
|
};
|
|
28329
28394
|
const files = [];
|
|
28330
28395
|
const localizationStatusNames = new Map(
|
|
@@ -28659,7 +28724,7 @@ ${indentNeoSourceNonEmptyLines(tracked.trim(), 2)}
|
|
|
28659
28724
|
${body ? `${signature} ${body}` : abstractContract ? `${signature};` : `native ${signature};`}`;
|
|
28660
28725
|
}
|
|
28661
28726
|
const type = renderMemberType(context, member);
|
|
28662
|
-
const initializer = (member.isStatic ? context.staticInitializers.get(member.id) : void 0) ?? renderDefault(context, member);
|
|
28727
|
+
const initializer = (member.isStatic ? context.staticInitializers.get(member.id) : void 0) ?? context.defaultInitializers.get(member.id) ?? renderDefault(context, member);
|
|
28663
28728
|
return `${annotations.join("\n")}
|
|
28664
28729
|
${prefix}${type} ${member.name}${initializer === null ? ";" : ` = ${initializer};`}`;
|
|
28665
28730
|
}
|
|
@@ -28720,7 +28785,10 @@ function memberSettings(context, member) {
|
|
|
28720
28785
|
}
|
|
28721
28786
|
if (member.multiselect) settings.push("multiselect: true");
|
|
28722
28787
|
} else if ((member.kind === "sprite" || member.kind === "audio") && member.templateId) {
|
|
28723
|
-
|
|
28788
|
+
const templateName = context.templateNames.get(member.templateId);
|
|
28789
|
+
settings.push(
|
|
28790
|
+
templateName !== void 0 ? `template: ${templateName}` : `template: Reference<Type>(id: ${quote(member.templateId)})`
|
|
28791
|
+
);
|
|
28724
28792
|
}
|
|
28725
28793
|
return settings.length ? [`@settings(${settings.join(", ")})`] : [];
|
|
28726
28794
|
}
|
|
@@ -28898,6 +28966,13 @@ function renderDefaultValue(context, member, wrapper) {
|
|
|
28898
28966
|
);
|
|
28899
28967
|
return member.multiselect ? `[${values.join(", ")}]` : values[0] ?? "null";
|
|
28900
28968
|
}
|
|
28969
|
+
if (member.kind === "enum" && typeof value === "string") {
|
|
28970
|
+
const schemaEnum = required(context.enums, member.enumId, "enum");
|
|
28971
|
+
const option = schemaEnum.options.find(
|
|
28972
|
+
(candidate) => candidate.id === value || candidate.key === value
|
|
28973
|
+
);
|
|
28974
|
+
if (option !== void 0) return `.${option.name}`;
|
|
28975
|
+
}
|
|
28901
28976
|
if (member.kind === "list" && Array.isArray(value)) {
|
|
28902
28977
|
const entry = required(context.members, member.entryMemberId, "list entry");
|
|
28903
28978
|
return `[${value.map((item) => renderNestedValue(context, entry, item)).join(", ")}]`;
|
|
@@ -28929,7 +29004,9 @@ function renderDefaultValue(context, member, wrapper) {
|
|
|
28929
29004
|
return member.multiselect ? `[${refs.join(", ")}]` : refs[0] ?? "null";
|
|
28930
29005
|
}
|
|
28931
29006
|
if ((member.kind === "sprite" || member.kind === "audio") && isObject(value) && typeof value.fileId === "string") {
|
|
28932
|
-
|
|
29007
|
+
const symbol = context.fileSymbols.get(value.fileId);
|
|
29008
|
+
const target = symbol ?? (member.kind === "sprite" ? `Reference<NeoImage>(id: ${quote(value.fileId)})` : `Reference<NeoAudioClip>(id: ${quote(value.fileId)})`);
|
|
29009
|
+
return member.kind === "sprite" ? `${target}.Slice(${typeof value.sliceIndex === "number" ? value.sliceIndex : 0})` : target;
|
|
28933
29010
|
}
|
|
28934
29011
|
if (isObject(value) && ["vector2", "vector2Int", "vector3", "vector3Int", "color"].includes(
|
|
28935
29012
|
member.kind
|
|
@@ -38744,7 +38821,7 @@ function emitStaticValueSourcesV4(records2) {
|
|
|
38744
38821
|
);
|
|
38745
38822
|
return emitStoredValueBindingSourcesV4(records2, memberIds);
|
|
38746
38823
|
}
|
|
38747
|
-
function
|
|
38824
|
+
function buildValueEmitContext(records2) {
|
|
38748
38825
|
const members = dataById(records2, "member");
|
|
38749
38826
|
const classes = dataById(records2, "class");
|
|
38750
38827
|
const values = dataById(records2, "value");
|
|
@@ -38752,7 +38829,7 @@ function emitStoredValueBindingSourcesV4(records2, memberIds, options = {}) {
|
|
|
38752
38829
|
const localizedTexts = dataById(records2, "localized-text");
|
|
38753
38830
|
const dialogues = dataById(records2, "dialogue");
|
|
38754
38831
|
const symbolsByValueId = staticSymbols(classes, members);
|
|
38755
|
-
|
|
38832
|
+
return {
|
|
38756
38833
|
members,
|
|
38757
38834
|
classes,
|
|
38758
38835
|
values,
|
|
@@ -38769,6 +38846,10 @@ function emitStoredValueBindingSourcesV4(records2, memberIds, options = {}) {
|
|
|
38769
38846
|
referencedValueIds: externallyReferencedValueIds(records2),
|
|
38770
38847
|
localizedTextIds: /* @__PURE__ */ new Set()
|
|
38771
38848
|
};
|
|
38849
|
+
}
|
|
38850
|
+
function emitStoredValueBindingSourcesV4(records2, memberIds, options = {}) {
|
|
38851
|
+
const context = buildValueEmitContext(records2);
|
|
38852
|
+
const members = context.members;
|
|
38772
38853
|
const initializers = /* @__PURE__ */ new Map();
|
|
38773
38854
|
const recordKeysByMember = /* @__PURE__ */ new Map();
|
|
38774
38855
|
for (const memberId of memberIds) {
|
|
@@ -38798,6 +38879,102 @@ function emitStoredValueBindingSourcesV4(records2, memberIds, options = {}) {
|
|
|
38798
38879
|
}
|
|
38799
38880
|
return { initializers, recordKeysByMember };
|
|
38800
38881
|
}
|
|
38882
|
+
function rowBackedDefaultBody(member, isPulledValueRow) {
|
|
38883
|
+
if (member.isStatic === true) return null;
|
|
38884
|
+
const defaultValue = member.defaultValue;
|
|
38885
|
+
if (!isObjectRecord2(defaultValue)) return null;
|
|
38886
|
+
const body = defaultValue.value;
|
|
38887
|
+
const referencesRows = (children) => children.length > 0 && children.every(
|
|
38888
|
+
(child) => typeof child === "string" && isPulledValueRow(child)
|
|
38889
|
+
);
|
|
38890
|
+
if (member.kind === MEMBER_KIND_CLASS && isObjectRecord2(body)) {
|
|
38891
|
+
return referencesRows(Object.values(body)) ? { kind: "class", body } : null;
|
|
38892
|
+
}
|
|
38893
|
+
if (member.kind === MEMBER_KIND_LIST && member.listKind !== "unordered" && Array.isArray(body)) {
|
|
38894
|
+
const rows = body.filter(
|
|
38895
|
+
(child) => typeof child === "string" && isPulledValueRow(child)
|
|
38896
|
+
);
|
|
38897
|
+
return rows.length > 0 && rows.length === body.length ? { kind: "list", body: rows } : null;
|
|
38898
|
+
}
|
|
38899
|
+
if (member.kind === MEMBER_KIND_DICTIONARY && isObjectRecord2(body)) {
|
|
38900
|
+
return referencesRows(Object.values(body)) ? { kind: "dictionary", body } : null;
|
|
38901
|
+
}
|
|
38902
|
+
return null;
|
|
38903
|
+
}
|
|
38904
|
+
function rowBackedDefaultMemberIdsV4(state) {
|
|
38905
|
+
const values = /* @__PURE__ */ new Set();
|
|
38906
|
+
for (const record3 of Object.values(state)) {
|
|
38907
|
+
if (record3.recordKind === "value") values.add(record3.recordId);
|
|
38908
|
+
}
|
|
38909
|
+
const result = /* @__PURE__ */ new Set();
|
|
38910
|
+
for (const record3 of Object.values(state)) {
|
|
38911
|
+
if (record3.recordKind !== "member" || !isObjectRecord2(record3.data)) {
|
|
38912
|
+
continue;
|
|
38913
|
+
}
|
|
38914
|
+
if (rowBackedDefaultBody(record3.data, (id2) => values.has(id2)) !== null) {
|
|
38915
|
+
result.add(record3.recordId);
|
|
38916
|
+
}
|
|
38917
|
+
}
|
|
38918
|
+
return result;
|
|
38919
|
+
}
|
|
38920
|
+
function emitMemberDefaultSourcesV4(records2) {
|
|
38921
|
+
const context = buildValueEmitContext(records2);
|
|
38922
|
+
const initializers = /* @__PURE__ */ new Map();
|
|
38923
|
+
const recordKeysByMember = /* @__PURE__ */ new Map();
|
|
38924
|
+
for (const record3 of records2.values()) {
|
|
38925
|
+
if (record3.deleted || record3.recordKind !== "member" || !isObjectRecord2(record3.data)) {
|
|
38926
|
+
continue;
|
|
38927
|
+
}
|
|
38928
|
+
const member = record3.data;
|
|
38929
|
+
const backed = rowBackedDefaultBody(member, (id2) => context.values.has(id2));
|
|
38930
|
+
if (backed === null) continue;
|
|
38931
|
+
const visited = /* @__PURE__ */ new Set();
|
|
38932
|
+
const defaultValue = isObjectRecord2(member.defaultValue) ? member.defaultValue : {};
|
|
38933
|
+
let expression;
|
|
38934
|
+
if (backed.kind === "class") {
|
|
38935
|
+
expression = classValue(
|
|
38936
|
+
context,
|
|
38937
|
+
member,
|
|
38938
|
+
{ classId: defaultValue.classId ?? null, value: backed.body },
|
|
38939
|
+
visited,
|
|
38940
|
+
false
|
|
38941
|
+
);
|
|
38942
|
+
} else if (backed.kind === "list") {
|
|
38943
|
+
expression = listValue(context, member, { value: backed.body }, visited);
|
|
38944
|
+
} else {
|
|
38945
|
+
expression = dictionaryValue(context, member, backed.body, visited);
|
|
38946
|
+
}
|
|
38947
|
+
initializers.set(record3.recordId, expression);
|
|
38948
|
+
recordKeysByMember.set(
|
|
38949
|
+
record3.recordId,
|
|
38950
|
+
/* @__PURE__ */ new Set([
|
|
38951
|
+
...[...visited].map((id2) => `value:${id2}`),
|
|
38952
|
+
...[...context.localizedTextIds].map((id2) => `localized-text:${id2}`)
|
|
38953
|
+
])
|
|
38954
|
+
);
|
|
38955
|
+
context.localizedTextIds.clear();
|
|
38956
|
+
}
|
|
38957
|
+
return { initializers, recordKeysByMember };
|
|
38958
|
+
}
|
|
38959
|
+
function qualifiedProjectFileSymbolsV4(records2) {
|
|
38960
|
+
const symbols = projectFileSymbols(records2);
|
|
38961
|
+
const result = /* @__PURE__ */ new Map();
|
|
38962
|
+
for (const record3 of records2.values()) {
|
|
38963
|
+
if (record3.deleted || record3.recordKind !== "project-file" || !isObjectRecord2(record3.data)) {
|
|
38964
|
+
continue;
|
|
38965
|
+
}
|
|
38966
|
+
const kind = record3.data.fileType;
|
|
38967
|
+
const symbol = symbols.get(record3.recordId);
|
|
38968
|
+
if (symbol === void 0 || kind !== "image" && kind !== "audio") {
|
|
38969
|
+
continue;
|
|
38970
|
+
}
|
|
38971
|
+
result.set(
|
|
38972
|
+
record3.recordId,
|
|
38973
|
+
`${kind === "image" ? "Images" : "AudioClips"}.${symbol}`
|
|
38974
|
+
);
|
|
38975
|
+
}
|
|
38976
|
+
return result;
|
|
38977
|
+
}
|
|
38801
38978
|
function lowerStaticValueSourcesV4(state, analysis, manifest) {
|
|
38802
38979
|
const bindings = [];
|
|
38803
38980
|
for (const sourceClass of analysis.schema.classes) {
|
|
@@ -38820,7 +38997,7 @@ function lowerStaticValueSourcesV4(state, analysis, manifest) {
|
|
|
38820
38997
|
}
|
|
38821
38998
|
return lowerStoredValueBindingsV4(state, manifest, bindings, { analysis });
|
|
38822
38999
|
}
|
|
38823
|
-
function
|
|
39000
|
+
function buildValueLowerContext(state, manifest, options = {}) {
|
|
38824
39001
|
const members = new Map(
|
|
38825
39002
|
manifest.members.map((member) => [member.id, member])
|
|
38826
39003
|
);
|
|
@@ -38834,7 +39011,7 @@ function lowerStoredValueBindingsV4(state, manifest, bindings, options = {}) {
|
|
|
38834
39011
|
manifest,
|
|
38835
39012
|
parsedInitializers
|
|
38836
39013
|
);
|
|
38837
|
-
|
|
39014
|
+
return {
|
|
38838
39015
|
state,
|
|
38839
39016
|
members,
|
|
38840
39017
|
classes,
|
|
@@ -38858,6 +39035,9 @@ function lowerStoredValueBindingsV4(state, manifest, bindings, options = {}) {
|
|
|
38858
39035
|
parsedInitializers,
|
|
38859
39036
|
reconstructed: /* @__PURE__ */ new Map()
|
|
38860
39037
|
};
|
|
39038
|
+
}
|
|
39039
|
+
function lowerStoredValueBindingsV4(state, manifest, bindings, options = {}) {
|
|
39040
|
+
const context = buildValueLowerContext(state, manifest, options);
|
|
38861
39041
|
const memberValueIds = /* @__PURE__ */ new Map();
|
|
38862
39042
|
const seeds = /* @__PURE__ */ new Map();
|
|
38863
39043
|
for (const binding of bindings) {
|
|
@@ -38869,6 +39049,143 @@ function lowerStoredValueBindingsV4(state, manifest, bindings, options = {}) {
|
|
|
38869
39049
|
seeds
|
|
38870
39050
|
};
|
|
38871
39051
|
}
|
|
39052
|
+
function lowerMemberDefaultSourcesV4(state, analysis, manifest) {
|
|
39053
|
+
const context = buildValueLowerContext(state, manifest, { analysis });
|
|
39054
|
+
const pulledValueIds = /* @__PURE__ */ new Set();
|
|
39055
|
+
for (const record3 of Object.values(state)) {
|
|
39056
|
+
if (record3.recordKind === "value") pulledValueIds.add(record3.recordId);
|
|
39057
|
+
}
|
|
39058
|
+
const memberDefaultValues = /* @__PURE__ */ new Map();
|
|
39059
|
+
for (const sourceClass of analysis.schema.classes) {
|
|
39060
|
+
for (const declaration of sourceClass.members) {
|
|
39061
|
+
if (declaration.kind !== "field" || declaration.initializer === null) {
|
|
39062
|
+
continue;
|
|
39063
|
+
}
|
|
39064
|
+
if (declaration.modifiers.includes("static")) continue;
|
|
39065
|
+
const label = `${sourceClass.name}.${declaration.name}`;
|
|
39066
|
+
const memberId = sourceIdentityId(declaration, "member", label);
|
|
39067
|
+
const baseData3 = stateData(context, "member", memberId);
|
|
39068
|
+
if (baseData3 === null) continue;
|
|
39069
|
+
const backed = rowBackedDefaultBody(
|
|
39070
|
+
baseData3,
|
|
39071
|
+
(id2) => pulledValueIds.has(id2)
|
|
39072
|
+
);
|
|
39073
|
+
if (backed === null) continue;
|
|
39074
|
+
const member = context.members.get(memberId);
|
|
39075
|
+
if (member === void 0) continue;
|
|
39076
|
+
const binding = {
|
|
39077
|
+
memberId,
|
|
39078
|
+
initializer: declaration.initializer,
|
|
39079
|
+
source: declaration.source,
|
|
39080
|
+
label
|
|
39081
|
+
};
|
|
39082
|
+
memberDefaultValues.set(
|
|
39083
|
+
memberId,
|
|
39084
|
+
lowerRowBackedDefault(context, member, backed, baseData3, binding)
|
|
39085
|
+
);
|
|
39086
|
+
}
|
|
39087
|
+
}
|
|
39088
|
+
return {
|
|
39089
|
+
records: [...context.reconstructed.values()],
|
|
39090
|
+
memberDefaultValues
|
|
39091
|
+
};
|
|
39092
|
+
}
|
|
39093
|
+
function lowerRowBackedDefault(context, member, backed, baseData3, binding) {
|
|
39094
|
+
const baseDefault = isObjectRecord2(baseData3.defaultValue) ? baseData3.defaultValue : {};
|
|
39095
|
+
const storedClassId = stringOrNull(baseDefault.classId);
|
|
39096
|
+
const expression = annotatedValue(
|
|
39097
|
+
parseCachedInitializer(context.parsedInitializers, binding.initializer)
|
|
39098
|
+
).expression;
|
|
39099
|
+
if (member.kind === "class" && backed.kind === "class") {
|
|
39100
|
+
if (expression.kind !== "new") {
|
|
39101
|
+
throw new Error(`Default value ${binding.label} requires new(...).`);
|
|
39102
|
+
}
|
|
39103
|
+
const currentClassId = storedClassId ?? member.classId;
|
|
39104
|
+
const classId = expression.className === null ? currentClassId : requiredClassByName(context, expression.className).id;
|
|
39105
|
+
const baseBody = backed.body;
|
|
39106
|
+
const body = {};
|
|
39107
|
+
for (const assignment of expression.initializer ?? []) {
|
|
39108
|
+
const childMember = classMemberByName(context, classId, assignment.name);
|
|
39109
|
+
const existingId = isObjectRecord2(baseBody) ? baseBody[assignment.name] : void 0;
|
|
39110
|
+
const childId = typeof existingId === "string" ? existingId : annotatedValue(assignment.value).id;
|
|
39111
|
+
if (childId === null || childId === void 0) {
|
|
39112
|
+
throw new Error(
|
|
39113
|
+
`Default value ${binding.label}.${assignment.name} has no existing owned value row. Creating new default rows from source is not implemented by this slice.`
|
|
39114
|
+
);
|
|
39115
|
+
}
|
|
39116
|
+
body[assignment.name] = lowerValueRow(
|
|
39117
|
+
context,
|
|
39118
|
+
childMember,
|
|
39119
|
+
assignment.value,
|
|
39120
|
+
childId,
|
|
39121
|
+
binding
|
|
39122
|
+
);
|
|
39123
|
+
}
|
|
39124
|
+
return {
|
|
39125
|
+
value: body,
|
|
39126
|
+
classId: classId === currentClassId ? storedClassId : classId
|
|
39127
|
+
};
|
|
39128
|
+
}
|
|
39129
|
+
if (member.kind === "list" && backed.kind === "list") {
|
|
39130
|
+
if (expression.kind !== "litList") {
|
|
39131
|
+
throw new Error(`Default value ${binding.label} requires [...].`);
|
|
39132
|
+
}
|
|
39133
|
+
const entryMember = requiredMember(context, member.entryMemberId);
|
|
39134
|
+
const existingIds = new Set(backed.body);
|
|
39135
|
+
const ids = expression.elements.map((element, index) => {
|
|
39136
|
+
const symbolId = sourceValueSymbol(context, element);
|
|
39137
|
+
if (symbolId !== null) {
|
|
39138
|
+
if (!existingIds.has(symbolId)) {
|
|
39139
|
+
throw new Error(
|
|
39140
|
+
`Default list ${binding.label} adds value ${symbolId}. Changing default value placement is not implemented by this slice.`
|
|
39141
|
+
);
|
|
39142
|
+
}
|
|
39143
|
+
return symbolId;
|
|
39144
|
+
}
|
|
39145
|
+
const itemId = annotatedValue(element).id;
|
|
39146
|
+
if (itemId === null) {
|
|
39147
|
+
throw new Error(
|
|
39148
|
+
`Default list ${binding.label}[${index}] has no @id. Creating new default rows from source is not implemented by this slice.`
|
|
39149
|
+
);
|
|
39150
|
+
}
|
|
39151
|
+
return lowerValueRow(context, entryMember, element, itemId, binding);
|
|
39152
|
+
});
|
|
39153
|
+
return { value: ids, classId: storedClassId };
|
|
39154
|
+
}
|
|
39155
|
+
if (member.kind === "dictionary" && backed.kind === "dictionary") {
|
|
39156
|
+
if (expression.kind !== "litDict") {
|
|
39157
|
+
throw new Error(`Default value ${binding.label} requires {...}.`);
|
|
39158
|
+
}
|
|
39159
|
+
const entryMember = requiredMember(context, member.entryMemberId);
|
|
39160
|
+
const baseBody = backed.body;
|
|
39161
|
+
const body = {};
|
|
39162
|
+
for (const entry of expression.entries) {
|
|
39163
|
+
if (entry.key.kind !== "litString") {
|
|
39164
|
+
throw new Error(
|
|
39165
|
+
`Default dictionary ${binding.label} requires string keys.`
|
|
39166
|
+
);
|
|
39167
|
+
}
|
|
39168
|
+
const existingId = isObjectRecord2(baseBody) ? baseBody[entry.key.value] : void 0;
|
|
39169
|
+
const entryId = typeof existingId === "string" ? existingId : annotatedValue(entry.value).id;
|
|
39170
|
+
if (entryId === null || entryId === void 0) {
|
|
39171
|
+
throw new Error(
|
|
39172
|
+
`Default dictionary ${binding.label}[${JSON.stringify(entry.key.value)}] has no existing owned value row. Creating new default rows from source is not implemented by this slice.`
|
|
39173
|
+
);
|
|
39174
|
+
}
|
|
39175
|
+
body[entry.key.value] = lowerValueRow(
|
|
39176
|
+
context,
|
|
39177
|
+
entryMember,
|
|
39178
|
+
entry.value,
|
|
39179
|
+
entryId,
|
|
39180
|
+
binding
|
|
39181
|
+
);
|
|
39182
|
+
}
|
|
39183
|
+
return { value: body, classId: storedClassId };
|
|
39184
|
+
}
|
|
39185
|
+
throw new Error(
|
|
39186
|
+
`Default value ${binding.label} does not match its persisted ${member.kind} container shape.`
|
|
39187
|
+
);
|
|
39188
|
+
}
|
|
38872
39189
|
function lowerStoredBinding(context, binding, memberValueIds, seeds) {
|
|
38873
39190
|
const member = context.members.get(binding.memberId);
|
|
38874
39191
|
if (member === void 0) {
|
|
@@ -39143,18 +39460,7 @@ function lowerClassValue(context, member, expression, base, source) {
|
|
|
39143
39460
|
const baseBody = isObjectRecord2(base.value) ? base.value : {};
|
|
39144
39461
|
const body = { ...baseBody };
|
|
39145
39462
|
for (const assignment of expression.initializer ?? []) {
|
|
39146
|
-
const
|
|
39147
|
-
if (typeof childMemberId !== "string") {
|
|
39148
|
-
throw new Error(
|
|
39149
|
-
`Class ${schemaClass2.name} has no stored member ${assignment.name}.`
|
|
39150
|
-
);
|
|
39151
|
-
}
|
|
39152
|
-
const childMember = context.members.get(childMemberId);
|
|
39153
|
-
if (childMember === void 0) {
|
|
39154
|
-
throw new Error(
|
|
39155
|
-
`Class ${schemaClass2.name}.${assignment.name} is missing its member record.`
|
|
39156
|
-
);
|
|
39157
|
-
}
|
|
39463
|
+
const childMember = classMemberByName(context, classId, assignment.name);
|
|
39158
39464
|
const childId = baseBody[assignment.name];
|
|
39159
39465
|
if (typeof childId !== "string") {
|
|
39160
39466
|
throw new Error(
|
|
@@ -39999,7 +40305,7 @@ function classValue(context, member, value, visited, targetTyped) {
|
|
|
39999
40305
|
...Object.keys(value.value).filter((key2) => !order.includes(key2))
|
|
40000
40306
|
]) {
|
|
40001
40307
|
const childId = value.value[key];
|
|
40002
|
-
const childMemberId = schema[key];
|
|
40308
|
+
const childMemberId = schema[key] ?? inheritedSchemaMemberId(context, schemaClass2, key);
|
|
40003
40309
|
if (typeof childId !== "string" || typeof childMemberId !== "string")
|
|
40004
40310
|
continue;
|
|
40005
40311
|
const childMember = context.members.get(childMemberId);
|
|
@@ -40013,9 +40319,23 @@ function classValue(context, member, value, visited, targetTyped) {
|
|
|
40013
40319
|
);
|
|
40014
40320
|
}
|
|
40015
40321
|
return fields.length === 0 ? targetTyped ? "new()" : `new ${name}()` : `${targetTyped ? "new()" : `new ${name}`} {
|
|
40016
|
-
${fields.map((field) =>
|
|
40322
|
+
${fields.map((field) => indentNeoSourceNonEmptyLines(field, 2)).join(",\n")}
|
|
40017
40323
|
}`;
|
|
40018
40324
|
}
|
|
40325
|
+
function inheritedSchemaMemberId(context, schemaClass2, key) {
|
|
40326
|
+
const visited = /* @__PURE__ */ new Set();
|
|
40327
|
+
let current = typeof schemaClass2.extendsClassId === "string" ? schemaClass2.extendsClassId : void 0;
|
|
40328
|
+
while (current !== void 0 && !visited.has(current)) {
|
|
40329
|
+
visited.add(current);
|
|
40330
|
+
const parent = context.classes.get(current);
|
|
40331
|
+
if (parent === void 0) return void 0;
|
|
40332
|
+
const schema = isObjectRecord2(parent.schema) ? parent.schema : {};
|
|
40333
|
+
const memberId = schema[key];
|
|
40334
|
+
if (typeof memberId === "string") return memberId;
|
|
40335
|
+
current = typeof parent.extendsClassId === "string" ? parent.extendsClassId : void 0;
|
|
40336
|
+
}
|
|
40337
|
+
return void 0;
|
|
40338
|
+
}
|
|
40019
40339
|
function listValue(context, member, value, visited) {
|
|
40020
40340
|
if (value.value === null) return "null";
|
|
40021
40341
|
const entryMember = context.members.get(stringField2(member, "entryMemberId"));
|
|
@@ -40027,7 +40347,7 @@ function listValue(context, member, value, visited) {
|
|
|
40027
40347
|
if (ids.length === 0) return "[]";
|
|
40028
40348
|
return `[
|
|
40029
40349
|
${ids.map(
|
|
40030
|
-
(id2) =>
|
|
40350
|
+
(id2) => indentNeoSourceNonEmptyLines(
|
|
40031
40351
|
emitValue(context, entryMember, id2, {
|
|
40032
40352
|
exposeIdentity: context.symbolsByValueId.get(id2) === void 0,
|
|
40033
40353
|
visited
|
|
@@ -40050,7 +40370,7 @@ function dictionaryValue(context, member, body, visited) {
|
|
|
40050
40370
|
return `{
|
|
40051
40371
|
${entries.flatMap(
|
|
40052
40372
|
([key, id2]) => typeof id2 === "string" ? [
|
|
40053
|
-
|
|
40373
|
+
indentNeoSourceNonEmptyLines(
|
|
40054
40374
|
`${quote4(key)}: ${emitValue(context, entryMember, id2, {
|
|
40055
40375
|
exposeIdentity: !context.symbolsByValueId.has(id2) && context.referencedValueIds.has(id2),
|
|
40056
40376
|
visited
|
|
@@ -40241,6 +40561,7 @@ function numberOr2(value, fallback) {
|
|
|
40241
40561
|
function quote4(value) {
|
|
40242
40562
|
return quoteNeoString(value);
|
|
40243
40563
|
}
|
|
40564
|
+
var MEMBER_KIND_DICTIONARY, MEMBER_KIND_LIST, MEMBER_KIND_CLASS;
|
|
40244
40565
|
var init_value_sources = __esm({
|
|
40245
40566
|
"src/project-source/value-sources.ts"() {
|
|
40246
40567
|
"use strict";
|
|
@@ -40249,6 +40570,9 @@ var init_value_sources = __esm({
|
|
|
40249
40570
|
init_project_files();
|
|
40250
40571
|
init_lower_members();
|
|
40251
40572
|
init_source_format();
|
|
40573
|
+
MEMBER_KIND_DICTIONARY = 5;
|
|
40574
|
+
MEMBER_KIND_LIST = 6;
|
|
40575
|
+
MEMBER_KIND_CLASS = 7;
|
|
40252
40576
|
}
|
|
40253
40577
|
});
|
|
40254
40578
|
|
|
@@ -40431,8 +40755,11 @@ function emitProjectDocumentFilesV4(records2) {
|
|
|
40431
40755
|
}
|
|
40432
40756
|
const manifest = documentsToProjectSchemaManifest(schemaRecords);
|
|
40433
40757
|
const staticValues = emitStaticValueSourcesV4(records2);
|
|
40758
|
+
const memberDefaults = emitMemberDefaultSourcesV4(records2);
|
|
40434
40759
|
const baseSource = emitProjectSourcesV4(manifest, {
|
|
40435
40760
|
staticInitializers: staticValues.initializers,
|
|
40761
|
+
defaultInitializers: memberDefaults.initializers,
|
|
40762
|
+
fileSymbols: qualifiedProjectFileSymbolsV4(records2),
|
|
40436
40763
|
relationEndpointExpressions: relationEndpointExpressions(records2)
|
|
40437
40764
|
});
|
|
40438
40765
|
const source = {
|
|
@@ -40440,7 +40767,11 @@ function emitProjectDocumentFilesV4(records2) {
|
|
|
40440
40767
|
files: baseSource.files.map((file) => {
|
|
40441
40768
|
const ownedKeys = file.recordKeys.flatMap((key) => {
|
|
40442
40769
|
if (!key.startsWith("member:")) return [];
|
|
40443
|
-
|
|
40770
|
+
const memberId = key.slice(7);
|
|
40771
|
+
return [
|
|
40772
|
+
...staticValues.recordKeysByMember.get(memberId) ?? [],
|
|
40773
|
+
...memberDefaults.recordKeysByMember.get(memberId) ?? []
|
|
40774
|
+
];
|
|
40444
40775
|
});
|
|
40445
40776
|
return ownedKeys.length === 0 ? file : { ...file, recordKeys: [...file.recordKeys, ...ownedKeys] };
|
|
40446
40777
|
})
|
|
@@ -42732,6 +43063,10 @@ function computeWorkspaceStatus(workspace, options = {}) {
|
|
|
42732
43063
|
let manifest;
|
|
42733
43064
|
let staticValueSeeds = /* @__PURE__ */ new Map();
|
|
42734
43065
|
let staticMemberValueIds = /* @__PURE__ */ new Map();
|
|
43066
|
+
let memberDefaults = {
|
|
43067
|
+
records: [],
|
|
43068
|
+
memberDefaultValues: /* @__PURE__ */ new Map()
|
|
43069
|
+
};
|
|
42735
43070
|
let projectAnalysisV4 = null;
|
|
42736
43071
|
try {
|
|
42737
43072
|
if (!baseManifest) {
|
|
@@ -42795,8 +43130,26 @@ function computeWorkspaceStatus(workspace, options = {}) {
|
|
|
42795
43130
|
};
|
|
42796
43131
|
}
|
|
42797
43132
|
manifest = lowerProjectSchemaV4(baseManifest, analysis, {
|
|
42798
|
-
staticValueIdsBySymbol: staticValueIdsBySymbol2(workspace.state.records)
|
|
43133
|
+
staticValueIdsBySymbol: staticValueIdsBySymbol2(workspace.state.records),
|
|
43134
|
+
projectFileIdsBySymbol: projectFileIdsBySymbol(workspace.state.records),
|
|
43135
|
+
rowBackedDefaultMemberIds: rowBackedDefaultMemberIdsV4(
|
|
43136
|
+
workspace.state.records
|
|
43137
|
+
)
|
|
42799
43138
|
});
|
|
43139
|
+
memberDefaults = lowerMemberDefaultSourcesV4(
|
|
43140
|
+
workspace.state.records,
|
|
43141
|
+
analysis,
|
|
43142
|
+
manifest
|
|
43143
|
+
);
|
|
43144
|
+
if (memberDefaults.memberDefaultValues.size > 0) {
|
|
43145
|
+
manifest = {
|
|
43146
|
+
...manifest,
|
|
43147
|
+
members: manifest.members.map((member) => {
|
|
43148
|
+
const lowered = memberDefaults.memberDefaultValues.get(member.id);
|
|
43149
|
+
return lowered === void 0 ? member : { ...member, defaultValue: lowered };
|
|
43150
|
+
})
|
|
43151
|
+
};
|
|
43152
|
+
}
|
|
42800
43153
|
(options.writeProjectAnalysisCache ?? writeProjectSourceAnalysisCacheV4)(
|
|
42801
43154
|
workspace.root,
|
|
42802
43155
|
analysis
|
|
@@ -42878,7 +43231,12 @@ function computeWorkspaceStatus(workspace, options = {}) {
|
|
|
42878
43231
|
const dialogueState = overlayProspectiveSourceRecords(
|
|
42879
43232
|
workspace.state.records,
|
|
42880
43233
|
documents,
|
|
42881
|
-
[
|
|
43234
|
+
[
|
|
43235
|
+
...staticValues.records,
|
|
43236
|
+
...memberDefaults.records,
|
|
43237
|
+
...rootRecords,
|
|
43238
|
+
...supplementalRecords
|
|
43239
|
+
],
|
|
42882
43240
|
staticMemberValueIds
|
|
42883
43241
|
);
|
|
42884
43242
|
const dialogueRecords = lowerDialogueProjectSourcesV4(
|
|
@@ -42887,6 +43245,7 @@ function computeWorkspaceStatus(workspace, options = {}) {
|
|
|
42887
43245
|
);
|
|
42888
43246
|
records2.push(
|
|
42889
43247
|
...staticValues.records,
|
|
43248
|
+
...memberDefaults.records,
|
|
42890
43249
|
...rootRecords,
|
|
42891
43250
|
...supplementalRecords,
|
|
42892
43251
|
...dialogueRecords
|