@neocompose/cli 0.27.1 → 0.28.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/dist/neo.mjs
CHANGED
|
@@ -1813,6 +1813,9 @@ var init_generated_csharp_identifiers = __esm({
|
|
|
1813
1813
|
});
|
|
1814
1814
|
|
|
1815
1815
|
// ../packages/neoscript-language/src/project.ts
|
|
1816
|
+
function neoScriptParameterIsOmittable(parameter4) {
|
|
1817
|
+
return parameter4.defaultValue !== void 0;
|
|
1818
|
+
}
|
|
1816
1819
|
function neoScriptRequiredConstructor(type) {
|
|
1817
1820
|
return type?.declaredConstructors?.find(
|
|
1818
1821
|
(candidate) => candidate.required === true
|
|
@@ -1820,7 +1823,7 @@ function neoScriptRequiredConstructor(type) {
|
|
|
1820
1823
|
}
|
|
1821
1824
|
function neoScriptParameterlessConstructor(type) {
|
|
1822
1825
|
return type.declaredConstructors?.find(
|
|
1823
|
-
(candidate) => candidate.parameters.
|
|
1826
|
+
(candidate) => candidate.parameters.every(neoScriptParameterIsOmittable)
|
|
1824
1827
|
) ?? null;
|
|
1825
1828
|
}
|
|
1826
1829
|
function isNeoScriptConstructionDocumentKind(kind) {
|
|
@@ -2357,11 +2360,11 @@ function signatureHelp(snapshot, position) {
|
|
|
2357
2360
|
return {
|
|
2358
2361
|
signatures: declared.map((candidate) => ({
|
|
2359
2362
|
label: `${type.name}(${candidate.parameters.map(
|
|
2360
|
-
(parameter4) => `${formatType(parameter4.type, snapshot.project)} ${parameter4.name}`
|
|
2363
|
+
(parameter4) => `${formatType(parameter4.type, snapshot.project)} ${parameter4.name}${parameterDefaultSuffix(parameter4)}`
|
|
2361
2364
|
).join(", ")})`,
|
|
2362
2365
|
...candidate.documentation ? { documentation: candidate.documentation } : {},
|
|
2363
2366
|
parameters: candidate.parameters.map((parameter4) => ({
|
|
2364
|
-
label: `${formatType(parameter4.type, snapshot.project)} ${parameter4.name}`,
|
|
2367
|
+
label: `${formatType(parameter4.type, snapshot.project)} ${parameter4.name}${parameterDefaultSuffix(parameter4)}`,
|
|
2365
2368
|
...parameter4.documentation ? { documentation: parameter4.documentation } : {}
|
|
2366
2369
|
}))
|
|
2367
2370
|
})),
|
|
@@ -2404,7 +2407,7 @@ function signatureHelp(snapshot, position) {
|
|
|
2404
2407
|
label: formatSymbolSignature(symbol, snapshot.project),
|
|
2405
2408
|
...symbol.documentation ? { documentation: symbol.documentation } : {},
|
|
2406
2409
|
parameters: symbol.parameters.map((parameter4) => ({
|
|
2407
|
-
label: `${formatType(parameter4.type, snapshot.project)} ${parameter4.name}`,
|
|
2410
|
+
label: `${formatType(parameter4.type, snapshot.project)} ${parameter4.name}${parameterDefaultSuffix(parameter4)}`,
|
|
2408
2411
|
...parameter4.documentation ? { documentation: parameter4.documentation } : {}
|
|
2409
2412
|
}))
|
|
2410
2413
|
}
|
|
@@ -4140,9 +4143,14 @@ function displaySymbolKind(symbol) {
|
|
|
4140
4143
|
}
|
|
4141
4144
|
return symbol.kind.charAt(0).toUpperCase() + symbol.kind.slice(1);
|
|
4142
4145
|
}
|
|
4146
|
+
function parameterDefaultSuffix(parameter4) {
|
|
4147
|
+
return parameter4.defaultValue === void 0 ? "" : ` = ${parameter4.defaultValue.displayText}`;
|
|
4148
|
+
}
|
|
4143
4149
|
function formatSymbolSignature(symbol, project) {
|
|
4144
4150
|
if (symbol.parameters !== void 0) {
|
|
4145
|
-
const parameters = symbol.parameters.map(
|
|
4151
|
+
const parameters = symbol.parameters.map(
|
|
4152
|
+
(item) => `${formatType(item.type, project)} ${item.name}${parameterDefaultSuffix(item)}`
|
|
4153
|
+
).join(", ");
|
|
4146
4154
|
const returnType = symbol.returnType ?? symbol.type;
|
|
4147
4155
|
const deferred = symbol.deferred ? "Task<" : "";
|
|
4148
4156
|
const end = symbol.deferred ? ">" : "";
|
|
@@ -7323,11 +7331,24 @@ var init_strict_parser = __esm({
|
|
|
7323
7331
|
function neoScriptArgumentNameSetKey(names) {
|
|
7324
7332
|
return [...names].map((name) => name.toLowerCase()).sort().join(",");
|
|
7325
7333
|
}
|
|
7326
|
-
function
|
|
7327
|
-
|
|
7328
|
-
|
|
7334
|
+
function neoScriptCallMatchesParameters(suppliedNames, parameters) {
|
|
7335
|
+
const supplied = new Set(suppliedNames.map((name) => name.toLowerCase()));
|
|
7336
|
+
const declared = new Set(
|
|
7337
|
+
parameters.map((parameter4) => parameter4.name.toLowerCase())
|
|
7338
|
+
);
|
|
7339
|
+
for (const name of supplied) {
|
|
7340
|
+
if (!declared.has(name)) return false;
|
|
7341
|
+
}
|
|
7342
|
+
return parameters.every(
|
|
7343
|
+
(parameter4) => parameter4.defaulted || supplied.has(parameter4.name.toLowerCase())
|
|
7329
7344
|
);
|
|
7330
7345
|
}
|
|
7346
|
+
function callableShape(parameters) {
|
|
7347
|
+
return parameters.map((parameter4) => ({
|
|
7348
|
+
name: parameter4.name,
|
|
7349
|
+
defaulted: neoScriptParameterIsOmittable(parameter4)
|
|
7350
|
+
}));
|
|
7351
|
+
}
|
|
7331
7352
|
function neoScriptPositionalTypeKey(type) {
|
|
7332
7353
|
switch (type.kind) {
|
|
7333
7354
|
case "primitive":
|
|
@@ -7385,8 +7406,108 @@ function validateNeoScriptOverloadSignatures(className, signatures) {
|
|
|
7385
7406
|
message: `Class '${className}' declares constructors (${parameterLists.join(") and (")}) that differ only by parameter name; generated C# would emit the same constructor signature twice.`
|
|
7386
7407
|
});
|
|
7387
7408
|
}
|
|
7409
|
+
errors.push(...defaultedTieErrors(className, signatures));
|
|
7410
|
+
errors.push(...effectiveArityCollisionErrors(className, signatures));
|
|
7411
|
+
return errors;
|
|
7412
|
+
}
|
|
7413
|
+
function defaultedTieErrors(className, signatures) {
|
|
7414
|
+
const errors = [];
|
|
7415
|
+
for (let first = 0; first < signatures.length; first += 1) {
|
|
7416
|
+
for (let second = first + 1; second < signatures.length; second += 1) {
|
|
7417
|
+
const left = signatures[first];
|
|
7418
|
+
const right = signatures[second];
|
|
7419
|
+
if (left === void 0 || right === void 0) continue;
|
|
7420
|
+
if (namedSignatureKey(left) === namedSignatureKey(right)) continue;
|
|
7421
|
+
if (left.parameters.length !== right.parameters.length) continue;
|
|
7422
|
+
const leftHasDefault = left.parameters.some(
|
|
7423
|
+
(parameter4) => parameter4.defaulted === true
|
|
7424
|
+
);
|
|
7425
|
+
const rightHasDefault = right.parameters.some(
|
|
7426
|
+
(parameter4) => parameter4.defaulted === true
|
|
7427
|
+
);
|
|
7428
|
+
if (!leftHasDefault && !rightHasDefault) continue;
|
|
7429
|
+
const tyingCall = tyingCallNames(left, right);
|
|
7430
|
+
if (tyingCall === null) continue;
|
|
7431
|
+
const callDescription = tyingCall.length === 0 ? "`new()`" : `\`new(${tyingCall.join(": \u2026, ")}: \u2026)\``;
|
|
7432
|
+
errors.push({
|
|
7433
|
+
kind: "duplicateNameSet",
|
|
7434
|
+
constructorIds: [left.id, right.id],
|
|
7435
|
+
message: `Class '${className}' declares constructors (${describeSignatureParameters(left)}) and (${describeSignatureParameters(right)}) that the call ${callDescription} would match with the same number of defaulted fill-ins and the same argument types; no call site could resolve between them.`
|
|
7436
|
+
});
|
|
7437
|
+
}
|
|
7438
|
+
}
|
|
7439
|
+
return errors;
|
|
7440
|
+
}
|
|
7441
|
+
function tyingCallNames(left, right) {
|
|
7442
|
+
const leftTypes = new Map(
|
|
7443
|
+
left.parameters.map((parameter4) => [
|
|
7444
|
+
parameter4.name.toLowerCase(),
|
|
7445
|
+
parameter4.typeKey
|
|
7446
|
+
])
|
|
7447
|
+
);
|
|
7448
|
+
const rightTypes = new Map(
|
|
7449
|
+
right.parameters.map((parameter4) => [
|
|
7450
|
+
parameter4.name.toLowerCase(),
|
|
7451
|
+
parameter4.typeKey
|
|
7452
|
+
])
|
|
7453
|
+
);
|
|
7454
|
+
const tying = /* @__PURE__ */ new Map();
|
|
7455
|
+
for (const parameter4 of [...left.parameters, ...right.parameters]) {
|
|
7456
|
+
if (parameter4.defaulted === true) continue;
|
|
7457
|
+
tying.set(parameter4.name.toLowerCase(), parameter4.name);
|
|
7458
|
+
}
|
|
7459
|
+
for (const name of tying.keys()) {
|
|
7460
|
+
const leftType = leftTypes.get(name);
|
|
7461
|
+
const rightType = rightTypes.get(name);
|
|
7462
|
+
if (leftType === void 0) return null;
|
|
7463
|
+
if (rightType === void 0) return null;
|
|
7464
|
+
if (leftType !== rightType) return null;
|
|
7465
|
+
}
|
|
7466
|
+
return [...tying.values()];
|
|
7467
|
+
}
|
|
7468
|
+
function effectiveArityCollisionErrors(className, signatures) {
|
|
7469
|
+
const errors = [];
|
|
7470
|
+
const byEffectiveKey = /* @__PURE__ */ new Map();
|
|
7471
|
+
for (const signature of signatures) {
|
|
7472
|
+
const minimumArity = signature.parameters.filter(
|
|
7473
|
+
(parameter4) => parameter4.defaulted !== true
|
|
7474
|
+
).length;
|
|
7475
|
+
for (let arity = minimumArity; arity <= signature.parameters.length; arity += 1) {
|
|
7476
|
+
const key = signature.parameters.slice(0, arity).map((parameter4) => parameter4.typeKey).join(",");
|
|
7477
|
+
byEffectiveKey.set(key, [
|
|
7478
|
+
...byEffectiveKey.get(key) ?? [],
|
|
7479
|
+
{ signature, arity }
|
|
7480
|
+
]);
|
|
7481
|
+
}
|
|
7482
|
+
}
|
|
7483
|
+
const reportedPairs = /* @__PURE__ */ new Set();
|
|
7484
|
+
for (const entries of byEffectiveKey.values()) {
|
|
7485
|
+
if (entries.length < 2) continue;
|
|
7486
|
+
const shortened = entries.some(
|
|
7487
|
+
(entry) => entry.arity < entry.signature.parameters.length
|
|
7488
|
+
);
|
|
7489
|
+
if (!shortened) continue;
|
|
7490
|
+
const ids = entries.map((entry) => entry.signature.id);
|
|
7491
|
+
const pairKey = [...ids].sort().join("|");
|
|
7492
|
+
if (reportedPairs.has(pairKey)) continue;
|
|
7493
|
+
reportedPairs.add(pairKey);
|
|
7494
|
+
const parameterLists = entries.map(
|
|
7495
|
+
(entry) => describeSignatureParameters(entry.signature)
|
|
7496
|
+
);
|
|
7497
|
+
errors.push({
|
|
7498
|
+
kind: "positionalCollision",
|
|
7499
|
+
constructorIds: ids,
|
|
7500
|
+
message: `Class '${className}' declares constructors (${parameterLists.join(") and (")}) that expose the same C# positional signature once defaulted parameters are omitted; C# would resolve the shared arity differently from NeoScript's named overloads.`
|
|
7501
|
+
});
|
|
7502
|
+
}
|
|
7388
7503
|
return errors;
|
|
7389
7504
|
}
|
|
7505
|
+
function describeSignatureParameters(signature) {
|
|
7506
|
+
return signature.parameters.map((parameter4) => {
|
|
7507
|
+
const defaulted = parameter4.defaulted === true ? " = \u2026" : "";
|
|
7508
|
+
return `${parameter4.name}${defaulted}`;
|
|
7509
|
+
}).join(", ");
|
|
7510
|
+
}
|
|
7390
7511
|
function namedSignatureKey(signature) {
|
|
7391
7512
|
return [...signature.parameters].map((parameter4) => `${parameter4.name.toLowerCase()}:${parameter4.typeKey}`).sort().join(",");
|
|
7392
7513
|
}
|
|
@@ -7397,23 +7518,35 @@ function validateNeoScriptDeclaredConstructorOverloads(className, constructors)
|
|
|
7397
7518
|
id: constructor2.id,
|
|
7398
7519
|
parameters: constructor2.parameters.map((parameter4) => ({
|
|
7399
7520
|
name: parameter4.name,
|
|
7400
|
-
typeKey: neoScriptPositionalTypeKey(parameter4.type)
|
|
7521
|
+
typeKey: neoScriptPositionalTypeKey(parameter4.type),
|
|
7522
|
+
defaulted: parameter4.defaultValue !== void 0
|
|
7401
7523
|
}))
|
|
7402
7524
|
}))
|
|
7403
7525
|
);
|
|
7404
7526
|
}
|
|
7405
7527
|
function resolveNeoScriptDeclaredConstructorOverload(constructors, args) {
|
|
7406
|
-
const
|
|
7407
|
-
const
|
|
7408
|
-
(constructor2) =>
|
|
7528
|
+
const suppliedNames = args.map((entry) => entry.name);
|
|
7529
|
+
const applicable = constructors.filter(
|
|
7530
|
+
(constructor2) => neoScriptCallMatchesParameters(
|
|
7531
|
+
suppliedNames,
|
|
7532
|
+
callableShape(constructor2.parameters)
|
|
7533
|
+
)
|
|
7534
|
+
);
|
|
7535
|
+
if (applicable.length === 0) return { kind: "noMatch" };
|
|
7536
|
+
const fewestFillIns = Math.min(
|
|
7537
|
+
...applicable.map(
|
|
7538
|
+
(constructor2) => constructor2.parameters.length - args.length
|
|
7539
|
+
)
|
|
7409
7540
|
);
|
|
7410
|
-
|
|
7411
|
-
|
|
7412
|
-
|
|
7541
|
+
const best = applicable.filter(
|
|
7542
|
+
(constructor2) => constructor2.parameters.length - args.length === fewestFillIns
|
|
7543
|
+
);
|
|
7544
|
+
if (best.length === 1) {
|
|
7545
|
+
const only = best[0];
|
|
7413
7546
|
if (!only) return { kind: "noMatch" };
|
|
7414
7547
|
return { kind: "resolved", constructor: only };
|
|
7415
7548
|
}
|
|
7416
|
-
const byType =
|
|
7549
|
+
const byType = best.filter(
|
|
7417
7550
|
(constructor2) => args.every((argument2) => {
|
|
7418
7551
|
const parameter4 = constructor2.parameters.find(
|
|
7419
7552
|
(candidate) => candidate.name.toLowerCase() === argument2.name.toLowerCase()
|
|
@@ -7428,17 +7561,23 @@ function resolveNeoScriptDeclaredConstructorOverload(constructors, args) {
|
|
|
7428
7561
|
if (!only) return { kind: "noMatch" };
|
|
7429
7562
|
return { kind: "resolved", constructor: only };
|
|
7430
7563
|
}
|
|
7431
|
-
if (byType.length === 0) return { kind: "ambiguous", candidates:
|
|
7564
|
+
if (byType.length === 0) return { kind: "ambiguous", candidates: best };
|
|
7432
7565
|
return { kind: "ambiguous", candidates: byType };
|
|
7433
7566
|
}
|
|
7434
7567
|
function describeNeoScriptDeclaredConstructors(className, constructors) {
|
|
7435
7568
|
return constructors.map(
|
|
7436
|
-
(constructor2) => `${className}(${constructor2.parameters.map(
|
|
7569
|
+
(constructor2) => `${className}(${constructor2.parameters.map(describeParameter).join(", ")})`
|
|
7437
7570
|
).join(", ");
|
|
7438
7571
|
}
|
|
7572
|
+
function describeParameter(parameter4) {
|
|
7573
|
+
const nullability = parameter4.required ? "" : "?";
|
|
7574
|
+
const defaulted = parameter4.defaultValue === void 0 ? "" : ` = ${parameter4.defaultValue.displayText}`;
|
|
7575
|
+
return `${parameter4.name}${nullability}${defaulted}`;
|
|
7576
|
+
}
|
|
7439
7577
|
var init_declared_constructors = __esm({
|
|
7440
7578
|
"../packages/neoscript-language/src/declared-constructors.ts"() {
|
|
7441
7579
|
"use strict";
|
|
7580
|
+
init_project();
|
|
7442
7581
|
}
|
|
7443
7582
|
});
|
|
7444
7583
|
|
|
@@ -8829,6 +8968,12 @@ function collectReturns(statements) {
|
|
|
8829
8968
|
}
|
|
8830
8969
|
return result;
|
|
8831
8970
|
}
|
|
8971
|
+
function functionArityMessage(name, minimum, maximum, got) {
|
|
8972
|
+
if (minimum === maximum) {
|
|
8973
|
+
return `Function '${name}' expects ${maximum} argument${maximum === 1 ? "" : "s"}, got ${got}.`;
|
|
8974
|
+
}
|
|
8975
|
+
return `Function '${name}' expects between ${minimum} and ${maximum} arguments, got ${got}.`;
|
|
8976
|
+
}
|
|
8832
8977
|
function requireArgCount(name, args, expected, pos) {
|
|
8833
8978
|
if (args.length === expected) return;
|
|
8834
8979
|
throw new CompileError(
|
|
@@ -12673,9 +12818,28 @@ var init_strict_resolver = __esm({
|
|
|
12673
12818
|
}));
|
|
12674
12819
|
}
|
|
12675
12820
|
}
|
|
12676
|
-
|
|
12821
|
+
const minimumArguments = parameters.filter(
|
|
12822
|
+
(parameter4) => !neoScriptParameterIsOmittable(parameter4)
|
|
12823
|
+
).length;
|
|
12824
|
+
if (argumentsList2.length < minimumArguments) {
|
|
12677
12825
|
throw new CompileError(
|
|
12678
|
-
|
|
12826
|
+
functionArityMessage(
|
|
12827
|
+
symbol.name,
|
|
12828
|
+
minimumArguments,
|
|
12829
|
+
parameters.length,
|
|
12830
|
+
argumentsList2.length
|
|
12831
|
+
),
|
|
12832
|
+
pos
|
|
12833
|
+
);
|
|
12834
|
+
}
|
|
12835
|
+
if (argumentsList2.length > parameters.length) {
|
|
12836
|
+
throw new CompileError(
|
|
12837
|
+
functionArityMessage(
|
|
12838
|
+
symbol.name,
|
|
12839
|
+
minimumArguments,
|
|
12840
|
+
parameters.length,
|
|
12841
|
+
argumentsList2.length
|
|
12842
|
+
),
|
|
12679
12843
|
pos
|
|
12680
12844
|
);
|
|
12681
12845
|
}
|
|
@@ -16595,12 +16759,25 @@ var init_project_source_parser = __esm({
|
|
|
16595
16759
|
const annotations = this.parseAnnotations();
|
|
16596
16760
|
const type = this.parseType();
|
|
16597
16761
|
const name = this.expectName("parameter name");
|
|
16762
|
+
let defaultValue;
|
|
16763
|
+
if (this.eat("=")) {
|
|
16764
|
+
const expressionStart = this.peek();
|
|
16765
|
+
defaultValue = this.captureUntilTopLevel(/* @__PURE__ */ new Set([",", ")"]), false);
|
|
16766
|
+
if (defaultValue.text.trim().length === 0) {
|
|
16767
|
+
throw this.failure(
|
|
16768
|
+
"missing-parameter-default",
|
|
16769
|
+
`Parameter '${name.text}' declares '=' but no default value. Provide a constant expression or remove the '='.`,
|
|
16770
|
+
expressionStart
|
|
16771
|
+
);
|
|
16772
|
+
}
|
|
16773
|
+
}
|
|
16598
16774
|
parameters.push({
|
|
16599
16775
|
annotations,
|
|
16600
16776
|
type,
|
|
16601
16777
|
name: name.text,
|
|
16602
16778
|
nameRange: name.range,
|
|
16603
|
-
|
|
16779
|
+
...defaultValue ? { defaultValue } : {},
|
|
16780
|
+
range: rangeFrom(start, this.previous())
|
|
16604
16781
|
});
|
|
16605
16782
|
if (!this.eat(",") && !this.at(")")) {
|
|
16606
16783
|
throw this.failure(
|
|
@@ -17173,7 +17350,7 @@ var init_project_schema_contract_generated = __esm({
|
|
|
17173
17350
|
"../packages/neoscript-language/src/project-schema-contract.generated.ts"() {
|
|
17174
17351
|
"use strict";
|
|
17175
17352
|
PROJECT_SCHEMA_MANIFEST_FORMAT_VERSION = 3;
|
|
17176
|
-
PROJECT_SCHEMA_MANIFEST_CONTRACT_VERSION = "3.
|
|
17353
|
+
PROJECT_SCHEMA_MANIFEST_CONTRACT_VERSION = "3.10";
|
|
17177
17354
|
PROJECT_FILE_UPLOAD_BATCH_SIZE = 32;
|
|
17178
17355
|
NEO_PROJECT_SOURCE_RECORD_CONTRACT = {
|
|
17179
17356
|
"recordFields": {
|
|
@@ -19272,6 +19449,24 @@ var init_project_source_construction_diagnostics = __esm({
|
|
|
19272
19449
|
"unbound-constructor-argument": "error",
|
|
19273
19450
|
/** §2.6. No overload's parameter-name set matches the call. */
|
|
19274
19451
|
"no-matching-constructor-overload": "error",
|
|
19452
|
+
/**
|
|
19453
|
+
* P65 §2.2. Two overload candidates tie under the subset match after the
|
|
19454
|
+
* fewest-fill-ins betterness and the type tie-break; the message lists the
|
|
19455
|
+
* candidates the call could not choose between.
|
|
19456
|
+
*/
|
|
19457
|
+
"ambiguous-constructor-call": "error",
|
|
19458
|
+
/**
|
|
19459
|
+
* P65 §1.3. A defaulted parameter declared before a non-defaulted one.
|
|
19460
|
+
* The code string is shared with `src/models/neoscript/parameter-defaults.ts`
|
|
19461
|
+
* so the push guards and the compiler name one rule identically.
|
|
19462
|
+
*/
|
|
19463
|
+
"default-before-required-parameter": "error",
|
|
19464
|
+
/**
|
|
19465
|
+
* P65 §1.2. A parameter default that does not fit the parameter's declared
|
|
19466
|
+
* type — a `null` default on a non-nullable parameter included. Shared with
|
|
19467
|
+
* the push-guard validator, like the placement code above.
|
|
19468
|
+
*/
|
|
19469
|
+
"parameter-default-type-mismatch": "error",
|
|
19275
19470
|
/** §2.5 g. An initializer key naming no member of the constructed class. */
|
|
19276
19471
|
"unknown-initializer-member": "error",
|
|
19277
19472
|
/**
|
|
@@ -19541,9 +19736,13 @@ function resolveInvokedConstructor(declaration, call, diagnostics) {
|
|
|
19541
19736
|
return true;
|
|
19542
19737
|
}
|
|
19543
19738
|
if (headerParameters.length === 0) return true;
|
|
19739
|
+
if (parameterListIsFullyDefaulted(headerParameters)) return true;
|
|
19740
|
+
const mandatory = headerParameters.filter(
|
|
19741
|
+
(parameter4) => parameter4.defaultValue === void 0
|
|
19742
|
+
);
|
|
19544
19743
|
diagnostics.push({
|
|
19545
19744
|
code: "required-constructor-not-invoked",
|
|
19546
|
-
message: `Class '${declaration.name}' declares the required constructor ${describeParameterList(declaration.name, headerParameters)}, so it cannot be constructed without passing ${describeNameList(
|
|
19745
|
+
message: `Class '${declaration.name}' declares the required constructor ${describeParameterList(declaration.name, headerParameters)}, so it cannot be constructed without passing ${describeNameList(mandatory.map((parameter4) => parameter4.name))}.`,
|
|
19547
19746
|
anchor: { kind: "site" }
|
|
19548
19747
|
});
|
|
19549
19748
|
return true;
|
|
@@ -19553,7 +19752,7 @@ function resolveInvokedConstructor(declaration, call, diagnostics) {
|
|
|
19553
19752
|
}
|
|
19554
19753
|
if (call.argumentNames.length === 0) {
|
|
19555
19754
|
return declaration.constructors.some(
|
|
19556
|
-
(constructor2) => constructor2.parameters
|
|
19755
|
+
(constructor2) => parameterListIsFullyDefaulted(constructor2.parameters)
|
|
19557
19756
|
);
|
|
19558
19757
|
}
|
|
19559
19758
|
if (declaration.constructors.length === 1) {
|
|
@@ -19565,13 +19764,17 @@ function resolveInvokedConstructor(declaration, call, diagnostics) {
|
|
|
19565
19764
|
);
|
|
19566
19765
|
return true;
|
|
19567
19766
|
}
|
|
19568
|
-
const
|
|
19569
|
-
|
|
19767
|
+
const suppliedNames = call.argumentNames.filter(
|
|
19768
|
+
(name) => name !== null
|
|
19570
19769
|
);
|
|
19571
19770
|
const matches = declaration.constructors.filter(
|
|
19572
|
-
(constructor2) =>
|
|
19573
|
-
|
|
19574
|
-
|
|
19771
|
+
(constructor2) => neoScriptCallMatchesParameters(
|
|
19772
|
+
suppliedNames,
|
|
19773
|
+
constructor2.parameters.map((parameter4) => ({
|
|
19774
|
+
name: parameter4.name,
|
|
19775
|
+
defaulted: parameter4.defaultValue !== void 0
|
|
19776
|
+
}))
|
|
19777
|
+
)
|
|
19575
19778
|
);
|
|
19576
19779
|
if (matches.length > 0) return true;
|
|
19577
19780
|
diagnostics.push({
|
|
@@ -19606,7 +19809,7 @@ function validateArgumentsAgainstParameters(className, parameters, call, diagnos
|
|
|
19606
19809
|
});
|
|
19607
19810
|
});
|
|
19608
19811
|
const missing = parameters.filter(
|
|
19609
|
-
(parameter4) => !supplied.has(parameter4.name.toLowerCase())
|
|
19812
|
+
(parameter4) => parameter4.defaultValue === void 0 && !supplied.has(parameter4.name.toLowerCase())
|
|
19610
19813
|
);
|
|
19611
19814
|
if (missing.length === 0) return;
|
|
19612
19815
|
diagnostics.push({
|
|
@@ -19615,6 +19818,9 @@ function validateArgumentsAgainstParameters(className, parameters, call, diagnos
|
|
|
19615
19818
|
anchor: { kind: "site" }
|
|
19616
19819
|
});
|
|
19617
19820
|
}
|
|
19821
|
+
function parameterListIsFullyDefaulted(parameters) {
|
|
19822
|
+
return parameters.every((parameter4) => parameter4.defaultValue !== void 0);
|
|
19823
|
+
}
|
|
19618
19824
|
function validateInitializerEntries(index, entry, call, diagnostics) {
|
|
19619
19825
|
if (call.initializerNames.length === 0) return;
|
|
19620
19826
|
const chain = baseChain(index, entry);
|
|
@@ -19746,13 +19952,12 @@ function substitute(type, bindings) {
|
|
|
19746
19952
|
arguments: type.arguments.map((argument2) => substitute(argument2, bindings))
|
|
19747
19953
|
};
|
|
19748
19954
|
}
|
|
19749
|
-
function argumentNameSetKey(names) {
|
|
19750
|
-
return [...names].map((name) => name.toLowerCase()).sort().join(",");
|
|
19751
|
-
}
|
|
19752
19955
|
function describeParameterList(className, parameters) {
|
|
19753
|
-
const rendered = parameters.map(
|
|
19754
|
-
|
|
19755
|
-
|
|
19956
|
+
const rendered = parameters.map((parameter4) => {
|
|
19957
|
+
const nullability = parameter4.type.nullable ? "?" : "";
|
|
19958
|
+
const defaulted = parameter4.defaultValue === void 0 ? "" : ` = ${parameter4.defaultValue.text}`;
|
|
19959
|
+
return `${parameter4.name}${nullability}${defaulted}`;
|
|
19960
|
+
}).join(", ");
|
|
19756
19961
|
return `${className}(${rendered})`;
|
|
19757
19962
|
}
|
|
19758
19963
|
function describeNameList(names) {
|
|
@@ -19781,6 +19986,7 @@ function push(diagnostics, uri, range2, code, message, related2 = []) {
|
|
|
19781
19986
|
var init_project_source_settlement = __esm({
|
|
19782
19987
|
"../packages/neoscript-language/src/project-source-settlement.ts"() {
|
|
19783
19988
|
"use strict";
|
|
19989
|
+
init_declared_constructors();
|
|
19784
19990
|
init_project_source_construction_diagnostics();
|
|
19785
19991
|
init_strict_compile_error();
|
|
19786
19992
|
init_strict_parser();
|
|
@@ -24443,6 +24649,223 @@ var init_project_source_type_checker = __esm({
|
|
|
24443
24649
|
}
|
|
24444
24650
|
});
|
|
24445
24651
|
|
|
24652
|
+
// ../packages/neoscript-language/src/project-source-parameter-defaults.ts
|
|
24653
|
+
function validateProjectSourceParameterDefaults(documents) {
|
|
24654
|
+
const diagnostics = [];
|
|
24655
|
+
const enumOptions = collectEnumOptions(documents);
|
|
24656
|
+
for (const [uri, document] of documents) {
|
|
24657
|
+
for (const declaration of document.declarations) {
|
|
24658
|
+
if (declaration.kind === "class") {
|
|
24659
|
+
if (declaration.headerParameters !== void 0) {
|
|
24660
|
+
validateParameterList(
|
|
24661
|
+
uri,
|
|
24662
|
+
declaration.headerParameters,
|
|
24663
|
+
{ deferred: false },
|
|
24664
|
+
enumOptions,
|
|
24665
|
+
diagnostics
|
|
24666
|
+
);
|
|
24667
|
+
}
|
|
24668
|
+
for (const constructor2 of declaration.constructors) {
|
|
24669
|
+
validateParameterList(
|
|
24670
|
+
uri,
|
|
24671
|
+
constructor2.parameters,
|
|
24672
|
+
{ deferred: false },
|
|
24673
|
+
enumOptions,
|
|
24674
|
+
diagnostics
|
|
24675
|
+
);
|
|
24676
|
+
}
|
|
24677
|
+
}
|
|
24678
|
+
if (declaration.kind === "class" || declaration.kind === "interface") {
|
|
24679
|
+
for (const member of declaration.members) {
|
|
24680
|
+
if (member.kind !== "function") continue;
|
|
24681
|
+
validateParameterList(
|
|
24682
|
+
uri,
|
|
24683
|
+
member.parameters,
|
|
24684
|
+
{ deferred: member.modifiers.includes("async") },
|
|
24685
|
+
enumOptions,
|
|
24686
|
+
diagnostics
|
|
24687
|
+
);
|
|
24688
|
+
}
|
|
24689
|
+
}
|
|
24690
|
+
}
|
|
24691
|
+
}
|
|
24692
|
+
return diagnostics;
|
|
24693
|
+
}
|
|
24694
|
+
function collectEnumOptions(documents) {
|
|
24695
|
+
const options = /* @__PURE__ */ new Map();
|
|
24696
|
+
for (const document of documents.values()) {
|
|
24697
|
+
for (const declaration of document.declarations) {
|
|
24698
|
+
if (declaration.kind !== "enum") continue;
|
|
24699
|
+
const names = options.get(declaration.name) ?? options.set(declaration.name, /* @__PURE__ */ new Set()).get(declaration.name);
|
|
24700
|
+
for (const option of declaration.options) names.add(option.name);
|
|
24701
|
+
}
|
|
24702
|
+
}
|
|
24703
|
+
return options;
|
|
24704
|
+
}
|
|
24705
|
+
function validateParameterList(uri, parameters, context, enumOptions, diagnostics) {
|
|
24706
|
+
let lastNonDefaultedIndex = -1;
|
|
24707
|
+
for (let index = parameters.length - 1; index >= 0; index -= 1) {
|
|
24708
|
+
if (parameters[index].defaultValue === void 0) {
|
|
24709
|
+
lastNonDefaultedIndex = index;
|
|
24710
|
+
break;
|
|
24711
|
+
}
|
|
24712
|
+
}
|
|
24713
|
+
parameters.forEach((parameter4, index) => {
|
|
24714
|
+
const defaultValue = parameter4.defaultValue;
|
|
24715
|
+
if (defaultValue === void 0) return;
|
|
24716
|
+
if (context.deferred) {
|
|
24717
|
+
diagnostics.push({
|
|
24718
|
+
uri,
|
|
24719
|
+
range: defaultValue.range,
|
|
24720
|
+
severity: "error",
|
|
24721
|
+
source: "neo-project",
|
|
24722
|
+
code: PARAMETER_DEFAULT_ON_DEFERRED_FUNCTION,
|
|
24723
|
+
message: `Parameter '${parameter4.name}' of a deferred function cannot declare a default: generated C# appends a trailing deferred-completion parameter, which a defaulted parameter may not precede.`
|
|
24724
|
+
});
|
|
24725
|
+
}
|
|
24726
|
+
if (index < lastNonDefaultedIndex) {
|
|
24727
|
+
diagnostics.push({
|
|
24728
|
+
uri,
|
|
24729
|
+
range: parameter4.range,
|
|
24730
|
+
severity: "error",
|
|
24731
|
+
source: "neo-project",
|
|
24732
|
+
code: DEFAULT_BEFORE_REQUIRED_PARAMETER,
|
|
24733
|
+
message: `Parameter '${parameter4.name}' declares a default before parameter '${parameters[lastNonDefaultedIndex].name}', which has none. Defaulted parameters must come after every non-defaulted parameter.`
|
|
24734
|
+
});
|
|
24735
|
+
}
|
|
24736
|
+
validateDefaultExpression(
|
|
24737
|
+
uri,
|
|
24738
|
+
parameter4,
|
|
24739
|
+
defaultValue,
|
|
24740
|
+
enumOptions,
|
|
24741
|
+
diagnostics
|
|
24742
|
+
);
|
|
24743
|
+
});
|
|
24744
|
+
}
|
|
24745
|
+
function validateDefaultExpression(uri, parameter4, defaultValue, enumOptions, diagnostics) {
|
|
24746
|
+
const constant = classifyConstantDefault(defaultValue.text);
|
|
24747
|
+
if (constant === null) {
|
|
24748
|
+
diagnostics.push({
|
|
24749
|
+
uri,
|
|
24750
|
+
range: defaultValue.range,
|
|
24751
|
+
severity: "error",
|
|
24752
|
+
source: "neo-project",
|
|
24753
|
+
code: NON_CONSTANT_PARAMETER_DEFAULT,
|
|
24754
|
+
message: `Parameter '${parameter4.name}' default must be a constant: a bool, number, or string literal, a leading-dot enum option, or null.`
|
|
24755
|
+
});
|
|
24756
|
+
return;
|
|
24757
|
+
}
|
|
24758
|
+
const mismatch = defaultTypeMismatch(
|
|
24759
|
+
parameter4.type,
|
|
24760
|
+
constant,
|
|
24761
|
+
enumOptions,
|
|
24762
|
+
parameter4.name
|
|
24763
|
+
);
|
|
24764
|
+
if (mismatch === null) return;
|
|
24765
|
+
diagnostics.push({
|
|
24766
|
+
uri,
|
|
24767
|
+
range: defaultValue.range,
|
|
24768
|
+
severity: "error",
|
|
24769
|
+
source: "neo-project",
|
|
24770
|
+
code: PARAMETER_DEFAULT_TYPE_MISMATCH,
|
|
24771
|
+
message: mismatch
|
|
24772
|
+
});
|
|
24773
|
+
}
|
|
24774
|
+
function classifyConstantDefault(text) {
|
|
24775
|
+
let expression;
|
|
24776
|
+
try {
|
|
24777
|
+
expression = parseExpression(text);
|
|
24778
|
+
} catch {
|
|
24779
|
+
return null;
|
|
24780
|
+
}
|
|
24781
|
+
return classifyConstantExpression(expression);
|
|
24782
|
+
}
|
|
24783
|
+
function classifyConstantExpression(expression) {
|
|
24784
|
+
switch (expression.kind) {
|
|
24785
|
+
case "litNull":
|
|
24786
|
+
return { kind: "null" };
|
|
24787
|
+
case "litBool":
|
|
24788
|
+
return { kind: "bool" };
|
|
24789
|
+
case "litInt":
|
|
24790
|
+
return { kind: "int" };
|
|
24791
|
+
case "litFloat":
|
|
24792
|
+
return { kind: "float" };
|
|
24793
|
+
case "litString":
|
|
24794
|
+
return { kind: "string" };
|
|
24795
|
+
case "contextualEnum":
|
|
24796
|
+
return { kind: "enumOption", optionName: expression.name };
|
|
24797
|
+
case "unary": {
|
|
24798
|
+
if (expression.op !== "-") return null;
|
|
24799
|
+
const operand = classifyConstantExpression(expression.operand);
|
|
24800
|
+
if (operand === null) return null;
|
|
24801
|
+
if (operand.kind !== "int" && operand.kind !== "float") return null;
|
|
24802
|
+
return operand;
|
|
24803
|
+
}
|
|
24804
|
+
default:
|
|
24805
|
+
return null;
|
|
24806
|
+
}
|
|
24807
|
+
}
|
|
24808
|
+
function defaultTypeMismatch(type, constant, enumOptions, parameterName) {
|
|
24809
|
+
if (constant.kind === "null") {
|
|
24810
|
+
if (type.nullable) return null;
|
|
24811
|
+
return `Parameter '${parameterName}' defaults to null, but its type '${formatSourceType(type)}' is not nullable.`;
|
|
24812
|
+
}
|
|
24813
|
+
const declaredEnumOptions = enumOptions.get(type.name);
|
|
24814
|
+
if (constant.kind === "enumOption") {
|
|
24815
|
+
if (declaredEnumOptions === void 0) {
|
|
24816
|
+
return `Parameter '${parameterName}' defaults to enum option '.${constant.optionName}', but its type '${formatSourceType(type)}' is not an enum.`;
|
|
24817
|
+
}
|
|
24818
|
+
if (!declaredEnumOptions.has(constant.optionName)) {
|
|
24819
|
+
return `Parameter '${parameterName}' defaults to '.${constant.optionName}', which enum '${type.name}' does not declare.`;
|
|
24820
|
+
}
|
|
24821
|
+
return null;
|
|
24822
|
+
}
|
|
24823
|
+
if (constantKindMatchesPrimitive(type.name, constant.kind)) return null;
|
|
24824
|
+
if (PRIMITIVE_PARAMETER_TYPES.has(type.name) || declaredEnumOptions !== void 0) {
|
|
24825
|
+
return `Parameter '${parameterName}' default is a ${describeConstant(constant)}, which does not match its declared type '${formatSourceType(type)}'.`;
|
|
24826
|
+
}
|
|
24827
|
+
return `Parameter '${parameterName}' of type '${formatSourceType(type)}' can only default to null${type.nullable ? "" : ", and only when the type is nullable"}.`;
|
|
24828
|
+
}
|
|
24829
|
+
function constantKindMatchesPrimitive(typeName, kind) {
|
|
24830
|
+
if (typeName === "bool") return kind === "bool";
|
|
24831
|
+
if (typeName === "int") return kind === "int";
|
|
24832
|
+
if (typeName === "float") return kind === "int" || kind === "float";
|
|
24833
|
+
if (typeName === "decimal") return kind === "int" || kind === "float";
|
|
24834
|
+
if (typeName === "string") return kind === "string";
|
|
24835
|
+
return false;
|
|
24836
|
+
}
|
|
24837
|
+
function describeConstant(constant) {
|
|
24838
|
+
if (constant.kind === "bool") return "bool literal";
|
|
24839
|
+
if (constant.kind === "string") return "string literal";
|
|
24840
|
+
if (constant.kind === "int") return "whole-number literal";
|
|
24841
|
+
return "fractional number literal";
|
|
24842
|
+
}
|
|
24843
|
+
function formatSourceType(type) {
|
|
24844
|
+
const argumentsText = type.typeArguments.length === 0 ? "" : `<${type.typeArguments.map(formatSourceType).join(", ")}>`;
|
|
24845
|
+
return `${type.name}${argumentsText}${type.nullable ? "?" : ""}`;
|
|
24846
|
+
}
|
|
24847
|
+
var PARAMETER_DEFAULT_DIAGNOSTIC_CODES, DEFAULT_BEFORE_REQUIRED_PARAMETER, PARAMETER_DEFAULT_TYPE_MISMATCH, NON_CONSTANT_PARAMETER_DEFAULT, PARAMETER_DEFAULT_ON_DEFERRED_FUNCTION, PRIMITIVE_PARAMETER_TYPES;
|
|
24848
|
+
var init_project_source_parameter_defaults = __esm({
|
|
24849
|
+
"../packages/neoscript-language/src/project-source-parameter-defaults.ts"() {
|
|
24850
|
+
"use strict";
|
|
24851
|
+
init_language_spec();
|
|
24852
|
+
init_strict_parser();
|
|
24853
|
+
PARAMETER_DEFAULT_DIAGNOSTIC_CODES = {
|
|
24854
|
+
defaultBeforeRequiredParameter: "default-before-required-parameter",
|
|
24855
|
+
parameterDefaultTypeMismatch: "parameter-default-type-mismatch",
|
|
24856
|
+
nonConstantParameterDefault: "non-constant-parameter-default",
|
|
24857
|
+
parameterDefaultOnDeferredFunction: "parameter-default-on-deferred-function"
|
|
24858
|
+
};
|
|
24859
|
+
({
|
|
24860
|
+
defaultBeforeRequiredParameter: DEFAULT_BEFORE_REQUIRED_PARAMETER,
|
|
24861
|
+
parameterDefaultTypeMismatch: PARAMETER_DEFAULT_TYPE_MISMATCH,
|
|
24862
|
+
nonConstantParameterDefault: NON_CONSTANT_PARAMETER_DEFAULT,
|
|
24863
|
+
parameterDefaultOnDeferredFunction: PARAMETER_DEFAULT_ON_DEFERRED_FUNCTION
|
|
24864
|
+
} = PARAMETER_DEFAULT_DIAGNOSTIC_CODES);
|
|
24865
|
+
PRIMITIVE_PARAMETER_TYPES = new Set(NEOSCRIPT_PRIMITIVE_TYPES);
|
|
24866
|
+
}
|
|
24867
|
+
});
|
|
24868
|
+
|
|
24446
24869
|
// ../packages/neoscript-language/src/project-source-analysis.ts
|
|
24447
24870
|
function isSystemReservedRecordId(id2) {
|
|
24448
24871
|
if (id2 === null) return false;
|
|
@@ -24500,6 +24923,7 @@ function analyzeNeoProjectSources(inputs, parsedDocuments = /* @__PURE__ */ new
|
|
|
24500
24923
|
validateSystemAnnotationAuthoring(documents, diagnostics);
|
|
24501
24924
|
validateTypeReferences(documents, symbols, diagnostics);
|
|
24502
24925
|
diagnostics.push(...validateProjectSourceTypes(documents));
|
|
24926
|
+
diagnostics.push(...validateProjectSourceParameterDefaults(documents));
|
|
24503
24927
|
diagnostics.push(...validateProjectSourceSettlement(documents));
|
|
24504
24928
|
diagnostics.push(...validateProjectSourceSemantics(documents));
|
|
24505
24929
|
const bodyCompilation = compileProjectSourceBodies(documents);
|
|
@@ -25108,6 +25532,7 @@ var init_project_source_analysis = __esm({
|
|
|
25108
25532
|
init_project_source_settlement();
|
|
25109
25533
|
init_project_source_script_compiler();
|
|
25110
25534
|
init_project_source_type_checker();
|
|
25535
|
+
init_project_source_parameter_defaults();
|
|
25111
25536
|
BUILTIN_TYPE_NAMES = /* @__PURE__ */ new Set([
|
|
25112
25537
|
...NEOSCRIPT_PRIMITIVE_TYPES,
|
|
25113
25538
|
...NEOSCRIPT_BUILTIN_TYPES,
|
|
@@ -25427,7 +25852,9 @@ function projectCompletions(analysis, document, position) {
|
|
|
25427
25852
|
items: constructorFields.map((field) => ({
|
|
25428
25853
|
label: field.name,
|
|
25429
25854
|
kind: "property",
|
|
25430
|
-
|
|
25855
|
+
// P65 §6. C#-style square brackets mark a defaulted parameter as
|
|
25856
|
+
// omittable at the call site.
|
|
25857
|
+
detail: field.defaultText === void 0 ? field.type : `[${field.type} = ${field.defaultText}]`,
|
|
25431
25858
|
insertText: `${field.name}: `
|
|
25432
25859
|
}))
|
|
25433
25860
|
};
|
|
@@ -25862,7 +26289,11 @@ function declaredConstructorNamedArguments(analysis, typeName, used) {
|
|
|
25862
26289
|
return [...fields.values()];
|
|
25863
26290
|
}
|
|
25864
26291
|
function parameterArgumentField(parameter4) {
|
|
25865
|
-
return {
|
|
26292
|
+
return {
|
|
26293
|
+
name: parameter4.name,
|
|
26294
|
+
type: sourceTypeText(parameter4.type),
|
|
26295
|
+
...parameter4.defaultValue === void 0 ? {} : { defaultText: parameter4.defaultValue.text }
|
|
26296
|
+
};
|
|
25866
26297
|
}
|
|
25867
26298
|
function projectInitializerMemberCompletions(analysis, document, position) {
|
|
25868
26299
|
const site = constructionSiteAt(analysis, document, position);
|
|
@@ -25922,6 +26353,13 @@ function constructibleMembers(analysis, typeName) {
|
|
|
25922
26353
|
}
|
|
25923
26354
|
return [...members.values()];
|
|
25924
26355
|
}
|
|
26356
|
+
function sourceParameterSignatureText(parameter4) {
|
|
26357
|
+
return constructorParameterLabel(sourceParameterProjection(parameter4));
|
|
26358
|
+
}
|
|
26359
|
+
function functionParameterLabel(parameter4) {
|
|
26360
|
+
const suffix = parameter4.defaultValue === void 0 ? "" : ` = ${parameter4.defaultValue.text}`;
|
|
26361
|
+
return `${parameter4.type.name} ${parameter4.name}${suffix}`;
|
|
26362
|
+
}
|
|
25925
26363
|
function sourceTypeText(type) {
|
|
25926
26364
|
const args = type.typeArguments.length > 0 ? `<${type.typeArguments.map(sourceTypeText).join(", ")}>` : "";
|
|
25927
26365
|
return `${type.name}${args}${type.nullable ? "?" : ""}`;
|
|
@@ -26048,7 +26486,7 @@ function projectConstructionContractMarkdown(analysis, className) {
|
|
|
26048
26486
|
const contract = classConstructionContract(index, className);
|
|
26049
26487
|
if (!contract) return "";
|
|
26050
26488
|
if (contract.kind === "required") {
|
|
26051
|
-
const parameters = contract.parameters.map(
|
|
26489
|
+
const parameters = contract.parameters.map(sourceParameterSignatureText).join(", ");
|
|
26052
26490
|
return `
|
|
26053
26491
|
|
|
26054
26492
|
Construct with \`new(${parameters})\` \u2014 this class declares a required constructor, so the implicit \`new\` is unavailable.`;
|
|
@@ -26063,9 +26501,7 @@ Construct with \`new(${parameters})\` \u2014 this class declares a required cons
|
|
|
26063
26501
|
}
|
|
26064
26502
|
if (contract.kind === "declared") {
|
|
26065
26503
|
const overloads = contract.constructors.map(
|
|
26066
|
-
(constructor2) => `\`${className}(${constructor2.parameters.map(
|
|
26067
|
-
(parameter4) => `${sourceTypeText(parameter4.type)} ${parameter4.name}`
|
|
26068
|
-
).join(", ")})\``
|
|
26504
|
+
(constructor2) => `\`${className}(${constructor2.parameters.map(sourceParameterSignatureText).join(", ")})\``
|
|
26069
26505
|
).join(", ");
|
|
26070
26506
|
lines.push(`Constructors: ${overloads}.`);
|
|
26071
26507
|
}
|
|
@@ -26187,13 +26623,11 @@ function projectSignatureHelp(analysis, document, position) {
|
|
|
26187
26623
|
if (functions.length === 0) return null;
|
|
26188
26624
|
return {
|
|
26189
26625
|
signatures: functions.map(({ owner, member }) => {
|
|
26190
|
-
const parameters = member.parameters.map(
|
|
26191
|
-
(parameter4) => `${parameter4.type.name} ${parameter4.name}`
|
|
26192
|
-
);
|
|
26626
|
+
const parameters = member.parameters.map(functionParameterLabel);
|
|
26193
26627
|
return {
|
|
26194
26628
|
label: `${member.type.name} ${owner}.${member.name}(${parameters.join(", ")})`,
|
|
26195
26629
|
parameters: member.parameters.map((parameter4) => ({
|
|
26196
|
-
label:
|
|
26630
|
+
label: functionParameterLabel(parameter4)
|
|
26197
26631
|
}))
|
|
26198
26632
|
};
|
|
26199
26633
|
}),
|
|
@@ -26959,7 +27393,10 @@ function findTypeDeclaration(analysis, name) {
|
|
|
26959
27393
|
return void 0;
|
|
26960
27394
|
}
|
|
26961
27395
|
function constructorParameterLabel(parameter4) {
|
|
26962
|
-
return `${parameter4.type} ${parameter4.name}`;
|
|
27396
|
+
return `${parameter4.type} ${parameter4.name}${parameterDefaultSuffix2(parameter4)}`;
|
|
27397
|
+
}
|
|
27398
|
+
function parameterDefaultSuffix2(parameter4) {
|
|
27399
|
+
return parameter4.defaultText === void 0 ? "" : ` = ${parameter4.defaultText}`;
|
|
26963
27400
|
}
|
|
26964
27401
|
function projectConstructorTypeName(analysis, document, callee, beforeCallee) {
|
|
26965
27402
|
if (beforeCallee?.text === "new") return callee.text;
|
|
@@ -26985,7 +27422,11 @@ function declarationConstructorParameters(declaration) {
|
|
|
26985
27422
|
).map((member) => ({ type: member.type.name, name: member.name }));
|
|
26986
27423
|
}
|
|
26987
27424
|
function sourceParameterProjection(parameter4) {
|
|
26988
|
-
return {
|
|
27425
|
+
return {
|
|
27426
|
+
type: sourceTypeText(parameter4.type),
|
|
27427
|
+
name: parameter4.name,
|
|
27428
|
+
...parameter4.defaultValue === void 0 ? {} : { defaultText: parameter4.defaultValue.text }
|
|
27429
|
+
};
|
|
26989
27430
|
}
|
|
26990
27431
|
function graphConstructorParameters(typeName) {
|
|
26991
27432
|
switch (typeName) {
|
|
@@ -27104,6 +27545,9 @@ function projectConstructionQuickFixes(analysis, document, diagnostic) {
|
|
|
27104
27545
|
if (diagnostic.code === "unknown-identifier") {
|
|
27105
27546
|
return moveParametersToClassHeaderFixes(analysis, document, diagnostic);
|
|
27106
27547
|
}
|
|
27548
|
+
if (diagnostic.code === "default-before-required-parameter") {
|
|
27549
|
+
return moveDefaultedParameterFixes(analysis, document, diagnostic);
|
|
27550
|
+
}
|
|
27107
27551
|
return [];
|
|
27108
27552
|
}
|
|
27109
27553
|
function settleRequiredMemberFixes(analysis, document, diagnostic) {
|
|
@@ -27209,10 +27653,13 @@ function placeholderValue(analysis, index, type, depth) {
|
|
|
27209
27653
|
if (declaration.modifiers.includes("abstract")) return null;
|
|
27210
27654
|
const contract = classConstructionContract(index, type.name);
|
|
27211
27655
|
if (contract?.kind !== "required") return "new()";
|
|
27212
|
-
|
|
27656
|
+
const mandatory = contract.parameters.filter(
|
|
27657
|
+
(parameter4) => parameter4.defaultValue === void 0
|
|
27658
|
+
);
|
|
27659
|
+
if (mandatory.length === 0) return "new()";
|
|
27213
27660
|
if (depth > 0) return null;
|
|
27214
27661
|
const args = [];
|
|
27215
|
-
for (const parameter4 of
|
|
27662
|
+
for (const parameter4 of mandatory) {
|
|
27216
27663
|
const value = placeholderValue(analysis, index, parameter4.type, depth + 1);
|
|
27217
27664
|
if (value === null) return null;
|
|
27218
27665
|
args.push(`${parameter4.name}: ${value}`);
|
|
@@ -27404,6 +27851,71 @@ function innerBodyText(constructor2) {
|
|
|
27404
27851
|
const trimmed = constructor2.body.text.trim();
|
|
27405
27852
|
return trimmed.startsWith("{") && trimmed.endsWith("}") ? trimmed.slice(1, -1) : trimmed;
|
|
27406
27853
|
}
|
|
27854
|
+
function moveDefaultedParameterFixes(analysis, document, diagnostic) {
|
|
27855
|
+
const source = analysis.documents.get(document.uri);
|
|
27856
|
+
if (!source) return [];
|
|
27857
|
+
const parameters = parameterListAt(source.declarations, diagnostic.range);
|
|
27858
|
+
if (parameters === null) return [];
|
|
27859
|
+
const first = parameters[0];
|
|
27860
|
+
const last = parameters[parameters.length - 1];
|
|
27861
|
+
if (!first || !last) return [];
|
|
27862
|
+
const text = new SourceText(document.text);
|
|
27863
|
+
const authored = (parameter4) => text.text.slice(
|
|
27864
|
+
text.offsetAt(parameter4.range.start),
|
|
27865
|
+
text.offsetAt(parameter4.range.end)
|
|
27866
|
+
);
|
|
27867
|
+
const reordered = [
|
|
27868
|
+
...parameters.filter((parameter4) => parameter4.defaultValue === void 0),
|
|
27869
|
+
...parameters.filter((parameter4) => parameter4.defaultValue !== void 0)
|
|
27870
|
+
];
|
|
27871
|
+
return [
|
|
27872
|
+
{
|
|
27873
|
+
title: "Move defaulted parameters after required parameters",
|
|
27874
|
+
kind: "quickfix",
|
|
27875
|
+
diagnostics: [diagnostic],
|
|
27876
|
+
edit: {
|
|
27877
|
+
changes: {
|
|
27878
|
+
[document.uri]: [
|
|
27879
|
+
{
|
|
27880
|
+
range: {
|
|
27881
|
+
start: first.range.start,
|
|
27882
|
+
end: last.range.end
|
|
27883
|
+
},
|
|
27884
|
+
newText: reordered.map(authored).join(", ")
|
|
27885
|
+
}
|
|
27886
|
+
]
|
|
27887
|
+
}
|
|
27888
|
+
},
|
|
27889
|
+
preferred: true
|
|
27890
|
+
}
|
|
27891
|
+
];
|
|
27892
|
+
}
|
|
27893
|
+
function parameterListAt(declarations, range2) {
|
|
27894
|
+
for (const declaration of declarations) {
|
|
27895
|
+
if (declaration.kind !== "class" && declaration.kind !== "interface") {
|
|
27896
|
+
continue;
|
|
27897
|
+
}
|
|
27898
|
+
const lists = [];
|
|
27899
|
+
if (declaration.kind === "class") {
|
|
27900
|
+
if (declaration.headerParameters !== void 0) {
|
|
27901
|
+
lists.push(declaration.headerParameters);
|
|
27902
|
+
}
|
|
27903
|
+
for (const constructor2 of declaration.constructors) {
|
|
27904
|
+
lists.push(constructor2.parameters);
|
|
27905
|
+
}
|
|
27906
|
+
}
|
|
27907
|
+
for (const member of declaration.members) {
|
|
27908
|
+
if (member.kind === "function") lists.push(member.parameters);
|
|
27909
|
+
}
|
|
27910
|
+
for (const list of lists) {
|
|
27911
|
+
const hit = list.some(
|
|
27912
|
+
(parameter4) => rangeContains(parameter4.range, range2.start)
|
|
27913
|
+
);
|
|
27914
|
+
if (hit) return list;
|
|
27915
|
+
}
|
|
27916
|
+
}
|
|
27917
|
+
return null;
|
|
27918
|
+
}
|
|
27407
27919
|
var NEW_CONSTRUCTIBLE_BUILTIN_TYPES;
|
|
27408
27920
|
var init_project_source_construction_quick_fixes = __esm({
|
|
27409
27921
|
"../packages/neoscript-language/src/project-source-construction-quick-fixes.ts"() {
|
|
@@ -27560,6 +28072,7 @@ function manifestParameter(uri, parameter4) {
|
|
|
27560
28072
|
name: parameter4.name,
|
|
27561
28073
|
type: manifestType(parameter4.type),
|
|
27562
28074
|
annotations: manifestAnnotations(parameter4.annotations),
|
|
28075
|
+
default: parameter4.defaultValue?.text ?? null,
|
|
27563
28076
|
source: { uri, range: parameter4.range }
|
|
27564
28077
|
};
|
|
27565
28078
|
}
|
|
@@ -27970,12 +28483,21 @@ function assertBaseClauseArguments(value, path) {
|
|
|
27970
28483
|
}
|
|
27971
28484
|
function assertParameter(value, path) {
|
|
27972
28485
|
const parameter4 = record(value, path);
|
|
27973
|
-
exactKeys(parameter4, path, [
|
|
28486
|
+
exactKeys(parameter4, path, [
|
|
28487
|
+
"name",
|
|
28488
|
+
"type",
|
|
28489
|
+
"annotations",
|
|
28490
|
+
"default",
|
|
28491
|
+
"source"
|
|
28492
|
+
]);
|
|
27974
28493
|
string(parameter4.name, `${path}.name`);
|
|
27975
28494
|
assertType(parameter4.type, `${path}.type`);
|
|
27976
28495
|
array(parameter4.annotations, `${path}.annotations`).forEach(
|
|
27977
28496
|
(annotation2, index) => assertAnnotation(annotation2, `${path}.annotations[${index}]`)
|
|
27978
28497
|
);
|
|
28498
|
+
if (parameter4.default !== null) {
|
|
28499
|
+
string(parameter4.default, `${path}.default`);
|
|
28500
|
+
}
|
|
27979
28501
|
assertLocation(parameter4.source, `${path}.source`);
|
|
27980
28502
|
}
|
|
27981
28503
|
function assertMember(value, path) {
|
|
@@ -28408,6 +28930,7 @@ function projectSchemaManifest(input, options = {}) {
|
|
|
28408
28930
|
members: memberById,
|
|
28409
28931
|
classes: schemaClassById,
|
|
28410
28932
|
interfaces: interfaceById,
|
|
28933
|
+
enums: indexById(enums, "ProjectSchemaManifest.enums"),
|
|
28411
28934
|
genericNames,
|
|
28412
28935
|
effectiveWritabilityByMemberId: effectiveMemberWritability(
|
|
28413
28936
|
members,
|
|
@@ -28469,7 +28992,8 @@ function groupDeclaredConstructors(declaredConstructors2, environment) {
|
|
|
28469
28992
|
(parameter4) => ({
|
|
28470
28993
|
name: parameter4.name,
|
|
28471
28994
|
type: parameter4.type,
|
|
28472
|
-
required: parameter4.type.nullable !== true
|
|
28995
|
+
required: parameter4.type.nullable !== true,
|
|
28996
|
+
...parameter4.defaultValue === void 0 ? {} : { defaultValue: parameter4.defaultValue }
|
|
28473
28997
|
})
|
|
28474
28998
|
),
|
|
28475
28999
|
...documentation === void 0 ? {} : { documentation },
|
|
@@ -29479,6 +30003,11 @@ function argumentsList(value, environment, field) {
|
|
|
29479
30003
|
environment,
|
|
29480
30004
|
`${field}.arguments[${index}].type`
|
|
29481
30005
|
),
|
|
30006
|
+
...manifestParameterDefault(
|
|
30007
|
+
argument2,
|
|
30008
|
+
environment,
|
|
30009
|
+
`${field}.arguments[${index}]`
|
|
30010
|
+
),
|
|
29482
30011
|
...spanAndSelectionLocations(
|
|
29483
30012
|
argument2.source,
|
|
29484
30013
|
argument2.selectionSpan ?? argument2.source,
|
|
@@ -29487,6 +30016,54 @@ function argumentsList(value, environment, field) {
|
|
|
29487
30016
|
)
|
|
29488
30017
|
}));
|
|
29489
30018
|
}
|
|
30019
|
+
function neoScriptParameterDefaultDisplayText(options) {
|
|
30020
|
+
const { value, kind } = options;
|
|
30021
|
+
if (value === null) return "null";
|
|
30022
|
+
if (kind === "enum") return `.${options.enumOptionName ?? String(value)}`;
|
|
30023
|
+
if (kind === "decimal" && typeof value === "string") return value;
|
|
30024
|
+
if (typeof value === "string") return JSON.stringify(value);
|
|
30025
|
+
return String(value);
|
|
30026
|
+
}
|
|
30027
|
+
function manifestParameterDefault(argument2, environment, field) {
|
|
30028
|
+
const declared = optionalRecord(argument2.default);
|
|
30029
|
+
if (declared === void 0) return {};
|
|
30030
|
+
const value = constantDefaultValue(declared.value, `${field}.default.value`);
|
|
30031
|
+
const type = record2(argument2.type, `${field}.type`);
|
|
30032
|
+
const kind = string2(type.kind, `${field}.type.kind`);
|
|
30033
|
+
const enumOptionName = kind === "enum" && typeof value === "string" ? manifestEnumOptionName(
|
|
30034
|
+
string2(type.enumId, `${field}.type.enumId`),
|
|
30035
|
+
value,
|
|
30036
|
+
environment
|
|
30037
|
+
) : void 0;
|
|
30038
|
+
return {
|
|
30039
|
+
defaultValue: {
|
|
30040
|
+
displayText: neoScriptParameterDefaultDisplayText({
|
|
30041
|
+
value,
|
|
30042
|
+
kind: kind === "enum" || kind === "decimal" ? kind : "other",
|
|
30043
|
+
...enumOptionName === void 0 ? {} : { enumOptionName }
|
|
30044
|
+
}),
|
|
30045
|
+
value
|
|
30046
|
+
}
|
|
30047
|
+
};
|
|
30048
|
+
}
|
|
30049
|
+
function constantDefaultValue(value, field) {
|
|
30050
|
+
if (value !== null && typeof value !== "boolean" && typeof value !== "number" && typeof value !== "string") {
|
|
30051
|
+
throw new Error(
|
|
30052
|
+
`${field} must be a \xA71.2 constant (boolean, number, string, or null), received ${JSON.stringify(value)}.`
|
|
30053
|
+
);
|
|
30054
|
+
}
|
|
30055
|
+
return value;
|
|
30056
|
+
}
|
|
30057
|
+
function manifestEnumOptionName(enumId, optionId, environment) {
|
|
30058
|
+
const schemaEnum = environment.enums.get(enumId);
|
|
30059
|
+
if (schemaEnum === void 0) return void 0;
|
|
30060
|
+
const options = records(schemaEnum.options ?? [], `enum ${enumId}.options`);
|
|
30061
|
+
const option = options.find(
|
|
30062
|
+
(candidate) => candidate.id === optionId || candidate.key === optionId
|
|
30063
|
+
);
|
|
30064
|
+
if (option === void 0) return void 0;
|
|
30065
|
+
return typeof option.name === "string" ? option.name : void 0;
|
|
30066
|
+
}
|
|
29490
30067
|
function sourceLocation(value, environment, field) {
|
|
29491
30068
|
const source = optionalRecord(value);
|
|
29492
30069
|
if (!source) return {};
|
|
@@ -30436,6 +31013,7 @@ var init_src = __esm({
|
|
|
30436
31013
|
init_project_source_construction_diagnostics();
|
|
30437
31014
|
init_project_source_construction_quick_fixes();
|
|
30438
31015
|
init_project_source_manifest();
|
|
31016
|
+
init_project_source_parameter_defaults();
|
|
30439
31017
|
init_project_source_settlement();
|
|
30440
31018
|
init_project_source_parser();
|
|
30441
31019
|
init_project_source_script_compiler();
|
|
@@ -32401,10 +32979,7 @@ function memberToDocumentFields(member, baseData3) {
|
|
|
32401
32979
|
}
|
|
32402
32980
|
if (member.kind === "function" || member.kind === "scriptFunction") {
|
|
32403
32981
|
fields.returnTypeInfo = manifestReturnTypeToDocument(member.returnType);
|
|
32404
|
-
fields.argumentTypes = member.arguments.map(
|
|
32405
|
-
name: argument2.name,
|
|
32406
|
-
...manifestTypeToDocument(argument2.type)
|
|
32407
|
-
}));
|
|
32982
|
+
fields.argumentTypes = member.arguments.map(manifestArgumentToDocument);
|
|
32408
32983
|
fields.deferred = member.deferred;
|
|
32409
32984
|
if (member.kind === "scriptFunction" && member.script !== null && member.bodyMode !== "ui") {
|
|
32410
32985
|
fields.code = member.script.sourceText;
|
|
@@ -32416,16 +32991,10 @@ function memberToDocumentFields(member, baseData3) {
|
|
|
32416
32991
|
}
|
|
32417
32992
|
if (member.kind === "delegate") {
|
|
32418
32993
|
fields.returnTypeInfo = manifestReturnTypeToDocument(member.returnType);
|
|
32419
|
-
fields.argumentTypes = member.arguments.map(
|
|
32420
|
-
name: argument2.name,
|
|
32421
|
-
...manifestTypeToDocument(argument2.type)
|
|
32422
|
-
}));
|
|
32994
|
+
fields.argumentTypes = member.arguments.map(manifestArgumentToDocument);
|
|
32423
32995
|
}
|
|
32424
32996
|
if (member.kind === "action") {
|
|
32425
|
-
fields.argumentTypes = member.arguments.map(
|
|
32426
|
-
name: argument2.name,
|
|
32427
|
-
...manifestTypeToDocument(argument2.type)
|
|
32428
|
-
}));
|
|
32997
|
+
fields.argumentTypes = member.arguments.map(manifestArgumentToDocument);
|
|
32429
32998
|
}
|
|
32430
32999
|
if (member.kind === "generic") {
|
|
32431
33000
|
fields.genericParamId = member.genericParamId;
|
|
@@ -32515,11 +33084,25 @@ function documentArgumentsToManifest(value, record3, source) {
|
|
|
32515
33084
|
`argumentTypes[${index}].name`
|
|
32516
33085
|
),
|
|
32517
33086
|
type: documentTypeToManifest(argument2, record3, `argumentTypes[${index}]`),
|
|
33087
|
+
default: documentParameterDefaultToManifest(
|
|
33088
|
+
argument2.defaultValue,
|
|
33089
|
+
record3,
|
|
33090
|
+
`argumentTypes[${index}].defaultValue`,
|
|
33091
|
+
source
|
|
33092
|
+
),
|
|
32518
33093
|
source,
|
|
32519
33094
|
selectionSpan: source
|
|
32520
33095
|
};
|
|
32521
33096
|
});
|
|
32522
33097
|
}
|
|
33098
|
+
function documentParameterDefaultToManifest(value, record3, path, source) {
|
|
33099
|
+
if (value === void 0 || value === null) return null;
|
|
33100
|
+
const wrapper = requireRecordValue(value, record3, path);
|
|
33101
|
+
if (!Object.hasOwn(wrapper, "value")) {
|
|
33102
|
+
throw invalidDocument(record3, path, 'must carry a "value" key');
|
|
33103
|
+
}
|
|
33104
|
+
return { value: wrapper.value, source };
|
|
33105
|
+
}
|
|
32523
33106
|
function optionalDocumentType(value, record3, path) {
|
|
32524
33107
|
if (value === null || value === void 0) return null;
|
|
32525
33108
|
return documentTypeToManifest(value, record3, path);
|
|
@@ -32668,6 +33251,13 @@ function documentTypeToManifest(value, record3, path) {
|
|
|
32668
33251
|
`unsupported type-info discriminator ${kind}`
|
|
32669
33252
|
);
|
|
32670
33253
|
}
|
|
33254
|
+
function manifestArgumentToDocument(argument2) {
|
|
33255
|
+
return {
|
|
33256
|
+
name: argument2.name,
|
|
33257
|
+
...manifestTypeToDocument(argument2.type),
|
|
33258
|
+
...argument2.default === null ? {} : { defaultValue: { value: argument2.default.value } }
|
|
33259
|
+
};
|
|
33260
|
+
}
|
|
32671
33261
|
function manifestReturnTypeToDocument(type) {
|
|
32672
33262
|
if (type.kind === "void") return { type: "Void", required: true };
|
|
32673
33263
|
return manifestTypeToDocument(type);
|
|
@@ -33407,10 +33997,7 @@ function interfaceToDocument(neoInterface) {
|
|
|
33407
33997
|
kind: "function",
|
|
33408
33998
|
...member.docsText === void 0 ? {} : { docsText: member.docsText },
|
|
33409
33999
|
returnTypeInfo: manifestReturnTypeToDocument(member.returnType),
|
|
33410
|
-
argumentTypes: member.arguments.map(
|
|
33411
|
-
name: argument2.name,
|
|
33412
|
-
...manifestTypeToDocument(argument2.type)
|
|
33413
|
-
})),
|
|
34000
|
+
argumentTypes: member.arguments.map(manifestArgumentToDocument),
|
|
33414
34001
|
deferred: member.deferred,
|
|
33415
34002
|
accessModifierKind: member.accessModifier
|
|
33416
34003
|
};
|
|
@@ -33909,10 +34496,7 @@ function constructorToDocument(declared) {
|
|
|
33909
34496
|
return omitUndefined({
|
|
33910
34497
|
id: declared.id,
|
|
33911
34498
|
classId: declared.classId,
|
|
33912
|
-
argumentTypes: declared.arguments.map(
|
|
33913
|
-
name: argument2.name,
|
|
33914
|
-
...manifestTypeToDocument(argument2.type)
|
|
33915
|
-
})),
|
|
34499
|
+
argumentTypes: declared.arguments.map(manifestArgumentToDocument),
|
|
33916
34500
|
code: declared.code,
|
|
33917
34501
|
baseArguments: declared.baseArguments,
|
|
33918
34502
|
baseInitializerFields: declared.baseInitializerFields,
|
|
@@ -35568,14 +36152,22 @@ function assertFunctionArgument(value, path) {
|
|
|
35568
36152
|
const argument2 = objectAt(value, path, [
|
|
35569
36153
|
"name",
|
|
35570
36154
|
"type",
|
|
36155
|
+
"default",
|
|
35571
36156
|
"source",
|
|
35572
36157
|
"selectionSpan"
|
|
35573
36158
|
]);
|
|
35574
36159
|
nonEmptyString(argument2.name, `${path}.name`);
|
|
35575
36160
|
assertType2(argument2.type, `${path}.type`);
|
|
36161
|
+
assertParameterDefault(argument2.default, `${path}.default`);
|
|
35576
36162
|
assertSpan(argument2.source, `${path}.source`);
|
|
35577
36163
|
assertSpan(argument2.selectionSpan, `${path}.selectionSpan`);
|
|
35578
36164
|
}
|
|
36165
|
+
function assertParameterDefault(value, path) {
|
|
36166
|
+
if (value === null) return;
|
|
36167
|
+
const parameterDefault = objectAt(value, path, ["value", "source"]);
|
|
36168
|
+
assertJsonValue(parameterDefault.value, `${path}.value`, 0);
|
|
36169
|
+
assertSpan(parameterDefault.source, `${path}.source`);
|
|
36170
|
+
}
|
|
35579
36171
|
function assertAbstractScriptInvariant(value, path) {
|
|
35580
36172
|
const isAbstract = value.modifier === "abstract" || value.modifier === "abstractOverride";
|
|
35581
36173
|
const hasUiBody = value.bodyMode === "ui" && value.uiAction !== void 0;
|
|
@@ -37789,7 +38381,30 @@ function isNSFunctionReturnTypeInfo(value) {
|
|
|
37789
38381
|
return isNSTypeInfo(value) || isNSTypeInfoVoid(value);
|
|
37790
38382
|
}
|
|
37791
38383
|
function isNSFunctionArgumentTypeInfo(value) {
|
|
37792
|
-
return isNSArgumentTypeInfo(value) && !typeInfoContainsUnknown(value, /* @__PURE__ */ new Set());
|
|
38384
|
+
return isNSArgumentTypeInfo(value) && !typeInfoContainsUnknown(value, /* @__PURE__ */ new Set()) && hasValidParameterDefault(value);
|
|
38385
|
+
}
|
|
38386
|
+
function hasValidParameterDefault(value) {
|
|
38387
|
+
const wrapper = value.defaultValue;
|
|
38388
|
+
if (wrapper === void 0) return true;
|
|
38389
|
+
if (typeof wrapper !== "object" || wrapper === null) return false;
|
|
38390
|
+
const keys = Object.keys(wrapper);
|
|
38391
|
+
if (keys.length !== 1 || keys[0] !== "value") return false;
|
|
38392
|
+
const payload = wrapper.value;
|
|
38393
|
+
if (payload === null) return !value.required;
|
|
38394
|
+
switch (value.type) {
|
|
38395
|
+
case 1 /* Bool */:
|
|
38396
|
+
return typeof payload === "boolean";
|
|
38397
|
+
case 2 /* Int */:
|
|
38398
|
+
return typeof payload === "number" && Number.isInteger(payload);
|
|
38399
|
+
case 4 /* Float */:
|
|
38400
|
+
return typeof payload === "number" && Number.isFinite(payload);
|
|
38401
|
+
case 20 /* Decimal */:
|
|
38402
|
+
case 3 /* String */:
|
|
38403
|
+
case 8 /* Enum */:
|
|
38404
|
+
return typeof payload === "string";
|
|
38405
|
+
default:
|
|
38406
|
+
return false;
|
|
38407
|
+
}
|
|
37793
38408
|
}
|
|
37794
38409
|
function typeInfoContainsUnknown(value, ancestors) {
|
|
37795
38410
|
if (value.type === NS_TYPE_UNKNOWN) return true;
|
|
@@ -38590,6 +39205,51 @@ var init_neoscript_guards = __esm({
|
|
|
38590
39205
|
}
|
|
38591
39206
|
});
|
|
38592
39207
|
|
|
39208
|
+
// ../src/models/neoscript/parameter-defaults.ts
|
|
39209
|
+
function parameterHasDefault(argument2) {
|
|
39210
|
+
return argument2.defaultValue !== void 0;
|
|
39211
|
+
}
|
|
39212
|
+
function hasAnyParameterDefault(argumentTypes) {
|
|
39213
|
+
return argumentTypes.some(parameterHasDefault);
|
|
39214
|
+
}
|
|
39215
|
+
function validateParameterDefaults(argumentTypes) {
|
|
39216
|
+
const violations = [];
|
|
39217
|
+
let lastNonDefaultedIndex = -1;
|
|
39218
|
+
for (let index = argumentTypes.length - 1; index >= 0; index -= 1) {
|
|
39219
|
+
const argument2 = argumentTypes[index];
|
|
39220
|
+
if (argument2 !== void 0 && !parameterHasDefault(argument2)) {
|
|
39221
|
+
lastNonDefaultedIndex = index;
|
|
39222
|
+
break;
|
|
39223
|
+
}
|
|
39224
|
+
}
|
|
39225
|
+
for (let index = 0; index < argumentTypes.length; index += 1) {
|
|
39226
|
+
const argument2 = argumentTypes[index];
|
|
39227
|
+
if (argument2 === void 0) continue;
|
|
39228
|
+
const defaultValue = argument2.defaultValue;
|
|
39229
|
+
if (defaultValue === void 0) continue;
|
|
39230
|
+
if (index < lastNonDefaultedIndex) {
|
|
39231
|
+
violations.push({
|
|
39232
|
+
code: "default-before-required-parameter",
|
|
39233
|
+
index,
|
|
39234
|
+
name: argument2.name
|
|
39235
|
+
});
|
|
39236
|
+
}
|
|
39237
|
+
if (defaultValue.value === null && argument2.required) {
|
|
39238
|
+
violations.push({
|
|
39239
|
+
code: "parameter-default-type-mismatch",
|
|
39240
|
+
index,
|
|
39241
|
+
name: argument2.name
|
|
39242
|
+
});
|
|
39243
|
+
}
|
|
39244
|
+
}
|
|
39245
|
+
return violations;
|
|
39246
|
+
}
|
|
39247
|
+
var init_parameter_defaults = __esm({
|
|
39248
|
+
"../src/models/neoscript/parameter-defaults.ts"() {
|
|
39249
|
+
"use strict";
|
|
39250
|
+
}
|
|
39251
|
+
});
|
|
39252
|
+
|
|
38593
39253
|
// ../src/models/interfaces/interface-graph.ts
|
|
38594
39254
|
function resolveInterfaceClosure(interfaceId, interfaces) {
|
|
38595
39255
|
const byId = new Map(
|
|
@@ -38726,6 +39386,7 @@ var init_neoscript = __esm({
|
|
|
38726
39386
|
"use strict";
|
|
38727
39387
|
init_neoscript_types();
|
|
38728
39388
|
init_neoscript_guards();
|
|
39389
|
+
init_parameter_defaults();
|
|
38729
39390
|
init_type_info_compatibility();
|
|
38730
39391
|
}
|
|
38731
39392
|
});
|
|
@@ -39384,14 +40045,20 @@ function isMemberFunctionBase(value) {
|
|
|
39384
40045
|
if (!Array.isArray(v.argumentTypes)) return false;
|
|
39385
40046
|
if (typeof v.deferred !== "boolean") return false;
|
|
39386
40047
|
const names = /* @__PURE__ */ new Set();
|
|
40048
|
+
const argumentTypes = [];
|
|
39387
40049
|
for (const arg of v.argumentTypes) {
|
|
39388
40050
|
if (!isNSFunctionArgumentTypeInfo(arg)) return false;
|
|
39389
40051
|
if (!isValidCallableIdentifier(arg.name)) return false;
|
|
39390
40052
|
if (arg.type === NS_TYPE_UNKNOWN) return false;
|
|
39391
40053
|
if (names.has(arg.name)) return false;
|
|
39392
40054
|
names.add(arg.name);
|
|
40055
|
+
argumentTypes.push(arg);
|
|
39393
40056
|
}
|
|
39394
|
-
return
|
|
40057
|
+
return hasValidParameterDefaults(argumentTypes, v.deferred);
|
|
40058
|
+
}
|
|
40059
|
+
function hasValidParameterDefaults(argumentTypes, deferred) {
|
|
40060
|
+
if (deferred && hasAnyParameterDefault(argumentTypes)) return false;
|
|
40061
|
+
return validateParameterDefaults(argumentTypes).length === 0;
|
|
39395
40062
|
}
|
|
39396
40063
|
function normalizedCompiledFunctionReturnType(typeInfo) {
|
|
39397
40064
|
if (typeInfo.type === NS_TYPE_VOID) {
|
|
@@ -39439,6 +40106,7 @@ function isMemberNSFunctionBase(value) {
|
|
|
39439
40106
|
if (v.action !== void 0 && v.action !== null) return false;
|
|
39440
40107
|
if (v.bodyMode !== void 0 && v.bodyMode !== "ui") return false;
|
|
39441
40108
|
const names = /* @__PURE__ */ new Set();
|
|
40109
|
+
const argumentTypes = [];
|
|
39442
40110
|
for (const argument2 of v.argumentTypes) {
|
|
39443
40111
|
if (!isNSFunctionArgumentTypeInfo(argument2)) return false;
|
|
39444
40112
|
if (argument2.type === NS_TYPE_UNKNOWN) return false;
|
|
@@ -39446,7 +40114,9 @@ function isMemberNSFunctionBase(value) {
|
|
|
39446
40114
|
if (NSFunctionArgumentReservedNames.has(argument2.name)) return false;
|
|
39447
40115
|
if (names.has(argument2.name)) return false;
|
|
39448
40116
|
names.add(argument2.name);
|
|
40117
|
+
argumentTypes.push(argument2);
|
|
39449
40118
|
}
|
|
40119
|
+
if (!hasValidParameterDefaults(argumentTypes, v.deferred)) return false;
|
|
39450
40120
|
if (v.isAbstract === true) {
|
|
39451
40121
|
if (v.bodyMode !== void 0) return false;
|
|
39452
40122
|
if (v.uiAction !== void 0 && v.uiAction !== null) return false;
|
|
@@ -39523,6 +40193,7 @@ function isMemberDelegateBase(value) {
|
|
|
39523
40193
|
if (argument2.type === NS_TYPE_UNKNOWN) return false;
|
|
39524
40194
|
if (names.has(argument2.name)) return false;
|
|
39525
40195
|
names.add(argument2.name);
|
|
40196
|
+
if (argument2.defaultValue !== void 0) return false;
|
|
39526
40197
|
}
|
|
39527
40198
|
const defaultValue = v.defaultValue;
|
|
39528
40199
|
if (defaultValue === void 0 || defaultValue === null) return true;
|
|
@@ -39561,6 +40232,7 @@ function isMemberActionBase(value) {
|
|
|
39561
40232
|
if (argument2.type === NS_TYPE_UNKNOWN) return false;
|
|
39562
40233
|
if (names.has(argument2.name)) return false;
|
|
39563
40234
|
names.add(argument2.name);
|
|
40235
|
+
if (argument2.defaultValue !== void 0) return false;
|
|
39564
40236
|
}
|
|
39565
40237
|
const defaultValue = v.defaultValue;
|
|
39566
40238
|
if (defaultValue === void 0 || defaultValue === null) return true;
|
|
@@ -39792,6 +40464,7 @@ function isMemberOverrideBase(value) {
|
|
|
39792
40464
|
if (v.argumentTypes !== void 0) {
|
|
39793
40465
|
if (!Array.isArray(v.argumentTypes)) return false;
|
|
39794
40466
|
if (!v.argumentTypes.every(isNSFunctionArgumentTypeInfo)) return false;
|
|
40467
|
+
if (hasAnyParameterDefault(v.argumentTypes)) return false;
|
|
39795
40468
|
}
|
|
39796
40469
|
if (v.deferred !== void 0 && typeof v.deferred !== "boolean") {
|
|
39797
40470
|
return false;
|
|
@@ -43670,7 +44343,11 @@ function isNeoInterfaceMember(value) {
|
|
|
43670
44343
|
if (!isNSFunctionArgumentTypeInfo(argumentType)) return false;
|
|
43671
44344
|
if (containsForbiddenMemberTypeInfo(argumentType)) return false;
|
|
43672
44345
|
}
|
|
43673
|
-
|
|
44346
|
+
if (typeof member.deferred !== "boolean") return false;
|
|
44347
|
+
if (member.deferred && hasAnyParameterDefault(member.argumentTypes)) {
|
|
44348
|
+
return false;
|
|
44349
|
+
}
|
|
44350
|
+
return validateParameterDefaults(member.argumentTypes).length === 0;
|
|
43674
44351
|
}
|
|
43675
44352
|
function isInterfaceMembersRecord(value) {
|
|
43676
44353
|
if (typeof value !== "object") return false;
|
|
@@ -43738,6 +44415,7 @@ var init_interface_types = __esm({
|
|
|
43738
44415
|
init_neoscript_types();
|
|
43739
44416
|
init_docs_text2();
|
|
43740
44417
|
init_neoscript_guards();
|
|
44418
|
+
init_parameter_defaults();
|
|
43741
44419
|
init_member_kinds();
|
|
43742
44420
|
}
|
|
43743
44421
|
});
|
|
@@ -46056,11 +46734,46 @@ function baseConstruction(requiredConstructor) {
|
|
|
46056
46734
|
function renderHeaderParameters(context, requiredConstructor) {
|
|
46057
46735
|
if (requiredConstructor === void 0) return "";
|
|
46058
46736
|
const parameters = requiredConstructor.arguments.map(
|
|
46059
|
-
(argument2) =>
|
|
46737
|
+
(argument2) => renderParameter(context, argument2)
|
|
46060
46738
|
);
|
|
46061
46739
|
if (parameters.length === 0 && requiredConstructor.code !== null) return "";
|
|
46062
46740
|
return `(${parameters.join(", ")})`;
|
|
46063
46741
|
}
|
|
46742
|
+
function renderParameter(context, argument2) {
|
|
46743
|
+
const declaration = `${renderType(context, argument2.type)} ${argument2.name}`;
|
|
46744
|
+
if (argument2.default === null) return declaration;
|
|
46745
|
+
return `${declaration} = ${renderParameterDefault(context, argument2)}`;
|
|
46746
|
+
}
|
|
46747
|
+
function renderParameterDefault(context, argument2) {
|
|
46748
|
+
const value = argument2.default?.value;
|
|
46749
|
+
if (value === null || value === void 0) return "null";
|
|
46750
|
+
if (argument2.type.kind === "enum") {
|
|
46751
|
+
if (typeof value !== "string") {
|
|
46752
|
+
throw new Error(
|
|
46753
|
+
`Parameter ${argument2.name} stores an enum default that is not an option id.`
|
|
46754
|
+
);
|
|
46755
|
+
}
|
|
46756
|
+
const schemaEnum = required(context.enums, argument2.type.enumId, "enum");
|
|
46757
|
+
const option = schemaEnum.options.find(
|
|
46758
|
+
(candidate) => candidate.id === value || candidate.key === value
|
|
46759
|
+
);
|
|
46760
|
+
if (option === void 0) {
|
|
46761
|
+
throw new Error(
|
|
46762
|
+
`Parameter ${argument2.name} defaults to option id ${quote(value)}, which its enum does not declare. Emitting it as null would delete the default on the next push.`
|
|
46763
|
+
);
|
|
46764
|
+
}
|
|
46765
|
+
return `.${option.name}`;
|
|
46766
|
+
}
|
|
46767
|
+
if (argument2.type.kind === "decimal" && typeof value === "string") {
|
|
46768
|
+
return value;
|
|
46769
|
+
}
|
|
46770
|
+
if (typeof value === "string") return quote(value);
|
|
46771
|
+
if (typeof value === "number") return formatNeoNumber(value);
|
|
46772
|
+
if (typeof value === "boolean") return String(value);
|
|
46773
|
+
throw new Error(
|
|
46774
|
+
`Parameter ${argument2.name} stores a default that is not a constant value.`
|
|
46775
|
+
);
|
|
46776
|
+
}
|
|
46064
46777
|
function emitInitBlock(code) {
|
|
46065
46778
|
if (code.trim().length === 0) return "init {\n}";
|
|
46066
46779
|
return `init {
|
|
@@ -46075,7 +46788,7 @@ function emitConstructor(context, schemaClass2, declared) {
|
|
|
46075
46788
|
...docsTextLines(declared.docsText),
|
|
46076
46789
|
id(declared.id).trimEnd()
|
|
46077
46790
|
];
|
|
46078
|
-
const parameters = declared.arguments.map((argument2) =>
|
|
46791
|
+
const parameters = declared.arguments.map((argument2) => renderParameter(context, argument2)).join(", ");
|
|
46079
46792
|
const baseClause = declared.baseArguments === void 0 || declared.baseArguments.length === 0 ? "" : `
|
|
46080
46793
|
: base(${declared.baseArguments.map((argument2) => `${argument2.name}: ${argument2.code}`).join(", ")})`;
|
|
46081
46794
|
const code = declared.code ?? "";
|
|
@@ -46145,9 +46858,7 @@ function emitInterface(context, value) {
|
|
|
46145
46858
|
return `${emitDocsText(member.docsText)}${id(member.id)}${access}${renderType(context, member.type)} ${member.name} { get;${member.settable ? " set;" : ""} }`;
|
|
46146
46859
|
}
|
|
46147
46860
|
const deferred = member.deferred ? "async " : "";
|
|
46148
|
-
return `${emitDocsText(member.docsText)}${id(member.id)}${access}${deferred}${renderReturnType(context, member.returnType)} ${member.name}(${member.arguments.map(
|
|
46149
|
-
(argument2) => `${renderType(context, argument2.type)} ${argument2.name}`
|
|
46150
|
-
).join(", ")});`;
|
|
46861
|
+
return `${emitDocsText(member.docsText)}${id(member.id)}${access}${deferred}${renderReturnType(context, member.returnType)} ${member.name}(${member.arguments.map((argument2) => renderParameter(context, argument2)).join(", ")});`;
|
|
46151
46862
|
});
|
|
46152
46863
|
return `${emitDocsText(value.docsText)}${id(value.id)}interface ${value.name}${bases.length ? ` : ${bases.join(", ")}` : ""} {
|
|
46153
46864
|
${members.map((member) => indentNeoSourceNonEmptyLines(member, 2)).join("\n\n")}
|
|
@@ -46195,9 +46906,7 @@ ${indentNeoSourceNonEmptyLines(setter, 4)}
|
|
|
46195
46906
|
${prefix}${renderType(context, member.returnType)} ${member.name}${body}`;
|
|
46196
46907
|
}
|
|
46197
46908
|
if (member.kind === "function" || member.kind === "scriptFunction") {
|
|
46198
|
-
const signature = `${prefix}${member.deferred ? "async " : ""}${renderReturnType(context, member.returnType)} ${member.name}(${member.arguments.map(
|
|
46199
|
-
(argument2) => `${renderType(context, argument2.type)} ${argument2.name}`
|
|
46200
|
-
).join(", ")})`;
|
|
46909
|
+
const signature = `${prefix}${member.deferred ? "async " : ""}${renderReturnType(context, member.returnType)} ${member.name}(${member.arguments.map((argument2) => renderParameter(context, argument2)).join(", ")})`;
|
|
46201
46910
|
const tracked = member.kind === "scriptFunction" ? member.script?.sourceText ?? uiFunctionSource(context, member) : null;
|
|
46202
46911
|
const body = tracked === null ? null : emitFunctionBody(tracked);
|
|
46203
46912
|
const abstractContract = member.modifier === "abstract" || member.modifier === "abstractOverride";
|
|
@@ -51280,13 +51989,13 @@ function withPersistedConstructorSignatures(index, classes, constructors) {
|
|
|
51280
51989
|
if (required2 !== void 0) {
|
|
51281
51990
|
persistedRequiredByClassName.set(
|
|
51282
51991
|
schemaClass2.name,
|
|
51283
|
-
required2.arguments.map(
|
|
51992
|
+
required2.arguments.map(persistedParameter)
|
|
51284
51993
|
);
|
|
51285
51994
|
}
|
|
51286
51995
|
}
|
|
51287
51996
|
const overloads = (schemaClass2.constructorIds ?? []).flatMap((id2) => {
|
|
51288
51997
|
const constructor2 = byId.get(id2);
|
|
51289
|
-
return constructor2 === void 0 ? [] : [constructor2.arguments.map(
|
|
51998
|
+
return constructor2 === void 0 ? [] : [constructor2.arguments.map(persistedParameter)];
|
|
51290
51999
|
});
|
|
51291
52000
|
if (overloads.length > 0) {
|
|
51292
52001
|
persistedByClassName.set(schemaClass2.name, overloads);
|
|
@@ -51298,6 +52007,10 @@ function withPersistedConstructorSignatures(index, classes, constructors) {
|
|
|
51298
52007
|
persistedRequiredByClassName
|
|
51299
52008
|
};
|
|
51300
52009
|
}
|
|
52010
|
+
function persistedParameter(argument2) {
|
|
52011
|
+
const hasDefault = argument2.default !== null && argument2.default !== void 0;
|
|
52012
|
+
return { name: argument2.name, defaulted: hasDefault };
|
|
52013
|
+
}
|
|
51301
52014
|
function declaresConstructors(index, className) {
|
|
51302
52015
|
if (className === null) return false;
|
|
51303
52016
|
if (index.requiredByClassName.has(className)) return true;
|
|
@@ -51307,16 +52020,24 @@ function declaresConstructors(index, className) {
|
|
|
51307
52020
|
function declaresParameterlessConstructor(index, className) {
|
|
51308
52021
|
if (className === null) return false;
|
|
51309
52022
|
const required2 = index.requiredByClassName.get(className);
|
|
51310
|
-
if (required2 !== void 0 && required2.parameters
|
|
52023
|
+
if (required2 !== void 0 && manifestListIsCallableBare(required2.parameters)) {
|
|
52024
|
+
return true;
|
|
52025
|
+
}
|
|
51311
52026
|
const persistedRequired = index.persistedRequiredByClassName.get(className);
|
|
51312
|
-
if (persistedRequired !== void 0 && persistedRequired
|
|
52027
|
+
if (persistedRequired !== void 0 && persistedListIsCallableBare(persistedRequired)) {
|
|
51313
52028
|
return true;
|
|
51314
52029
|
}
|
|
51315
52030
|
const declared = index.byClassName.get(className);
|
|
51316
|
-
if (declared?.some((entry) => entry.parameters
|
|
52031
|
+
if (declared?.some((entry) => manifestListIsCallableBare(entry.parameters)) === true) {
|
|
51317
52032
|
return true;
|
|
51318
52033
|
}
|
|
51319
|
-
return index.persistedByClassName.get(className)?.some(
|
|
52034
|
+
return index.persistedByClassName.get(className)?.some(persistedListIsCallableBare) ?? false;
|
|
52035
|
+
}
|
|
52036
|
+
function manifestListIsCallableBare(parameters) {
|
|
52037
|
+
return parameters.every((parameter4) => parameter4.default !== null);
|
|
52038
|
+
}
|
|
52039
|
+
function persistedListIsCallableBare(parameters) {
|
|
52040
|
+
return parameters.every((parameter4) => parameter4.defaulted);
|
|
51320
52041
|
}
|
|
51321
52042
|
function initializerRequiresEvaluation(index, expression, targetClassName, runtimeIdentifiers = /* @__PURE__ */ new Set()) {
|
|
51322
52043
|
if (expression.kind === "annotated") {
|
|
@@ -51346,7 +52067,11 @@ function requiredConstructorParameterNames(index, className) {
|
|
|
51346
52067
|
if (required2 !== void 0) {
|
|
51347
52068
|
return new Set(required2.parameters.map((parameter4) => parameter4.name));
|
|
51348
52069
|
}
|
|
51349
|
-
return new Set(
|
|
52070
|
+
return new Set(
|
|
52071
|
+
(index.persistedRequiredByClassName.get(className) ?? []).map(
|
|
52072
|
+
(parameter4) => parameter4.name
|
|
52073
|
+
)
|
|
52074
|
+
);
|
|
51350
52075
|
}
|
|
51351
52076
|
function expressionReadsRuntimeIdentifier(expression, runtimeIdentifiers) {
|
|
51352
52077
|
if (runtimeIdentifiers.size === 0) return false;
|
|
@@ -51438,7 +52163,8 @@ function validateDeclaredConstructorOverloads(declaration) {
|
|
|
51438
52163
|
id: declared.id ?? `${declaration.name}#${String(index)}`,
|
|
51439
52164
|
parameters: declared.parameters.map((parameter4) => ({
|
|
51440
52165
|
name: parameter4.name,
|
|
51441
|
-
typeKey: positionalTypeKey(parameter4.type)
|
|
52166
|
+
typeKey: positionalTypeKey(parameter4.type),
|
|
52167
|
+
defaulted: parameter4.default !== null
|
|
51442
52168
|
}))
|
|
51443
52169
|
}))
|
|
51444
52170
|
).map((error) => ({
|
|
@@ -51464,6 +52190,102 @@ var init_declared_constructors2 = __esm({
|
|
|
51464
52190
|
}
|
|
51465
52191
|
});
|
|
51466
52192
|
|
|
52193
|
+
// src/project-source/lower-parameter-defaults.ts
|
|
52194
|
+
function lowerParameterDefault(context, parameter4, loweredType, path) {
|
|
52195
|
+
if (parameter4.default === null) return null;
|
|
52196
|
+
const expression = parseExpression(parameter4.default);
|
|
52197
|
+
return {
|
|
52198
|
+
value: lowerParameterDefaultValue(context, expression, loweredType, path),
|
|
52199
|
+
source: span({ source: parameter4.source })
|
|
52200
|
+
};
|
|
52201
|
+
}
|
|
52202
|
+
function lowerParameterDefaultValue(context, expression, type, path) {
|
|
52203
|
+
switch (expression.kind) {
|
|
52204
|
+
case "litNull":
|
|
52205
|
+
if (!type.nullable) {
|
|
52206
|
+
throw new Error(
|
|
52207
|
+
`Parameter ${path} defaults to null, but its type is not nullable.`
|
|
52208
|
+
);
|
|
52209
|
+
}
|
|
52210
|
+
return null;
|
|
52211
|
+
case "litBool":
|
|
52212
|
+
if (type.kind !== "bool") {
|
|
52213
|
+
throw new Error(
|
|
52214
|
+
`Parameter ${path} defaults to a bool literal, but its type is ${type.kind}.`
|
|
52215
|
+
);
|
|
52216
|
+
}
|
|
52217
|
+
return expression.value;
|
|
52218
|
+
case "litString":
|
|
52219
|
+
if (type.kind !== "string") {
|
|
52220
|
+
throw new Error(
|
|
52221
|
+
`Parameter ${path} defaults to a string literal, but its type is ${type.kind}.`
|
|
52222
|
+
);
|
|
52223
|
+
}
|
|
52224
|
+
return expression.value;
|
|
52225
|
+
case "litInt":
|
|
52226
|
+
if (type.kind === "decimal") return expression.raw;
|
|
52227
|
+
if (type.kind !== "int" && type.kind !== "float") {
|
|
52228
|
+
throw new Error(
|
|
52229
|
+
`Parameter ${path} defaults to a number literal, but its type is ${type.kind}.`
|
|
52230
|
+
);
|
|
52231
|
+
}
|
|
52232
|
+
return expression.value;
|
|
52233
|
+
case "litFloat":
|
|
52234
|
+
if (type.kind === "decimal") return expression.raw;
|
|
52235
|
+
if (type.kind !== "float") {
|
|
52236
|
+
throw new Error(
|
|
52237
|
+
`Parameter ${path} defaults to a fractional literal, but its type is ${type.kind}.`
|
|
52238
|
+
);
|
|
52239
|
+
}
|
|
52240
|
+
return expression.value;
|
|
52241
|
+
case "unary": {
|
|
52242
|
+
if (expression.op !== "-") {
|
|
52243
|
+
throw new Error(
|
|
52244
|
+
`Parameter ${path} default uses unary ${JSON.stringify(expression.op)}, which is not a constant spelling.`
|
|
52245
|
+
);
|
|
52246
|
+
}
|
|
52247
|
+
const operand = lowerParameterDefaultValue(
|
|
52248
|
+
context,
|
|
52249
|
+
expression.operand,
|
|
52250
|
+
type,
|
|
52251
|
+
path
|
|
52252
|
+
);
|
|
52253
|
+
if (typeof operand === "number") return -operand;
|
|
52254
|
+
if (type.kind === "decimal" && typeof operand === "string") {
|
|
52255
|
+
return operand.startsWith("-") ? operand.slice(1) : `-${operand}`;
|
|
52256
|
+
}
|
|
52257
|
+
throw new Error(
|
|
52258
|
+
`Parameter ${path} default applies unary minus to a non-numeric literal.`
|
|
52259
|
+
);
|
|
52260
|
+
}
|
|
52261
|
+
case "contextualEnum": {
|
|
52262
|
+
if (type.kind !== "enum") {
|
|
52263
|
+
throw new Error(
|
|
52264
|
+
`Parameter ${path} defaults to enum option .${expression.name}, but its type is ${type.kind}.`
|
|
52265
|
+
);
|
|
52266
|
+
}
|
|
52267
|
+
const optionId = context.enumOptionsByName.get(type.enumId)?.get(expression.name);
|
|
52268
|
+
if (optionId === void 0) {
|
|
52269
|
+
throw new Error(
|
|
52270
|
+
`Parameter ${path} defaults to .${expression.name}, which its enum does not declare.`
|
|
52271
|
+
);
|
|
52272
|
+
}
|
|
52273
|
+
return optionId;
|
|
52274
|
+
}
|
|
52275
|
+
default:
|
|
52276
|
+
throw new Error(
|
|
52277
|
+
`Parameter ${path} default is not a constant expression.`
|
|
52278
|
+
);
|
|
52279
|
+
}
|
|
52280
|
+
}
|
|
52281
|
+
var init_lower_parameter_defaults = __esm({
|
|
52282
|
+
"src/project-source/lower-parameter-defaults.ts"() {
|
|
52283
|
+
"use strict";
|
|
52284
|
+
init_src();
|
|
52285
|
+
init_lower_support();
|
|
52286
|
+
}
|
|
52287
|
+
});
|
|
52288
|
+
|
|
51467
52289
|
// src/project-source/init-source.ts
|
|
51468
52290
|
function commentEndIndex(source, index) {
|
|
51469
52291
|
if (source[index] !== "/") return null;
|
|
@@ -51700,12 +52522,21 @@ function lowerClassConstructors(context, declaration, classId, lowerParameterTyp
|
|
|
51700
52522
|
const declared = declaration.constructors.map((declared2) => {
|
|
51701
52523
|
const id2 = declaredConstructorId2(declaration, declared2);
|
|
51702
52524
|
const base = context.baseConstructors.get(id2);
|
|
51703
|
-
const parameters = declared2.parameters.map((parameter4) =>
|
|
51704
|
-
|
|
51705
|
-
|
|
51706
|
-
|
|
51707
|
-
|
|
51708
|
-
|
|
52525
|
+
const parameters = declared2.parameters.map((parameter4) => {
|
|
52526
|
+
const parameterType = lowerParameterType(parameter4.type, declaration);
|
|
52527
|
+
return {
|
|
52528
|
+
name: parameter4.name,
|
|
52529
|
+
type: parameterType,
|
|
52530
|
+
default: lowerParameterDefault(
|
|
52531
|
+
context,
|
|
52532
|
+
parameter4,
|
|
52533
|
+
parameterType,
|
|
52534
|
+
`${declaration.name}.${declared2.name}(${parameter4.name})`
|
|
52535
|
+
),
|
|
52536
|
+
source: span({ source: parameter4.source }),
|
|
52537
|
+
selectionSpan: span({ source: parameter4.source })
|
|
52538
|
+
};
|
|
52539
|
+
});
|
|
51709
52540
|
const baseArguments = (declared2.baseArguments ?? []).map((argument2) => ({
|
|
51710
52541
|
name: argument2.name,
|
|
51711
52542
|
code: argument2.expression.trim()
|
|
@@ -51746,12 +52577,21 @@ function lowerRequiredConstructor(context, declaration, classId, lowerParameterT
|
|
|
51746
52577
|
selectionSpan: sourceSpan
|
|
51747
52578
|
},
|
|
51748
52579
|
classId,
|
|
51749
|
-
arguments: required2.parameters.map((parameter4) =>
|
|
51750
|
-
|
|
51751
|
-
|
|
51752
|
-
|
|
51753
|
-
|
|
51754
|
-
|
|
52580
|
+
arguments: required2.parameters.map((parameter4) => {
|
|
52581
|
+
const parameterType = lowerParameterType(parameter4.type, declaration);
|
|
52582
|
+
return {
|
|
52583
|
+
name: parameter4.name,
|
|
52584
|
+
type: parameterType,
|
|
52585
|
+
default: lowerParameterDefault(
|
|
52586
|
+
context,
|
|
52587
|
+
parameter4,
|
|
52588
|
+
parameterType,
|
|
52589
|
+
`${declaration.name}(${parameter4.name})`
|
|
52590
|
+
),
|
|
52591
|
+
source: span({ source: parameter4.source }),
|
|
52592
|
+
selectionSpan: span({ source: parameter4.source })
|
|
52593
|
+
};
|
|
52594
|
+
}),
|
|
51755
52595
|
code: requiredConstructorBody(required2.body, base?.code),
|
|
51756
52596
|
...baseArguments.length === 0 ? {} : {
|
|
51757
52597
|
baseArguments: baseArguments.map(
|
|
@@ -51834,10 +52674,10 @@ function recordBaseParameterNames(context, baseName, suppliedNames) {
|
|
|
51834
52674
|
function selectOverload(candidates, suppliedNames) {
|
|
51835
52675
|
if (candidates.length === 0) return null;
|
|
51836
52676
|
if (candidates.length === 1) return candidates[0];
|
|
51837
|
-
const key =
|
|
51838
|
-
return candidates.find((names) =>
|
|
52677
|
+
const key = argumentNameSetKey(suppliedNames);
|
|
52678
|
+
return candidates.find((names) => argumentNameSetKey(names) === key) ?? null;
|
|
51839
52679
|
}
|
|
51840
|
-
function
|
|
52680
|
+
function argumentNameSetKey(names) {
|
|
51841
52681
|
return [...names].map((name) => name.toLowerCase()).sort().join(",");
|
|
51842
52682
|
}
|
|
51843
52683
|
function baseTypeName(declaration) {
|
|
@@ -51876,6 +52716,7 @@ var init_lower_constructors = __esm({
|
|
|
51876
52716
|
init_src();
|
|
51877
52717
|
init_required_constructor_id();
|
|
51878
52718
|
init_declared_constructors2();
|
|
52719
|
+
init_lower_parameter_defaults();
|
|
51879
52720
|
init_init_source();
|
|
51880
52721
|
init_lower_support();
|
|
51881
52722
|
}
|
|
@@ -52223,12 +53064,21 @@ function lowerMemberKind(context, ownerClass, declaration, id2, owner) {
|
|
|
52223
53064
|
if (declaration.kind === "function") {
|
|
52224
53065
|
const returnType = declaration.type.name === "void" ? { kind: "void", nullable: false } : lowerType(context, declaration.type, ownerClass);
|
|
52225
53066
|
const argumentsValue = declaration.parameters.map(
|
|
52226
|
-
(parameter4) =>
|
|
52227
|
-
|
|
52228
|
-
|
|
52229
|
-
|
|
52230
|
-
|
|
52231
|
-
|
|
53067
|
+
(parameter4) => {
|
|
53068
|
+
const parameterType = lowerType(context, parameter4.type, ownerClass);
|
|
53069
|
+
return {
|
|
53070
|
+
name: parameter4.name,
|
|
53071
|
+
type: parameterType,
|
|
53072
|
+
default: lowerParameterDefault(
|
|
53073
|
+
context,
|
|
53074
|
+
parameter4,
|
|
53075
|
+
parameterType,
|
|
53076
|
+
`${ownerClass.name}.${declaration.name}(${parameter4.name})`
|
|
53077
|
+
),
|
|
53078
|
+
source: span(parameter4),
|
|
53079
|
+
selectionSpan: span(parameter4)
|
|
53080
|
+
};
|
|
53081
|
+
}
|
|
52232
53082
|
);
|
|
52233
53083
|
const settings = annotation(declaration.annotations, "settings");
|
|
52234
53084
|
const logicMode = contextualEnumArgument(settings, "logic");
|
|
@@ -52458,6 +53308,7 @@ function lowerFieldMember(context, ownerClass, declaration, id2, commonInput, ba
|
|
|
52458
53308
|
arguments: fieldType.arguments.slice(1).map((argumentType, index) => ({
|
|
52459
53309
|
name: `p${index + 1}`,
|
|
52460
53310
|
type: lowerType(context, argumentType, ownerClass),
|
|
53311
|
+
default: null,
|
|
52461
53312
|
source: span(declaration),
|
|
52462
53313
|
selectionSpan: span(declaration)
|
|
52463
53314
|
}))
|
|
@@ -52482,6 +53333,7 @@ function lowerFieldMember(context, ownerClass, declaration, id2, commonInput, ba
|
|
|
52482
53333
|
arguments: fieldType.arguments.map((argumentType, index) => ({
|
|
52483
53334
|
name: `p${index + 1}`,
|
|
52484
53335
|
type: lowerType(context, argumentType, ownerClass),
|
|
53336
|
+
default: null,
|
|
52485
53337
|
source: span(declaration),
|
|
52486
53338
|
selectionSpan: span(declaration)
|
|
52487
53339
|
}))
|
|
@@ -52941,12 +53793,21 @@ function lowerInterface(context, declaration) {
|
|
|
52941
53793
|
name: member.name,
|
|
52942
53794
|
...member.docsText === void 0 ? {} : { docsText: member.docsText },
|
|
52943
53795
|
returnType: member.type.name === "void" ? { kind: "void", nullable: false } : lowerType(context, member.type),
|
|
52944
|
-
arguments: member.parameters.map((parameter4) =>
|
|
52945
|
-
|
|
52946
|
-
|
|
52947
|
-
|
|
52948
|
-
|
|
52949
|
-
|
|
53796
|
+
arguments: member.parameters.map((parameter4) => {
|
|
53797
|
+
const parameterType = lowerType(context, parameter4.type);
|
|
53798
|
+
return {
|
|
53799
|
+
name: parameter4.name,
|
|
53800
|
+
type: parameterType,
|
|
53801
|
+
default: lowerParameterDefault(
|
|
53802
|
+
context,
|
|
53803
|
+
parameter4,
|
|
53804
|
+
parameterType,
|
|
53805
|
+
`${declaration.name}.${member.name}(${parameter4.name})`
|
|
53806
|
+
),
|
|
53807
|
+
source: span(parameter4),
|
|
53808
|
+
selectionSpan: span(parameter4)
|
|
53809
|
+
};
|
|
53810
|
+
}),
|
|
52950
53811
|
deferred: member.modifiers.includes("async"),
|
|
52951
53812
|
accessModifier,
|
|
52952
53813
|
source
|
|
@@ -54264,6 +55125,7 @@ var init_lower_members = __esm({
|
|
|
54264
55125
|
init_src();
|
|
54265
55126
|
init_lower_support();
|
|
54266
55127
|
init_lower_constructors();
|
|
55128
|
+
init_lower_parameter_defaults();
|
|
54267
55129
|
init_declared_constructors2();
|
|
54268
55130
|
init_init_source();
|
|
54269
55131
|
init_ui_action_source();
|
|
@@ -54399,7 +55261,8 @@ function createNeoScriptDocumentContext(context, projectOverride) {
|
|
|
54399
55261
|
const parameters = context.functionArguments?.map((argument2, index) => ({
|
|
54400
55262
|
id: `function-parameter:${index}:${argument2.name}`,
|
|
54401
55263
|
name: argument2.name,
|
|
54402
|
-
type: toLanguageType(argument2, context)
|
|
55264
|
+
type: toLanguageType(argument2, context),
|
|
55265
|
+
...parameterDefaultDescriptor(argument2, context)
|
|
54403
55266
|
}));
|
|
54404
55267
|
return {
|
|
54405
55268
|
kind: documentKind,
|
|
@@ -54421,6 +55284,32 @@ function createNeoScriptDocumentContext(context, projectOverride) {
|
|
|
54421
55284
|
} : {}
|
|
54422
55285
|
};
|
|
54423
55286
|
}
|
|
55287
|
+
function parameterDefaultDescriptor(argument2, context) {
|
|
55288
|
+
if (argument2.defaultValue === void 0) return {};
|
|
55289
|
+
const value = argument2.defaultValue.value;
|
|
55290
|
+
const enumOptionName = argument2.type === 8 /* Enum */ && typeof value === "string" ? analyzerEnumOptionName(argument2.enumId, value, context) : void 0;
|
|
55291
|
+
return {
|
|
55292
|
+
defaultValue: {
|
|
55293
|
+
displayText: neoScriptParameterDefaultDisplayText({
|
|
55294
|
+
value,
|
|
55295
|
+
kind: parameterDefaultSpellingKind(argument2.type),
|
|
55296
|
+
...enumOptionName === void 0 ? {} : { enumOptionName }
|
|
55297
|
+
}),
|
|
55298
|
+
value
|
|
55299
|
+
}
|
|
55300
|
+
};
|
|
55301
|
+
}
|
|
55302
|
+
function parameterDefaultSpellingKind(type) {
|
|
55303
|
+
if (type === 8 /* Enum */) return "enum";
|
|
55304
|
+
if (type === 20 /* Decimal */) return "decimal";
|
|
55305
|
+
return "other";
|
|
55306
|
+
}
|
|
55307
|
+
function analyzerEnumOptionName(enumId, optionId, context) {
|
|
55308
|
+
const enumDefinition = context.vm.enums.find(
|
|
55309
|
+
(candidate) => candidate.id === enumId
|
|
55310
|
+
);
|
|
55311
|
+
return enumDefinition?.options[optionId]?.name;
|
|
55312
|
+
}
|
|
54424
55313
|
function createNeoScriptProject(context) {
|
|
54425
55314
|
const languageTypes = [];
|
|
54426
55315
|
for (const schemaClass2 of context.vm.classes) {
|
|
@@ -54708,7 +55597,8 @@ function declaredConstructors(schemaClass2, context) {
|
|
|
54708
55597
|
parameters: record3.argumentTypes.map((argument2) => ({
|
|
54709
55598
|
name: argument2.name,
|
|
54710
55599
|
type: toLanguageType(argument2, context),
|
|
54711
|
-
required: argument2.required
|
|
55600
|
+
required: argument2.required,
|
|
55601
|
+
...parameterDefaultDescriptor(argument2, context)
|
|
54712
55602
|
})),
|
|
54713
55603
|
...record3.docsText ? { documentation: record3.docsText } : {},
|
|
54714
55604
|
...record3.id === required2 ? { required: true } : {}
|
|
@@ -54784,7 +55674,8 @@ function memberToSymbol(record3, schemaKey, containingClass2, ownerClassId, inde
|
|
|
54784
55674
|
(argument2, argumentIndex) => ({
|
|
54785
55675
|
id: `${record3.id}:argument:${argumentIndex}`,
|
|
54786
55676
|
name: argument2.name,
|
|
54787
|
-
type: toLanguageType(argument2, context, genericEnvironment)
|
|
55677
|
+
type: toLanguageType(argument2, context, genericEnvironment),
|
|
55678
|
+
...parameterDefaultDescriptor(argument2, context)
|
|
54788
55679
|
})
|
|
54789
55680
|
),
|
|
54790
55681
|
deferred: authoredCallable.deferred,
|
|
@@ -54955,7 +55846,8 @@ function interfaceMemberToSymbol(neoInterface, key, member, context, inherited)
|
|
|
54955
55846
|
parameters: member.argumentTypes.map((argument2, index) => ({
|
|
54956
55847
|
id: `${neoInterface.id}:member:${key}:argument:${index}`,
|
|
54957
55848
|
name: argument2.name,
|
|
54958
|
-
type: toLanguageType(argument2, context)
|
|
55849
|
+
type: toLanguageType(argument2, context),
|
|
55850
|
+
...parameterDefaultDescriptor(argument2, context)
|
|
54959
55851
|
})),
|
|
54960
55852
|
deferred: member.deferred,
|
|
54961
55853
|
abstract: true,
|
|
@@ -56535,13 +57427,13 @@ function resolveBaseConstructorOverload(args, owner) {
|
|
|
56535
57427
|
`Constructor "${args.constructor.id}" declares a base call, but base class "${baseClass.name}" declares no constructors.`
|
|
56536
57428
|
);
|
|
56537
57429
|
}
|
|
56538
|
-
const requested =
|
|
57430
|
+
const requested = argumentNameSetKey2(
|
|
56539
57431
|
(args.constructor.baseArguments ?? []).map(
|
|
56540
57432
|
(baseArgument) => baseArgument.name
|
|
56541
57433
|
)
|
|
56542
57434
|
);
|
|
56543
57435
|
const matches = candidates.filter(
|
|
56544
|
-
(candidate) =>
|
|
57436
|
+
(candidate) => argumentNameSetKey2(
|
|
56545
57437
|
candidate.argumentTypes.map((argument2) => argument2.name)
|
|
56546
57438
|
) === requested
|
|
56547
57439
|
);
|
|
@@ -56597,7 +57489,7 @@ function declaredConstructorsOfClass(constructors, schemaClass2) {
|
|
|
56597
57489
|
return [record3];
|
|
56598
57490
|
});
|
|
56599
57491
|
}
|
|
56600
|
-
function
|
|
57492
|
+
function argumentNameSetKey2(names) {
|
|
56601
57493
|
return [...names].map((name) => name.toLowerCase()).sort().join(", ");
|
|
56602
57494
|
}
|
|
56603
57495
|
function describeConstructorOverloads(constructors) {
|
|
@@ -59911,16 +60803,21 @@ function executeCompiledFunction(action, ctx, args, allowFallthroughReturn, runt
|
|
|
59911
60803
|
`Corrupt NSFunction IR: compiled body has ${action.parameters.length - 2} argument parameter(s), but its runtime signature declares ${expectedCount}.`
|
|
59912
60804
|
);
|
|
59913
60805
|
}
|
|
59914
|
-
|
|
60806
|
+
const filledArgs = runtimeSignature === void 0 ? args : fillTrailingParameterDefaults(
|
|
60807
|
+
args,
|
|
60808
|
+
runtimeSignature.argumentTypes,
|
|
60809
|
+
"NSFunction"
|
|
60810
|
+
);
|
|
60811
|
+
if (filledArgs.length !== expectedCount) {
|
|
59915
60812
|
throw new NSGetterRuntimeError(
|
|
59916
|
-
`NSFunction expected ${expectedCount} argument(s), got ${
|
|
60813
|
+
`NSFunction expected ${expectedCount} argument(s), got ${filledArgs.length}.`
|
|
59917
60814
|
);
|
|
59918
60815
|
}
|
|
59919
60816
|
const scope = createTopLevelScope(ctx);
|
|
59920
|
-
for (let index = 0; index <
|
|
60817
|
+
for (let index = 0; index < filledArgs.length; index += 1) {
|
|
59921
60818
|
const parameter4 = action.parameters[index + 2];
|
|
59922
60819
|
const runtimeTypeInfo = runtimeArgumentTypes[index];
|
|
59923
|
-
const value2 =
|
|
60820
|
+
const value2 = filledArgs[index];
|
|
59924
60821
|
if (!runtimeValueMatchesType(value2, runtimeTypeInfo, ctx)) {
|
|
59925
60822
|
throw new NSGetterRuntimeError(
|
|
59926
60823
|
`NSFunction argument ${index + 1} does not match its declared runtime type.`
|
|
@@ -59961,6 +60858,57 @@ function executeCompiledFunction(action, ctx, args, allowFallthroughReturn, runt
|
|
|
59961
60858
|
}
|
|
59962
60859
|
return value;
|
|
59963
60860
|
}
|
|
60861
|
+
function fillTrailingParameterDefaults(args, argumentTypes, subject) {
|
|
60862
|
+
const maxArity = argumentTypes.length;
|
|
60863
|
+
const minArity = argumentTypes.filter(
|
|
60864
|
+
(parameter4) => !parameterHasDefault(parameter4)
|
|
60865
|
+
).length;
|
|
60866
|
+
const expectedArity = minArity === maxArity ? `${maxArity} argument(s)` : `between ${minArity} and ${maxArity} argument(s)`;
|
|
60867
|
+
if (args.length > maxArity) {
|
|
60868
|
+
throw new NSGetterRuntimeError(
|
|
60869
|
+
`${subject} expected ${expectedArity}, got ${args.length}.`
|
|
60870
|
+
);
|
|
60871
|
+
}
|
|
60872
|
+
if (args.length < minArity) {
|
|
60873
|
+
throw new NSGetterRuntimeError(
|
|
60874
|
+
`${subject} expected ${expectedArity}, got ${args.length}.`
|
|
60875
|
+
);
|
|
60876
|
+
}
|
|
60877
|
+
if (args.length === maxArity) return args;
|
|
60878
|
+
const filled = [...args];
|
|
60879
|
+
for (let index = args.length; index < maxArity; index += 1) {
|
|
60880
|
+
const parameter4 = argumentTypes[index];
|
|
60881
|
+
if (parameter4 === void 0) {
|
|
60882
|
+
throw new NSGetterRuntimeError(
|
|
60883
|
+
`${subject} has a hole in its argument types at position ${index}.`
|
|
60884
|
+
);
|
|
60885
|
+
}
|
|
60886
|
+
filled.push(parameterDefaultRuntimeValue(parameter4, subject));
|
|
60887
|
+
}
|
|
60888
|
+
return filled;
|
|
60889
|
+
}
|
|
60890
|
+
function parameterDefaultRuntimeValue(parameter4, subject) {
|
|
60891
|
+
const defaultValue = parameter4.defaultValue;
|
|
60892
|
+
if (defaultValue === void 0) {
|
|
60893
|
+
throw new NSGetterRuntimeError(
|
|
60894
|
+
`${subject} parameter '${parameter4.name}' was omitted but declares no default.`
|
|
60895
|
+
);
|
|
60896
|
+
}
|
|
60897
|
+
if (defaultValue.value === null) return null;
|
|
60898
|
+
if (parameter4.type === 8 /* Enum */) return [defaultValue.value];
|
|
60899
|
+
return defaultValue.value;
|
|
60900
|
+
}
|
|
60901
|
+
function fillCallableCallSiteArguments(args, member, ctx) {
|
|
60902
|
+
if (member === null) return args;
|
|
60903
|
+
if (member.kind !== 13 /* Function */ && member.kind !== 23 /* NSFunction */) {
|
|
60904
|
+
return args;
|
|
60905
|
+
}
|
|
60906
|
+
const signature = resolveCallableSignature(member.id, member.kind, ctx);
|
|
60907
|
+
if (signature === null) return args;
|
|
60908
|
+
if (!hasAnyParameterDefault(signature.argumentTypes)) return args;
|
|
60909
|
+
const subject = member.kind === 13 /* Function */ ? `Function '${member.name}'` : `NSFunction '${member.name}'`;
|
|
60910
|
+
return fillTrailingParameterDefaults(args, signature.argumentTypes, subject);
|
|
60911
|
+
}
|
|
59964
60912
|
function createChildScope(parent) {
|
|
59965
60913
|
return new NeoScriptScope(parent);
|
|
59966
60914
|
}
|
|
@@ -61257,8 +62205,11 @@ function evalPointer(pointer, scope, ctx) {
|
|
|
61257
62205
|
if (pointer.receiver.kind === "instance" && pointer.optional === true && (innerThis === null || innerThis === void 0)) {
|
|
61258
62206
|
return null;
|
|
61259
62207
|
}
|
|
61260
|
-
const
|
|
62208
|
+
const suppliedArgs = pointer.args.map(
|
|
62209
|
+
(arg) => evalPointer(arg, scope, ctx)
|
|
62210
|
+
);
|
|
61261
62211
|
const member = pointer.receiver.kind === "static" ? evalMemberById(ctx.vm, pointer.receiver.memberId) : resolveEffectiveCallableMember(pointer, innerThis, ctx);
|
|
62212
|
+
const args = fillCallableCallSiteArguments(suppliedArgs, member, ctx);
|
|
61262
62213
|
const interceptedMemberId = member?.id ?? pointer.memberId ?? pointer.memberKey ?? pointer.callSiteId;
|
|
61263
62214
|
consumeBudget(ctx, "workUnits", 1, "work unit");
|
|
61264
62215
|
const intercepted = ctx.callInterceptor?.({
|
|
@@ -61781,13 +62732,21 @@ function substituteCallableSignatureForReceiver(signature, receiver, ctx) {
|
|
|
61781
62732
|
ctx
|
|
61782
62733
|
),
|
|
61783
62734
|
argumentTypes: signature.argumentTypes.map((argument2) => {
|
|
62735
|
+
if (!typeInfoContainsGeneric(argument2)) return argument2;
|
|
61784
62736
|
const substituted = substituteRuntimeTypeInfo(argument2, env, ctx);
|
|
61785
62737
|
if (substituted.type === NS_TYPE_VOID) {
|
|
61786
62738
|
throw new NSGetterRuntimeError(
|
|
61787
62739
|
`Generic NSFunction argument '${argument2.name}' resolved to Void.`
|
|
61788
62740
|
);
|
|
61789
62741
|
}
|
|
61790
|
-
|
|
62742
|
+
const named = { ...substituted, name: argument2.name };
|
|
62743
|
+
if (argument2.defaultValue === void 0) return named;
|
|
62744
|
+
if (argument2.defaultValue.value !== null) {
|
|
62745
|
+
throw new NSGetterRuntimeError(
|
|
62746
|
+
`Generic NSFunction parameter '${argument2.name}' carries a non-null constant default, which a generic parameter cannot declare.`
|
|
62747
|
+
);
|
|
62748
|
+
}
|
|
62749
|
+
return { ...named, defaultValue: { value: null } };
|
|
61791
62750
|
})
|
|
61792
62751
|
};
|
|
61793
62752
|
} catch (error) {
|
|
@@ -64262,15 +65221,21 @@ function resolveDeclaredConstructorRecord(info, schemaClass2, ctx) {
|
|
|
64262
65221
|
`Declared constructor call on '${schemaClass2.name}' passes the same argument name twice.`
|
|
64263
65222
|
);
|
|
64264
65223
|
}
|
|
64265
|
-
|
|
65224
|
+
const supplied = new Set(suppliedNames);
|
|
65225
|
+
for (const parameter4 of record3.argumentTypes) {
|
|
65226
|
+
if (supplied.has(parameter4.name)) continue;
|
|
65227
|
+
if (parameterHasDefault(parameter4)) continue;
|
|
64266
65228
|
throw new NSGetterRuntimeError(
|
|
64267
|
-
`
|
|
65229
|
+
`Declared constructor call on '${schemaClass2.name}' has no argument for parameter '${parameter4.name}'.`
|
|
64268
65230
|
);
|
|
64269
65231
|
}
|
|
64270
|
-
|
|
64271
|
-
|
|
65232
|
+
const declaredNames = new Set(
|
|
65233
|
+
record3.argumentTypes.map((parameter4) => parameter4.name)
|
|
65234
|
+
);
|
|
65235
|
+
for (const name of suppliedNames) {
|
|
65236
|
+
if (declaredNames.has(name)) continue;
|
|
64272
65237
|
throw new NSGetterRuntimeError(
|
|
64273
|
-
`Declared constructor call on '${schemaClass2.name}'
|
|
65238
|
+
`Declared constructor call on '${schemaClass2.name}' names unknown parameter '${name}'.`
|
|
64274
65239
|
);
|
|
64275
65240
|
}
|
|
64276
65241
|
return record3;
|
|
@@ -64281,6 +65246,12 @@ function evaluateDeclaredConstructorArguments(info, record3, scope, ctx) {
|
|
|
64281
65246
|
byName.set(argument2.name, evalPointer(argument2.valuePointer, scope, ctx));
|
|
64282
65247
|
}
|
|
64283
65248
|
return record3.argumentTypes.map((parameter4) => {
|
|
65249
|
+
if (!byName.has(parameter4.name)) {
|
|
65250
|
+
return parameterDefaultRuntimeValue(
|
|
65251
|
+
parameter4,
|
|
65252
|
+
`Constructor '${record3.id}'`
|
|
65253
|
+
);
|
|
65254
|
+
}
|
|
64284
65255
|
const value = byName.get(parameter4.name);
|
|
64285
65256
|
if (parameter4.type !== 20 /* Decimal */) return value;
|
|
64286
65257
|
if (typeof value !== "number") return value;
|
|
@@ -64311,7 +65282,7 @@ function resolveBaseConstructorRecord(record3, ctx) {
|
|
|
64311
65282
|
if (baseArguments.length === 0) {
|
|
64312
65283
|
if (candidates.length === 0) return null;
|
|
64313
65284
|
const parameterless = candidates.find(
|
|
64314
|
-
(candidate) => candidate.argumentTypes.
|
|
65285
|
+
(candidate) => candidate.argumentTypes.every(parameterHasDefault)
|
|
64315
65286
|
);
|
|
64316
65287
|
if (parameterless === void 0) {
|
|
64317
65288
|
throw new NSGetterRuntimeError(
|
|
@@ -64322,17 +65293,32 @@ function resolveBaseConstructorRecord(record3, ctx) {
|
|
|
64322
65293
|
}
|
|
64323
65294
|
const names = new Set(baseArguments.map((argument2) => argument2.name));
|
|
64324
65295
|
const matches = candidates.filter(
|
|
64325
|
-
(candidate) => candidate.argumentTypes.
|
|
65296
|
+
(candidate) => candidate.argumentTypes.every(
|
|
65297
|
+
(parameter4) => names.has(parameter4.name) || parameterHasDefault(parameter4)
|
|
65298
|
+
) && [...names].every(
|
|
65299
|
+
(name) => candidate.argumentTypes.some((parameter4) => parameter4.name === name)
|
|
65300
|
+
)
|
|
64326
65301
|
);
|
|
64327
|
-
|
|
64328
|
-
if (firstMatch === void 0) {
|
|
65302
|
+
if (matches.length === 0) {
|
|
64329
65303
|
throw new NSGetterRuntimeError(
|
|
64330
65304
|
`Constructor '${record3.id}' on '${owningClass.name}' calls ': base(${[...names].join(", ")})', which matches no constructor on its base class.`
|
|
64331
65305
|
);
|
|
64332
65306
|
}
|
|
64333
|
-
|
|
65307
|
+
const fewestFillIns = Math.min(
|
|
65308
|
+
...matches.map((candidate) => candidate.argumentTypes.length - names.size)
|
|
65309
|
+
);
|
|
65310
|
+
const best = matches.filter(
|
|
65311
|
+
(candidate) => candidate.argumentTypes.length - names.size === fewestFillIns
|
|
65312
|
+
);
|
|
65313
|
+
const firstMatch = best[0];
|
|
65314
|
+
if (firstMatch === void 0) {
|
|
65315
|
+
throw new NSGetterRuntimeError(
|
|
65316
|
+
`Constructor '${record3.id}' on '${owningClass.name}' resolved ': base(${[...names].join(", ")})' to an empty betterness set.`
|
|
65317
|
+
);
|
|
65318
|
+
}
|
|
65319
|
+
if (best.length > 1) {
|
|
64334
65320
|
throw new NSGetterRuntimeError(
|
|
64335
|
-
`Constructor '${record3.id}' on '${owningClass.name}' calls ': base(${[...names].join(", ")})', which matches ${
|
|
65321
|
+
`Constructor '${record3.id}' on '${owningClass.name}' calls ': base(${[...names].join(", ")})', which matches ${best.length} base constructors: ${best.map((candidate) => candidate.id).join(", ")}.`
|
|
64336
65322
|
);
|
|
64337
65323
|
}
|
|
64338
65324
|
return firstMatch;
|
|
@@ -64366,6 +65352,12 @@ function evaluateBaseConstructorArguments(record3, baseRecord, argumentValues, t
|
|
|
64366
65352
|
}
|
|
64367
65353
|
return baseRecord.argumentTypes.map((parameter4) => {
|
|
64368
65354
|
if (!byName.has(parameter4.name)) {
|
|
65355
|
+
if (parameterHasDefault(parameter4)) {
|
|
65356
|
+
return parameterDefaultRuntimeValue(
|
|
65357
|
+
parameter4,
|
|
65358
|
+
`Constructor '${baseRecord.id}'`
|
|
65359
|
+
);
|
|
65360
|
+
}
|
|
64369
65361
|
throw new NSGetterRuntimeError(
|
|
64370
65362
|
`Constructor '${record3.id}' calls ': base(...)' without an argument for base parameter '${parameter4.name}'.`
|
|
64371
65363
|
);
|
|
@@ -66479,12 +67471,15 @@ function isNeoClassConstructorBase(value) {
|
|
|
66479
67471
|
if (typeof v.code !== "string" && v.code !== null) return false;
|
|
66480
67472
|
if (!Array.isArray(v.argumentTypes)) return false;
|
|
66481
67473
|
const parameterNames = /* @__PURE__ */ new Set();
|
|
67474
|
+
const argumentTypes = [];
|
|
66482
67475
|
for (const argument2 of v.argumentTypes) {
|
|
66483
67476
|
if (!isNSFunctionArgumentTypeInfo(argument2)) return false;
|
|
66484
67477
|
if (!isValidCallableIdentifier(argument2.name)) return false;
|
|
66485
67478
|
if (parameterNames.has(argument2.name)) return false;
|
|
66486
67479
|
parameterNames.add(argument2.name);
|
|
67480
|
+
argumentTypes.push(argument2);
|
|
66487
67481
|
}
|
|
67482
|
+
if (validateParameterDefaults(argumentTypes).length > 0) return false;
|
|
66488
67483
|
if (v.baseArguments !== void 0 && v.baseArguments !== null) {
|
|
66489
67484
|
if (!Array.isArray(v.baseArguments)) return false;
|
|
66490
67485
|
const baseNames = /* @__PURE__ */ new Set();
|
|
@@ -76040,7 +77035,7 @@ function stableValue(value) {
|
|
|
76040
77035
|
if (Array.isArray(value)) return value.map(stableValue);
|
|
76041
77036
|
if (!isRecord7(value)) return value;
|
|
76042
77037
|
const normalized = Object.fromEntries(
|
|
76043
|
-
Object.entries(value).filter(([key]) => key !== "name").sort(([left], [right]) => left.localeCompare(right)).map(([key, entry]) => [key, stableValue(entry)])
|
|
77038
|
+
Object.entries(value).filter(([key]) => key !== "name" && key !== "defaultValue").sort(([left], [right]) => left.localeCompare(right)).map(([key, entry]) => [key, stableValue(entry)])
|
|
76044
77039
|
);
|
|
76045
77040
|
return normalized;
|
|
76046
77041
|
}
|
|
@@ -76142,11 +77137,81 @@ function isOpaqueNSFunctionReturnTypeInfo(value) {
|
|
|
76142
77137
|
return isOpaqueNSTypeInfo(value);
|
|
76143
77138
|
}
|
|
76144
77139
|
function isOpaqueNSFunctionArgumentTypeInfo(value) {
|
|
76145
|
-
return isOpaqueNSTypeInfo(value) && isOpaqueCallableIdentifier(value.name) && !opaqueTypeInfoContainsUnknown(value);
|
|
77140
|
+
return isOpaqueNSTypeInfo(value) && isOpaqueCallableIdentifier(value.name) && !opaqueTypeInfoContainsUnknown(value) && hasValidOpaqueParameterDefault(value);
|
|
76146
77141
|
}
|
|
76147
77142
|
function isOpaqueConstructorArgumentTypeInfo(value) {
|
|
76148
77143
|
if (!isRecord7(value)) return false;
|
|
76149
|
-
return isOpaqueNSTypeInfo(value) && (value.name === "value" || isOpaqueCallableIdentifier(value.name)) && !opaqueTypeInfoContainsUnknown(value);
|
|
77144
|
+
return isOpaqueNSTypeInfo(value) && (value.name === "value" || isOpaqueCallableIdentifier(value.name)) && !opaqueTypeInfoContainsUnknown(value) && hasValidOpaqueParameterDefault(value);
|
|
77145
|
+
}
|
|
77146
|
+
function hasValidOpaqueParameterDefault(value) {
|
|
77147
|
+
const wrapper = value.defaultValue;
|
|
77148
|
+
if (wrapper === void 0) return true;
|
|
77149
|
+
if (!isRecord7(wrapper)) return false;
|
|
77150
|
+
const keys = Object.keys(wrapper);
|
|
77151
|
+
if (keys.length !== 1 || keys[0] !== "value") return false;
|
|
77152
|
+
const payload = wrapper.value;
|
|
77153
|
+
if (payload === null) return value.required === false;
|
|
77154
|
+
if (value.type === 1) return typeof payload === "boolean";
|
|
77155
|
+
if (value.type === 2) {
|
|
77156
|
+
return typeof payload === "number" && Number.isInteger(payload);
|
|
77157
|
+
}
|
|
77158
|
+
if (value.type === 4) {
|
|
77159
|
+
return typeof payload === "number" && Number.isFinite(payload);
|
|
77160
|
+
}
|
|
77161
|
+
if (value.type === 3 || value.type === 8 || value.type === 20) {
|
|
77162
|
+
return typeof payload === "string";
|
|
77163
|
+
}
|
|
77164
|
+
return false;
|
|
77165
|
+
}
|
|
77166
|
+
function opaqueParameterDefaultsPlacedLast(argumentTypes) {
|
|
77167
|
+
let seenDefault = false;
|
|
77168
|
+
for (const argument2 of argumentTypes) {
|
|
77169
|
+
if (argument2.defaultValue !== void 0) {
|
|
77170
|
+
seenDefault = true;
|
|
77171
|
+
continue;
|
|
77172
|
+
}
|
|
77173
|
+
if (seenDefault) return false;
|
|
77174
|
+
}
|
|
77175
|
+
return true;
|
|
77176
|
+
}
|
|
77177
|
+
function opaqueArgumentsHaveDefault(argumentTypes) {
|
|
77178
|
+
return argumentTypes.some(
|
|
77179
|
+
(argument2) => isRecord7(argument2) && argument2.defaultValue !== void 0
|
|
77180
|
+
);
|
|
77181
|
+
}
|
|
77182
|
+
function assertOpaqueParameterDefaultsValid(member) {
|
|
77183
|
+
const argumentTypes = member.argumentTypes;
|
|
77184
|
+
if (!Array.isArray(argumentTypes)) return;
|
|
77185
|
+
if (!opaqueArgumentsHaveDefault(argumentTypes)) return;
|
|
77186
|
+
if (member.kind === 25 || member.kind === 26) {
|
|
77187
|
+
throw new Error(
|
|
77188
|
+
`Member "${member.name}" (${member.id}) is a delegate or action, whose parameters are an unnamed positional type list and cannot carry a default value.`
|
|
77189
|
+
);
|
|
77190
|
+
}
|
|
77191
|
+
if (member.kind !== 13 && member.kind !== 23) {
|
|
77192
|
+
throw new Error(
|
|
77193
|
+
`Member "${member.name}" (${member.id}) is not callable and cannot declare parameter default values.`
|
|
77194
|
+
);
|
|
77195
|
+
}
|
|
77196
|
+
if (member.deferred === true) {
|
|
77197
|
+
throw new Error(
|
|
77198
|
+
`Function "${member.name}" (${member.id}) is deferred, and generated C# appends a trailing deferred parameter that a defaulted parameter cannot precede.`
|
|
77199
|
+
);
|
|
77200
|
+
}
|
|
77201
|
+
const parameters = [];
|
|
77202
|
+
for (const argument2 of argumentTypes) {
|
|
77203
|
+
if (!isRecord7(argument2) || !hasValidOpaqueParameterDefault(argument2)) {
|
|
77204
|
+
throw new Error(
|
|
77205
|
+
`Function "${member.name}" (${member.id}) declares a parameter default value that does not match the parameter's type.`
|
|
77206
|
+
);
|
|
77207
|
+
}
|
|
77208
|
+
parameters.push(argument2);
|
|
77209
|
+
}
|
|
77210
|
+
if (!opaqueParameterDefaultsPlacedLast(parameters)) {
|
|
77211
|
+
throw new Error(
|
|
77212
|
+
`Function "${member.name}" (${member.id}) declares a defaulted parameter before a non-defaulted one; defaulted parameters must come last.`
|
|
77213
|
+
);
|
|
77214
|
+
}
|
|
76150
77215
|
}
|
|
76151
77216
|
function memberSignature(member) {
|
|
76152
77217
|
if (member.kind === "property") {
|
|
@@ -76180,6 +77245,7 @@ function assertProjectInterfaceDocumentValid(view, options = {}) {
|
|
|
76180
77245
|
}
|
|
76181
77246
|
for (const member of members) {
|
|
76182
77247
|
assertOpaqueMemberDefaultValueValid(member);
|
|
77248
|
+
assertOpaqueParameterDefaultsValid(member);
|
|
76183
77249
|
assertOpaqueCallableOverrideValid(member, membersById);
|
|
76184
77250
|
assertOpaqueNSFunctionValid(member, membersById);
|
|
76185
77251
|
if (member.isAbstract === true && member.defaultValue != null) {
|
|
@@ -77556,11 +78622,11 @@ function assertOpaqueConstructorValid(declaredConstructor) {
|
|
|
77556
78622
|
);
|
|
77557
78623
|
}
|
|
77558
78624
|
names.add(name);
|
|
77559
|
-
|
|
77560
|
-
|
|
77561
|
-
|
|
77562
|
-
|
|
77563
|
-
|
|
78625
|
+
}
|
|
78626
|
+
if (!opaqueParameterDefaultsPlacedLast(argumentTypes)) {
|
|
78627
|
+
throw new Error(
|
|
78628
|
+
`Constructor "${declaredConstructor.id}" declares a defaulted parameter before a non-defaulted one; defaulted parameters must come last.`
|
|
78629
|
+
);
|
|
77564
78630
|
}
|
|
77565
78631
|
assertOpaqueCompiledConstructorAction(declaredConstructor, argumentTypes);
|
|
77566
78632
|
assertOpaqueConstructorBaseClauseValid(declaredConstructor);
|
|
@@ -103403,8 +104469,8 @@ var init_registry2 = __esm({
|
|
|
103403
104469
|
"use strict";
|
|
103404
104470
|
PROJECT_SCHEMA_CONTRACT = Object.freeze({
|
|
103405
104471
|
formatVersion: 3,
|
|
103406
|
-
contractVersion: "3.
|
|
103407
|
-
cliVersion: "0.
|
|
104472
|
+
contractVersion: "3.10",
|
|
104473
|
+
cliVersion: "0.28.0",
|
|
103408
104474
|
projectFileUploadBatchSize: 32,
|
|
103409
104475
|
documentRecords: {
|
|
103410
104476
|
member: {
|
|
@@ -109970,7 +111036,7 @@ There is no --keep-current: preserving current semantic state defines flatten.
|
|
|
109970
111036
|
async function main() {
|
|
109971
111037
|
const args = parseArgs(process.argv.slice(2));
|
|
109972
111038
|
if (args.command === "--version") {
|
|
109973
|
-
console.log("0.
|
|
111039
|
+
console.log("0.28.0");
|
|
109974
111040
|
return;
|
|
109975
111041
|
}
|
|
109976
111042
|
if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {
|