@neocompose/cli 0.89.8 → 0.89.9
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 +12 -0
- package/dist/neo-runtime.mjs +1533 -446
- package/dist/test-worker.mjs +213 -23
- 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/constructors.md +20 -0
- package/skills/neocompose-cli/references/declarations/declarations.md +3 -0
- package/skills/neocompose-cli/references/neoscript/collections.md +2 -0
- package/skills/neocompose-cli/references/neoscript/delegates-and-listeners.md +2 -0
- package/skills/neocompose-cli/references/values/identities.md +9 -8
- package/skills/neocompose-cli/references/world/variants.md +5 -2
package/dist/test-worker.mjs
CHANGED
|
@@ -25397,6 +25397,7 @@ function indexRuntimeCollectionChange(collection, entry, ctx, removedEntries = n
|
|
|
25397
25397
|
indexes4.memberByRowId.clear();
|
|
25398
25398
|
}
|
|
25399
25399
|
if (Array.isArray(collection)) forgetLocalListIndexes(ctx, collection);
|
|
25400
|
+
else indexes4.declaredListByArray = /* @__PURE__ */ new WeakMap();
|
|
25400
25401
|
markOverlayMutated(ctx, collection);
|
|
25401
25402
|
if (ctx.__valueOverlay instanceof LazyValueOverlay)
|
|
25402
25403
|
indexes4.overlayRevision = ctx.__valueOverlay.revision;
|
|
@@ -29012,6 +29013,7 @@ function replaceRowValue(row, value, receiver, ctx) {
|
|
|
29012
29013
|
unindexEvaluatorRow(indexes4, row, true);
|
|
29013
29014
|
row.value = value;
|
|
29014
29015
|
indexEvaluatorRow(indexes4, row, true);
|
|
29016
|
+
indexes4.declaredListByArray = /* @__PURE__ */ new WeakMap();
|
|
29015
29017
|
markOverlayMutated(ctx, receiver);
|
|
29016
29018
|
if (ctx.__valueOverlay instanceof LazyValueOverlay)
|
|
29017
29019
|
indexes4.overlayRevision = ctx.__valueOverlay.revision;
|
|
@@ -33268,6 +33270,17 @@ function runtimeTypeCheck(value, checkType, ctx, seenCollections = /* @__PURE__
|
|
|
33268
33270
|
case 8 /* Enum */:
|
|
33269
33271
|
return Array.isArray(value) && value.every((v) => typeof v === "string");
|
|
33270
33272
|
case 7 /* Class */: {
|
|
33273
|
+
if (isVariantClassId(checkType.classId)) {
|
|
33274
|
+
if (!isVariantRefValue(value)) return false;
|
|
33275
|
+
const targetParameter = evaluatorSchemaIndex(ctx).classesById.get(
|
|
33276
|
+
checkType.classId
|
|
33277
|
+
)?.genericParams?.[0];
|
|
33278
|
+
const target = targetParameter === void 0 ? void 0 : receiverClosedTypeArguments(checkType.typeArguments, ctx)?.[targetParameter.id];
|
|
33279
|
+
return target?.type !== 7 /* Class */ || evaluatorSchemaIndex(ctx).classIsOrExtends(
|
|
33280
|
+
value.classId,
|
|
33281
|
+
target.classId
|
|
33282
|
+
);
|
|
33283
|
+
}
|
|
33271
33284
|
if (typeof value !== "object") return false;
|
|
33272
33285
|
const row = trackedRowForValueReference(value, ctx);
|
|
33273
33286
|
const runtimeClassId = row === null ? void 0 : classIdForValueRow(row, ctx);
|
|
@@ -38464,6 +38477,21 @@ function encodeRequiredConstructorArgument(args) {
|
|
|
38464
38477
|
`Constructor argument '${args.parameterId}' has an unresolved generic type.`
|
|
38465
38478
|
);
|
|
38466
38479
|
}
|
|
38480
|
+
if (args.typeInfo.type === 7 /* Class */ && isVariantClassId(args.typeInfo.classId)) {
|
|
38481
|
+
if (args.value === null || args.value === void 0) return null;
|
|
38482
|
+
const selection = readVariantSelection(
|
|
38483
|
+
args.value,
|
|
38484
|
+
`Constructor argument '${args.parameterId}'`
|
|
38485
|
+
);
|
|
38486
|
+
if (selection.rowValueId !== null) {
|
|
38487
|
+
adoptTracked(selection.rowValueId, "variant-row");
|
|
38488
|
+
}
|
|
38489
|
+
return {
|
|
38490
|
+
classId: selection.classId,
|
|
38491
|
+
variantId: selection.variantId,
|
|
38492
|
+
...selection.rowValueId === null ? {} : { rowValueId: selection.rowValueId }
|
|
38493
|
+
};
|
|
38494
|
+
}
|
|
38467
38495
|
if (args.typeInfo.type === 7 /* Class */ || args.typeInfo.type === 22 /* Interface */) {
|
|
38468
38496
|
if (args.value === null || args.value === void 0) return null;
|
|
38469
38497
|
const aggregateId2 = trackedId ?? replayedAggregateId;
|
|
@@ -45504,22 +45532,29 @@ function lookupEntryTypeInfo2(member, collectionTypeInfo) {
|
|
|
45504
45532
|
}
|
|
45505
45533
|
|
|
45506
45534
|
// ../packages/neoscript-runtime/src/values/member-declared-type-info.ts
|
|
45507
|
-
function resolveMemberDeclaredTypeInfo(member, members2, ownerClass = null, env) {
|
|
45535
|
+
function resolveMemberDeclaredTypeInfo(member, members2, classes, ownerClass = null, env) {
|
|
45508
45536
|
return resolveMemberDeclaredTypeInfoInternal(
|
|
45509
45537
|
member,
|
|
45510
45538
|
members2,
|
|
45539
|
+
classes,
|
|
45511
45540
|
/* @__PURE__ */ new Set(),
|
|
45512
45541
|
ownerClass,
|
|
45513
45542
|
env,
|
|
45514
45543
|
ownerClass === null ? void 0 : classConstrainedGenerics([ownerClass])
|
|
45515
45544
|
);
|
|
45516
45545
|
}
|
|
45517
|
-
function resolveMemberDeclaredTypeInfoInternal(member, members2, seen, ownerClass, env, isClassConstrained) {
|
|
45546
|
+
function resolveMemberDeclaredTypeInfoInternal(member, members2, classes, seen, ownerClass, env, isClassConstrained) {
|
|
45518
45547
|
const resolved = env === void 0 ? resolveMember(member, members2) : substituteMember(member, env, members2);
|
|
45519
45548
|
const memberId = getField(resolved, "id");
|
|
45520
45549
|
if (typeof memberId === "string" && seen.has(memberId)) return null;
|
|
45521
45550
|
const nextSeen = typeof memberId === "string" ? /* @__PURE__ */ new Set([...seen, memberId]) : new Set(seen);
|
|
45522
45551
|
if (isMemberNSPropertyBase(resolved)) return resolved.returnTypeInfo;
|
|
45552
|
+
if (isMemberVariantBase(resolved)) {
|
|
45553
|
+
return variantMemberDeclaredTypeInfo(
|
|
45554
|
+
resolved,
|
|
45555
|
+
neoVariantSystemClass(classes, resolved.valueTypeInfo != null)
|
|
45556
|
+
);
|
|
45557
|
+
}
|
|
45523
45558
|
if (isClassSlotMember(resolved)) {
|
|
45524
45559
|
const typeArguments = Object.fromEntries(
|
|
45525
45560
|
Object.entries(declaredSlotArguments(resolved) ?? {}).flatMap(
|
|
@@ -45539,6 +45574,7 @@ function resolveMemberDeclaredTypeInfoInternal(member, members2, seen, ownerClas
|
|
|
45539
45574
|
const argumentType2 = resolveMemberDeclaredTypeInfoInternal(
|
|
45540
45575
|
argumentMember,
|
|
45541
45576
|
members2,
|
|
45577
|
+
classes,
|
|
45542
45578
|
nextSeen,
|
|
45543
45579
|
ownerClass,
|
|
45544
45580
|
env,
|
|
@@ -45609,6 +45645,7 @@ function resolveMemberDeclaredTypeInfoInternal(member, members2, seen, ownerClas
|
|
|
45609
45645
|
const typeInfo = resolveMemberDeclaredTypeInfoInternal(
|
|
45610
45646
|
descriptor,
|
|
45611
45647
|
members2,
|
|
45648
|
+
classes,
|
|
45612
45649
|
nextSeen,
|
|
45613
45650
|
ownerClass,
|
|
45614
45651
|
env,
|
|
@@ -45637,6 +45674,7 @@ function resolveMemberDeclaredTypeInfoInternal(member, members2, seen, ownerClas
|
|
|
45637
45674
|
const entryTypeInfo = resolveMemberDeclaredTypeInfoInternal(
|
|
45638
45675
|
entry,
|
|
45639
45676
|
members2,
|
|
45677
|
+
classes,
|
|
45640
45678
|
nextSeen,
|
|
45641
45679
|
ownerClass,
|
|
45642
45680
|
env,
|
|
@@ -45661,6 +45699,7 @@ function resolveMemberDeclaredTypeInfoInternal(member, members2, seen, ownerClas
|
|
|
45661
45699
|
return resolveMemberDeclaredTypeInfoInternal(
|
|
45662
45700
|
collection,
|
|
45663
45701
|
members2,
|
|
45702
|
+
classes,
|
|
45664
45703
|
nextSeen,
|
|
45665
45704
|
ownerClass,
|
|
45666
45705
|
env,
|
|
@@ -45703,6 +45742,15 @@ function recordEntries(value) {
|
|
|
45703
45742
|
if (typeof value !== "object" || value === null) return [];
|
|
45704
45743
|
return Object.values(value);
|
|
45705
45744
|
}
|
|
45745
|
+
function isVariantArgument(value, typeInfo) {
|
|
45746
|
+
return typeInfo?.type === 7 /* Class */ && isVariantClassId(typeInfo.classId) && isVariantRefValue(value);
|
|
45747
|
+
}
|
|
45748
|
+
function remapVariantArgument(value, typeInfo, remap) {
|
|
45749
|
+
if (!isVariantArgument(value, typeInfo)) return value;
|
|
45750
|
+
if (typeof value.rowValueId !== "string") return value;
|
|
45751
|
+
const rowValueId = remap(value.rowValueId);
|
|
45752
|
+
return rowValueId === value.rowValueId ? value : { ...value, rowValueId };
|
|
45753
|
+
}
|
|
45706
45754
|
var MaterializedValueGraphContext = class _MaterializedValueGraphContext {
|
|
45707
45755
|
/**
|
|
45708
45756
|
* P79 §7a. Generic in the caller's document view so a pass typed against a
|
|
@@ -45939,7 +45987,7 @@ var MaterializedValueGraphContext = class _MaterializedValueGraphContext {
|
|
|
45939
45987
|
const typeInfo = parameterTypes.get(parameterId);
|
|
45940
45988
|
return [
|
|
45941
45989
|
parameterId,
|
|
45942
|
-
typeInfo !== void 0 && (isAggregateTypeInfo(typeInfo) || typeInfo.type === 29 /* Reference */) && typeof argument2 === "string" ? rewriteId(argument2) : argument2
|
|
45990
|
+
typeInfo !== void 0 && (isAggregateTypeInfo(typeInfo) || typeInfo.type === 29 /* Reference */) && typeof argument2 === "string" ? rewriteId(argument2) : remapVariantArgument(argument2, typeInfo, rewriteId)
|
|
45943
45991
|
];
|
|
45944
45992
|
}
|
|
45945
45993
|
)
|
|
@@ -45975,15 +46023,18 @@ var MaterializedValueGraphContext = class _MaterializedValueGraphContext {
|
|
|
45975
46023
|
ids.push(edge.targetValueId);
|
|
45976
46024
|
return ids;
|
|
45977
46025
|
}
|
|
45978
|
-
/**
|
|
46026
|
+
/** Reference targets and bound lookup rows retained by creation data. */
|
|
45979
46027
|
referenceArgumentIds(row) {
|
|
45980
46028
|
if (!isLiteralValueContent(row)) return [];
|
|
45981
46029
|
const args = row.constructorArgs;
|
|
45982
46030
|
if (args === void 0 || args === null) return [];
|
|
45983
46031
|
const ids = [];
|
|
45984
|
-
for (const parameterId of this.
|
|
46032
|
+
for (const [parameterId, typeInfo] of this.constructorParameterTypes(row)) {
|
|
45985
46033
|
const argument2 = args[parameterId];
|
|
45986
|
-
if (typeof argument2 === "string")
|
|
46034
|
+
if (typeInfo.type === 29 /* Reference */ && typeof argument2 === "string")
|
|
46035
|
+
ids.push(argument2);
|
|
46036
|
+
else if (isVariantArgument(argument2, typeInfo) && typeof argument2.rowValueId === "string")
|
|
46037
|
+
ids.push(argument2.rowValueId);
|
|
45987
46038
|
}
|
|
45988
46039
|
return ids;
|
|
45989
46040
|
}
|
|
@@ -45992,23 +46043,23 @@ var MaterializedValueGraphContext = class _MaterializedValueGraphContext {
|
|
|
45992
46043
|
const args = row.constructorArgs;
|
|
45993
46044
|
if (args === void 0 || args === null) return args;
|
|
45994
46045
|
let remapped;
|
|
45995
|
-
for (const parameterId of this.
|
|
46046
|
+
for (const [parameterId, typeInfo] of this.constructorParameterTypes(
|
|
45996
46047
|
row,
|
|
45997
46048
|
contextualMember
|
|
45998
46049
|
)) {
|
|
45999
46050
|
const argument2 = args[parameterId];
|
|
46000
|
-
|
|
46001
|
-
const target = remap(argument2);
|
|
46051
|
+
const target = typeInfo.type === 29 /* Reference */ && typeof argument2 === "string" ? remap(argument2) : remapVariantArgument(argument2, typeInfo, remap);
|
|
46002
46052
|
if (target !== argument2) (remapped ??= { ...args })[parameterId] = target;
|
|
46003
46053
|
}
|
|
46004
46054
|
return remapped ?? args;
|
|
46005
46055
|
}
|
|
46006
|
-
*
|
|
46007
|
-
|
|
46008
|
-
|
|
46009
|
-
|
|
46010
|
-
|
|
46011
|
-
if (typeInfo
|
|
46056
|
+
*variantArgumentSelections(row) {
|
|
46057
|
+
if (!isLiteralValueContent(row)) return;
|
|
46058
|
+
if (row.constructorArgs == null) return;
|
|
46059
|
+
for (const [parameterId, typeInfo] of this.constructorParameterTypes(row)) {
|
|
46060
|
+
const argument2 = row.constructorArgs[parameterId];
|
|
46061
|
+
if (isVariantArgument(argument2, typeInfo)) yield argument2;
|
|
46062
|
+
}
|
|
46012
46063
|
}
|
|
46013
46064
|
slotEntries(row) {
|
|
46014
46065
|
const value = row.value;
|
|
@@ -46109,6 +46160,17 @@ var MaterializedValueGraphContext = class _MaterializedValueGraphContext {
|
|
|
46109
46160
|
if (member === void 0) return null;
|
|
46110
46161
|
return this.memberTypeInfo(member, env);
|
|
46111
46162
|
}
|
|
46163
|
+
if ((rawTypeInfo.type === 7 /* Class */ || rawTypeInfo.type === 22 /* Interface */) && rawTypeInfo.typeArguments !== void 0) {
|
|
46164
|
+
const typeArguments = {};
|
|
46165
|
+
for (const [parameterId, argument2] of Object.entries(
|
|
46166
|
+
rawTypeInfo.typeArguments
|
|
46167
|
+
)) {
|
|
46168
|
+
const resolved = this.resolveTypeInfo(argument2, env);
|
|
46169
|
+
if (resolved === null) return null;
|
|
46170
|
+
typeArguments[parameterId] = resolved;
|
|
46171
|
+
}
|
|
46172
|
+
return { ...rawTypeInfo, typeArguments };
|
|
46173
|
+
}
|
|
46112
46174
|
if (rawTypeInfo.type === 30 /* Tuple */) {
|
|
46113
46175
|
const elements = [];
|
|
46114
46176
|
for (const element of rawTypeInfo.elements) {
|
|
@@ -46140,7 +46202,8 @@ var MaterializedValueGraphContext = class _MaterializedValueGraphContext {
|
|
|
46140
46202
|
const member = substituteMember(rawMember, env, this.document.members);
|
|
46141
46203
|
const typeInfo = resolveMemberDeclaredTypeInfo(
|
|
46142
46204
|
member,
|
|
46143
|
-
this.document.members
|
|
46205
|
+
this.document.members,
|
|
46206
|
+
this.document.classes
|
|
46144
46207
|
);
|
|
46145
46208
|
return typeInfo === null ? null : this.resolveTypeInfo(typeInfo, env);
|
|
46146
46209
|
} catch {
|
|
@@ -46377,7 +46440,11 @@ function tryResolveTypeInfo(document2, rawTypeInfo, env) {
|
|
|
46377
46440
|
function tryMemberTypeInfo(document2, rawMember, env) {
|
|
46378
46441
|
try {
|
|
46379
46442
|
const member = substituteMember(rawMember, env, document2.members);
|
|
46380
|
-
const typeInfo = resolveMemberDeclaredTypeInfo(
|
|
46443
|
+
const typeInfo = resolveMemberDeclaredTypeInfo(
|
|
46444
|
+
member,
|
|
46445
|
+
document2.members,
|
|
46446
|
+
document2.classes
|
|
46447
|
+
);
|
|
46381
46448
|
if (typeInfo === null) return null;
|
|
46382
46449
|
return tryResolveTypeInfo(document2, typeInfo, env);
|
|
46383
46450
|
} catch {
|
|
@@ -58921,11 +58988,97 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
|
|
|
58921
58988
|
if (callee.kind !== "member") return null;
|
|
58922
58989
|
const isInitialize = callee.name === VARIANT_INITIALIZE_NAME;
|
|
58923
58990
|
const isApply = callee.name === VARIANT_APPLY_NAME;
|
|
58924
|
-
|
|
58991
|
+
const isBind = callee.name === "Bind";
|
|
58992
|
+
if (!isInitialize && !isApply && !isBind) return null;
|
|
58925
58993
|
if (callee.receiver.kind === "ident" && !this.hasValueReceiver(callee.receiver.name, scope) && this.project.typeByName.has(callee.receiver.name)) {
|
|
58926
58994
|
return null;
|
|
58927
58995
|
}
|
|
58928
58996
|
const receiver = receiverValue ? receiverValue() : this.resolveExpression(callee.receiver, scope);
|
|
58997
|
+
if (isBind) {
|
|
58998
|
+
const variantInfo2 = this.variantTypeInfo(receiver.type);
|
|
58999
|
+
if (variantInfo2 === null) return null;
|
|
59000
|
+
if (variantInfo2.valueType === null) {
|
|
59001
|
+
throw new CompileError("Only a lookup variant can bind a row.", pos);
|
|
59002
|
+
}
|
|
59003
|
+
if (callee.optional === true) {
|
|
59004
|
+
throw new CompileError("Bind requires a non-null lookup variant.", pos);
|
|
59005
|
+
}
|
|
59006
|
+
if (receiver.pointer.type !== "variant" /* Variant */) {
|
|
59007
|
+
throw new CompileError(
|
|
59008
|
+
"Bind requires a declared lookup variant path.",
|
|
59009
|
+
pos
|
|
59010
|
+
);
|
|
59011
|
+
}
|
|
59012
|
+
requireArgCount("NeoLookupVariant.Bind", argumentsList2, 1, pos);
|
|
59013
|
+
const row2 = argumentsList2[0];
|
|
59014
|
+
if (row2.kind !== "call") {
|
|
59015
|
+
throw new CompileError(
|
|
59016
|
+
'Bind requires Reference(id: "value-id").',
|
|
59017
|
+
row2.pos
|
|
59018
|
+
);
|
|
59019
|
+
}
|
|
59020
|
+
if (row2.callee.kind !== "ident" || row2.callee.name !== "Reference") {
|
|
59021
|
+
throw new CompileError(
|
|
59022
|
+
"Bind requires a Reference row argument.",
|
|
59023
|
+
row2.pos
|
|
59024
|
+
);
|
|
59025
|
+
}
|
|
59026
|
+
requireArgCount("Bind Reference", row2.args, 1, row2.pos);
|
|
59027
|
+
if (row2.argumentNames?.[0] !== "id") {
|
|
59028
|
+
throw new CompileError(
|
|
59029
|
+
'Bind requires Reference(id: "value-id").',
|
|
59030
|
+
row2.pos
|
|
59031
|
+
);
|
|
59032
|
+
}
|
|
59033
|
+
const id = row2.args[0];
|
|
59034
|
+
if (id.kind !== "litString") {
|
|
59035
|
+
throw new CompileError(
|
|
59036
|
+
"Bound row id must be a string literal.",
|
|
59037
|
+
id.pos
|
|
59038
|
+
);
|
|
59039
|
+
}
|
|
59040
|
+
if (id.value.length === 0) {
|
|
59041
|
+
throw new CompileError("Bound row id must not be empty.", id.pos);
|
|
59042
|
+
}
|
|
59043
|
+
if (row2.typeArguments !== void 0) {
|
|
59044
|
+
if (row2.typeArguments.length !== 1) {
|
|
59045
|
+
throw new CompileError(
|
|
59046
|
+
"Reference requires exactly one generic target type.",
|
|
59047
|
+
row2.pos
|
|
59048
|
+
);
|
|
59049
|
+
}
|
|
59050
|
+
this.requireAssignable(
|
|
59051
|
+
this.resolveType(row2.typeArguments[0]),
|
|
59052
|
+
variantInfo2.valueType,
|
|
59053
|
+
row2.pos,
|
|
59054
|
+
"Lookup variant row"
|
|
59055
|
+
);
|
|
59056
|
+
}
|
|
59057
|
+
const rowType = this.context.persistedReferenceTypes?.get(id.value);
|
|
59058
|
+
if (rowType !== void 0) {
|
|
59059
|
+
this.requireAssignable(
|
|
59060
|
+
neoScriptReadType(rowType),
|
|
59061
|
+
variantInfo2.valueType,
|
|
59062
|
+
row2.pos,
|
|
59063
|
+
"Lookup variant row"
|
|
59064
|
+
);
|
|
59065
|
+
}
|
|
59066
|
+
const bound = this.project.typeByName.get(NEO_VARIANT_TYPE_NAME);
|
|
59067
|
+
if (bound === void 0) {
|
|
59068
|
+
throw new CompileError(
|
|
59069
|
+
`The seeded '${NEO_VARIANT_TYPE_NAME}' class is missing.`,
|
|
59070
|
+
pos
|
|
59071
|
+
);
|
|
59072
|
+
}
|
|
59073
|
+
return {
|
|
59074
|
+
pointer: { ...receiver.pointer, rowValueId: id.value },
|
|
59075
|
+
type: {
|
|
59076
|
+
kind: "named",
|
|
59077
|
+
typeId: bound.id,
|
|
59078
|
+
typeArguments: receiver.type.kind === "named" ? receiver.type.typeArguments?.slice(0, 1) ?? [] : []
|
|
59079
|
+
}
|
|
59080
|
+
};
|
|
59081
|
+
}
|
|
58929
59082
|
if (isInitialize) {
|
|
58930
59083
|
const variantInfo2 = this.variantTypeInfo(receiver.type);
|
|
58931
59084
|
if (variantInfo2 === null) return null;
|
|
@@ -60827,6 +60980,33 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
|
|
|
60827
60980
|
typeArguments
|
|
60828
60981
|
);
|
|
60829
60982
|
}
|
|
60983
|
+
if (callee.kind === "lambda" && expected !== void 0) {
|
|
60984
|
+
rejectTypeArguments();
|
|
60985
|
+
const parameterTypes = callee.params.map((parameter3) => {
|
|
60986
|
+
if (parameter3.type === null) {
|
|
60987
|
+
throw new CompileError(
|
|
60988
|
+
"An immediately invoked lambda requires explicit parameter types.",
|
|
60989
|
+
parameter3.pos
|
|
60990
|
+
);
|
|
60991
|
+
}
|
|
60992
|
+
return this.resolveType(parameter3.type);
|
|
60993
|
+
});
|
|
60994
|
+
return this.resolveDelegateCall(
|
|
60995
|
+
this.resolveDelegateLambda(
|
|
60996
|
+
callee,
|
|
60997
|
+
{
|
|
60998
|
+
kind: "delegate",
|
|
60999
|
+
parameterTypes,
|
|
61000
|
+
returnType: expected
|
|
61001
|
+
},
|
|
61002
|
+
scope
|
|
61003
|
+
),
|
|
61004
|
+
argumentsList2,
|
|
61005
|
+
scope,
|
|
61006
|
+
pos,
|
|
61007
|
+
false
|
|
61008
|
+
);
|
|
61009
|
+
}
|
|
60830
61010
|
const variantCall = this.resolveVariantCall(
|
|
60831
61011
|
callee,
|
|
60832
61012
|
argumentsList2,
|
|
@@ -71527,7 +71707,7 @@ function resolveAnalyzerMember(context, member) {
|
|
|
71527
71707
|
}
|
|
71528
71708
|
|
|
71529
71709
|
// ../src/runtime/neoscript/neoscript-language-context-adapter.ts
|
|
71530
|
-
var NEOSCRIPT_COMPILER_ADAPTER_REVISION =
|
|
71710
|
+
var NEOSCRIPT_COMPILER_ADAPTER_REVISION = 7;
|
|
71531
71711
|
var UNKNOWN_TYPE = {
|
|
71532
71712
|
kind: "primitive",
|
|
71533
71713
|
name: "unknown"
|
|
@@ -73817,6 +73997,7 @@ function compileMemberInitializerBody(args) {
|
|
|
73817
73997
|
const returnTypeInfo = resolveMemberDeclaredTypeInfo(
|
|
73818
73998
|
args.member,
|
|
73819
73999
|
members2,
|
|
74000
|
+
args.classes,
|
|
73820
74001
|
args.thisClass
|
|
73821
74002
|
);
|
|
73822
74003
|
if (returnTypeInfo === null) {
|
|
@@ -73864,7 +74045,8 @@ function compileValueRowInitializerBody(args) {
|
|
|
73864
74045
|
}
|
|
73865
74046
|
const returnTypeInfo = resolveMemberDeclaredTypeInfo(
|
|
73866
74047
|
args.member,
|
|
73867
|
-
args.members
|
|
74048
|
+
args.members,
|
|
74049
|
+
args.classes
|
|
73868
74050
|
);
|
|
73869
74051
|
if (returnTypeInfo === null) {
|
|
73870
74052
|
throw new Error(
|
|
@@ -73997,7 +74179,9 @@ function compilationProjectForDocument(document2, state) {
|
|
|
73997
74179
|
classes: document2.classes,
|
|
73998
74180
|
enums: document2.enums,
|
|
73999
74181
|
interfaces: document2.interfaces,
|
|
74000
|
-
constructors: document2.constructors ?? []
|
|
74182
|
+
constructors: document2.constructors ?? [],
|
|
74183
|
+
variants: document2.variants ?? [],
|
|
74184
|
+
variantFolders: document2.variantFolders ?? []
|
|
74001
74185
|
});
|
|
74002
74186
|
return state.compilationProject;
|
|
74003
74187
|
}
|
|
@@ -74093,6 +74277,8 @@ function compileValueInitializerDependency(document2, valueId, compilationProjec
|
|
|
74093
74277
|
enums: document2.enums,
|
|
74094
74278
|
interfaces: document2.interfaces,
|
|
74095
74279
|
constructors: document2.constructors ?? [],
|
|
74280
|
+
variants: document2.variants ?? [],
|
|
74281
|
+
variantFolders: document2.variantFolders ?? [],
|
|
74096
74282
|
member: site.member,
|
|
74097
74283
|
valueRow: { ...site.row },
|
|
74098
74284
|
valueId: site.row.id,
|
|
@@ -74111,7 +74297,9 @@ function compileMemberInitializerDependency(document2, memberId, compilationProj
|
|
|
74111
74297
|
classes: document2.classes,
|
|
74112
74298
|
enums: document2.enums,
|
|
74113
74299
|
interfaces: document2.interfaces,
|
|
74114
|
-
constructors: document2.constructors ?? []
|
|
74300
|
+
constructors: document2.constructors ?? [],
|
|
74301
|
+
variants: document2.variants ?? [],
|
|
74302
|
+
variantFolders: document2.variantFolders ?? []
|
|
74115
74303
|
};
|
|
74116
74304
|
const memberIndex = documentMemberCompilationIndex(document2);
|
|
74117
74305
|
const member = memberIndex.membersById.get(memberId);
|
|
@@ -86384,7 +86572,9 @@ function buildNeoScriptProject(document2) {
|
|
|
86384
86572
|
classes: document2.classes,
|
|
86385
86573
|
enums: document2.enums,
|
|
86386
86574
|
interfaces: document2.interfaces,
|
|
86387
|
-
constructors: document2.constructors ?? []
|
|
86575
|
+
constructors: document2.constructors ?? [],
|
|
86576
|
+
variants: document2.variants,
|
|
86577
|
+
variantFolders: document2.variantFolders
|
|
86388
86578
|
});
|
|
86389
86579
|
}
|
|
86390
86580
|
function neoScriptProjectFingerprint(document2) {
|
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.9 -->
|
|
147
147
|
```
|
|
148
148
|
|
|
149
149
|
Keep this skill on current behavior. Upgrade steps, rollout prerequisites,
|
|
@@ -31,6 +31,26 @@ Foo value = new(bar: "BAR", isFun: true) { IsFun = false };
|
|
|
31
31
|
- A header constructor disables implicit parameterless `new` and forbids
|
|
32
32
|
other constructor overloads. Its derived identity takes no `@id`.
|
|
33
33
|
|
|
34
|
+
## Variant parameters
|
|
35
|
+
|
|
36
|
+
Constructors accept `NeoVariant<T>` and `NeoLookupVariant<T, TValue>` selections,
|
|
37
|
+
including nullable selections and generic targets such as `NeoVariant<Kid<int>>`.
|
|
38
|
+
A member initializer can retain the selection for each instance:
|
|
39
|
+
|
|
40
|
+
```neo
|
|
41
|
+
class Box : NeoObject {}
|
|
42
|
+
class Made(NeoVariant<Box> selection) {
|
|
43
|
+
public NeoVariant<Box> Selection = selection;
|
|
44
|
+
}
|
|
45
|
+
Made value = new(Box.Variants.Base);
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Push and export retain the selected variant and any bound lookup row for replay.
|
|
49
|
+
`null` is an empty nullable selection; `Box.Variants.Base` selects the base class.
|
|
50
|
+
To pass a bound lookup selection directly, use a declared variant path and a
|
|
51
|
+
stored row ID, such as `new Made(Box.Variants.Seeds.BySeed.Bind(Reference(id: "row-id")))`.
|
|
52
|
+
This compiles to a fixed selection; `Bind` does not evaluate a dynamic row expression.
|
|
53
|
+
|
|
34
54
|
## Declared constructors
|
|
35
55
|
|
|
36
56
|
Declare overloadable constructors as members when each body owns its own
|
|
@@ -39,6 +39,9 @@ abstract class Item<TContext extends SomeClass> : INamed {
|
|
|
39
39
|
The `@id`s above are pulled IDs. New declarations omit them; push assigns them.
|
|
40
40
|
Never put `@id` on inferred list/dictionary entry types or derived structural
|
|
41
41
|
descriptors.
|
|
42
|
+
Generic bindings and their nested collection descriptors follow the owning
|
|
43
|
+
declaration's identity. Deleting and recreating an idless declaration creates
|
|
44
|
+
fresh bindings; retaining its pulled IDs preserves them.
|
|
42
45
|
|
|
43
46
|
## Modifiers
|
|
44
47
|
|
|
@@ -50,6 +50,8 @@ return this.Beds
|
|
|
50
50
|
entries. Declared index lookups (`items.Index.Name[key]`) preserve the source
|
|
51
51
|
entries' write permissions: writable fields can be updated through unique
|
|
52
52
|
results or a bucket's entries, while bucket membership stays read-only.
|
|
53
|
+
Subsequent index lookups reflect writes to indexed fields, including writes
|
|
54
|
+
through `Where` results.
|
|
53
55
|
|
|
54
56
|
## Reductions
|
|
55
57
|
|
|
@@ -18,6 +18,8 @@ List<Item> ready = this.Items.Where((item) => item.Count > 0);
|
|
|
18
18
|
- Call any non-null delegate expression directly: `callbacks[0](value)`,
|
|
19
19
|
`(cond ? a : b)()`, `Factory.Make()()`. Force-unwrap a nullable one first:
|
|
20
20
|
`callbacks["key"]!()`. Void delegates are statements only.
|
|
21
|
+
- A typed lambda can be called immediately when its result has an expected
|
|
22
|
+
type: `int n = ((int x) => x + 1)(2);`. Declare each parameter's type.
|
|
21
23
|
- Inside a class body, invoke delegate and action members directly:
|
|
22
24
|
`Selector()`, `OnUpdated()`.
|
|
23
25
|
|
|
@@ -70,7 +70,6 @@ stored instance rather than building a copy. Its owning placement keeps it,
|
|
|
70
70
|
so a constructor that stores it needs a `Reference` field:
|
|
71
71
|
|
|
72
72
|
```neo
|
|
73
|
-
@id("86ac7c7d-8d3b-4642-9def-cdf32643bdc5")
|
|
74
73
|
DeliveryQuest HARD_AS_STONE = new();
|
|
75
74
|
// The core quest list owns HARD_AS_STONE.
|
|
76
75
|
WorkflowStep UNLOCK = new QuestUnlockStep(HARD_AS_STONE);
|
|
@@ -82,13 +81,15 @@ class QuestUnlockStep(DeliveryQuest quest) : WorkflowStep {
|
|
|
82
81
|
|
|
83
82
|
- The local needs exactly one owning placement. Unowned locals, ambiguous
|
|
84
83
|
placements, and cycles are source errors.
|
|
85
|
-
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
84
|
+
- New nested locals can be referenced before their first push or export, including
|
|
85
|
+
inside lists, dictionaries, and constructor-backed owners. Preparation resolves
|
|
86
|
+
each reference to the row its unique owner creates. Aliases share that identity.
|
|
87
|
+
Sibling constructor arguments and explicit `Reference(LOCAL)` calls reuse the
|
|
88
|
+
child within the same owning tree. A parent constructor may borrow a child
|
|
89
|
+
that one of its field overrides owns; pull preserves both uses.
|
|
90
|
+
Direct `Reference(LOCAL)` fields resolve after the owning constructor runs.
|
|
91
|
+
- Push writes assigned IDs back to source. Dry-run and export prepare the same
|
|
92
|
+
references without requiring hand-written IDs or an earlier push.
|
|
92
93
|
- A member default is a construction template, so its local is not a single
|
|
93
94
|
stored instance.
|
|
94
95
|
- Owned locals inside evaluated initializers need directly addressable fields,
|
|
@@ -44,6 +44,8 @@ frame. For editing an existing clip, see [frame overrides](animation.md).
|
|
|
44
44
|
- Selections compare equal when class, variant, and bound lookup row match.
|
|
45
45
|
An unset optional selection differs from `Base`.
|
|
46
46
|
|
|
47
|
+
Variant selections can also be [constructor parameters](../declarations/constructors.md#variant-parameters). A constructor can retain a named, base, or bound lookup selection in a member initializer.
|
|
48
|
+
|
|
47
49
|
## Folders
|
|
48
50
|
|
|
49
51
|
```neo
|
|
@@ -112,8 +114,9 @@ NeoLookupVariant<ExampleObject, NeoSortingLayer> Layered = new(
|
|
|
112
114
|
## Type restrictions
|
|
113
115
|
|
|
114
116
|
`NeoVariantFolder` and `NeoLookupVariantFolder` are top-level records, never
|
|
115
|
-
member or parameter types. Variant handles are valid as Variant members
|
|
116
|
-
not as collection entries, lookup targets,
|
|
117
|
+
member or parameter types. Variant handles are valid as Variant members and
|
|
118
|
+
constructor parameters, not as collection entries, lookup targets, ordinary
|
|
119
|
+
function parameters, or generic bindings.
|
|
117
120
|
|
|
118
121
|
## Stored overrides
|
|
119
122
|
|