@neocompose/cli 0.76.3 → 0.77.0
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 +1028 -206
- package/dist/test-worker.mjs +121 -50
- 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-and-construction.md +26 -9
- package/skills/neocompose-cli/references/neoscript.md +1 -1
package/dist/test-worker.mjs
CHANGED
|
@@ -4587,7 +4587,10 @@ function isMemberEnum(value) {
|
|
|
4587
4587
|
if (!isWithId(value)) return false;
|
|
4588
4588
|
return isWithId(value);
|
|
4589
4589
|
}
|
|
4590
|
-
function
|
|
4590
|
+
function isLookupSelection(selection) {
|
|
4591
|
+
return selection === void 0 || selection === 0 /* Single */ || selection === 1 /* Multi */;
|
|
4592
|
+
}
|
|
4593
|
+
function isMemberCollectionLookupBase(value) {
|
|
4591
4594
|
const v = asMemberBaseForKind(value, 9 /* Lookup */);
|
|
4592
4595
|
if (v === null) return false;
|
|
4593
4596
|
if (typeof v.collectionMemberId !== "string") return false;
|
|
@@ -4598,7 +4601,22 @@ function isMemberLookupBase(value) {
|
|
|
4598
4601
|
if (v.declaredTypeInfo !== void 0 && v.declaredTypeInfo !== null && !isNSTypeInfo(v.declaredTypeInfo)) {
|
|
4599
4602
|
return false;
|
|
4600
4603
|
}
|
|
4601
|
-
return v.selection
|
|
4604
|
+
return isLookupSelection(v.selection);
|
|
4605
|
+
}
|
|
4606
|
+
function isMemberTypeLookupBase(value) {
|
|
4607
|
+
const v = asMemberBaseForKind(value, 9 /* Lookup */);
|
|
4608
|
+
if (v === null) return false;
|
|
4609
|
+
if (v.collectionMemberId !== void 0) return false;
|
|
4610
|
+
if (v.collectionValueId !== void 0) return false;
|
|
4611
|
+
if (!isLookupTargetTypeInfo(v.declaredTypeInfo)) return false;
|
|
4612
|
+
return isLookupSelection(v.selection);
|
|
4613
|
+
}
|
|
4614
|
+
function isLookupTargetTypeInfo(value) {
|
|
4615
|
+
if (!isNSTypeInfo(value)) return false;
|
|
4616
|
+
return value.type === 7 /* Class */ || value.type === 21 /* Generic */;
|
|
4617
|
+
}
|
|
4618
|
+
function isMemberLookupBase(value) {
|
|
4619
|
+
return isMemberCollectionLookupBase(value) || isMemberTypeLookupBase(value);
|
|
4602
4620
|
}
|
|
4603
4621
|
function isMemberLookup(value) {
|
|
4604
4622
|
if (!isMemberLookupBase(value)) return false;
|
|
@@ -18677,7 +18695,11 @@ function evalInstructions(instructions, scope, ctx, options) {
|
|
|
18677
18695
|
}
|
|
18678
18696
|
let targetTypeInfo = ins.target.typeInfo;
|
|
18679
18697
|
if (lookupAssignment && targetTypeInfo.type !== 9 /* Lookup */ && targetTypeInfo.type !== 18 /* DialogueLookup */) {
|
|
18680
|
-
targetTypeInfo = {
|
|
18698
|
+
targetTypeInfo = member.collectionMemberId === void 0 ? {
|
|
18699
|
+
type: 9 /* Lookup */,
|
|
18700
|
+
required: targetTypeInfo.required,
|
|
18701
|
+
entryTypeInfo: targetTypeInfo
|
|
18702
|
+
} : {
|
|
18681
18703
|
type: 9 /* Lookup */,
|
|
18682
18704
|
required: targetTypeInfo.required,
|
|
18683
18705
|
entryTypeInfo: targetTypeInfo,
|
|
@@ -21362,6 +21384,13 @@ function runtimeTypeInfoForMember(rawMember, env, ctx, seen) {
|
|
|
21362
21384
|
};
|
|
21363
21385
|
}
|
|
21364
21386
|
if (isMemberLookup(member)) {
|
|
21387
|
+
if (member.collectionMemberId === void 0) {
|
|
21388
|
+
const entryTypeInfo2 = {
|
|
21389
|
+
...substituteRuntimeTypeInfo(member.declaredTypeInfo, env, ctx),
|
|
21390
|
+
required: isMultiSelectionMember(member) ? true : false
|
|
21391
|
+
};
|
|
21392
|
+
return isMultiSelectionMember(member) ? { type: 9 /* Lookup */, required, entryTypeInfo: entryTypeInfo2 } : entryTypeInfo2;
|
|
21393
|
+
}
|
|
21365
21394
|
const collection = evalMemberById(ctx.vm, member.collectionMemberId);
|
|
21366
21395
|
if (collection === null) {
|
|
21367
21396
|
throw new NSGetterRuntimeError(
|
|
@@ -28225,17 +28254,21 @@ function projectListenerEndpoint(args) {
|
|
|
28225
28254
|
|
|
28226
28255
|
// ../packages/models/src/members/lookup-declared-type.ts
|
|
28227
28256
|
function lookupDeclaredTypeInfo(member, collectionTypeInfo) {
|
|
28228
|
-
|
|
28229
|
-
if (
|
|
28230
|
-
return null;
|
|
28231
|
-
}
|
|
28232
|
-
const entryTypeInfo = member.declaredTypeInfo ?? collectionTypeInfo.entryTypeInfo;
|
|
28257
|
+
const entryTypeInfo = lookupEntryTypeInfo(member, collectionTypeInfo);
|
|
28258
|
+
if (entryTypeInfo === null) return null;
|
|
28233
28259
|
if (isMultiSelectionMember(member) !== true) {
|
|
28234
28260
|
return {
|
|
28235
28261
|
...entryTypeInfo,
|
|
28236
28262
|
required: isRequiredMember(member)
|
|
28237
28263
|
};
|
|
28238
28264
|
}
|
|
28265
|
+
if (member.collectionMemberId === void 0) {
|
|
28266
|
+
return {
|
|
28267
|
+
type: 9 /* Lookup */,
|
|
28268
|
+
required: isRequiredMember(member),
|
|
28269
|
+
entryTypeInfo
|
|
28270
|
+
};
|
|
28271
|
+
}
|
|
28239
28272
|
return {
|
|
28240
28273
|
type: 9 /* Lookup */,
|
|
28241
28274
|
required: isRequiredMember(member),
|
|
@@ -28244,6 +28277,15 @@ function lookupDeclaredTypeInfo(member, collectionTypeInfo) {
|
|
|
28244
28277
|
collectionValueId: member.collectionValueId ?? null
|
|
28245
28278
|
};
|
|
28246
28279
|
}
|
|
28280
|
+
function lookupEntryTypeInfo(member, collectionTypeInfo) {
|
|
28281
|
+
if (member.collectionMemberId === void 0) return member.declaredTypeInfo;
|
|
28282
|
+
const collection = collectionTypeInfo(member.collectionMemberId);
|
|
28283
|
+
if (collection === null) return null;
|
|
28284
|
+
if (collection.type !== 6 /* List */ && collection.type !== 5 /* Dictionary */) {
|
|
28285
|
+
return null;
|
|
28286
|
+
}
|
|
28287
|
+
return member.declaredTypeInfo ?? collection.entryTypeInfo;
|
|
28288
|
+
}
|
|
28247
28289
|
|
|
28248
28290
|
// ../packages/neoscript-runtime/src/values/member-declared-type-info.ts
|
|
28249
28291
|
function resolveMemberDeclaredTypeInfo(member, members, ownerClass = null) {
|
|
@@ -28351,19 +28393,18 @@ function resolveMemberDeclaredTypeInfoInternal(member, members, seen, ownerClass
|
|
|
28351
28393
|
};
|
|
28352
28394
|
}
|
|
28353
28395
|
if (isMemberLookupBase(resolved)) {
|
|
28354
|
-
|
|
28355
|
-
|
|
28356
|
-
|
|
28357
|
-
|
|
28358
|
-
|
|
28359
|
-
|
|
28360
|
-
resolveMemberDeclaredTypeInfoInternal(
|
|
28396
|
+
return lookupDeclaredTypeInfo(resolved, (collectionMemberId) => {
|
|
28397
|
+
const collection = members.find(
|
|
28398
|
+
(candidate) => candidate.id === collectionMemberId
|
|
28399
|
+
);
|
|
28400
|
+
if (collection === void 0) return null;
|
|
28401
|
+
return resolveMemberDeclaredTypeInfoInternal(
|
|
28361
28402
|
collection,
|
|
28362
28403
|
members,
|
|
28363
28404
|
nextSeen,
|
|
28364
28405
|
ownerClass
|
|
28365
|
-
)
|
|
28366
|
-
);
|
|
28406
|
+
);
|
|
28407
|
+
});
|
|
28367
28408
|
}
|
|
28368
28409
|
if (resolved.kind === 9 /* Lookup */) return null;
|
|
28369
28410
|
if (!memberKindSupportsStorage(resolved.kind)) return null;
|
|
@@ -36073,7 +36114,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
|
|
|
36073
36114
|
local,
|
|
36074
36115
|
localType,
|
|
36075
36116
|
"local" /* Local */,
|
|
36076
|
-
initial
|
|
36117
|
+
localOwnership(initial),
|
|
36077
36118
|
this.localWriteTargetRoot(initial, scope)
|
|
36078
36119
|
)
|
|
36079
36120
|
);
|
|
@@ -39326,6 +39367,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
|
|
|
39326
39367
|
} : {}
|
|
39327
39368
|
};
|
|
39328
39369
|
}
|
|
39370
|
+
const writability = member.writability ? toWritability(member.writability, this.writesUserData) : void 0;
|
|
39329
39371
|
return {
|
|
39330
39372
|
pointer: {
|
|
39331
39373
|
type: "staticMember" /* StaticMember */,
|
|
@@ -39333,8 +39375,10 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
|
|
|
39333
39375
|
},
|
|
39334
39376
|
type: member.type,
|
|
39335
39377
|
symbol: member,
|
|
39336
|
-
...
|
|
39337
|
-
|
|
39378
|
+
...writability ? { writability } : {},
|
|
39379
|
+
...member.lookup ? {
|
|
39380
|
+
entryWritability: this.lookupEntryWritability(member, writability),
|
|
39381
|
+
entryUserData: this.lookupEntryUserData(member)
|
|
39338
39382
|
} : {}
|
|
39339
39383
|
};
|
|
39340
39384
|
}
|
|
@@ -39634,7 +39678,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
|
|
|
39634
39678
|
const readonlySlot = member.readonlyDeclaration === true;
|
|
39635
39679
|
const storageWritability = this.memberWritability(member, receiver);
|
|
39636
39680
|
const writability = readonlySlot ? "readOnly" /* ReadOnly */ : storageWritability;
|
|
39637
|
-
const entryWritability = member.lookup ? this.lookupEntryWritability(member, receiver) : readonlySlot ? storageWritability : void 0;
|
|
39681
|
+
const entryWritability = member.lookup ? this.lookupEntryWritability(member, receiver.writability) : readonlySlot ? storageWritability : void 0;
|
|
39638
39682
|
const userData = this.memberUserData(member, receiver);
|
|
39639
39683
|
const entryUserData = member.lookup ? this.lookupEntryUserData(member) : readonlySlot && userData;
|
|
39640
39684
|
const lookupWire = member.lookup?.multiselect === true && memberType2.kind === "set" ? {
|
|
@@ -39644,7 +39688,7 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
|
|
|
39644
39688
|
{ ...memberType2.elementType, nullable: false },
|
|
39645
39689
|
this.project
|
|
39646
39690
|
),
|
|
39647
|
-
collectionMemberId: member.lookup.collectionMemberId,
|
|
39691
|
+
...member.lookup.collectionMemberId !== void 0 ? { collectionMemberId: member.lookup.collectionMemberId } : {},
|
|
39648
39692
|
...member.lookup.collectionValueId !== void 0 ? { collectionValueId: member.lookup.collectionValueId } : {}
|
|
39649
39693
|
} : void 0;
|
|
39650
39694
|
return {
|
|
@@ -39768,16 +39812,18 @@ var StrictNeoScriptResolver = class _StrictNeoScriptResolver {
|
|
|
39768
39812
|
}
|
|
39769
39813
|
lookupEntryUserData(member) {
|
|
39770
39814
|
if (!member.lookup) return false;
|
|
39771
|
-
const
|
|
39815
|
+
const collectionMemberId = member.lookup.collectionMemberId;
|
|
39816
|
+
if (collectionMemberId === void 0) return false;
|
|
39817
|
+
const collectionWritability = member.lookup.collectionWritability ?? this.project.symbolById.get(collectionMemberId)?.writability;
|
|
39772
39818
|
return collectionWritability === "user";
|
|
39773
39819
|
}
|
|
39774
|
-
lookupEntryWritability(member,
|
|
39820
|
+
lookupEntryWritability(member, receiverWritability) {
|
|
39775
39821
|
if (!member.lookup) return "readOnly" /* ReadOnly */;
|
|
39776
|
-
const
|
|
39777
|
-
|
|
39778
|
-
);
|
|
39822
|
+
const collectionMemberId = member.lookup.collectionMemberId;
|
|
39823
|
+
if (collectionMemberId === void 0) return "runtime" /* Runtime */;
|
|
39824
|
+
const target = this.project.symbolById.get(collectionMemberId);
|
|
39779
39825
|
const targetWritability = member.lookup.collectionWritability ? toWritability(member.lookup.collectionWritability, this.writesUserData) : target?.writability ? toWritability(target.writability, this.writesUserData) : target?.writable ? "runtime" /* Runtime */ : "readOnly" /* ReadOnly */;
|
|
39780
|
-
if (
|
|
39826
|
+
if (receiverWritability === "immutable" /* Immutable */) {
|
|
39781
39827
|
if (targetWritability === "save" /* Save */) {
|
|
39782
39828
|
return "immutableToSaveLookup" /* ImmutableToSaveLookup */;
|
|
39783
39829
|
}
|
|
@@ -43974,6 +44020,12 @@ function bindConstructorArgumentNames(className, declared, argumentNames, pos) {
|
|
|
43974
44020
|
return parameter3.name;
|
|
43975
44021
|
});
|
|
43976
44022
|
}
|
|
44023
|
+
function localOwnership(initial) {
|
|
44024
|
+
if (initial.entryWritability !== void 0 && (initial.type.kind === "named" || initial.type.kind === "typeParameter")) {
|
|
44025
|
+
return initial.entryWritability;
|
|
44026
|
+
}
|
|
44027
|
+
return initial.writability ?? "local" /* Local */;
|
|
44028
|
+
}
|
|
43977
44029
|
function scopeVariable(name, value, sourceType, writability, ownership, writeRoot, readonlyBinding) {
|
|
43978
44030
|
return {
|
|
43979
44031
|
name,
|
|
@@ -46055,12 +46107,10 @@ function memberSymbol(member, schemaKey, environment, field) {
|
|
|
46055
46107
|
environment
|
|
46056
46108
|
);
|
|
46057
46109
|
}
|
|
46058
|
-
const
|
|
46059
|
-
const lookupCollectionWritability =
|
|
46060
|
-
lookupCollectionMemberId
|
|
46061
|
-
);
|
|
46110
|
+
const lookupCollection = kind === "lookup" ? lookupCollectionMemberId(member, field) : null;
|
|
46111
|
+
const lookupCollectionWritability = lookupCollection === null ? void 0 : environment.effectiveWritabilityByMemberId.get(lookupCollection);
|
|
46062
46112
|
const lookup = kind === "lookup" ? {
|
|
46063
|
-
collectionMemberId:
|
|
46113
|
+
...lookupCollection === null ? {} : { collectionMemberId: lookupCollection },
|
|
46064
46114
|
...member.collectionValueId === null || typeof member.collectionValueId === "string" ? { collectionValueId: member.collectionValueId } : {},
|
|
46065
46115
|
multiselect: boolean(member.multiselect, `${field}.multiselect`),
|
|
46066
46116
|
...lookupCollectionWritability === void 0 ? {} : { collectionWritability: lookupCollectionWritability }
|
|
@@ -46074,6 +46124,10 @@ function memberSymbol(member, schemaKey, environment, field) {
|
|
|
46074
46124
|
...lookup ? { lookup } : {}
|
|
46075
46125
|
};
|
|
46076
46126
|
}
|
|
46127
|
+
function lookupCollectionMemberId(member, field) {
|
|
46128
|
+
if (member.collectionMemberId === null) return null;
|
|
46129
|
+
return string(member.collectionMemberId, `${field}.collectionMemberId`);
|
|
46130
|
+
}
|
|
46077
46131
|
function interfaceType(value, environment, field) {
|
|
46078
46132
|
const id = string(value.id, `${field}.id`);
|
|
46079
46133
|
return {
|
|
@@ -46542,9 +46596,8 @@ function memberType(member, environment, visiting, field) {
|
|
|
46542
46596
|
};
|
|
46543
46597
|
}
|
|
46544
46598
|
if (kind === "lookup") {
|
|
46545
|
-
const
|
|
46546
|
-
|
|
46547
|
-
);
|
|
46599
|
+
const collectionMemberId = lookupCollectionMemberId(member, field);
|
|
46600
|
+
const collection = collectionMemberId === null ? void 0 : environment.members.get(collectionMemberId);
|
|
46548
46601
|
const collectionType = collection ? memberType(collection, environment, next, `${field}.collection`) : unknownType();
|
|
46549
46602
|
const declared = optionalRecord(member.declaredType);
|
|
46550
46603
|
const declaredType = declared ? manifestType(declared, environment, `${field}.declaredType`) : null;
|
|
@@ -48159,6 +48212,13 @@ function memberToSymbol(record4, schemaKey, containingClass, ownerClassId, index
|
|
|
48159
48212
|
};
|
|
48160
48213
|
}
|
|
48161
48214
|
if (isMemberLookupBase(resolved)) {
|
|
48215
|
+
if (resolved.collectionMemberId === void 0) {
|
|
48216
|
+
return {
|
|
48217
|
+
...common,
|
|
48218
|
+
kind: "property",
|
|
48219
|
+
lookup: { multiselect: isMultiSelectionMember(resolved) }
|
|
48220
|
+
};
|
|
48221
|
+
}
|
|
48162
48222
|
const collectionWritability = uniqueEffectiveWritability(
|
|
48163
48223
|
resolved.collectionMemberId,
|
|
48164
48224
|
context
|
|
@@ -48520,12 +48580,12 @@ function memberRuntimeType(record4, context, seen = /* @__PURE__ */ new Set(), g
|
|
|
48520
48580
|
if (!isMemberLookupBase(member)) return UNKNOWN_TYPE;
|
|
48521
48581
|
const declared = member.declaredTypeInfo ? toLanguageType(member.declaredTypeInfo, context, genericEnvironment) : null;
|
|
48522
48582
|
const narrowed = declared && !isUnknownType3(declared) ? declared : null;
|
|
48523
|
-
const entry = narrowed ?? lookupCollectionEntryType(
|
|
48583
|
+
const entry = narrowed ?? (member.collectionMemberId === void 0 ? null : lookupCollectionEntryType(
|
|
48524
48584
|
member.collectionMemberId,
|
|
48525
48585
|
context,
|
|
48526
48586
|
nextSeen,
|
|
48527
48587
|
genericEnvironment
|
|
48528
|
-
);
|
|
48588
|
+
));
|
|
48529
48589
|
if (!entry) return UNKNOWN_TYPE;
|
|
48530
48590
|
return isMultiSelectionMember(member) ? {
|
|
48531
48591
|
kind: "set",
|
|
@@ -54156,12 +54216,23 @@ var schemaMemberSchema = variant("kind", [
|
|
|
54156
54216
|
enumId: nonEmptyString,
|
|
54157
54217
|
multiselect: boolean2()
|
|
54158
54218
|
}),
|
|
54159
|
-
|
|
54160
|
-
|
|
54161
|
-
|
|
54162
|
-
|
|
54163
|
-
|
|
54164
|
-
|
|
54219
|
+
pipe(
|
|
54220
|
+
memberSchema("lookup", {
|
|
54221
|
+
/** `null` on an unbound `Reference<T>` (P107), typed by `declaredType`. */
|
|
54222
|
+
collectionMemberId: nullable(nonEmptyString),
|
|
54223
|
+
collectionValueId: nullableId,
|
|
54224
|
+
multiselect: boolean2(),
|
|
54225
|
+
declaredType: nullable(schemaTypeSchema)
|
|
54226
|
+
}),
|
|
54227
|
+
check(
|
|
54228
|
+
(member) => member.collectionMemberId !== null || member.collectionValueId === null,
|
|
54229
|
+
"A lookup collection value requires a collection member."
|
|
54230
|
+
),
|
|
54231
|
+
check(
|
|
54232
|
+
(member) => member.collectionMemberId !== null || member.declaredType?.kind === "class" || member.declaredType?.kind === "generic",
|
|
54233
|
+
"A lookup without a collection needs a class or generic declared type."
|
|
54234
|
+
)
|
|
54235
|
+
),
|
|
54165
54236
|
memberSchema("dialogueLookup", {
|
|
54166
54237
|
dialogueGroupId: nullableId,
|
|
54167
54238
|
multiselect: boolean2()
|
|
@@ -54559,10 +54630,8 @@ function memberFromDocument(record4, members, owners, classNames, context) {
|
|
|
54559
54630
|
return {
|
|
54560
54631
|
...common,
|
|
54561
54632
|
kind: "lookup",
|
|
54562
|
-
collectionMemberId:
|
|
54563
|
-
field("collectionMemberId",
|
|
54564
|
-
record4,
|
|
54565
|
-
"collectionMemberId"
|
|
54633
|
+
collectionMemberId: optionalStringOrNull(
|
|
54634
|
+
field("collectionMemberId", null)
|
|
54566
54635
|
),
|
|
54567
54636
|
collectionValueId: optionalStringOrNull(field("collectionValueId", null)),
|
|
54568
54637
|
multiselect: ordinalValue(
|
|
@@ -54880,7 +54949,9 @@ function memberToDocumentFields(member, baseData) {
|
|
|
54880
54949
|
}
|
|
54881
54950
|
}
|
|
54882
54951
|
if (member.kind === "lookup") {
|
|
54883
|
-
|
|
54952
|
+
if (member.collectionMemberId !== null) {
|
|
54953
|
+
fields.collectionMemberId = member.collectionMemberId;
|
|
54954
|
+
}
|
|
54884
54955
|
if (member.collectionValueId !== null) {
|
|
54885
54956
|
fields.collectionValueId = member.collectionValueId;
|
|
54886
54957
|
}
|
|
@@ -56869,7 +56940,7 @@ var INITIALIZER_KEY_PLACEHOLDER = new RegExp(
|
|
|
56869
56940
|
|
|
56870
56941
|
// ../packages/manifest/schema-contract/registry.mjs
|
|
56871
56942
|
var PROJECT_SCHEMA_CONTRACT = Object.freeze({
|
|
56872
|
-
cliVersion: "0.
|
|
56943
|
+
cliVersion: "0.77.0",
|
|
56873
56944
|
projectFileUploadBatchSize: 32,
|
|
56874
56945
|
documentRecords: {
|
|
56875
56946
|
member: {
|
package/package.json
CHANGED
|
@@ -129,7 +129,7 @@ wrappers.
|
|
|
129
129
|
The marker near the top of `SKILL.md` must exactly match the package version:
|
|
130
130
|
|
|
131
131
|
```html
|
|
132
|
-
<!-- reviewed-through-cli: 0.
|
|
132
|
+
<!-- reviewed-through-cli: 0.77.0 -->
|
|
133
133
|
```
|
|
134
134
|
|
|
135
135
|
The quoted version above is checked too, so this instruction cannot go stale
|
|
@@ -86,11 +86,11 @@ that does not authorize copying the annotation onto authored records.
|
|
|
86
86
|
|
|
87
87
|
Use context-aware typed annotations:
|
|
88
88
|
|
|
89
|
-
- `@settings(...)` for format/search/
|
|
89
|
+
- `@settings(...)` for format/search/collection/editor constraints.
|
|
90
90
|
- `@storage(allowed: ...)` on classes and storage keys on members.
|
|
91
91
|
- `@visibility(.Hidden)` only on a class; absence means visible.
|
|
92
92
|
- Stateful settings use contextual enum cases, such as
|
|
93
|
-
`@settings(format: .Plain)` and `@settings(
|
|
93
|
+
`@settings(format: .Plain)` and `@settings(kind: .Unordered)`.
|
|
94
94
|
- `@settings(...)` before a `List` element or `Dictionary` value type
|
|
95
95
|
configures the collection's entries: `List<@settings(format: .Plain) string>`,
|
|
96
96
|
`Dictionary<string, @settings(min: 0) int>`. Only the member that declares
|
|
@@ -231,14 +231,31 @@ the instance's recorded constructor or variant. They track later source-default
|
|
|
231
231
|
edits until that field is explicitly overridden; resetting an override makes it
|
|
232
232
|
virtual again.
|
|
233
233
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
selects several
|
|
237
|
-
|
|
234
|
+
Declare a lookup member as `Reference<T>`. `public Reference<Config> Config`
|
|
235
|
+
selects one row and reads as `Config`. `public Set<Reference<Config>> Configs`
|
|
236
|
+
selects several and reads as `Set<Config>`. An initializer body for a single
|
|
237
|
+
reference returns one row, never a set. `T` with `@settings(collection:)` is an
|
|
238
|
+
error; the language server's quick fix respells it.
|
|
238
239
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
240
|
+
`@settings(collection: Owner.Member)` binds the reference to one collection.
|
|
241
|
+
Without it the reference is unbound: it selects any stored row of `T` or a
|
|
242
|
+
subclass, anywhere in the project. The selected row's store decides writes. A
|
|
243
|
+
write through it to a Save row lands, and to an asset row it errors. Its
|
|
244
|
+
generated C# property is the read-only interface; call `TryWritable` to write.
|
|
245
|
+
|
|
246
|
+
An unbound default can name its row by a unique index:
|
|
247
|
+
|
|
248
|
+
```neo
|
|
249
|
+
public Reference<Item> StarterSeed = root.Assets.Items.Index.Slug["seed.carrot"]!;
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
The receiver is a `root` path to a List, `.Index.<Name>` is a unique index on
|
|
253
|
+
it, and the key is a string literal. Any other shape stays initializer code.
|
|
254
|
+
|
|
255
|
+
A `Reference<T>` member satisfies an interface `T Foo { get; }` or
|
|
256
|
+
`{ get; set; }` and an abstract `T Foo { get; }`.
|
|
257
|
+
|
|
258
|
+
Constructor and function parameters use `Set<T>` for several selections.
|
|
242
259
|
|
|
243
260
|
Declare a multicast event as `NeoAction<…>`. Its value is an ordered listener
|
|
244
261
|
set, so give it a bracketed list of method groups — never a lambda, and never
|
|
@@ -569,7 +569,7 @@ locally, like push. If another commit lands while it runs, the run is refused:
|
|
|
569
569
|
run it again. `neo loc` writes work the same way: a write refused because
|
|
570
570
|
another commit landed is run again.
|
|
571
571
|
|
|
572
|
-
VS Code rename follows override families and class constructors, resolves contextual enum options such as `.Success`, renames a constructor parameter's named arguments (`new Item(count: 1)`) in bodies, initializers, specs, and base clauses, and keeps local-variable renames scoped to their declaration. Assigned IDs are not required for these refactorings. Inferred locals initialized with conditional expressions retain their common branch type for member completion, navigation, and rename.
|
|
572
|
+
VS Code rename follows override families and class constructors, resolves contextual enum options such as `.Success`, renames a constructor parameter's named arguments (`new Item(count: 1)`) in bodies, initializers, specs, and base clauses, and keeps local-variable renames scoped to their declaration. Assigned IDs are not required for these refactorings. Inferred locals initialized with conditional expressions retain their common branch type for member completion, navigation, and rename. Direct parenthesized expressions and chained delegate factory calls retain their result type too. `List.Repeat` results infer their element type from the value, explicit call-site type arguments, and expected list type, including for inferred locals and direct indexed access. Lambda returns use the delegate signature for target-typed constructors and enum argument suggestions. Member completion also follows optional access and null-forgiving receivers, including dictionary lookups.
|
|
573
573
|
|
|
574
574
|
## Member change listeners
|
|
575
575
|
|