@neocompose/cli 0.31.4 → 0.31.5
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,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.31.5] - 2026-08-15
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- Resolve callable members through generic class and interface constraints, so
|
|
8
|
+
an open generic value can call guaranteed APIs such as `Class.Clone()`.
|
|
9
|
+
|
|
3
10
|
## [0.31.4] - 2026-08-14
|
|
4
11
|
|
|
5
12
|
### Fixed
|
package/dist/neo.mjs
CHANGED
|
@@ -1832,6 +1832,21 @@ var init_generated_csharp_identifiers = __esm({
|
|
|
1832
1832
|
});
|
|
1833
1833
|
|
|
1834
1834
|
// ../packages/neoscript-language/src/project.ts
|
|
1835
|
+
function neoScriptMemberLookupType(type) {
|
|
1836
|
+
if (type.kind !== "typeParameter") return type;
|
|
1837
|
+
const visited = /* @__PURE__ */ new Set();
|
|
1838
|
+
let current = type;
|
|
1839
|
+
let nullable = type.nullable === true;
|
|
1840
|
+
while (current.kind === "typeParameter") {
|
|
1841
|
+
if (visited.has(current.id) || current.constraint === void 0) {
|
|
1842
|
+
return type;
|
|
1843
|
+
}
|
|
1844
|
+
visited.add(current.id);
|
|
1845
|
+
nullable ||= current.constraint.nullable === true;
|
|
1846
|
+
current = current.constraint;
|
|
1847
|
+
}
|
|
1848
|
+
return nullable && current.nullable !== true ? { ...current, nullable: true } : current;
|
|
1849
|
+
}
|
|
1835
1850
|
function neoScriptParameterIsOmittable(parameter4) {
|
|
1836
1851
|
return parameter4.defaultValue !== void 0;
|
|
1837
1852
|
}
|
|
@@ -3160,7 +3175,8 @@ function completionItemsForResolution(snapshot, resolved, word) {
|
|
|
3160
3175
|
(member) => member.static === true && isMemberCompletionAccessible(snapshot, staticType, member)
|
|
3161
3176
|
).map((member) => symbolCompletion(member, word, snapshot));
|
|
3162
3177
|
}
|
|
3163
|
-
const
|
|
3178
|
+
const memberType2 = neoScriptMemberLookupType(resolved.type);
|
|
3179
|
+
const owner = memberType2.kind === "named" ? snapshot.project.typeById.get(memberType2.typeId) : void 0;
|
|
3164
3180
|
return membersForType(snapshot, resolved.type).filter(
|
|
3165
3181
|
(symbol) => owner === void 0 || isMemberCompletionAccessible(snapshot, owner, symbol)
|
|
3166
3182
|
).map((symbol) => symbolCompletion(symbol, word, snapshot));
|
|
@@ -3174,6 +3190,17 @@ function isMemberCompletionAccessible(snapshot, owner, symbol) {
|
|
|
3174
3190
|
}) === null;
|
|
3175
3191
|
}
|
|
3176
3192
|
function membersForType(snapshot, type) {
|
|
3193
|
+
const memberType2 = neoScriptMemberLookupType(type);
|
|
3194
|
+
if (memberType2 !== type) {
|
|
3195
|
+
const members = [...membersForType(snapshot, memberType2)];
|
|
3196
|
+
if (type.kind !== "typeParameter" || type.nullable === true) return members;
|
|
3197
|
+
const named = memberType2.kind === "named" ? snapshot.project.typeById.get(memberType2.typeId) : void 0;
|
|
3198
|
+
if (named?.kind !== "class") return members;
|
|
3199
|
+
const cloneId = `builtin:${named.id}:Clone`;
|
|
3200
|
+
return members.map(
|
|
3201
|
+
(member) => member.id === cloneId ? cloneSymbol(named, type) : member
|
|
3202
|
+
);
|
|
3203
|
+
}
|
|
3177
3204
|
if (type.kind === "named") {
|
|
3178
3205
|
const named = snapshot.project.typeById.get(type.typeId);
|
|
3179
3206
|
if (!named) return [];
|
|
@@ -3950,13 +3977,13 @@ function stringContainsSymbol() {
|
|
|
3950
3977
|
"Returns true when the string contains the substring."
|
|
3951
3978
|
);
|
|
3952
3979
|
}
|
|
3953
|
-
function cloneSymbol(type) {
|
|
3980
|
+
function cloneSymbol(type, returnType = { kind: "named", typeId: type.id }) {
|
|
3954
3981
|
return {
|
|
3955
3982
|
id: `builtin:${type.id}:Clone`,
|
|
3956
3983
|
name: "Clone",
|
|
3957
3984
|
kind: "method",
|
|
3958
|
-
type:
|
|
3959
|
-
returnType
|
|
3985
|
+
type: returnType,
|
|
3986
|
+
returnType,
|
|
3960
3987
|
parameters: [],
|
|
3961
3988
|
documentation: `Deep-copy this ${type.name} into a new parentless writable value.`
|
|
3962
3989
|
};
|
|
@@ -11871,11 +11898,12 @@ var init_strict_resolver = __esm({
|
|
|
11871
11898
|
pos
|
|
11872
11899
|
);
|
|
11873
11900
|
}
|
|
11874
|
-
|
|
11875
|
-
|
|
11901
|
+
const memberReceiverType = neoScriptMemberLookupType(receiver.type);
|
|
11902
|
+
if (memberReceiverType.kind === "named") {
|
|
11903
|
+
const type = this.project.typeById.get(memberReceiverType.typeId);
|
|
11876
11904
|
if (!type) {
|
|
11877
11905
|
throw new CompileError(
|
|
11878
|
-
`Type ${
|
|
11906
|
+
`Type ${memberReceiverType.typeId} was not found in the project.`,
|
|
11879
11907
|
pos
|
|
11880
11908
|
);
|
|
11881
11909
|
}
|
|
@@ -11909,7 +11937,7 @@ var init_strict_resolver = __esm({
|
|
|
11909
11937
|
}
|
|
11910
11938
|
const memberType2 = substituteTypeParameters(
|
|
11911
11939
|
member.type,
|
|
11912
|
-
|
|
11940
|
+
memberReceiverType,
|
|
11913
11941
|
type
|
|
11914
11942
|
);
|
|
11915
11943
|
if (member.computed === true) {
|
|
@@ -12350,8 +12378,9 @@ var init_strict_resolver = __esm({
|
|
|
12350
12378
|
pos
|
|
12351
12379
|
);
|
|
12352
12380
|
}
|
|
12353
|
-
|
|
12354
|
-
|
|
12381
|
+
const memberReceiverType = neoScriptMemberLookupType(receiver.type);
|
|
12382
|
+
if (memberReceiverType.kind === "named") {
|
|
12383
|
+
const type = this.project.typeById.get(memberReceiverType.typeId);
|
|
12355
12384
|
const member = type?.members.find(
|
|
12356
12385
|
(candidate) => (candidate.kind === "function" || candidate.kind === "method") && candidate.name === callee.name
|
|
12357
12386
|
);
|
|
@@ -12365,7 +12394,10 @@ var init_strict_resolver = __esm({
|
|
|
12365
12394
|
}
|
|
12366
12395
|
return this.resolveSymbolCall(
|
|
12367
12396
|
member,
|
|
12368
|
-
{
|
|
12397
|
+
{
|
|
12398
|
+
kind: "instance",
|
|
12399
|
+
expression: memberReceiverType === receiver.type ? receiver : { ...receiver, type: memberReceiverType }
|
|
12400
|
+
},
|
|
12369
12401
|
argumentsList2,
|
|
12370
12402
|
scope,
|
|
12371
12403
|
pos,
|
|
@@ -12385,7 +12417,7 @@ var init_strict_resolver = __esm({
|
|
|
12385
12417
|
pos
|
|
12386
12418
|
);
|
|
12387
12419
|
}
|
|
12388
|
-
const schemaClass2 = toWireType(
|
|
12420
|
+
const schemaClass2 = toWireType(memberReceiverType, this.project);
|
|
12389
12421
|
return {
|
|
12390
12422
|
pointer: {
|
|
12391
12423
|
type: "function" /* Function */,
|
|
@@ -110651,7 +110683,7 @@ var init_registry2 = __esm({
|
|
|
110651
110683
|
PROJECT_SCHEMA_CONTRACT = Object.freeze({
|
|
110652
110684
|
formatVersion: 3,
|
|
110653
110685
|
contractVersion: "3.12",
|
|
110654
|
-
cliVersion: "0.31.
|
|
110686
|
+
cliVersion: "0.31.5",
|
|
110655
110687
|
projectFileUploadBatchSize: 32,
|
|
110656
110688
|
documentRecords: {
|
|
110657
110689
|
member: {
|
|
@@ -117246,7 +117278,7 @@ There is no --keep-current: preserving current semantic state defines flatten.
|
|
|
117246
117278
|
async function main() {
|
|
117247
117279
|
const args = parseArgs(process.argv.slice(2));
|
|
117248
117280
|
if (args.command === "--version") {
|
|
117249
|
-
console.log("0.31.
|
|
117281
|
+
console.log("0.31.5");
|
|
117250
117282
|
return;
|
|
117251
117283
|
}
|
|
117252
117284
|
if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {
|
package/package.json
CHANGED
|
@@ -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.31.
|
|
86
|
+
<!-- reviewed-through-cli: 0.31.5 -->
|
|
87
87
|
```
|
|
88
88
|
|
|
89
89
|
The quoted version above is checked too, so this instruction cannot go stale
|