@neocompose/cli 0.21.3 → 0.21.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.21.4] - 2026-08-03
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- `neo pull --reset` emits the canonical `SpriteInfo.Empty` spelling for the
|
|
8
|
+
required empty-sprite sentinel and does not mistake its empty file id for a
|
|
9
|
+
missing project file.
|
|
10
|
+
- Parameterized declaration templates compile with their class-header scope
|
|
11
|
+
without being evaluated before a concrete invocation supplies arguments.
|
|
12
|
+
- Canonical lowering reuses persisted generic argument identities, so a fresh
|
|
13
|
+
reset remains a semantic no-op instead of creating replacement binding rows.
|
|
14
|
+
|
|
3
15
|
## [0.21.3] - 2026-08-03
|
|
4
16
|
|
|
5
17
|
### Fixed
|
package/dist/neo.mjs
CHANGED
|
@@ -9045,7 +9045,8 @@ var init_strict_resolver = __esm({
|
|
|
9045
9045
|
);
|
|
9046
9046
|
case "call":
|
|
9047
9047
|
if (expression.callee.kind === "ident" && expression.callee.name === "Reference" && Array.isArray(expression.typeArguments)) {
|
|
9048
|
-
|
|
9048
|
+
const [referenceTypeArgument] = expression.typeArguments;
|
|
9049
|
+
if (expression.typeArguments.length !== 1 || referenceTypeArgument === void 0) {
|
|
9049
9050
|
throw new CompileError(
|
|
9050
9051
|
"Reference requires exactly one generic target type.",
|
|
9051
9052
|
expression.pos
|
|
@@ -9057,7 +9058,7 @@ var init_strict_resolver = __esm({
|
|
|
9057
9058
|
expression.pos
|
|
9058
9059
|
);
|
|
9059
9060
|
}
|
|
9060
|
-
const referencedType = this.resolveType(
|
|
9061
|
+
const referencedType = this.resolveType(referenceTypeArgument);
|
|
9061
9062
|
if (expected !== void 0 && !isNeoScriptTypeAssignable(referencedType, expected, this.project)) {
|
|
9062
9063
|
throw new CompileError(
|
|
9063
9064
|
`Reference target ${this.describe(referencedType)} is not assignable to ${this.describe(expected)}.`,
|
|
@@ -9111,7 +9112,7 @@ var init_strict_resolver = __esm({
|
|
|
9111
9112
|
if (requiredConstructor === null && !callMatchesDeclaredOverloadNames(declared, expression)) {
|
|
9112
9113
|
this.rejectConstructorProjectionInConstructionBody(expression);
|
|
9113
9114
|
}
|
|
9114
|
-
const projectionCall = requiredConstructor === null && expression.argumentNames === void 0 && callHasPositionalArguments(expression) && declaredTarget
|
|
9115
|
+
const projectionCall = requiredConstructor === null && declaredTarget?.constructorSignature !== void 0 && (expression.argumentNames === void 0 && callHasPositionalArguments(expression) || expression.argumentNames !== void 0 && declaredTarget.constructorSignature.namedProjections !== void 0);
|
|
9115
9116
|
if (declared.length > 0 && !projectionCall) {
|
|
9116
9117
|
return this.resolveDeclaredConstructor(
|
|
9117
9118
|
className,
|
|
@@ -9120,13 +9121,13 @@ var init_strict_resolver = __esm({
|
|
|
9120
9121
|
expression.pos
|
|
9121
9122
|
);
|
|
9122
9123
|
}
|
|
9123
|
-
if (expression.argumentNames) {
|
|
9124
|
+
if (expression.argumentNames && !projectionCall) {
|
|
9124
9125
|
throw new CompileError(
|
|
9125
9126
|
"Named constructor arguments require a declaration-aware project source context.",
|
|
9126
9127
|
expression.pos
|
|
9127
9128
|
);
|
|
9128
9129
|
}
|
|
9129
|
-
if (expression.initializer && expression.initializer.length > 0) {
|
|
9130
|
+
if (expression.initializer && expression.initializer.length > 0 && !projectionCall) {
|
|
9130
9131
|
throw new CompileError(
|
|
9131
9132
|
"Object initializers are available to project source construction and are not executable NeoScript constructors.",
|
|
9132
9133
|
expression.pos
|
|
@@ -9134,9 +9135,10 @@ var init_strict_resolver = __esm({
|
|
|
9134
9135
|
}
|
|
9135
9136
|
return this.resolveClassConstructor(
|
|
9136
9137
|
className,
|
|
9137
|
-
expression
|
|
9138
|
+
expression,
|
|
9138
9139
|
scope,
|
|
9139
|
-
expression.pos
|
|
9140
|
+
expression.pos,
|
|
9141
|
+
expected
|
|
9140
9142
|
);
|
|
9141
9143
|
}
|
|
9142
9144
|
case "annotated":
|
|
@@ -10544,7 +10546,7 @@ var init_strict_resolver = __esm({
|
|
|
10544
10546
|
type: optional ? { ...delegateType.returnType, nullable: true } : delegateType.returnType
|
|
10545
10547
|
};
|
|
10546
10548
|
}
|
|
10547
|
-
resolveClassConstructor(className,
|
|
10549
|
+
resolveClassConstructor(className, expression, scope, pos, expected) {
|
|
10548
10550
|
const schemaClass2 = this.project.typeByName.get(className);
|
|
10549
10551
|
if (!schemaClass2 || schemaClass2.kind !== "class") {
|
|
10550
10552
|
throw new CompileError(
|
|
@@ -10566,26 +10568,86 @@ var init_strict_resolver = __esm({
|
|
|
10566
10568
|
pos
|
|
10567
10569
|
);
|
|
10568
10570
|
}
|
|
10571
|
+
const targetType = this.constructorTargetType(
|
|
10572
|
+
schemaClass2,
|
|
10573
|
+
expression,
|
|
10574
|
+
expected
|
|
10575
|
+
);
|
|
10576
|
+
const parameters = signature.parameters.map((parameter3) => ({
|
|
10577
|
+
...parameter3,
|
|
10578
|
+
valueType: substituteTypeParameters(
|
|
10579
|
+
parameter3.valueType,
|
|
10580
|
+
targetType,
|
|
10581
|
+
schemaClass2
|
|
10582
|
+
),
|
|
10583
|
+
parameterType: substituteTypeParameters(
|
|
10584
|
+
parameter3.parameterType,
|
|
10585
|
+
targetType,
|
|
10586
|
+
schemaClass2
|
|
10587
|
+
)
|
|
10588
|
+
}));
|
|
10589
|
+
const argumentsList2 = expression.args;
|
|
10590
|
+
const namedProjections = signature.namedProjections;
|
|
10591
|
+
if (expression.argumentNames !== void 0) {
|
|
10592
|
+
if (namedProjections === void 0) {
|
|
10593
|
+
throw new CompileError(
|
|
10594
|
+
`Class '${className}' exposes no named constructor projection.`,
|
|
10595
|
+
pos
|
|
10596
|
+
);
|
|
10597
|
+
}
|
|
10598
|
+
if (argumentsList2.length !== namedProjections.length) {
|
|
10599
|
+
throw new CompileError(
|
|
10600
|
+
`${className} constructor requires ${namedProjections.length} named argument${namedProjections.length === 1 ? "" : "s"} but got ${argumentsList2.length}.`,
|
|
10601
|
+
pos
|
|
10602
|
+
);
|
|
10603
|
+
}
|
|
10604
|
+
if (expression.argumentNames.length !== argumentsList2.length) {
|
|
10605
|
+
throw new CompileError(
|
|
10606
|
+
`${className} constructor projection requires every argument to be named.`,
|
|
10607
|
+
pos
|
|
10608
|
+
);
|
|
10609
|
+
}
|
|
10610
|
+
}
|
|
10569
10611
|
const requiredCount = signature.parameters.filter(
|
|
10570
10612
|
(parameter3) => parameter3.required
|
|
10571
10613
|
).length;
|
|
10572
|
-
if (argumentsList2.length < requiredCount) {
|
|
10614
|
+
if (expression.argumentNames === void 0 && argumentsList2.length < requiredCount) {
|
|
10573
10615
|
throw new CompileError(
|
|
10574
10616
|
`${className} constructor requires ${requiredCount} argument${requiredCount === 1 ? "" : "s"} but got ${argumentsList2.length}.`,
|
|
10575
10617
|
pos
|
|
10576
10618
|
);
|
|
10577
10619
|
}
|
|
10578
|
-
if (argumentsList2.length >
|
|
10620
|
+
if (expression.argumentNames === void 0 && argumentsList2.length > parameters.length) {
|
|
10579
10621
|
throw new CompileError(
|
|
10580
|
-
`${className} constructor accepts at most ${
|
|
10622
|
+
`${className} constructor accepts at most ${parameters.length} argument${parameters.length === 1 ? "" : "s"} but got ${argumentsList2.length}.`,
|
|
10581
10623
|
pos
|
|
10582
10624
|
);
|
|
10583
10625
|
}
|
|
10584
10626
|
const fields = argumentsList2.map((argument2, index) => {
|
|
10585
|
-
const
|
|
10627
|
+
const projectionName = expression.argumentNames?.[index];
|
|
10628
|
+
const projection = projectionName === void 0 ? void 0 : namedProjections?.find(
|
|
10629
|
+
(candidate) => candidate.name === projectionName
|
|
10630
|
+
);
|
|
10631
|
+
if (projectionName !== void 0 && projection === void 0) {
|
|
10632
|
+
throw new CompileError(
|
|
10633
|
+
`Class '${className}' has no constructor projection named '${projectionName}'.`,
|
|
10634
|
+
argument2.pos
|
|
10635
|
+
);
|
|
10636
|
+
}
|
|
10637
|
+
if (projection !== void 0 && expression.argumentNames?.findIndex(
|
|
10638
|
+
(candidate) => candidate === projection.name
|
|
10639
|
+
) !== index) {
|
|
10640
|
+
throw new CompileError(
|
|
10641
|
+
`Constructor argument '${projection.name}' is supplied more than once.`,
|
|
10642
|
+
argument2.pos
|
|
10643
|
+
);
|
|
10644
|
+
}
|
|
10645
|
+
const parameter3 = projection === void 0 ? parameters[index] : parameters.find(
|
|
10646
|
+
(candidate) => candidate.memberId === projection.memberId
|
|
10647
|
+
);
|
|
10586
10648
|
if (!parameter3) {
|
|
10587
10649
|
throw new Error(
|
|
10588
|
-
`NeoScript constructor ${className} lost parameter ${index + 1} after argument-count validation.`
|
|
10650
|
+
projection === void 0 ? `NeoScript constructor ${className} lost parameter ${index + 1} after argument-count validation.` : `NeoScript constructor ${className} projection '${projection.name}' names missing member '${projection.memberId}'.`
|
|
10589
10651
|
);
|
|
10590
10652
|
}
|
|
10591
10653
|
const value = this.resolveExpression(
|
|
@@ -10605,7 +10667,20 @@ var init_strict_resolver = __esm({
|
|
|
10605
10667
|
valuePointer: value.pointer
|
|
10606
10668
|
};
|
|
10607
10669
|
});
|
|
10608
|
-
|
|
10670
|
+
if (namedProjections !== void 0 && expression.argumentNames !== void 0) {
|
|
10671
|
+
for (const projection of namedProjections) {
|
|
10672
|
+
if (!expression.argumentNames.includes(projection.name)) {
|
|
10673
|
+
throw new CompileError(
|
|
10674
|
+
`${className} constructor is missing named argument '${projection.name}'.`,
|
|
10675
|
+
pos
|
|
10676
|
+
);
|
|
10677
|
+
}
|
|
10678
|
+
}
|
|
10679
|
+
}
|
|
10680
|
+
fields.push(
|
|
10681
|
+
...this.resolveCallSiteInitializerFields(schemaClass2, expression, scope)
|
|
10682
|
+
);
|
|
10683
|
+
const schemaClassInfo = toWireType(targetType, this.project);
|
|
10609
10684
|
if (schemaClassInfo.type !== 7 /* Class */) {
|
|
10610
10685
|
throw new Error(
|
|
10611
10686
|
`NeoScript constructor ${className} has non-Class return type ${this.describe(signature.returnType)}.`
|
|
@@ -10619,10 +10694,35 @@ var init_strict_resolver = __esm({
|
|
|
10619
10694
|
info: { schemaClassInfo, fields }
|
|
10620
10695
|
}
|
|
10621
10696
|
},
|
|
10622
|
-
type: { ...
|
|
10697
|
+
type: { ...targetType, nullable: false },
|
|
10623
10698
|
writability: "session" /* Session */
|
|
10624
10699
|
};
|
|
10625
10700
|
}
|
|
10701
|
+
constructorTargetType(schemaClass2, expression, expected) {
|
|
10702
|
+
const typeArguments = expression.typeArguments?.map(
|
|
10703
|
+
(argument2) => this.resolveType(argument2)
|
|
10704
|
+
);
|
|
10705
|
+
if (typeArguments !== void 0 && typeArguments.length !== (schemaClass2.typeParameters?.length ?? 0)) {
|
|
10706
|
+
throw new CompileError(
|
|
10707
|
+
`Class '${schemaClass2.name}' expects ${schemaClass2.typeParameters?.length ?? 0} type argument${schemaClass2.typeParameters?.length === 1 ? "" : "s"} but got ${typeArguments.length}.`,
|
|
10708
|
+
expression.pos
|
|
10709
|
+
);
|
|
10710
|
+
}
|
|
10711
|
+
if (typeArguments !== void 0) {
|
|
10712
|
+
return {
|
|
10713
|
+
kind: "named",
|
|
10714
|
+
typeId: schemaClass2.id,
|
|
10715
|
+
typeArguments
|
|
10716
|
+
};
|
|
10717
|
+
}
|
|
10718
|
+
if (expected?.kind === "named" && expected.typeId === schemaClass2.id) {
|
|
10719
|
+
return { ...expected, nullable: false };
|
|
10720
|
+
}
|
|
10721
|
+
return {
|
|
10722
|
+
kind: "named",
|
|
10723
|
+
typeId: schemaClass2.id
|
|
10724
|
+
};
|
|
10725
|
+
}
|
|
10626
10726
|
/**
|
|
10627
10727
|
* P43 §7.1. P29's `new T(id: "…")` projection names a class-default row,
|
|
10628
10728
|
* which is exactly the wrong identity inside a construction body: member
|
|
@@ -44500,7 +44600,13 @@ function lowerFieldMember(context, ownerClass, declaration, id2, commonInput, ba
|
|
|
44500
44600
|
classId,
|
|
44501
44601
|
...partial ? { partial: true } : {},
|
|
44502
44602
|
schemaKeyOrder: base?.kind === "class" ? base.schemaKeyOrder : null,
|
|
44503
|
-
classArguments: lowerClassArguments(
|
|
44603
|
+
classArguments: lowerClassArguments(
|
|
44604
|
+
context,
|
|
44605
|
+
ownerClass,
|
|
44606
|
+
id2,
|
|
44607
|
+
fieldType,
|
|
44608
|
+
base?.kind === "class" ? base.classArguments : void 0
|
|
44609
|
+
)
|
|
44504
44610
|
};
|
|
44505
44611
|
}
|
|
44506
44612
|
throw new Error(
|
|
@@ -45575,7 +45681,7 @@ function genericParameterName(context, genericParamId) {
|
|
|
45575
45681
|
}
|
|
45576
45682
|
return "object";
|
|
45577
45683
|
}
|
|
45578
|
-
function lowerClassArguments(context, ownerClass, ownerMemberId, type) {
|
|
45684
|
+
function lowerClassArguments(context, ownerClass, ownerMemberId, type, baseArguments) {
|
|
45579
45685
|
const classId = context.classIdsByName.get(type.name);
|
|
45580
45686
|
if (!classId) return {};
|
|
45581
45687
|
const parameters = [
|
|
@@ -45591,7 +45697,8 @@ function lowerClassArguments(context, ownerClass, ownerMemberId, type) {
|
|
|
45591
45697
|
result[parameterId] = { kind: "generic", genericParamId: ownerParameter };
|
|
45592
45698
|
continue;
|
|
45593
45699
|
}
|
|
45594
|
-
const
|
|
45700
|
+
const baseBinding = baseArguments?.[parameterId];
|
|
45701
|
+
const memberId = baseBinding?.kind === "member" ? baseBinding.memberId : derivedGenericArgumentMemberId(ownerMemberId, parameterId);
|
|
45595
45702
|
result[parameterId] = { kind: "member", memberId };
|
|
45596
45703
|
lowerGenericArgument(
|
|
45597
45704
|
context,
|
|
@@ -45611,6 +45718,7 @@ function lowerExtendsBindings(context, declaration, baseClassId, argumentsValue)
|
|
|
45611
45718
|
];
|
|
45612
45719
|
const result = {};
|
|
45613
45720
|
const declarationId = materializedId(declaration, "class", declaration.name);
|
|
45721
|
+
const baseBindings = context.baseClasses.get(declarationId)?.extendsGenericBindings ?? {};
|
|
45614
45722
|
for (const [[parameterName, parameterId], argumentType] of zip(
|
|
45615
45723
|
parameters,
|
|
45616
45724
|
argumentsValue
|
|
@@ -45620,7 +45728,8 @@ function lowerExtendsBindings(context, declaration, baseClassId, argumentsValue)
|
|
|
45620
45728
|
result[parameterId] = { kind: "generic", genericParamId: local };
|
|
45621
45729
|
continue;
|
|
45622
45730
|
}
|
|
45623
|
-
const
|
|
45731
|
+
const baseBinding = baseBindings[parameterId];
|
|
45732
|
+
const memberId = baseBinding?.kind === "member" ? baseBinding.memberId : derivedGenericArgumentMemberId(declarationId, parameterId);
|
|
45624
45733
|
result[parameterId] = { kind: "member", memberId };
|
|
45625
45734
|
lowerGenericArgument(
|
|
45626
45735
|
context,
|
|
@@ -47646,6 +47755,15 @@ function renderDefaultValue(context, member, wrapper) {
|
|
|
47646
47755
|
`${member.kind === "sprite" ? "Sprite" : "Audio"} member ${JSON.stringify(member.name)} default stores a file value with no fileId. Emitting it as null would delete the default on the next push.`
|
|
47647
47756
|
);
|
|
47648
47757
|
}
|
|
47758
|
+
if (value.fileId.length === 0) {
|
|
47759
|
+
const sliceIndex = typeof value.sliceIndex === "number" ? value.sliceIndex : 0;
|
|
47760
|
+
if (member.kind === "sprite" && sliceIndex === 0) {
|
|
47761
|
+
return "SpriteInfo.Empty";
|
|
47762
|
+
}
|
|
47763
|
+
throw new Error(
|
|
47764
|
+
`${member.kind === "sprite" ? "Sprite" : "Audio"} member ${JSON.stringify(member.name)} default stores an invalid empty file value.`
|
|
47765
|
+
);
|
|
47766
|
+
}
|
|
47649
47767
|
const symbol = context.fileSymbols.get(value.fileId);
|
|
47650
47768
|
const target = symbol ?? (member.kind === "sprite" ? `Reference<NeoImage>(id: ${quote(value.fileId)})` : `Reference<NeoAudioClip>(id: ${quote(value.fileId)})`);
|
|
47651
47769
|
return member.kind === "sprite" ? `${target}.Slice(${typeof value.sliceIndex === "number" ? value.sliceIndex : 0})` : target;
|
|
@@ -48582,6 +48700,7 @@ function validateFinalizedFileAssignmentsV4(records2, options = {}) {
|
|
|
48582
48700
|
return;
|
|
48583
48701
|
}
|
|
48584
48702
|
if (!isObjectRecord2(value)) return;
|
|
48703
|
+
if (isEmptySpriteValue(value)) return;
|
|
48585
48704
|
if (isStructuredLeafPartialValue(value)) {
|
|
48586
48705
|
visitSpriteFileField(
|
|
48587
48706
|
value[STRUCTURED_LEAF_PARTIAL_KEY].fileId,
|
|
@@ -52582,7 +52701,10 @@ function classToLanguageType(schemaClass2, context) {
|
|
|
52582
52701
|
}
|
|
52583
52702
|
function constructorSignature(schemaClass2, members, context, genericEnvironment) {
|
|
52584
52703
|
if (schemaClass2.isAbstract) return {};
|
|
52585
|
-
|
|
52704
|
+
const projections = inheritedConstructorProjections(schemaClass2, context);
|
|
52705
|
+
if (projections.length === 0 && !isClosedClass(schemaClass2.id, context.vm.classes)) {
|
|
52706
|
+
return {};
|
|
52707
|
+
}
|
|
52586
52708
|
if (resolveAllowedStorage(schemaClass2.id, context.vm.classes) === "immutable" /* Immutable */) {
|
|
52587
52709
|
return { constructorUnavailableReason: "immutableOnly" };
|
|
52588
52710
|
}
|
|
@@ -52603,11 +52725,43 @@ function constructorSignature(schemaClass2, members, context, genericEnvironment
|
|
|
52603
52725
|
defaultValue: "defaultValue" in resolved ? resolved.defaultValue : void 0
|
|
52604
52726
|
};
|
|
52605
52727
|
} catch {
|
|
52728
|
+
if (projections.some((projection) => projection.memberId === memberId)) {
|
|
52729
|
+
return { required: true };
|
|
52730
|
+
}
|
|
52606
52731
|
return null;
|
|
52607
52732
|
}
|
|
52608
52733
|
}
|
|
52609
52734
|
);
|
|
52610
|
-
return {
|
|
52735
|
+
return {
|
|
52736
|
+
constructorSignature: {
|
|
52737
|
+
...signature,
|
|
52738
|
+
...projections.length === 0 ? {} : {
|
|
52739
|
+
namedProjections: projections.map((projection) => ({
|
|
52740
|
+
name: projection.parameterName,
|
|
52741
|
+
memberId: projection.memberId
|
|
52742
|
+
}))
|
|
52743
|
+
}
|
|
52744
|
+
}
|
|
52745
|
+
};
|
|
52746
|
+
}
|
|
52747
|
+
function inheritedConstructorProjections(schemaClass2, context) {
|
|
52748
|
+
const classesById = new Map(
|
|
52749
|
+
context.vm.classes.map((candidate) => [candidate.id, candidate])
|
|
52750
|
+
);
|
|
52751
|
+
const projections = [];
|
|
52752
|
+
const claimed = /* @__PURE__ */ new Set();
|
|
52753
|
+
const visited = /* @__PURE__ */ new Set();
|
|
52754
|
+
let current = schemaClass2;
|
|
52755
|
+
while (current !== void 0 && !visited.has(current.id)) {
|
|
52756
|
+
visited.add(current.id);
|
|
52757
|
+
for (const projection of current.constructorProjections ?? []) {
|
|
52758
|
+
if (claimed.has(projection.parameterName)) continue;
|
|
52759
|
+
claimed.add(projection.parameterName);
|
|
52760
|
+
projections.push(projection);
|
|
52761
|
+
}
|
|
52762
|
+
current = current.extendsClassId ? classesById.get(current.extendsClassId) : void 0;
|
|
52763
|
+
}
|
|
52764
|
+
return projections;
|
|
52611
52765
|
}
|
|
52612
52766
|
function declaredConstructors(schemaClass2, context) {
|
|
52613
52767
|
const requiredConstructorId2 = schemaClass2.requiredConstructorId;
|
|
@@ -54316,13 +54470,37 @@ function throwNamedBodyCompileFailure(args) {
|
|
|
54316
54470
|
});
|
|
54317
54471
|
}
|
|
54318
54472
|
function resolveMemberDeclaredTypeInfo(member, members) {
|
|
54473
|
+
return resolveMemberDeclaredTypeInfoInternal(member, members, /* @__PURE__ */ new Set());
|
|
54474
|
+
}
|
|
54475
|
+
function resolveMemberDeclaredTypeInfoInternal(member, members, seen) {
|
|
54319
54476
|
const resolved = resolveMember2(member, members);
|
|
54477
|
+
const memberId = getField(resolved, "id");
|
|
54478
|
+
if (typeof memberId === "string" && seen.has(memberId)) return null;
|
|
54479
|
+
const nextSeen = typeof memberId === "string" ? /* @__PURE__ */ new Set([...seen, memberId]) : new Set(seen);
|
|
54320
54480
|
if (isMemberNSPropertyBase(resolved)) return resolved.returnTypeInfo;
|
|
54321
54481
|
if (isMemberClassBase(resolved)) {
|
|
54482
|
+
const typeArguments = Object.fromEntries(
|
|
54483
|
+
Object.entries(resolved.classArguments ?? {}).flatMap(
|
|
54484
|
+
([genericParamId, binding]) => {
|
|
54485
|
+
if (binding.kind !== "member") return [];
|
|
54486
|
+
const argumentMember = members.find(
|
|
54487
|
+
(candidate) => candidate.id === binding.memberId
|
|
54488
|
+
);
|
|
54489
|
+
if (argumentMember === void 0) return [];
|
|
54490
|
+
const argumentType = resolveMemberDeclaredTypeInfoInternal(
|
|
54491
|
+
argumentMember,
|
|
54492
|
+
members,
|
|
54493
|
+
nextSeen
|
|
54494
|
+
);
|
|
54495
|
+
return argumentType === null ? [] : [[genericParamId, { ...argumentType, required: true }]];
|
|
54496
|
+
}
|
|
54497
|
+
)
|
|
54498
|
+
);
|
|
54322
54499
|
return {
|
|
54323
54500
|
type: 7 /* Class */,
|
|
54324
54501
|
required: resolved.required,
|
|
54325
|
-
classId: resolved.classId
|
|
54502
|
+
classId: resolved.classId,
|
|
54503
|
+
...Object.keys(typeArguments).length === 0 ? {} : { typeArguments }
|
|
54326
54504
|
};
|
|
54327
54505
|
}
|
|
54328
54506
|
if (isMemberEnumBase(resolved)) {
|
|
@@ -54349,7 +54527,11 @@ function resolveMemberDeclaredTypeInfo(member, members) {
|
|
|
54349
54527
|
(candidate) => candidate.id === resolved.entryMemberId
|
|
54350
54528
|
);
|
|
54351
54529
|
if (entry === void 0) return null;
|
|
54352
|
-
const entryTypeInfo =
|
|
54530
|
+
const entryTypeInfo = resolveMemberDeclaredTypeInfoInternal(
|
|
54531
|
+
entry,
|
|
54532
|
+
members,
|
|
54533
|
+
nextSeen
|
|
54534
|
+
);
|
|
54353
54535
|
if (entryTypeInfo === null) return null;
|
|
54354
54536
|
return {
|
|
54355
54537
|
type: resolved.kind,
|
|
@@ -54365,7 +54547,7 @@ function resolveMemberDeclaredTypeInfo(member, members) {
|
|
|
54365
54547
|
if (collection === void 0) return null;
|
|
54366
54548
|
return lookupDeclaredTypeInfo(
|
|
54367
54549
|
resolved,
|
|
54368
|
-
|
|
54550
|
+
resolveMemberDeclaredTypeInfoInternal(collection, members, nextSeen)
|
|
54369
54551
|
);
|
|
54370
54552
|
}
|
|
54371
54553
|
if (!memberKindSupportsStorage(resolved.kind)) return null;
|
|
@@ -75316,15 +75498,16 @@ function replayStoredConstructionV4(args) {
|
|
|
75316
75498
|
member: compileMember,
|
|
75317
75499
|
valueRow: candidate,
|
|
75318
75500
|
valueId: args.valueId,
|
|
75319
|
-
//
|
|
75320
|
-
//
|
|
75321
|
-
initializerOwnerClass: null
|
|
75501
|
+
// Instance calls are self-contained. Declaration calls inherit the class
|
|
75502
|
+
// header parameters that are in lexical scope at their source site.
|
|
75503
|
+
initializerOwnerClass: args.initializerOwnerClass ?? null
|
|
75322
75504
|
});
|
|
75323
75505
|
if (!isMemberValue(candidate) || !isInitValueContent(candidate)) {
|
|
75324
75506
|
throw new Error(
|
|
75325
75507
|
`Construction replay for value "${args.valueId}" did not compile an initializer row.`
|
|
75326
75508
|
);
|
|
75327
75509
|
}
|
|
75510
|
+
if (args.evaluate === false) return /* @__PURE__ */ new Map();
|
|
75328
75511
|
const materialized = materializeInitializerValue({
|
|
75329
75512
|
document,
|
|
75330
75513
|
// Constructor-only rows have no structural member owner. Use the same
|
|
@@ -76434,7 +76617,7 @@ function lowerRowBackedDefault(context, member, backed, baseData3, binding) {
|
|
|
76434
76617
|
const assignmentSlices = objectInitializerSlices(binding.initializer);
|
|
76435
76618
|
for (const assignment of expression.initializer ?? []) {
|
|
76436
76619
|
const childMember = classMemberByName(context, classId, assignment.name);
|
|
76437
|
-
if (
|
|
76620
|
+
if (inheritedConstructorProjections2(context.classes, schemaClass2.id).some(
|
|
76438
76621
|
(projection) => projection.memberId === childMember.id
|
|
76439
76622
|
)) {
|
|
76440
76623
|
throw new Error(
|
|
@@ -76847,7 +77030,7 @@ function lowerSeedRow(context, member, sourceExpression, source, valueId, path,
|
|
|
76847
77030
|
effectiveClass.id,
|
|
76848
77031
|
assignment.name
|
|
76849
77032
|
);
|
|
76850
|
-
if (
|
|
77033
|
+
if (inheritedConstructorProjections2(
|
|
76851
77034
|
context.classes,
|
|
76852
77035
|
effectiveClass.id
|
|
76853
77036
|
).some((projection) => projection.memberId === childMember.id)) {
|
|
@@ -77145,15 +77328,17 @@ function lowerValueRow(context, member, sourceExpression, expectedValueId, sourc
|
|
|
77145
77328
|
`Value ${expectedValueId} stores constructor arguments but its declared member ${resolvedMember.name} is not a Class.`
|
|
77146
77329
|
);
|
|
77147
77330
|
}
|
|
77148
|
-
|
|
77149
|
-
|
|
77150
|
-
|
|
77151
|
-
|
|
77152
|
-
|
|
77153
|
-
(
|
|
77154
|
-
|
|
77155
|
-
|
|
77156
|
-
|
|
77331
|
+
if (source.purpose === "stored") {
|
|
77332
|
+
context.initializerReconciliations.set(expectedValueId, {
|
|
77333
|
+
valueId: expectedValueId,
|
|
77334
|
+
code,
|
|
77335
|
+
storedConstructorArgs: storedConstructorArgs === null ? null : structuredClone(storedConstructorArgs),
|
|
77336
|
+
settleFields: expression.kind === "new" ? (expression.initializer ?? []).map(
|
|
77337
|
+
(assignment) => assignment.name
|
|
77338
|
+
) : [],
|
|
77339
|
+
site: referenceSite(source, expression)
|
|
77340
|
+
});
|
|
77341
|
+
}
|
|
77157
77342
|
const value2 = lowerClassValue(
|
|
77158
77343
|
context,
|
|
77159
77344
|
resolvedMember,
|
|
@@ -77348,7 +77533,7 @@ function lowerClassValue(context, member, expression, base, source, outerEnviron
|
|
|
77348
77533
|
}
|
|
77349
77534
|
for (const assignment of expression.initializer ?? []) {
|
|
77350
77535
|
const childMember = classMemberByName(context, classId, assignment.name);
|
|
77351
|
-
if (
|
|
77536
|
+
if (inheritedConstructorProjections2(context.classes, schemaClass2.id).some(
|
|
77352
77537
|
(projection) => projection.memberId === childMember.id
|
|
77353
77538
|
)) {
|
|
77354
77539
|
throw new Error(
|
|
@@ -77530,7 +77715,7 @@ function classInheritanceChain(classes, classId) {
|
|
|
77530
77715
|
}
|
|
77531
77716
|
return chain;
|
|
77532
77717
|
}
|
|
77533
|
-
function
|
|
77718
|
+
function inheritedConstructorProjections2(classes, classId) {
|
|
77534
77719
|
const resolved = [];
|
|
77535
77720
|
const claimed = /* @__PURE__ */ new Set();
|
|
77536
77721
|
for (const schemaClass2 of classInheritanceChain(classes, classId)) {
|
|
@@ -77551,7 +77736,7 @@ function inheritedProjectionSchemaKey(classes, classId, memberId) {
|
|
|
77551
77736
|
return null;
|
|
77552
77737
|
}
|
|
77553
77738
|
function resolveConstructorProjectionArguments(context, schemaClass2, expression, ownerValueId, environment, source) {
|
|
77554
|
-
const projections =
|
|
77739
|
+
const projections = inheritedConstructorProjections2(
|
|
77555
77740
|
context.classes,
|
|
77556
77741
|
schemaClass2.id
|
|
77557
77742
|
);
|
|
@@ -79856,7 +80041,7 @@ function manifestMemberTypeName(context, member) {
|
|
|
79856
80041
|
return fixedSourceTypeNameForKind(member.kind) ?? member.kind;
|
|
79857
80042
|
}
|
|
79858
80043
|
function constructorProjectionSource(context, classId, body, visited, environment) {
|
|
79859
|
-
const projections =
|
|
80044
|
+
const projections = inheritedConstructorProjections2(
|
|
79860
80045
|
context.manifestClasses,
|
|
79861
80046
|
classId
|
|
79862
80047
|
);
|
|
@@ -84019,11 +84204,12 @@ function replayAnimationDeclarationInitializersV4(records2, document) {
|
|
|
84019
84204
|
});
|
|
84020
84205
|
if (initializers.length === 0) return document;
|
|
84021
84206
|
const rootKinds = /* @__PURE__ */ new Map();
|
|
84207
|
+
const rootOwners = /* @__PURE__ */ new Map();
|
|
84022
84208
|
const owners = resolveOwnerMembersForValues(
|
|
84023
84209
|
document,
|
|
84024
84210
|
new Set(initializers.map(({ row }) => row.id)),
|
|
84025
84211
|
void 0,
|
|
84026
|
-
|
|
84212
|
+
rootOwners,
|
|
84027
84213
|
rootKinds
|
|
84028
84214
|
);
|
|
84029
84215
|
const pulled = /* @__PURE__ */ new Map();
|
|
@@ -84048,12 +84234,20 @@ function replayAnimationDeclarationInitializersV4(records2, document) {
|
|
|
84048
84234
|
if (!classBelongsToAnimationFamily(document.classes, declaredClassId)) {
|
|
84049
84235
|
continue;
|
|
84050
84236
|
}
|
|
84237
|
+
const rootOwner = rootOwners.get(row.id);
|
|
84238
|
+
const rootOwnerId = Reflect.get(rootOwner ?? {}, "id");
|
|
84239
|
+
const initializerOwnerClass = typeof rootOwnerId !== "string" ? null : findSchemaPlacement(rootOwnerId, document.classes)?.ownerClass ?? null;
|
|
84051
84240
|
const replay = replayStoredConstructionV4({
|
|
84052
84241
|
records: pulled,
|
|
84053
84242
|
valueId: row.id,
|
|
84054
84243
|
code,
|
|
84055
84244
|
member: owner,
|
|
84056
|
-
compileDocumentBodies: true
|
|
84245
|
+
compileDocumentBodies: true,
|
|
84246
|
+
initializerOwnerClass,
|
|
84247
|
+
// A parameterized declaration is a template. Its arguments exist only
|
|
84248
|
+
// at concrete construction sites, so validate the authored body here
|
|
84249
|
+
// without fabricating values for the class header parameters.
|
|
84250
|
+
evaluate: initializerOwnerClass?.requiredConstructorId === void 0 || initializerOwnerClass.requiredConstructorId === null
|
|
84057
84251
|
});
|
|
84058
84252
|
for (const [id2, value] of replay) {
|
|
84059
84253
|
if (!isMemberValue(value)) {
|
|
@@ -84437,6 +84631,7 @@ var init_workspace_status = __esm({
|
|
|
84437
84631
|
init_project_documents();
|
|
84438
84632
|
init_animation_clips();
|
|
84439
84633
|
init_classes();
|
|
84634
|
+
init_inheritance();
|
|
84440
84635
|
init_members();
|
|
84441
84636
|
init_value_row_owner_members();
|
|
84442
84637
|
init_project2();
|
package/package.json
CHANGED
|
@@ -73,7 +73,7 @@ wrappers.
|
|
|
73
73
|
The marker near the top of `SKILL.md` must exactly match the package version:
|
|
74
74
|
|
|
75
75
|
```html
|
|
76
|
-
<!-- reviewed-through-cli: 0.21.
|
|
76
|
+
<!-- reviewed-through-cli: 0.21.4 -->
|
|
77
77
|
```
|
|
78
78
|
|
|
79
79
|
The quoted version above is checked too, so this instruction cannot go stale
|