@neocompose/cli 0.35.0 → 0.36.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 +39 -0
- package/dist/neo.mjs +303 -103
- package/package.json +1 -1
- package/skills/neocompose-cli/SKILL.md +3 -1
- package/skills/neocompose-cli/references/animation-and-world-authoring.md +6 -1
- package/skills/neocompose-cli/references/cli-development.md +1 -1
- package/skills/neocompose-cli/references/neoscript.md +17 -2
- package/skills/neocompose-cli/references/values-identities-and-references.md +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,44 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.36.0] - 2026-08-19
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Add collection `Count` property access, optional-predicate `Count(...)`, and
|
|
8
|
+
list `IndexOf(value)` across NeoScript compilation, IntelliSense, web/CLI
|
|
9
|
+
evaluation, Unity export validation, and the matching Unity runtime.
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- **Breaking:** Unity export schema version is now 26 and the NeoScript
|
|
14
|
+
compiler revision is now 13. Exports containing `indexOf` or predicate
|
|
15
|
+
`count` IR require the matching Unity SDK.
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- Prevent VS Code completion from replacing an existing identifier when an
|
|
20
|
+
author inserts `this.` before it.
|
|
21
|
+
- Restrict action invocation and `NeoAction.Clear()` to the declaring class
|
|
22
|
+
and its derived classes. Public external callers may still subscribe and
|
|
23
|
+
unsubscribe with `+=` and `-=`.
|
|
24
|
+
- Keep declaration-pattern bindings for indexed expressions such as
|
|
25
|
+
`items[index] is Item item`, so the bound local remains available inside the
|
|
26
|
+
successful branch without incorrectly treating the indexed expression as a
|
|
27
|
+
stable dotted narrowing path.
|
|
28
|
+
- Diagnose `NeoAction<void>` with the canonical zero-argument spelling,
|
|
29
|
+
`NeoAction`, instead of later reporting the misleading invocation arity.
|
|
30
|
+
|
|
31
|
+
## [0.35.1] - 2026-08-19
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
|
|
35
|
+
- Treat `Partial<T>` values as sparse deltas throughout lowering and emission,
|
|
36
|
+
without invoking or reconstructing `T`'s required constructor.
|
|
37
|
+
- Materialize complete Unity defaults for template-less image and audio
|
|
38
|
+
registry entries instead of writing an invalid template override shape.
|
|
39
|
+
- Keep declarations inside variant delegate closures out of the global-child
|
|
40
|
+
registry, so separate `initialize` and `apply` closures may reuse local names.
|
|
41
|
+
|
|
3
42
|
## [0.35.0] - 2026-08-19
|
|
4
43
|
|
|
5
44
|
### Added
|
package/dist/neo.mjs
CHANGED
|
@@ -2313,7 +2313,7 @@ function formatType(type, project) {
|
|
|
2313
2313
|
)
|
|
2314
2314
|
].join(", ")}>${suffix}`;
|
|
2315
2315
|
case "action":
|
|
2316
|
-
return `NeoAction<${type.parameterTypes.map((parameter4) => formatType(parameter4, project)).join(", ")}
|
|
2316
|
+
return `${type.parameterTypes.length === 0 ? "NeoAction" : `NeoAction<${type.parameterTypes.map((parameter4) => formatType(parameter4, project)).join(", ")}>`}${suffix}`;
|
|
2317
2317
|
}
|
|
2318
2318
|
}
|
|
2319
2319
|
var UNKNOWN_TYPE;
|
|
@@ -2416,7 +2416,8 @@ function complete(snapshot, position) {
|
|
|
2416
2416
|
if (insidePlainString(snapshot.lexed.tokens, offset)) {
|
|
2417
2417
|
return { isIncomplete: false, items: [] };
|
|
2418
2418
|
}
|
|
2419
|
-
const
|
|
2419
|
+
const wordAtCursor = wordRangeAt(snapshot.source.text, offset);
|
|
2420
|
+
const word = { start: wordAtCursor.start, end: offset };
|
|
2420
2421
|
const prefix = snapshot.source.text.slice(word.start, offset);
|
|
2421
2422
|
const tokens = significantTokensBefore(snapshot.lexed.tokens, word.start);
|
|
2422
2423
|
const tail = tokens[tokens.length - 1];
|
|
@@ -4129,10 +4130,20 @@ function collectionSymbols(kind, type) {
|
|
|
4129
4130
|
method(
|
|
4130
4131
|
"Count",
|
|
4131
4132
|
{ kind: "primitive", name: "int" },
|
|
4132
|
-
[],
|
|
4133
|
-
"Return the entry count."
|
|
4133
|
+
[optionalCollectionPredicate(kind, entryType, keyType)],
|
|
4134
|
+
"Return the entry count, optionally restricted by a predicate. It may also be read as a property."
|
|
4134
4135
|
)
|
|
4135
4136
|
];
|
|
4137
|
+
if (kind === "list") {
|
|
4138
|
+
symbols.push(
|
|
4139
|
+
method(
|
|
4140
|
+
"IndexOf",
|
|
4141
|
+
{ kind: "primitive", name: "int" },
|
|
4142
|
+
[parameter2("value", entryType)],
|
|
4143
|
+
"Return the first matching index, or -1."
|
|
4144
|
+
)
|
|
4145
|
+
);
|
|
4146
|
+
}
|
|
4136
4147
|
if (!canMutate) return symbols;
|
|
4137
4148
|
if (kind === "dictionary") {
|
|
4138
4149
|
symbols.push(
|
|
@@ -4192,6 +4203,20 @@ function collectionSymbols(kind, type) {
|
|
|
4192
4203
|
function lambdaParameters(kind, entry, key) {
|
|
4193
4204
|
return kind === "dictionary" ? [parameter2("key", key), parameter2("value", entry)] : [parameter2("item", entry)];
|
|
4194
4205
|
}
|
|
4206
|
+
function optionalCollectionPredicate(kind, entry, key) {
|
|
4207
|
+
return {
|
|
4208
|
+
name: "predicate",
|
|
4209
|
+
type: {
|
|
4210
|
+
kind: "delegate",
|
|
4211
|
+
returnType: { kind: "primitive", name: "bool" },
|
|
4212
|
+
parameterTypes: lambdaParameters(kind, entry, key).map(
|
|
4213
|
+
(candidate) => candidate.type
|
|
4214
|
+
),
|
|
4215
|
+
nullable: true
|
|
4216
|
+
},
|
|
4217
|
+
defaultValue: { displayText: "null", value: null }
|
|
4218
|
+
};
|
|
4219
|
+
}
|
|
4195
4220
|
function method(name, returnType, parameters, documentation) {
|
|
4196
4221
|
return {
|
|
4197
4222
|
id: `builtin:collection:${name}`,
|
|
@@ -4311,7 +4336,13 @@ function inferLambdaParameterType(local, snapshot) {
|
|
|
4311
4336
|
(token) => token.start === snapshot.source.offsetAt(local.nameRange.start)
|
|
4312
4337
|
);
|
|
4313
4338
|
if (declarationIndex < 0) return UNKNOWN_TYPE;
|
|
4314
|
-
const lambdaMethods = /* @__PURE__ */ new Set([
|
|
4339
|
+
const lambdaMethods = /* @__PURE__ */ new Set([
|
|
4340
|
+
"Where",
|
|
4341
|
+
"First",
|
|
4342
|
+
"FirstOrDefault",
|
|
4343
|
+
"Select",
|
|
4344
|
+
"Count"
|
|
4345
|
+
]);
|
|
4315
4346
|
for (let cursor = declarationIndex - 1; cursor >= 1; cursor--) {
|
|
4316
4347
|
const open = tokens[cursor];
|
|
4317
4348
|
const method2 = tokens[cursor - 1];
|
|
@@ -4354,7 +4385,10 @@ function symbolCompletion(symbol, word, snapshot) {
|
|
|
4354
4385
|
range: snapshot.source.range(word.start, word.end),
|
|
4355
4386
|
newText: insertText
|
|
4356
4387
|
},
|
|
4357
|
-
|
|
4388
|
+
// `.` is a completion trigger, not a commit character. Treating it as
|
|
4389
|
+
// both lets VS Code accept a stale selection while an author prefixes an
|
|
4390
|
+
// existing identifier (for example, typing `this.` before a member).
|
|
4391
|
+
...callable2 ? { commitCharacters: ["("] } : {},
|
|
4358
4392
|
symbolId: symbol.id
|
|
4359
4393
|
};
|
|
4360
4394
|
}
|
|
@@ -4370,7 +4404,7 @@ function typeCompletion(type, word, snapshot) {
|
|
|
4370
4404
|
range: snapshot.source.range(word.start, word.end),
|
|
4371
4405
|
newText: type.name
|
|
4372
4406
|
},
|
|
4373
|
-
commitCharacters: ["
|
|
4407
|
+
commitCharacters: ["<"],
|
|
4374
4408
|
symbolId: type.id
|
|
4375
4409
|
};
|
|
4376
4410
|
}
|
|
@@ -4386,7 +4420,7 @@ function indexCompletion(index, word, snapshot) {
|
|
|
4386
4420
|
range: snapshot.source.range(word.start, word.end),
|
|
4387
4421
|
newText: index.name
|
|
4388
4422
|
},
|
|
4389
|
-
commitCharacters: ["
|
|
4423
|
+
commitCharacters: ["["],
|
|
4390
4424
|
symbolId: index.id
|
|
4391
4425
|
};
|
|
4392
4426
|
}
|
|
@@ -8510,7 +8544,7 @@ var NEOSCRIPT_COMPILER_REVISION;
|
|
|
8510
8544
|
var init_strict_ir = __esm({
|
|
8511
8545
|
"../packages/neoscript-language/src/strict-ir.ts"() {
|
|
8512
8546
|
"use strict";
|
|
8513
|
-
NEOSCRIPT_COMPILER_REVISION =
|
|
8547
|
+
NEOSCRIPT_COMPILER_REVISION = 13;
|
|
8514
8548
|
}
|
|
8515
8549
|
});
|
|
8516
8550
|
|
|
@@ -8535,8 +8569,10 @@ function pathRoot(path) {
|
|
|
8535
8569
|
}
|
|
8536
8570
|
function factsFromIsCheck(expression, whenTrue) {
|
|
8537
8571
|
const path = canonicalPath(expression.operand);
|
|
8538
|
-
if (!path) return [];
|
|
8539
8572
|
const nullCheck = expression.type.kind === "primitive" && expression.type.name === "null";
|
|
8573
|
+
if (path === null && (!whenTrue || nullCheck || !expression.bindingName)) {
|
|
8574
|
+
return [];
|
|
8575
|
+
}
|
|
8540
8576
|
if (whenTrue) {
|
|
8541
8577
|
return nullCheck ? [{ expression: expression.operand, path, nullValue: true }] : [
|
|
8542
8578
|
{
|
|
@@ -12156,10 +12192,10 @@ var init_strict_resolver = __esm({
|
|
|
12156
12192
|
applyFactsToScope(outerScope, targetScope, facts, mode = "all") {
|
|
12157
12193
|
for (const fact of facts) {
|
|
12158
12194
|
if (mode === "bindings-only" && !fact.bindingName) continue;
|
|
12159
|
-
const rootEntry = outerScope.lookup(pathRoot(fact.path));
|
|
12160
|
-
if (!rootEntry) continue;
|
|
12161
12195
|
const natural = this.resolveExpression(fact.expression, outerScope);
|
|
12196
|
+
const rootEntry = fact.path === null ? null : outerScope.lookup(pathRoot(fact.path));
|
|
12162
12197
|
if (fact.nullValue) {
|
|
12198
|
+
if (fact.path === null || rootEntry === null) continue;
|
|
12163
12199
|
if (fact.loose === true && natural.type.kind === "primitive" && (natural.type.name === "string" || natural.type.name === "int" || natural.type.name === "float" || natural.type.name === "bool")) {
|
|
12164
12200
|
continue;
|
|
12165
12201
|
}
|
|
@@ -12176,7 +12212,7 @@ var init_strict_resolver = __esm({
|
|
|
12176
12212
|
const naturalDefinition = natural.type.kind === "named" ? this.project.typeById.get(natural.type.typeId) : void 0;
|
|
12177
12213
|
const retainConcreteClass = !fact.bindingName && naturalDefinition?.kind === "class" && targetDefinition?.kind === "interface";
|
|
12178
12214
|
const narrowed = retainConcreteClass ? { ...natural.type, nullable: false } : { ...target, nullable: false };
|
|
12179
|
-
if (mode === "all") {
|
|
12215
|
+
if (mode === "all" && fact.path !== null && rootEntry !== null) {
|
|
12180
12216
|
targetScope.narrow(fact.path, rootEntry, narrowed);
|
|
12181
12217
|
}
|
|
12182
12218
|
if (fact.bindingName) {
|
|
@@ -12193,6 +12229,7 @@ var init_strict_resolver = __esm({
|
|
|
12193
12229
|
}
|
|
12194
12230
|
continue;
|
|
12195
12231
|
}
|
|
12232
|
+
if (fact.path === null || rootEntry === null) continue;
|
|
12196
12233
|
if (!isNullable(natural.type)) continue;
|
|
12197
12234
|
targetScope.narrow(fact.path, rootEntry, {
|
|
12198
12235
|
...natural.type,
|
|
@@ -12650,6 +12687,19 @@ var init_strict_resolver = __esm({
|
|
|
12650
12687
|
indexSurface: receiver.type
|
|
12651
12688
|
};
|
|
12652
12689
|
}
|
|
12690
|
+
if (name === "Count" && collectionPartsFor(receiver) !== null) {
|
|
12691
|
+
if (nullPropagating) {
|
|
12692
|
+
throw new CompileError(
|
|
12693
|
+
"Null-propagating collection Count access is not supported; coalesce or narrow the collection first.",
|
|
12694
|
+
pos
|
|
12695
|
+
);
|
|
12696
|
+
}
|
|
12697
|
+
return intrinsic(
|
|
12698
|
+
"count" /* Count */,
|
|
12699
|
+
{ collectionPointer: receiver.pointer },
|
|
12700
|
+
{ kind: "primitive", name: "int" }
|
|
12701
|
+
);
|
|
12702
|
+
}
|
|
12653
12703
|
const primitiveMember = resolvePrimitiveMember(receiver.type, name);
|
|
12654
12704
|
if (primitiveMember) {
|
|
12655
12705
|
if (isPrimitive(receiver.type, "DialogueRef")) {
|
|
@@ -14395,10 +14445,50 @@ var init_strict_resolver = __esm({
|
|
|
14395
14445
|
const collection = collectionPartsFor(receiver);
|
|
14396
14446
|
if (!collection) return null;
|
|
14397
14447
|
if (name === "Count") {
|
|
14398
|
-
|
|
14448
|
+
if (args.length > 1) {
|
|
14449
|
+
throw new CompileError(
|
|
14450
|
+
`Count expects zero or one predicate, got ${args.length}.`,
|
|
14451
|
+
pos
|
|
14452
|
+
);
|
|
14453
|
+
}
|
|
14454
|
+
const fn = args[0] ? this.resolveCollectionLambda(
|
|
14455
|
+
args[0],
|
|
14456
|
+
collection,
|
|
14457
|
+
{ kind: "primitive", name: "bool" },
|
|
14458
|
+
scope,
|
|
14459
|
+
pos
|
|
14460
|
+
) : void 0;
|
|
14399
14461
|
return intrinsic(
|
|
14400
14462
|
"count" /* Count */,
|
|
14401
|
-
{
|
|
14463
|
+
{
|
|
14464
|
+
collectionPointer: receiver.pointer,
|
|
14465
|
+
...fn ? { function: fn } : {}
|
|
14466
|
+
},
|
|
14467
|
+
{ kind: "primitive", name: "int" }
|
|
14468
|
+
);
|
|
14469
|
+
}
|
|
14470
|
+
if (name === "IndexOf" && collection.kind === "list") {
|
|
14471
|
+
requireArgCount(name, args, 1, pos);
|
|
14472
|
+
const expectedValueType = collectionOperationValueType(
|
|
14473
|
+
receiver,
|
|
14474
|
+
collection
|
|
14475
|
+
);
|
|
14476
|
+
const value = this.resolveExpression(
|
|
14477
|
+
requiredAt(args, 0),
|
|
14478
|
+
scope,
|
|
14479
|
+
expectedValueType
|
|
14480
|
+
);
|
|
14481
|
+
this.requireCollectionOperationAssignable(
|
|
14482
|
+
value.type,
|
|
14483
|
+
expectedValueType,
|
|
14484
|
+
receiver,
|
|
14485
|
+
collection,
|
|
14486
|
+
pos,
|
|
14487
|
+
"IndexOf argument"
|
|
14488
|
+
);
|
|
14489
|
+
return intrinsic(
|
|
14490
|
+
"indexOf" /* IndexOf */,
|
|
14491
|
+
{ collectionPointer: receiver.pointer, valuePointer: value.pointer },
|
|
14402
14492
|
{ kind: "primitive", name: "int" }
|
|
14403
14493
|
);
|
|
14404
14494
|
}
|
|
@@ -14790,6 +14880,7 @@ var init_strict_resolver = __esm({
|
|
|
14790
14880
|
* return and no optional form to carry.
|
|
14791
14881
|
*/
|
|
14792
14882
|
resolveActionCall(action, actionType, expression, scope) {
|
|
14883
|
+
this.assertActionControlAccessible(action, "invoke", expression.pos);
|
|
14793
14884
|
if (expression.callee.kind === "member" && expression.callee.optional) {
|
|
14794
14885
|
throw new CompileError(
|
|
14795
14886
|
`${this.describe(actionType)} is never null, so optional-chained invocation is not supported.`,
|
|
@@ -15047,6 +15138,7 @@ var init_strict_resolver = __esm({
|
|
|
15047
15138
|
}
|
|
15048
15139
|
const receiver = this.resolveExpression(expression.callee.receiver, scope);
|
|
15049
15140
|
if (receiver.type.kind !== "action") return null;
|
|
15141
|
+
this.assertActionControlAccessible(receiver, "clear", pos);
|
|
15050
15142
|
if (expression.callee.optional) {
|
|
15051
15143
|
throw new CompileError(
|
|
15052
15144
|
`${this.describe(receiver.type)} is never null, so optional-chained Clear is not supported.`,
|
|
@@ -15109,6 +15201,34 @@ var init_strict_resolver = __esm({
|
|
|
15109
15201
|
}
|
|
15110
15202
|
};
|
|
15111
15203
|
}
|
|
15204
|
+
/**
|
|
15205
|
+
* An action's declared accessibility controls who may subscribe. Invoking
|
|
15206
|
+
* or clearing its listener set is a separate, protected-like capability:
|
|
15207
|
+
* the declaring class and its subclasses may raise/reset the action, while
|
|
15208
|
+
* public callers remain limited to `+=` and `-=`.
|
|
15209
|
+
*/
|
|
15210
|
+
assertActionControlAccessible(action, operation, pos) {
|
|
15211
|
+
const symbol = action.symbol;
|
|
15212
|
+
const owner = symbol === void 0 ? void 0 : symbol.inheritedFrom ? this.project.typeById.get(symbol.inheritedFrom.typeId) : [...this.project.typeById.values()].find(
|
|
15213
|
+
(type) => type.members.some(
|
|
15214
|
+
(candidate) => candidate.id === symbol.id && candidate.inheritedFrom === void 0
|
|
15215
|
+
)
|
|
15216
|
+
);
|
|
15217
|
+
if (symbol !== void 0 && owner !== void 0 && memberAccessFailure({
|
|
15218
|
+
project: this.project,
|
|
15219
|
+
context: this.context,
|
|
15220
|
+
owner,
|
|
15221
|
+
symbol: { ...symbol, accessModifier: "protected" }
|
|
15222
|
+
}) === null) {
|
|
15223
|
+
return;
|
|
15224
|
+
}
|
|
15225
|
+
const verb = operation === "invoke" ? "invoked" : "cleared";
|
|
15226
|
+
const actionName = symbol === void 0 ? this.describe(action.type) : `'${owner?.name ?? symbol.inheritedFrom?.typeName ?? "Unknown"}.${symbol.name}'`;
|
|
15227
|
+
throw new CompileError(
|
|
15228
|
+
`Action ${actionName} can only be ${verb} from its declaring class or a derived class; external callers may only subscribe with '+=' or '-='.`,
|
|
15229
|
+
pos
|
|
15230
|
+
);
|
|
15231
|
+
}
|
|
15112
15232
|
resolveConditionalExpression(expression, scope, expected) {
|
|
15113
15233
|
const condition = this.toBool(
|
|
15114
15234
|
this.resolveExpression(expression.condition, scope),
|
|
@@ -18907,6 +19027,14 @@ function collectGlobalChildEntries(sourceText, declaration) {
|
|
|
18907
19027
|
let pendingAnnotations = [];
|
|
18908
19028
|
for (let index = 0; index < tokens.length; index++) {
|
|
18909
19029
|
const token = tokens[index];
|
|
19030
|
+
if (token.text === "(" || token.text === "[") {
|
|
19031
|
+
groupDepth++;
|
|
19032
|
+
continue;
|
|
19033
|
+
}
|
|
19034
|
+
if (token.text === ")" || token.text === "]") {
|
|
19035
|
+
groupDepth--;
|
|
19036
|
+
continue;
|
|
19037
|
+
}
|
|
18910
19038
|
if (token.text === "{") {
|
|
18911
19039
|
braceDepth++;
|
|
18912
19040
|
continue;
|
|
@@ -18916,14 +19044,6 @@ function collectGlobalChildEntries(sourceText, declaration) {
|
|
|
18916
19044
|
continue;
|
|
18917
19045
|
}
|
|
18918
19046
|
if (braceDepth !== 1) continue;
|
|
18919
|
-
if (token.text === "(" || token.text === "[") {
|
|
18920
|
-
groupDepth++;
|
|
18921
|
-
continue;
|
|
18922
|
-
}
|
|
18923
|
-
if (token.text === ")" || token.text === "]") {
|
|
18924
|
-
groupDepth--;
|
|
18925
|
-
continue;
|
|
18926
|
-
}
|
|
18927
19047
|
if (groupDepth !== 0) continue;
|
|
18928
19048
|
if (token.text === ";") {
|
|
18929
19049
|
pendingAnnotations = [];
|
|
@@ -26556,6 +26676,15 @@ function validateTypeApplication(uri, type, genericParameters, environment, diag
|
|
|
26556
26676
|
return;
|
|
26557
26677
|
}
|
|
26558
26678
|
if (type.name === "NeoAction") {
|
|
26679
|
+
if (type.typeArguments.some((argument2) => argument2.name === "void")) {
|
|
26680
|
+
diagnose(
|
|
26681
|
+
diagnostics,
|
|
26682
|
+
uri,
|
|
26683
|
+
type.range,
|
|
26684
|
+
"invalid-member-type",
|
|
26685
|
+
"Type 'NeoAction' cannot use 'void' as a parameter type; spell a zero-argument action as bare 'NeoAction'."
|
|
26686
|
+
);
|
|
26687
|
+
}
|
|
26559
26688
|
if (type.typeArguments.length > 16) {
|
|
26560
26689
|
diagnose(
|
|
26561
26690
|
diagnostics,
|
|
@@ -29087,10 +29216,8 @@ function maskOutsideProjectBody(text, start, end) {
|
|
|
29087
29216
|
}
|
|
29088
29217
|
function projectWordRange(text, offset) {
|
|
29089
29218
|
let start = offset;
|
|
29090
|
-
let end = offset;
|
|
29091
29219
|
while (start > 0 && /[A-Za-z0-9_]/.test(text[start - 1] ?? "")) start--;
|
|
29092
|
-
|
|
29093
|
-
return { start, end };
|
|
29220
|
+
return { start, end: offset };
|
|
29094
29221
|
}
|
|
29095
29222
|
function isContextualDot(text, wordStart) {
|
|
29096
29223
|
if (text[wordStart - 1] !== ".") return false;
|
|
@@ -42957,6 +43084,13 @@ function isNSFunctionContains(value) {
|
|
|
42957
43084
|
if (typeof info !== "object" || info === null) return false;
|
|
42958
43085
|
return isNSPointer(info.collectionPointer) && isNSPointer(info.valuePointer);
|
|
42959
43086
|
}
|
|
43087
|
+
function isNSFunctionIndexOf(value) {
|
|
43088
|
+
const v = value;
|
|
43089
|
+
if (v?.type !== "indexOf" /* indexOf */) return false;
|
|
43090
|
+
const info = v.info;
|
|
43091
|
+
if (typeof info !== "object" || info === null) return false;
|
|
43092
|
+
return isNSPointer(info.collectionPointer) && isNSPointer(info.valuePointer);
|
|
43093
|
+
}
|
|
42960
43094
|
function isNSFunctionStringOp(value) {
|
|
42961
43095
|
const v = value;
|
|
42962
43096
|
if (v?.type !== "stringOp" /* stringOp */) return false;
|
|
@@ -43010,12 +43144,7 @@ function isNSFunctionListRepeat(value) {
|
|
|
43010
43144
|
}
|
|
43011
43145
|
function isNSFunctionCount(value) {
|
|
43012
43146
|
const v = value;
|
|
43013
|
-
|
|
43014
|
-
const info = v.info;
|
|
43015
|
-
if (typeof info !== "object" || info === null) return false;
|
|
43016
|
-
return isNSPointer(
|
|
43017
|
-
info.collectionPointer
|
|
43018
|
-
);
|
|
43147
|
+
return v?.type === "count" /* count */ && isNSCollectionOptionalBoolFunction(v.info);
|
|
43019
43148
|
}
|
|
43020
43149
|
function isNSDialogueMemoryFunctionInfo(value) {
|
|
43021
43150
|
if (typeof value !== "object" || value === null) return false;
|
|
@@ -43052,7 +43181,7 @@ function isNSFunctionImageSlice(value) {
|
|
|
43052
43181
|
return isNSPointer(info.sliceIndexPointer);
|
|
43053
43182
|
}
|
|
43054
43183
|
function isNSFunction(value) {
|
|
43055
|
-
return isNSFunctionClassConstructor(value) || isNSFunctionClassClone(value) || isNSFunctionListIndex(value) || isNSFunctionSelect(value) || isNSFunctionFirst(value) || isNSFunctionFirstOrDefault(value) || isNSFunctionWhere(value) || isNSFunctionContains(value) || // stringOp was missing from this chain since its introduction — a
|
|
43184
|
+
return isNSFunctionClassConstructor(value) || isNSFunctionClassClone(value) || isNSFunctionListIndex(value) || isNSFunctionSelect(value) || isNSFunctionFirst(value) || isNSFunctionFirstOrDefault(value) || isNSFunctionWhere(value) || isNSFunctionContains(value) || isNSFunctionIndexOf(value) || // stringOp was missing from this chain since its introduction — a
|
|
43056
43185
|
// compiled getter using ToLower()/StartsWith() would fail pointer
|
|
43057
43186
|
// validation anywhere isNSFunction gates. Fixed alongside decimalOp.
|
|
43058
43187
|
isNSFunctionStringOp(value) || isNSFunctionDecimalOp(value) || isNSFunctionMathOp(value) || isNSFunctionListRepeat(value) || isNSFunctionCount(value) || isNSFunctionVisitCount(value) || isNSFunctionHasVisited(value) || isNSFunctionVectorConstructor(value) || isNSFunctionImageSlice(value) || isNSFunctionVariantInitialize(value) || isNSFunctionVariantApply(value) || isNSFunctionDeclaredConstructor(value);
|
|
@@ -43277,7 +43406,12 @@ function minimumNeoScriptCompilerRevisionForIR(node, visited = /* @__PURE__ */ n
|
|
|
43277
43406
|
visited.add(node);
|
|
43278
43407
|
const discriminatorRevision = "type" in node && typeof node.type === "string" ? MINIMUM_REVISION_BY_IR_DISCRIMINATOR.get(node.type) ?? 1 : 1;
|
|
43279
43408
|
const fallbackRevision = "missingMemberFallback" in node && node.missingMemberFallback === "valueEquality" ? 12 : 1;
|
|
43280
|
-
|
|
43409
|
+
const countPredicateRevision = "type" in node && node.type === "count" /* count */ && "info" in node && typeof node.info === "object" && node.info !== null && "function" in node.info && node.info.function !== void 0 && node.info.function !== null ? 13 : 1;
|
|
43410
|
+
let minimum = Math.max(
|
|
43411
|
+
discriminatorRevision,
|
|
43412
|
+
fallbackRevision,
|
|
43413
|
+
countPredicateRevision
|
|
43414
|
+
);
|
|
43281
43415
|
const isLiteralValue = "typeInfo" in node && "value" in node && !("type" in node);
|
|
43282
43416
|
for (const [key, child] of Object.entries(node)) {
|
|
43283
43417
|
if (isLiteralValue && key === "value") continue;
|
|
@@ -43379,7 +43513,8 @@ var init_neoscript_guards = __esm({
|
|
|
43379
43513
|
["removeActionListener" /* removeActionListener */, 8],
|
|
43380
43514
|
["callAction" /* callAction */, 8],
|
|
43381
43515
|
["conditional" /* conditional */, 12],
|
|
43382
|
-
["delegateClosure" /* delegateClosure */, 12]
|
|
43516
|
+
["delegateClosure" /* delegateClosure */, 12],
|
|
43517
|
+
["indexOf" /* indexOf */, 13]
|
|
43383
43518
|
]);
|
|
43384
43519
|
}
|
|
43385
43520
|
});
|
|
@@ -48137,6 +48272,20 @@ function buildDefaultUnityTexture2DImportSettings() {
|
|
|
48137
48272
|
}
|
|
48138
48273
|
};
|
|
48139
48274
|
}
|
|
48275
|
+
function buildDefaultUnityAudioClipImportSettings() {
|
|
48276
|
+
return {
|
|
48277
|
+
forceToMono: false,
|
|
48278
|
+
normalize: true,
|
|
48279
|
+
loadInBackground: false,
|
|
48280
|
+
ambisonic: false,
|
|
48281
|
+
loadType: "decompress-on-load" /* DecompressOnLoad */,
|
|
48282
|
+
compressionFormat: "vorbis" /* Vorbis */,
|
|
48283
|
+
quality: 1,
|
|
48284
|
+
sampleRateSetting: "preserve-sample-rate" /* PreserveSampleRate */,
|
|
48285
|
+
overrideSampleRate: null,
|
|
48286
|
+
preloadAudioData: true
|
|
48287
|
+
};
|
|
48288
|
+
}
|
|
48140
48289
|
function isUnityVector2(value) {
|
|
48141
48290
|
const v = value;
|
|
48142
48291
|
if (!isObject(value)) return false;
|
|
@@ -53024,6 +53173,20 @@ var init_project_file_registry = __esm({
|
|
|
53024
53173
|
});
|
|
53025
53174
|
|
|
53026
53175
|
// src/project-source/project-file-source.ts
|
|
53176
|
+
function projectFileUnityImportSettingsV4(kind, templateId) {
|
|
53177
|
+
if (templateId === null) {
|
|
53178
|
+
return {
|
|
53179
|
+
...kind === "image" ? buildDefaultUnityTexture2DImportSettings() : buildDefaultUnityAudioClipImportSettings(),
|
|
53180
|
+
templateId: null
|
|
53181
|
+
};
|
|
53182
|
+
}
|
|
53183
|
+
return {
|
|
53184
|
+
...kind === "image" ? { type: "texture-2d" } : {},
|
|
53185
|
+
templateId,
|
|
53186
|
+
overridePaths: [],
|
|
53187
|
+
values: {}
|
|
53188
|
+
};
|
|
53189
|
+
}
|
|
53027
53190
|
function emitProjectFileRegistrySourcesV4(records2) {
|
|
53028
53191
|
const liveFiles = [...records2.values()].filter((record3) => record3.recordKind === "project-file" && !record3.deleted).map((record3) => ({ record: record3, data: requireFileData(record3) }));
|
|
53029
53192
|
assertUniqueProjectBinaryPaths(liveFiles);
|
|
@@ -53142,12 +53305,10 @@ function lowerTrustedProjectFileRegistrySourcesV4(state, analysis, trustedPendin
|
|
|
53142
53305
|
});
|
|
53143
53306
|
}
|
|
53144
53307
|
if (importSettingsChanged) {
|
|
53145
|
-
next[settingsField] =
|
|
53146
|
-
|
|
53147
|
-
|
|
53148
|
-
|
|
53149
|
-
values: {}
|
|
53150
|
-
};
|
|
53308
|
+
next[settingsField] = projectFileUnityImportSettingsV4(
|
|
53309
|
+
declaration.kind,
|
|
53310
|
+
declaration.templateId
|
|
53311
|
+
);
|
|
53151
53312
|
}
|
|
53152
53313
|
return {
|
|
53153
53314
|
recordKind: "project-file",
|
|
@@ -53445,6 +53606,7 @@ var init_project_file_source = __esm({
|
|
|
53445
53606
|
init_source_format();
|
|
53446
53607
|
init_project_file_registry();
|
|
53447
53608
|
init_members();
|
|
53609
|
+
init_unity_import_settings();
|
|
53448
53610
|
REGISTRY_ENTRY = /(?:@id\(\s*("(?:[^"\\]|\\.)*")\s*\)\s*)?(?:@settings\(([\s\S]*?)\)\s*)?(NeoImage|NeoAudioClip)\s+([A-Za-z_][A-Za-z0-9_]*)\s*=\s*new\(\s*("(?:[^"\\]|\\.)*")\s*\)\s*;/gy;
|
|
53449
53611
|
assignDeterministicFileSymbols = assignDeterministicProjectFileSymbols;
|
|
53450
53612
|
}
|
|
@@ -70393,7 +70555,23 @@ function evalFunction(fn, scope, ctx) {
|
|
|
70393
70555
|
}
|
|
70394
70556
|
case "count" /* count */: {
|
|
70395
70557
|
const c = evalPointer(fn.info.collectionPointer, scope, ctx);
|
|
70396
|
-
|
|
70558
|
+
const innerFn = fn.info.function ?? null;
|
|
70559
|
+
if (innerFn === null) return collectionLength(c);
|
|
70560
|
+
const isList = isListCollection(c);
|
|
70561
|
+
let count = 0;
|
|
70562
|
+
const callback = prepareCollectionCallback(
|
|
70563
|
+
innerFn,
|
|
70564
|
+
scope,
|
|
70565
|
+
ctx,
|
|
70566
|
+
isList,
|
|
70567
|
+
"predicate",
|
|
70568
|
+
() => {
|
|
70569
|
+
count += 1;
|
|
70570
|
+
return 0 /* Continue */;
|
|
70571
|
+
}
|
|
70572
|
+
);
|
|
70573
|
+
iterateCollection(c, ctx, callback);
|
|
70574
|
+
return count;
|
|
70397
70575
|
}
|
|
70398
70576
|
case "contains" /* contains */: {
|
|
70399
70577
|
const c = evalPointer(fn.info.collectionPointer, scope, ctx);
|
|
@@ -70417,6 +70595,23 @@ function evalFunction(fn, scope, ctx) {
|
|
|
70417
70595
|
});
|
|
70418
70596
|
return containsResolvedEntry;
|
|
70419
70597
|
}
|
|
70598
|
+
case "indexOf" /* indexOf */: {
|
|
70599
|
+
const collection = listArg(
|
|
70600
|
+
evalPointer(fn.info.collectionPointer, scope, ctx),
|
|
70601
|
+
"IndexOf receiver"
|
|
70602
|
+
);
|
|
70603
|
+
const target = evalPointer(fn.info.valuePointer, scope, ctx);
|
|
70604
|
+
const targetReferenceId = typeof target === "string" ? target : findKnownRowIdByValueReference(target, ctx);
|
|
70605
|
+
let found = -1;
|
|
70606
|
+
iterateCollection(collection, ctx, (entry, key, valueId) => {
|
|
70607
|
+
if (valueId !== null && valueId === targetReferenceId || jsEqual(entry, target)) {
|
|
70608
|
+
found = numberArg(key, "IndexOf index");
|
|
70609
|
+
return 1 /* Break */;
|
|
70610
|
+
}
|
|
70611
|
+
return 0 /* Continue */;
|
|
70612
|
+
});
|
|
70613
|
+
return found;
|
|
70614
|
+
}
|
|
70420
70615
|
case "decimalOp" /* decimalOp */: {
|
|
70421
70616
|
const info = fn.info;
|
|
70422
70617
|
const receiverRaw = evalPointer(info.receiverPointer, scope, ctx);
|
|
@@ -98181,11 +98376,11 @@ function lowerMemberDefaultSourcesV4(state, analysis, manifest, options = {}) {
|
|
|
98181
98376
|
context.parsedInitializers,
|
|
98182
98377
|
declaration.initializer
|
|
98183
98378
|
);
|
|
98184
|
-
const requiresEvaluation =
|
|
98185
|
-
context
|
|
98379
|
+
const requiresEvaluation = memberInitializerRequiresEvaluation(
|
|
98380
|
+
context,
|
|
98381
|
+
member,
|
|
98186
98382
|
annotatedValue(expression).expression,
|
|
98187
|
-
|
|
98188
|
-
bindingRuntimeIdentifiers(context, binding)
|
|
98383
|
+
binding
|
|
98189
98384
|
);
|
|
98190
98385
|
const baseData3 = stateData(context, "member", memberId);
|
|
98191
98386
|
const annotatedExpression = annotatedValue(expression).expression;
|
|
@@ -98676,12 +98871,7 @@ function declaredCollectionMemberIds(context, collectionMemberId) {
|
|
|
98676
98871
|
}
|
|
98677
98872
|
function defaultRequiresOwnedRows(context, member, sourceExpression, source) {
|
|
98678
98873
|
const expression = annotatedValue(sourceExpression).expression;
|
|
98679
|
-
if (
|
|
98680
|
-
context.declaredConstructors,
|
|
98681
|
-
expression,
|
|
98682
|
-
memberClassName(context, member),
|
|
98683
|
-
bindingRuntimeIdentifiers(context, source)
|
|
98684
|
-
)) {
|
|
98874
|
+
if (memberInitializerRequiresEvaluation(context, member, expression, source)) {
|
|
98685
98875
|
return false;
|
|
98686
98876
|
}
|
|
98687
98877
|
if (member.kind === "class") return expression.kind === "new";
|
|
@@ -98693,6 +98883,15 @@ function defaultRequiresOwnedRows(context, member, sourceExpression, source) {
|
|
|
98693
98883
|
}
|
|
98694
98884
|
return false;
|
|
98695
98885
|
}
|
|
98886
|
+
function memberInitializerRequiresEvaluation(context, member, expression, source) {
|
|
98887
|
+
if (member.kind === "class" && member.partial === true) return false;
|
|
98888
|
+
return initializerRequiresEvaluation(
|
|
98889
|
+
context.declaredConstructors,
|
|
98890
|
+
expression,
|
|
98891
|
+
memberClassName(context, member),
|
|
98892
|
+
bindingRuntimeIdentifiers(context, source)
|
|
98893
|
+
);
|
|
98894
|
+
}
|
|
98696
98895
|
function indexInitAuthoredRowIds(context, initSource, owner) {
|
|
98697
98896
|
indexAuthoredRowIds(context.initAuthoredRowIds, initSource, owner);
|
|
98698
98897
|
}
|
|
@@ -99240,7 +99439,7 @@ function lowerSeedRow(context, member, sourceExpression, source, valueId, path,
|
|
|
99240
99439
|
member,
|
|
99241
99440
|
inheritedEnvironment
|
|
99242
99441
|
);
|
|
99243
|
-
if (context.structuralConstruction && resolvedMember.kind === "class" && expression.kind === "new" && structurallyConstructedClassId(context, resolvedMember, expression) !== null) {
|
|
99442
|
+
if (context.structuralConstruction && resolvedMember.kind === "class" && resolvedMember.partial !== true && expression.kind === "new" && structurallyConstructedClassId(context, resolvedMember, expression) !== null) {
|
|
99244
99443
|
return lowerStructuralConstructionRow(
|
|
99245
99444
|
context,
|
|
99246
99445
|
resolvedMember,
|
|
@@ -99255,11 +99454,11 @@ function lowerSeedRow(context, member, sourceExpression, source, valueId, path,
|
|
|
99255
99454
|
authoredSlice
|
|
99256
99455
|
);
|
|
99257
99456
|
}
|
|
99258
|
-
if (!isStoredCallableLiteral(resolvedMember.kind, expression) &&
|
|
99259
|
-
context
|
|
99457
|
+
if (!isStoredCallableLiteral(resolvedMember.kind, expression) && memberInitializerRequiresEvaluation(
|
|
99458
|
+
context,
|
|
99459
|
+
resolvedMember,
|
|
99260
99460
|
expression,
|
|
99261
|
-
|
|
99262
|
-
bindingRuntimeIdentifiers(context, source)
|
|
99461
|
+
source
|
|
99263
99462
|
)) {
|
|
99264
99463
|
const unattachedId = annotated.id === null ? unattachedAuthoredRowId(authoredSlice) : null;
|
|
99265
99464
|
if (unattachedId !== null) {
|
|
@@ -99321,7 +99520,8 @@ function lowerSeedRow(context, member, sourceExpression, source, valueId, path,
|
|
|
99321
99520
|
if (effectiveClass === void 0) {
|
|
99322
99521
|
throw new Error(`Unknown value class ${resolvedMember.classId}.`);
|
|
99323
99522
|
}
|
|
99324
|
-
|
|
99523
|
+
const partial = resolvedMember.partial === true;
|
|
99524
|
+
if (!partial && effectiveClass.declarationModifier === "abstract") {
|
|
99325
99525
|
throw new Error(
|
|
99326
99526
|
`Cannot instantiate abstract class ${effectiveClass.name} for ${path}. Use a concrete descendant instead.`
|
|
99327
99527
|
);
|
|
@@ -99339,13 +99539,15 @@ function lowerSeedRow(context, member, sourceExpression, source, valueId, path,
|
|
|
99339
99539
|
expression,
|
|
99340
99540
|
declaredEnvironment
|
|
99341
99541
|
);
|
|
99342
|
-
|
|
99343
|
-
|
|
99344
|
-
|
|
99345
|
-
|
|
99346
|
-
|
|
99347
|
-
|
|
99348
|
-
|
|
99542
|
+
if (!partial) {
|
|
99543
|
+
validateConstructedGenericArguments(
|
|
99544
|
+
context,
|
|
99545
|
+
effectiveClass,
|
|
99546
|
+
expression,
|
|
99547
|
+
environment,
|
|
99548
|
+
path
|
|
99549
|
+
);
|
|
99550
|
+
}
|
|
99349
99551
|
genericBindings = animationChildOverrideSeedBindings(
|
|
99350
99552
|
context,
|
|
99351
99553
|
effectiveClass,
|
|
@@ -99355,19 +99557,20 @@ function lowerSeedRow(context, member, sourceExpression, source, valueId, path,
|
|
|
99355
99557
|
);
|
|
99356
99558
|
const body = {};
|
|
99357
99559
|
const argumentSlices = constructorArgumentValueSlices(authoredSlice);
|
|
99358
|
-
|
|
99359
|
-
projectedMember,
|
|
99360
|
-
schemaKey,
|
|
99361
|
-
argument: argument2,
|
|
99362
|
-
argumentIndex
|
|
99363
|
-
} of resolveConstructorProjectionArguments(
|
|
99560
|
+
const projectedArguments = partial ? [] : resolveConstructorProjectionArguments(
|
|
99364
99561
|
context,
|
|
99365
99562
|
effectiveClass,
|
|
99366
99563
|
expression,
|
|
99367
99564
|
valueId,
|
|
99368
99565
|
environment,
|
|
99369
99566
|
source
|
|
99370
|
-
)
|
|
99567
|
+
);
|
|
99568
|
+
for (const {
|
|
99569
|
+
projectedMember,
|
|
99570
|
+
schemaKey,
|
|
99571
|
+
argument: argument2,
|
|
99572
|
+
argumentIndex
|
|
99573
|
+
} of projectedArguments) {
|
|
99371
99574
|
const childPath = `${path}.${schemaKey}`;
|
|
99372
99575
|
const childValueId = pendingNestedValueId(source, childPath);
|
|
99373
99576
|
if (rows.has(childValueId)) {
|
|
@@ -99413,7 +99616,7 @@ function lowerSeedRow(context, member, sourceExpression, source, valueId, path,
|
|
|
99413
99616
|
effectiveClass.id,
|
|
99414
99617
|
assignment.name
|
|
99415
99618
|
);
|
|
99416
|
-
if (inheritedLegacyConstructorProjections(
|
|
99619
|
+
if (!partial && inheritedLegacyConstructorProjections(
|
|
99417
99620
|
context.classes,
|
|
99418
99621
|
effectiveClass.id
|
|
99419
99622
|
).some((projection) => projection.memberId === childMember.id)) {
|
|
@@ -99853,11 +100056,11 @@ function lowerValueRow(context, member, sourceExpression, expectedValueId, sourc
|
|
|
99853
100056
|
member,
|
|
99854
100057
|
environment
|
|
99855
100058
|
);
|
|
99856
|
-
if (!isStoredCallableLiteral(resolvedMember.kind, expression) &&
|
|
99857
|
-
context
|
|
100059
|
+
if (!isStoredCallableLiteral(resolvedMember.kind, expression) && memberInitializerRequiresEvaluation(
|
|
100060
|
+
context,
|
|
100061
|
+
resolvedMember,
|
|
99858
100062
|
expression,
|
|
99859
|
-
|
|
99860
|
-
bindingRuntimeIdentifiers(context, source)
|
|
100063
|
+
source
|
|
99861
100064
|
)) {
|
|
99862
100065
|
const code = initializerExpressionSlice(authoredSlice);
|
|
99863
100066
|
if (code === void 0) {
|
|
@@ -100075,7 +100278,8 @@ function lowerClassValue(context, member, expression, base, source, outerEnviron
|
|
|
100075
100278
|
const schemaClass2 = context.classes.get(classId);
|
|
100076
100279
|
if (schemaClass2 === void 0)
|
|
100077
100280
|
throw new Error(`Unknown value class ${classId}.`);
|
|
100078
|
-
|
|
100281
|
+
const partial = member.partial === true;
|
|
100282
|
+
if (!partial && schemaClass2.declarationModifier === "abstract") {
|
|
100079
100283
|
throw new Error(
|
|
100080
100284
|
`Cannot instantiate abstract class ${schemaClass2.name} for value ${String(base.id)}. Use a concrete descendant instead.`
|
|
100081
100285
|
);
|
|
@@ -100090,13 +100294,15 @@ function lowerClassValue(context, member, expression, base, source, outerEnviron
|
|
|
100090
100294
|
expression,
|
|
100091
100295
|
declaredEnvironment
|
|
100092
100296
|
);
|
|
100093
|
-
|
|
100094
|
-
|
|
100095
|
-
|
|
100096
|
-
|
|
100097
|
-
|
|
100098
|
-
|
|
100099
|
-
|
|
100297
|
+
if (!partial) {
|
|
100298
|
+
validateConstructedGenericArguments(
|
|
100299
|
+
context,
|
|
100300
|
+
schemaClass2,
|
|
100301
|
+
expression,
|
|
100302
|
+
environment,
|
|
100303
|
+
String(base.id ?? member.name)
|
|
100304
|
+
);
|
|
100305
|
+
}
|
|
100100
100306
|
const baseBody = isObjectRecord2(base.value) ? base.value : {};
|
|
100101
100307
|
const body = retainedStoredClassBody(
|
|
100102
100308
|
context,
|
|
@@ -100104,7 +100310,7 @@ function lowerClassValue(context, member, expression, base, source, outerEnviron
|
|
|
100104
100310
|
baseBody
|
|
100105
100311
|
);
|
|
100106
100312
|
const assignmentSlices = objectInitializerSlices(authoredSlice);
|
|
100107
|
-
if (materializedConstruction !== "preserve") {
|
|
100313
|
+
if (!partial && materializedConstruction !== "preserve") {
|
|
100108
100314
|
lowerConstructorProjections(
|
|
100109
100315
|
context,
|
|
100110
100316
|
schemaClass2,
|
|
@@ -100119,7 +100325,7 @@ function lowerClassValue(context, member, expression, base, source, outerEnviron
|
|
|
100119
100325
|
}
|
|
100120
100326
|
for (const assignment of expression.initializer ?? []) {
|
|
100121
100327
|
const childMember = classMemberByName(context, classId, assignment.name);
|
|
100122
|
-
if (inheritedLegacyConstructorProjections(
|
|
100328
|
+
if (!partial && inheritedLegacyConstructorProjections(
|
|
100123
100329
|
context.classes,
|
|
100124
100330
|
schemaClass2.id
|
|
100125
100331
|
).some((projection) => projection.memberId === childMember.id)) {
|
|
@@ -102173,7 +102379,7 @@ function classValue(context, member, value, visited, targetTyped, outerEnvironme
|
|
|
102173
102379
|
const hasStoredConstruction = isObjectRecord2(value.constructorArgs);
|
|
102174
102380
|
let projection;
|
|
102175
102381
|
try {
|
|
102176
|
-
projection = hasStoredConstruction ? {
|
|
102382
|
+
projection = partial ? { arguments: [], memberIds: /* @__PURE__ */ new Set(), targetValueIds: [] } : hasStoredConstruction ? {
|
|
102177
102383
|
arguments: [],
|
|
102178
102384
|
memberIds: new Set(
|
|
102179
102385
|
effectiveConstructorProjections(
|
|
@@ -102210,7 +102416,7 @@ function classValue(context, member, value, visited, targetTyped, outerEnvironme
|
|
|
102210
102416
|
const name = classValueTypeName(context, classId, member, environment);
|
|
102211
102417
|
let storedConstruction;
|
|
102212
102418
|
try {
|
|
102213
|
-
storedConstruction = storedConstructorCallSource(
|
|
102419
|
+
storedConstruction = partial ? null : storedConstructorCallSource(
|
|
102214
102420
|
context,
|
|
102215
102421
|
schemaClass2,
|
|
102216
102422
|
value,
|
|
@@ -104166,12 +104372,10 @@ function lowerProjectFileRegistrySourcesV4(root, state, analysis, options = {})
|
|
|
104166
104372
|
});
|
|
104167
104373
|
}
|
|
104168
104374
|
if (importSettingsChanged) {
|
|
104169
|
-
next[settingsField] =
|
|
104170
|
-
|
|
104171
|
-
|
|
104172
|
-
|
|
104173
|
-
values: {}
|
|
104174
|
-
};
|
|
104375
|
+
next[settingsField] = projectFileUnityImportSettingsV4(
|
|
104376
|
+
declaration.kind,
|
|
104377
|
+
declaration.templateId
|
|
104378
|
+
);
|
|
104175
104379
|
}
|
|
104176
104380
|
return {
|
|
104177
104381
|
recordKind: "project-file",
|
|
@@ -104203,12 +104407,7 @@ function lowerDiscoveredProjectBinariesV4(root, state, analysis) {
|
|
|
104203
104407
|
const templateId = binary.kind === "image" ? optionalString3(projectData.defaultTextureTemplateId) : optionalString3(projectData.defaultAudioClipTemplateId);
|
|
104204
104408
|
const settingsField = binary.kind === "image" ? "unityTextureSettings" : "unityAudioClipSettings";
|
|
104205
104409
|
const otherSettingsField = binary.kind === "image" ? "unityAudioClipSettings" : "unityTextureSettings";
|
|
104206
|
-
const settings =
|
|
104207
|
-
...binary.kind === "image" ? { type: "texture-2d" } : {},
|
|
104208
|
-
templateId,
|
|
104209
|
-
overridePaths: [],
|
|
104210
|
-
values: {}
|
|
104211
|
-
};
|
|
104410
|
+
const settings = projectFileUnityImportSettingsV4(binary.kind, templateId);
|
|
104212
104411
|
const now = Date.now();
|
|
104213
104412
|
return {
|
|
104214
104413
|
recordKind: "project-file",
|
|
@@ -104581,6 +104780,7 @@ var init_project_files = __esm({
|
|
|
104581
104780
|
init_source_format();
|
|
104582
104781
|
init_members();
|
|
104583
104782
|
init_project_file_registry();
|
|
104783
|
+
init_project_file_source();
|
|
104584
104784
|
SUPPORTED_BINARY_TYPES = /* @__PURE__ */ new Map([
|
|
104585
104785
|
[".png", { kind: "image", mimeType: "image/png" }],
|
|
104586
104786
|
[".jpg", { kind: "image", mimeType: "image/jpeg" }],
|
|
@@ -113595,7 +113795,7 @@ var init_registry2 = __esm({
|
|
|
113595
113795
|
PROJECT_SCHEMA_CONTRACT = Object.freeze({
|
|
113596
113796
|
formatVersion: 3,
|
|
113597
113797
|
contractVersion: "3.14",
|
|
113598
|
-
cliVersion: "0.
|
|
113798
|
+
cliVersion: "0.36.0",
|
|
113599
113799
|
projectFileUploadBatchSize: 32,
|
|
113600
113800
|
documentRecords: {
|
|
113601
113801
|
member: {
|
|
@@ -120197,7 +120397,7 @@ There is no --keep-current: preserving current semantic state defines flatten.
|
|
|
120197
120397
|
async function main() {
|
|
120198
120398
|
const args = parseArgs(process.argv.slice(2));
|
|
120199
120399
|
if (args.command === "--version") {
|
|
120200
|
-
console.log("0.
|
|
120400
|
+
console.log("0.36.0");
|
|
120201
120401
|
return;
|
|
120202
120402
|
}
|
|
120203
120403
|
if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@ description: >-
|
|
|
9
9
|
`@neocompose/cli` or `node cli/bin/neo.mjs` in the neo-compose repository.
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
<!-- reviewed-through-cli: 0.
|
|
12
|
+
<!-- reviewed-through-cli: 0.36.0 -->
|
|
13
13
|
|
|
14
14
|
# Neo Compose CLI
|
|
15
15
|
|
|
@@ -197,6 +197,8 @@ AudioClipRegistry AudioClips = new() {
|
|
|
197
197
|
Use `Images.Sword.Slice(0)` for a sprite and `AudioClips.SwordHit` for audio.
|
|
198
198
|
Renaming the registry symbol, moving the local presentation, or replacing bytes
|
|
199
199
|
retains the file ID.
|
|
200
|
+
Omitting `@settings(template: ...)` uses the complete built-in Unity import
|
|
201
|
+
defaults for that file kind.
|
|
200
202
|
|
|
201
203
|
## Resolve conflicts by identity
|
|
202
204
|
|
|
@@ -50,7 +50,12 @@ NeoVariant<ExampleObject> Down = new(
|
|
|
50
50
|
`() => new ExampleObject(.Down)` works; `apply` is void, so its expression
|
|
51
51
|
body must be a call or an assignment, as in
|
|
52
52
|
`(source) => source.FacingDir = .Down`. The server compiles them, so authored
|
|
53
|
-
source carries only the code.
|
|
53
|
+
source carries only the code. Each closure has its own lexical scope, so
|
|
54
|
+
local names may be reused between `initialize` and `apply`.
|
|
55
|
+
- `overrides` and each child override's `overrides` value are `Partial<T>`
|
|
56
|
+
deltas over existing instances. They may use inferred `new { ... }` or
|
|
57
|
+
explicit `new Partial<T> { ... }`, and never pass arguments to or invoke
|
|
58
|
+
`T`'s constructor—even when `T` has a required constructor.
|
|
54
59
|
|
|
55
60
|
Folders are records too, declared as their own globals and assigned per
|
|
56
61
|
variant. Nesting is spelled in the path with `/`; intermediate segments are
|
|
@@ -83,7 +83,7 @@ wrappers.
|
|
|
83
83
|
The marker near the top of `SKILL.md` must exactly match the package version:
|
|
84
84
|
|
|
85
85
|
```html
|
|
86
|
-
<!-- reviewed-through-cli: 0.
|
|
86
|
+
<!-- reviewed-through-cli: 0.36.0 -->
|
|
87
87
|
```
|
|
88
88
|
|
|
89
89
|
The quoted version above is checked too, so this instruction cannot go stale
|
|
@@ -80,9 +80,14 @@ Prefer `--json` for automation.
|
|
|
80
80
|
|
|
81
81
|
Inside an inline Class body, unqualified names resolve against that Class;
|
|
82
82
|
invoke delegate and action members directly with `Selector()` or `OnChanged()`.
|
|
83
|
+
Spell a zero-argument action as bare `NeoAction`; type arguments name action
|
|
84
|
+
parameters, so `NeoAction<void>` is invalid rather than a zero-argument alias.
|
|
83
85
|
Clear every subscribed listener from a stored action with
|
|
84
86
|
`this.OnChanged.Clear()`. `Clear()` is a mutating statement and follows the
|
|
85
|
-
action member's effective storage and writability.
|
|
87
|
+
action member's effective storage and writability. Only the action's declaring
|
|
88
|
+
class and derived classes may invoke it or call `Clear()`; public external
|
|
89
|
+
callers may subscribe and unsubscribe with `+=` and `-=` but cannot raise or
|
|
90
|
+
reset the action.
|
|
86
91
|
|
|
87
92
|
Inline `NeoDelegate` lambdas may be returned or stored and may read surrounding
|
|
88
93
|
locals and parameters. Those values are captured when the lambda is created,
|
|
@@ -172,7 +177,17 @@ enum, parameter, or local may shadow it. Qualified members use their owner's
|
|
|
172
177
|
namespace and may be named `Math`; access one as `this.Math` or
|
|
173
178
|
`SomeValue.Math` without colliding with the builtin qualifier.
|
|
174
179
|
|
|
175
|
-
##
|
|
180
|
+
## Collection builtins
|
|
181
|
+
|
|
182
|
+
Lists expose their size as either `items.Count` or `items.Count()`. Use
|
|
183
|
+
`items.Count((item) => predicate)` to count only matching entries without
|
|
184
|
+
materializing a filtered list. The same Count forms work on Dictionary and Set
|
|
185
|
+
collections; dictionary predicates may accept `(key, value)` just like the
|
|
186
|
+
other collection callbacks.
|
|
187
|
+
|
|
188
|
+
Use `items.IndexOf(value)` to return the zero-based index of the first equal
|
|
189
|
+
list entry, or `-1` when the value is absent. `IndexOf` is list-only and uses
|
|
190
|
+
the same value/reference equality as `Contains`.
|
|
176
191
|
|
|
177
192
|
Use `List.Repeat(value, count)` to build a list of `count` copies of a value
|
|
178
193
|
instead of hand-counting a literal or looping around `Add`:
|
|
@@ -170,7 +170,8 @@ diff, and dry-run do not rewrite its registry. A successful push creates the
|
|
|
170
170
|
record, uploads verified bytes, and materializes its declaration and ID.
|
|
171
171
|
|
|
172
172
|
Edit the typed registry declaration directly when an explicit symbol or
|
|
173
|
-
non-default template is needed before push.
|
|
173
|
+
non-default template is needed before push. With no template annotation, the
|
|
174
|
+
CLI persists the complete built-in Unity defaults for the file kind.
|
|
174
175
|
|
|
175
176
|
Pull/push compare server-verified SHA-256, not storage ETags. A divergent
|
|
176
177
|
binary keeps local bytes and writes the verified remote side under
|