@neocompose/cli 0.31.4 → 0.31.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.31.6] - 2026-08-15
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Improve shared NeoScript editor intelligence with inferred-type and
|
|
8
|
+
low-noise parameter inlay hints, spelling-aware diagnostics and quick fixes,
|
|
9
|
+
and a contextual `var`-to-explicit-type refactoring.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Disambiguate same-named types, values, members, and contextual enum options
|
|
14
|
+
by their expression role, receiver, and expected type. Member completion and
|
|
15
|
+
navigation now separate static and instance access and follow inherited
|
|
16
|
+
members with derived-first hiding.
|
|
17
|
+
|
|
18
|
+
## [0.31.5] - 2026-08-15
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- Resolve callable members through generic class and interface constraints, so
|
|
23
|
+
an open generic value can call guaranteed APIs such as `Class.Clone()`.
|
|
24
|
+
|
|
3
25
|
## [0.31.4] - 2026-08-14
|
|
4
26
|
|
|
5
27
|
### Fixed
|
package/dist/neo.mjs
CHANGED
|
@@ -1832,6 +1832,21 @@ var init_generated_csharp_identifiers = __esm({
|
|
|
1832
1832
|
});
|
|
1833
1833
|
|
|
1834
1834
|
// ../packages/neoscript-language/src/project.ts
|
|
1835
|
+
function neoScriptMemberLookupType(type) {
|
|
1836
|
+
if (type.kind !== "typeParameter") return type;
|
|
1837
|
+
const visited = /* @__PURE__ */ new Set();
|
|
1838
|
+
let current = type;
|
|
1839
|
+
let nullable = type.nullable === true;
|
|
1840
|
+
while (current.kind === "typeParameter") {
|
|
1841
|
+
if (visited.has(current.id) || current.constraint === void 0) {
|
|
1842
|
+
return type;
|
|
1843
|
+
}
|
|
1844
|
+
visited.add(current.id);
|
|
1845
|
+
nullable ||= current.constraint.nullable === true;
|
|
1846
|
+
current = current.constraint;
|
|
1847
|
+
}
|
|
1848
|
+
return nullable && current.nullable !== true ? { ...current, nullable: true } : current;
|
|
1849
|
+
}
|
|
1835
1850
|
function neoScriptParameterIsOmittable(parameter4) {
|
|
1836
1851
|
return parameter4.defaultValue !== void 0;
|
|
1837
1852
|
}
|
|
@@ -2469,14 +2484,19 @@ function signatureHelp(snapshot, position) {
|
|
|
2469
2484
|
function inlayHints(snapshot, range2) {
|
|
2470
2485
|
const hints = [];
|
|
2471
2486
|
for (const call of snapshot.parsed.calls) {
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2487
|
+
const reference2 = snapshot.parsed.references.find(
|
|
2488
|
+
(candidate) => candidate.range.start.line === call.nameRange.start.line && candidate.range.start.character === call.nameRange.start.character
|
|
2489
|
+
);
|
|
2490
|
+
const resolution = reference2 ? resolveReference(snapshot, reference2) : null;
|
|
2491
|
+
const parameterNames = call.kind === "constructor" ? constructorParameterNames(resolution?.staticType) : resolution?.symbol?.parameters?.map((parameter4) => parameter4.name);
|
|
2475
2492
|
if (!parameterNames) continue;
|
|
2476
2493
|
for (let index = 0; index < call.argumentRanges.length; index++) {
|
|
2477
2494
|
const argumentRange = call.argumentRanges[index];
|
|
2478
2495
|
const parameterName = parameterNames[index];
|
|
2479
2496
|
if (!argumentRange || !parameterName) continue;
|
|
2497
|
+
if (obviousParameterName(snapshot, argumentRange, parameterName)) {
|
|
2498
|
+
continue;
|
|
2499
|
+
}
|
|
2480
2500
|
const position = firstNonWhitespacePosition(snapshot, argumentRange);
|
|
2481
2501
|
if (range2 && !positionInRange(position, range2)) continue;
|
|
2482
2502
|
hints.push({
|
|
@@ -2487,8 +2507,59 @@ function inlayHints(snapshot, range2) {
|
|
|
2487
2507
|
});
|
|
2488
2508
|
}
|
|
2489
2509
|
}
|
|
2510
|
+
for (const local of snapshot.parsed.locals) {
|
|
2511
|
+
if (!local.inferred || !local.contextualKeywordRange) continue;
|
|
2512
|
+
const type = resolveDeclaredType(local, snapshot);
|
|
2513
|
+
if (type.kind === "primitive" && type.name === "unknown") continue;
|
|
2514
|
+
const position = local.nameRange.end;
|
|
2515
|
+
if (range2 && !positionInRange(position, range2)) continue;
|
|
2516
|
+
hints.push({
|
|
2517
|
+
position,
|
|
2518
|
+
label: `: ${formatType(type, snapshot.project)}`,
|
|
2519
|
+
kind: "type",
|
|
2520
|
+
paddingLeft: false
|
|
2521
|
+
});
|
|
2522
|
+
}
|
|
2490
2523
|
return hints;
|
|
2491
2524
|
}
|
|
2525
|
+
function obviousParameterName(snapshot, argumentRange, parameterName) {
|
|
2526
|
+
const start = snapshot.source.offsetAt(argumentRange.start);
|
|
2527
|
+
const end = snapshot.source.offsetAt(argumentRange.end);
|
|
2528
|
+
const argument2 = snapshot.source.text.slice(start, end).trim();
|
|
2529
|
+
return /^[A-Za-z_][A-Za-z0-9_]*$/.test(argument2) && normalizeHintName(argument2) === normalizeHintName(parameterName);
|
|
2530
|
+
}
|
|
2531
|
+
function normalizeHintName(name) {
|
|
2532
|
+
return name.replaceAll("_", "").toLocaleLowerCase();
|
|
2533
|
+
}
|
|
2534
|
+
function inferredTypeRefactorings(snapshot, range2) {
|
|
2535
|
+
return snapshot.parsed.locals.flatMap((local) => {
|
|
2536
|
+
if (!local.inferred || !local.contextualKeywordRange || !rangesIntersect(local.declarationRange, range2)) {
|
|
2537
|
+
return [];
|
|
2538
|
+
}
|
|
2539
|
+
const type = resolveDeclaredType(local, snapshot);
|
|
2540
|
+
if (type.kind === "primitive" && type.name === "unknown") return [];
|
|
2541
|
+
const formatted = formatType(type, snapshot.project);
|
|
2542
|
+
return [
|
|
2543
|
+
{
|
|
2544
|
+
title: `Use explicit type '${formatted}'`,
|
|
2545
|
+
kind: "refactor.rewrite",
|
|
2546
|
+
edit: {
|
|
2547
|
+
changes: {
|
|
2548
|
+
[snapshot.uri]: [
|
|
2549
|
+
{ range: local.contextualKeywordRange, newText: formatted }
|
|
2550
|
+
]
|
|
2551
|
+
}
|
|
2552
|
+
}
|
|
2553
|
+
}
|
|
2554
|
+
];
|
|
2555
|
+
});
|
|
2556
|
+
}
|
|
2557
|
+
function rangesIntersect(left, right) {
|
|
2558
|
+
return positionCompare(left.start, right.end) <= 0 && positionCompare(right.start, left.end) <= 0;
|
|
2559
|
+
}
|
|
2560
|
+
function positionCompare(left, right) {
|
|
2561
|
+
return left.line - right.line || left.character - right.character;
|
|
2562
|
+
}
|
|
2492
2563
|
function constructorParameterNames(type) {
|
|
2493
2564
|
const declared = type?.declaredConstructors ?? [];
|
|
2494
2565
|
if (declared.length > 0) {
|
|
@@ -3160,7 +3231,8 @@ function completionItemsForResolution(snapshot, resolved, word) {
|
|
|
3160
3231
|
(member) => member.static === true && isMemberCompletionAccessible(snapshot, staticType, member)
|
|
3161
3232
|
).map((member) => symbolCompletion(member, word, snapshot));
|
|
3162
3233
|
}
|
|
3163
|
-
const
|
|
3234
|
+
const memberType2 = neoScriptMemberLookupType(resolved.type);
|
|
3235
|
+
const owner = memberType2.kind === "named" ? snapshot.project.typeById.get(memberType2.typeId) : void 0;
|
|
3164
3236
|
return membersForType(snapshot, resolved.type).filter(
|
|
3165
3237
|
(symbol) => owner === void 0 || isMemberCompletionAccessible(snapshot, owner, symbol)
|
|
3166
3238
|
).map((symbol) => symbolCompletion(symbol, word, snapshot));
|
|
@@ -3174,6 +3246,17 @@ function isMemberCompletionAccessible(snapshot, owner, symbol) {
|
|
|
3174
3246
|
}) === null;
|
|
3175
3247
|
}
|
|
3176
3248
|
function membersForType(snapshot, type) {
|
|
3249
|
+
const memberType2 = neoScriptMemberLookupType(type);
|
|
3250
|
+
if (memberType2 !== type) {
|
|
3251
|
+
const members = [...membersForType(snapshot, memberType2)];
|
|
3252
|
+
if (type.kind !== "typeParameter" || type.nullable === true) return members;
|
|
3253
|
+
const named = memberType2.kind === "named" ? snapshot.project.typeById.get(memberType2.typeId) : void 0;
|
|
3254
|
+
if (named?.kind !== "class") return members;
|
|
3255
|
+
const cloneId = `builtin:${named.id}:Clone`;
|
|
3256
|
+
return members.map(
|
|
3257
|
+
(member) => member.id === cloneId ? cloneSymbol(named, type) : member
|
|
3258
|
+
);
|
|
3259
|
+
}
|
|
3177
3260
|
if (type.kind === "named") {
|
|
3178
3261
|
const named = snapshot.project.typeById.get(type.typeId);
|
|
3179
3262
|
if (!named) return [];
|
|
@@ -3950,13 +4033,13 @@ function stringContainsSymbol() {
|
|
|
3950
4033
|
"Returns true when the string contains the substring."
|
|
3951
4034
|
);
|
|
3952
4035
|
}
|
|
3953
|
-
function cloneSymbol(type) {
|
|
4036
|
+
function cloneSymbol(type, returnType = { kind: "named", typeId: type.id }) {
|
|
3954
4037
|
return {
|
|
3955
4038
|
id: `builtin:${type.id}:Clone`,
|
|
3956
4039
|
name: "Clone",
|
|
3957
4040
|
kind: "method",
|
|
3958
|
-
type:
|
|
3959
|
-
returnType
|
|
4041
|
+
type: returnType,
|
|
4042
|
+
returnType,
|
|
3960
4043
|
parameters: [],
|
|
3961
4044
|
documentation: `Deep-copy this ${type.name} into a new parentless writable value.`
|
|
3962
4045
|
};
|
|
@@ -11871,11 +11954,12 @@ var init_strict_resolver = __esm({
|
|
|
11871
11954
|
pos
|
|
11872
11955
|
);
|
|
11873
11956
|
}
|
|
11874
|
-
|
|
11875
|
-
|
|
11957
|
+
const memberReceiverType = neoScriptMemberLookupType(receiver.type);
|
|
11958
|
+
if (memberReceiverType.kind === "named") {
|
|
11959
|
+
const type = this.project.typeById.get(memberReceiverType.typeId);
|
|
11876
11960
|
if (!type) {
|
|
11877
11961
|
throw new CompileError(
|
|
11878
|
-
`Type ${
|
|
11962
|
+
`Type ${memberReceiverType.typeId} was not found in the project.`,
|
|
11879
11963
|
pos
|
|
11880
11964
|
);
|
|
11881
11965
|
}
|
|
@@ -11909,7 +11993,7 @@ var init_strict_resolver = __esm({
|
|
|
11909
11993
|
}
|
|
11910
11994
|
const memberType2 = substituteTypeParameters(
|
|
11911
11995
|
member.type,
|
|
11912
|
-
|
|
11996
|
+
memberReceiverType,
|
|
11913
11997
|
type
|
|
11914
11998
|
);
|
|
11915
11999
|
if (member.computed === true) {
|
|
@@ -12350,8 +12434,9 @@ var init_strict_resolver = __esm({
|
|
|
12350
12434
|
pos
|
|
12351
12435
|
);
|
|
12352
12436
|
}
|
|
12353
|
-
|
|
12354
|
-
|
|
12437
|
+
const memberReceiverType = neoScriptMemberLookupType(receiver.type);
|
|
12438
|
+
if (memberReceiverType.kind === "named") {
|
|
12439
|
+
const type = this.project.typeById.get(memberReceiverType.typeId);
|
|
12355
12440
|
const member = type?.members.find(
|
|
12356
12441
|
(candidate) => (candidate.kind === "function" || candidate.kind === "method") && candidate.name === callee.name
|
|
12357
12442
|
);
|
|
@@ -12365,7 +12450,10 @@ var init_strict_resolver = __esm({
|
|
|
12365
12450
|
}
|
|
12366
12451
|
return this.resolveSymbolCall(
|
|
12367
12452
|
member,
|
|
12368
|
-
{
|
|
12453
|
+
{
|
|
12454
|
+
kind: "instance",
|
|
12455
|
+
expression: memberReceiverType === receiver.type ? receiver : { ...receiver, type: memberReceiverType }
|
|
12456
|
+
},
|
|
12369
12457
|
argumentsList2,
|
|
12370
12458
|
scope,
|
|
12371
12459
|
pos,
|
|
@@ -12385,7 +12473,7 @@ var init_strict_resolver = __esm({
|
|
|
12385
12473
|
pos
|
|
12386
12474
|
);
|
|
12387
12475
|
}
|
|
12388
|
-
const schemaClass2 = toWireType(
|
|
12476
|
+
const schemaClass2 = toWireType(memberReceiverType, this.project);
|
|
12389
12477
|
return {
|
|
12390
12478
|
pointer: {
|
|
12391
12479
|
type: "function" /* Function */,
|
|
@@ -17457,7 +17545,7 @@ var init_project_source_parser = __esm({
|
|
|
17457
17545
|
|
|
17458
17546
|
// ../packages/neoscript-language/src/project-source-tokens.ts
|
|
17459
17547
|
function rangeContains(range2, position) {
|
|
17460
|
-
return
|
|
17548
|
+
return positionCompare2(range2.start, position) <= 0 && positionCompare2(position, range2.end) <= 0;
|
|
17461
17549
|
}
|
|
17462
17550
|
function rangeSize(range2) {
|
|
17463
17551
|
return (range2.end.line - range2.start.line) * 1e6 + range2.end.character - range2.start.character;
|
|
@@ -17585,9 +17673,9 @@ function tripleInterpolationEnd(text, start, limit) {
|
|
|
17585
17673
|
return null;
|
|
17586
17674
|
}
|
|
17587
17675
|
function rangesEqual(left, right) {
|
|
17588
|
-
return
|
|
17676
|
+
return positionCompare2(left.start, right.start) === 0 && positionCompare2(left.end, right.end) === 0;
|
|
17589
17677
|
}
|
|
17590
|
-
function
|
|
17678
|
+
function positionCompare2(left, right) {
|
|
17591
17679
|
return left.line === right.line ? left.character - right.character : left.line - right.line;
|
|
17592
17680
|
}
|
|
17593
17681
|
var PROJECT_TOKEN_CACHE;
|
|
@@ -17692,7 +17780,7 @@ function scanAnnotation(tokens, atIndex) {
|
|
|
17692
17780
|
};
|
|
17693
17781
|
}
|
|
17694
17782
|
function rangeWithin(outer, inner) {
|
|
17695
|
-
return
|
|
17783
|
+
return positionCompare2(outer.start, inner.start) <= 0 && positionCompare2(inner.end, outer.end) <= 0;
|
|
17696
17784
|
}
|
|
17697
17785
|
var init_project_source_registry = __esm({
|
|
17698
17786
|
"../packages/neoscript-language/src/project-source-registry.ts"() {
|
|
@@ -26441,7 +26529,8 @@ function collectDeclarationSymbols(uri, document, declaration, symbols, diagnost
|
|
|
26441
26529
|
void 0,
|
|
26442
26530
|
member.type.name,
|
|
26443
26531
|
member.kind === "function",
|
|
26444
|
-
member.docsText
|
|
26532
|
+
member.docsText,
|
|
26533
|
+
member.modifiers.includes("static")
|
|
26445
26534
|
);
|
|
26446
26535
|
if (member.kind === "function") {
|
|
26447
26536
|
for (const parameter4 of member.parameters) {
|
|
@@ -26531,7 +26620,7 @@ function collectFlowSymbols(uri, content, ownerName, scopeRange, symbols, diagno
|
|
|
26531
26620
|
}
|
|
26532
26621
|
}
|
|
26533
26622
|
}
|
|
26534
|
-
function collectSymbol(uri, kind, name, range2, annotations, ownerName, symbols, diagnostics, scopeRange, detail, callable2, documentation) {
|
|
26623
|
+
function collectSymbol(uri, kind, name, range2, annotations, ownerName, symbols, diagnostics, scopeRange, detail, callable2, documentation, staticMember) {
|
|
26535
26624
|
if (RESERVED_NAMES3.has(name)) {
|
|
26536
26625
|
diagnostics.push({
|
|
26537
26626
|
uri,
|
|
@@ -26561,6 +26650,7 @@ function collectSymbol(uri, kind, name, range2, annotations, ownerName, symbols,
|
|
|
26561
26650
|
...scopeRange ? { scopeRange } : {},
|
|
26562
26651
|
...detail ? { detail } : {},
|
|
26563
26652
|
...callable2 ? { callable: callable2 } : {},
|
|
26653
|
+
...staticMember ? { static: true } : {},
|
|
26564
26654
|
...documentation ? { documentation } : {},
|
|
26565
26655
|
location: { uri, range: range2 }
|
|
26566
26656
|
});
|
|
@@ -27345,16 +27435,16 @@ function projectAnnotationNamesAt(analysis, document, position) {
|
|
|
27345
27435
|
const containing = declarationContaining(source, position);
|
|
27346
27436
|
if (containing?.kind === "enum") return ["id"];
|
|
27347
27437
|
if (containing?.kind === "class" || containing?.kind === "interface") {
|
|
27348
|
-
if (
|
|
27438
|
+
if (positionCompare2(position, containing.nameRange.start) < 0) {
|
|
27349
27439
|
return projectDeclarationAnnotationNames(containing);
|
|
27350
27440
|
}
|
|
27351
27441
|
const member = containing.members.find(
|
|
27352
|
-
(candidate) => rangeContains(candidate.range, position) ||
|
|
27442
|
+
(candidate) => rangeContains(candidate.range, position) || positionCompare2(position, candidate.range.start) <= 0
|
|
27353
27443
|
);
|
|
27354
27444
|
return projectMemberAnnotationNames(member);
|
|
27355
27445
|
}
|
|
27356
27446
|
const following = source.declarations.find(
|
|
27357
|
-
(declaration) =>
|
|
27447
|
+
(declaration) => positionCompare2(position, declaration.range.start) <= 0
|
|
27358
27448
|
);
|
|
27359
27449
|
if (following) return projectDeclarationAnnotationNames(following);
|
|
27360
27450
|
return ["id"];
|
|
@@ -27696,7 +27786,10 @@ function sourceTypeAt(document, position) {
|
|
|
27696
27786
|
}
|
|
27697
27787
|
function projectMemberCompletions(analysis, document, position) {
|
|
27698
27788
|
const tokens = projectTokens(document).filter(
|
|
27699
|
-
(token) => token.kind !== "eof" && token.kind !== "comment" &&
|
|
27789
|
+
(token) => token.kind !== "eof" && token.kind !== "comment" && // Auto-inserted/future punctuation at the cursor has not been authored
|
|
27790
|
+
// yet for completion purposes. Including a semicolon that starts at the
|
|
27791
|
+
// cursor makes `Device.|;` lose the dot it is completing.
|
|
27792
|
+
positionCompare2(token.range.start, position) < 0
|
|
27700
27793
|
);
|
|
27701
27794
|
let cursor = tokens.length - 1;
|
|
27702
27795
|
const current = tokens[cursor];
|
|
@@ -27708,16 +27801,19 @@ function projectMemberCompletions(analysis, document, position) {
|
|
|
27708
27801
|
if (!owner || owner.kind !== "identifier") return null;
|
|
27709
27802
|
const resolvedOwner = projectSymbolAt(analysis, document, owner.range.start);
|
|
27710
27803
|
if (!resolvedOwner) return null;
|
|
27711
|
-
const ownerNames =
|
|
27712
|
-
|
|
27713
|
-
|
|
27714
|
-
|
|
27715
|
-
|
|
27804
|
+
const ownerNames = projectReceiverOwnerNames(analysis, resolvedOwner.symbol);
|
|
27805
|
+
if (ownerNames.length === 0) return null;
|
|
27806
|
+
const members = [];
|
|
27807
|
+
const seenNames = /* @__PURE__ */ new Set();
|
|
27808
|
+
for (const ownerName of ownerNames) {
|
|
27809
|
+
for (const symbol of analysis.symbols) {
|
|
27810
|
+
if (symbol.kind !== "member" && symbol.kind !== "graphChild" && symbol.kind !== "enumOption" || symbol.ownerName !== ownerName || !projectQualifiedSymbolMatchesReceiver(symbol, resolvedOwner.symbol) || seenNames.has(symbol.name)) {
|
|
27811
|
+
continue;
|
|
27812
|
+
}
|
|
27813
|
+
seenNames.add(symbol.name);
|
|
27814
|
+
members.push(symbol);
|
|
27815
|
+
}
|
|
27716
27816
|
}
|
|
27717
|
-
if (ownerNames.size === 0) return null;
|
|
27718
|
-
const members = analysis.symbols.filter(
|
|
27719
|
-
(symbol) => (symbol.kind === "member" || symbol.kind === "graphChild") && symbol.ownerName !== void 0 && ownerNames.has(symbol.ownerName)
|
|
27720
|
-
);
|
|
27721
27817
|
return members.length > 0 ? members : null;
|
|
27722
27818
|
}
|
|
27723
27819
|
function projectConstructorArgumentCompletions(analysis, document, position) {
|
|
@@ -27860,7 +27956,7 @@ function projectConstructionIndex(analysis) {
|
|
|
27860
27956
|
}
|
|
27861
27957
|
function projectDottedPathBefore(document, position) {
|
|
27862
27958
|
const tokens = projectTokens(document).filter(
|
|
27863
|
-
(token) => token.kind !== "eof" && token.kind !== "comment" &&
|
|
27959
|
+
(token) => token.kind !== "eof" && token.kind !== "comment" && positionCompare2(token.range.start, position) < 0
|
|
27864
27960
|
);
|
|
27865
27961
|
let cursor = tokens.length - 1;
|
|
27866
27962
|
const current = tokens[cursor];
|
|
@@ -27987,7 +28083,7 @@ function projectGraphTargetCompletions(analysis, document, position) {
|
|
|
27987
28083
|
const declaration = source ? declarationContaining(source, position) : void 0;
|
|
27988
28084
|
if (declaration?.kind !== "class") return null;
|
|
27989
28085
|
const member = declaration.members.filter(
|
|
27990
|
-
(candidate) =>
|
|
28086
|
+
(candidate) => positionCompare2(candidate.range.start, position) <= 0
|
|
27991
28087
|
).at(-1);
|
|
27992
28088
|
if (member?.kind !== "field" || !member.flowInitializer) return null;
|
|
27993
28089
|
return analysis.symbols.filter(
|
|
@@ -28315,6 +28411,9 @@ function projectInlayHints(analysis, document, range2) {
|
|
|
28315
28411
|
if (!argumentToken || argumentToken.named) continue;
|
|
28316
28412
|
const name = parameterNames[argument2];
|
|
28317
28413
|
if (!name) continue;
|
|
28414
|
+
if (argumentToken.identifier && normalizeProjectHintName(argumentToken.identifier) === normalizeProjectHintName(name)) {
|
|
28415
|
+
continue;
|
|
28416
|
+
}
|
|
28318
28417
|
if (range2 && !rangeContains(range2, argumentToken.start)) continue;
|
|
28319
28418
|
hints.push({
|
|
28320
28419
|
position: argumentToken.start,
|
|
@@ -28334,6 +28433,10 @@ function projectInlayHints(analysis, document, range2) {
|
|
|
28334
28433
|
}
|
|
28335
28434
|
return hints;
|
|
28336
28435
|
}
|
|
28436
|
+
function projectInferredTypeRefactorings(analysis, document, range2) {
|
|
28437
|
+
const snapshot = projectBodySnapshotAt(analysis, document, range2.start) ?? projectBodySnapshotAt(analysis, document, range2.end);
|
|
28438
|
+
return snapshot ? inferredTypeRefactorings(snapshot, range2) : [];
|
|
28439
|
+
}
|
|
28337
28440
|
function projectCallParameterNames(analysis, document, callee, beforeCallee) {
|
|
28338
28441
|
if (callee.text === "Reference") return null;
|
|
28339
28442
|
if (callee.text === "Pause") {
|
|
@@ -28380,7 +28483,8 @@ function projectCallArguments(tokens, openIndex) {
|
|
|
28380
28483
|
if (depth === 0 && atArgumentStart) {
|
|
28381
28484
|
result.push({
|
|
28382
28485
|
start: token.range.start,
|
|
28383
|
-
named: token.kind === "identifier" && tokens[index + 1]?.text === ":"
|
|
28486
|
+
named: token.kind === "identifier" && tokens[index + 1]?.text === ":",
|
|
28487
|
+
...token.kind === "identifier" && (tokens[index + 1]?.text === "," || tokens[index + 1]?.text === ")") ? { identifier: token.text } : {}
|
|
28384
28488
|
});
|
|
28385
28489
|
atArgumentStart = false;
|
|
28386
28490
|
}
|
|
@@ -28392,6 +28496,9 @@ function projectCallArguments(tokens, openIndex) {
|
|
|
28392
28496
|
}
|
|
28393
28497
|
return result;
|
|
28394
28498
|
}
|
|
28499
|
+
function normalizeProjectHintName(name) {
|
|
28500
|
+
return name.replaceAll("_", "").toLocaleLowerCase();
|
|
28501
|
+
}
|
|
28395
28502
|
function positionKey(position) {
|
|
28396
28503
|
return `${position.line}:${position.character}`;
|
|
28397
28504
|
}
|
|
@@ -28576,7 +28683,7 @@ function projectSemanticTokens(document, analysis) {
|
|
|
28576
28683
|
);
|
|
28577
28684
|
}
|
|
28578
28685
|
return result.sort(
|
|
28579
|
-
(left, right) =>
|
|
28686
|
+
(left, right) => positionCompare2(left.range.start, right.range.start)
|
|
28580
28687
|
);
|
|
28581
28688
|
}
|
|
28582
28689
|
function isProjectContextualKeyword(tokens, tokenIndex) {
|
|
@@ -28607,7 +28714,8 @@ function indexedProjectSymbolAt(analysis, document, position, index) {
|
|
|
28607
28714
|
(candidate) => candidate.start === token.start && candidate.end === token.end
|
|
28608
28715
|
);
|
|
28609
28716
|
const source = analysis.documents.get(document.uri);
|
|
28610
|
-
|
|
28717
|
+
const typePosition = source && sourceTypeAt(source, token.range.start);
|
|
28718
|
+
if (typePosition || sourceTokens[tokenIndex - 1]?.text === "new") {
|
|
28611
28719
|
const types = candidates.filter(
|
|
28612
28720
|
(symbol) => symbol.kind === "class" || symbol.kind === "interface" || symbol.kind === "enum" || symbol.kind === "genericParameter"
|
|
28613
28721
|
);
|
|
@@ -28620,10 +28728,15 @@ function indexedProjectSymbolAt(analysis, document, position, index) {
|
|
|
28620
28728
|
);
|
|
28621
28729
|
if (scoped.length > 0) return { token, symbol: scoped[0] };
|
|
28622
28730
|
const visibleCandidates = candidates.filter((symbol) => !symbol.scopeRange);
|
|
28623
|
-
if (visibleCandidates.length === 1) {
|
|
28624
|
-
return { token, symbol: visibleCandidates[0] };
|
|
28625
|
-
}
|
|
28626
28731
|
if (visibleCandidates.length === 0) return null;
|
|
28732
|
+
const contextualEnum = contextualProjectEnumOptionSymbol(
|
|
28733
|
+
analysis,
|
|
28734
|
+
document,
|
|
28735
|
+
token,
|
|
28736
|
+
visibleCandidates,
|
|
28737
|
+
source
|
|
28738
|
+
);
|
|
28739
|
+
if (contextualEnum) return { token, symbol: contextualEnum };
|
|
28627
28740
|
if (sourceTokens[tokenIndex + 1]?.text === "=" && sourceTokens[tokenIndex + 2]?.text !== "=") {
|
|
28628
28741
|
const constructed = constructionMemberSymbol(
|
|
28629
28742
|
analysis,
|
|
@@ -28634,7 +28747,7 @@ function indexedProjectSymbolAt(analysis, document, position, index) {
|
|
|
28634
28747
|
if (constructed) return { token, symbol: constructed };
|
|
28635
28748
|
}
|
|
28636
28749
|
const owner = source ? declarationContaining(source, token.range.start)?.name : void 0;
|
|
28637
|
-
if (owner) {
|
|
28750
|
+
if (owner && sourceTokens[tokenIndex - 1]?.text !== ".") {
|
|
28638
28751
|
const owned = visibleCandidates.filter(
|
|
28639
28752
|
(symbol) => symbol.ownerName === owner
|
|
28640
28753
|
);
|
|
@@ -28648,24 +28761,100 @@ function indexedProjectSymbolAt(analysis, document, position, index) {
|
|
|
28648
28761
|
dotOwner.range.start,
|
|
28649
28762
|
index
|
|
28650
28763
|
);
|
|
28651
|
-
const ownerNames =
|
|
28652
|
-
if (resolvedOwner) {
|
|
28653
|
-
const typeName = projectSymbolTypeName(resolvedOwner.symbol);
|
|
28654
|
-
if (typeName) ownerNames.add(typeName);
|
|
28655
|
-
if (resolvedOwner.symbol.kind === "global") {
|
|
28656
|
-
ownerNames.add(resolvedOwner.symbol.name);
|
|
28657
|
-
}
|
|
28658
|
-
} else {
|
|
28659
|
-
ownerNames.add(dotOwner.text);
|
|
28660
|
-
}
|
|
28764
|
+
const ownerNames = resolvedOwner ? projectReceiverOwnerNames(analysis, resolvedOwner.symbol) : [dotOwner.text];
|
|
28661
28765
|
const qualified = visibleCandidates.filter(
|
|
28662
|
-
(symbol) => symbol.ownerName !== void 0 && ownerNames.
|
|
28766
|
+
(symbol) => symbol.ownerName !== void 0 && ownerNames.includes(symbol.ownerName) && (resolvedOwner === null || projectQualifiedSymbolMatchesReceiver(symbol, resolvedOwner.symbol))
|
|
28663
28767
|
);
|
|
28664
|
-
|
|
28768
|
+
for (const ownerName of ownerNames) {
|
|
28769
|
+
const nearest = qualified.filter(
|
|
28770
|
+
(symbol) => symbol.ownerName === ownerName
|
|
28771
|
+
);
|
|
28772
|
+
if (nearest.length === 1) return { token, symbol: nearest[0] };
|
|
28773
|
+
if (nearest.length > 1) return null;
|
|
28774
|
+
}
|
|
28775
|
+
return null;
|
|
28665
28776
|
}
|
|
28666
|
-
const
|
|
28777
|
+
const values = visibleCandidates.filter(
|
|
28778
|
+
(symbol) => !isProjectTypeSymbol(symbol)
|
|
28779
|
+
);
|
|
28780
|
+
if (values.length === 1) return { token, symbol: values[0] };
|
|
28781
|
+
const projectLevel = (values.length > 0 ? values : visibleCandidates).filter(
|
|
28782
|
+
(symbol) => !symbol.ownerName
|
|
28783
|
+
);
|
|
28667
28784
|
return projectLevel.length === 1 ? { token, symbol: projectLevel[0] } : null;
|
|
28668
28785
|
}
|
|
28786
|
+
function isProjectTypeSymbol(symbol) {
|
|
28787
|
+
return symbol.kind === "class" || symbol.kind === "interface" || symbol.kind === "enum" || symbol.kind === "genericParameter";
|
|
28788
|
+
}
|
|
28789
|
+
function projectQualifiedSymbolMatchesReceiver(symbol, receiver) {
|
|
28790
|
+
if (isProjectTypeSymbol(receiver)) {
|
|
28791
|
+
if (receiver.kind === "enum") return symbol.kind === "enumOption";
|
|
28792
|
+
return symbol.kind === "member" && symbol.static === true;
|
|
28793
|
+
}
|
|
28794
|
+
if (symbol.kind === "enumOption") return false;
|
|
28795
|
+
return symbol.kind !== "member" || symbol.static !== true;
|
|
28796
|
+
}
|
|
28797
|
+
function projectReceiverOwnerNames(analysis, receiver) {
|
|
28798
|
+
const result = [];
|
|
28799
|
+
const visitedTypes = /* @__PURE__ */ new Set();
|
|
28800
|
+
const appendTypeAndBases = (typeName2) => {
|
|
28801
|
+
if (visitedTypes.has(typeName2)) return;
|
|
28802
|
+
visitedTypes.add(typeName2);
|
|
28803
|
+
if (!result.includes(typeName2)) result.push(typeName2);
|
|
28804
|
+
const declaration = findTypeDeclaration(analysis, typeName2);
|
|
28805
|
+
if (declaration?.kind !== "class" && declaration?.kind !== "interface") {
|
|
28806
|
+
return;
|
|
28807
|
+
}
|
|
28808
|
+
for (const base of declaration.baseTypes) {
|
|
28809
|
+
const resolved = findTypeDeclaration(analysis, base.name);
|
|
28810
|
+
if (resolved?.kind === "class" || resolved?.kind === "interface") {
|
|
28811
|
+
appendTypeAndBases(base.name);
|
|
28812
|
+
}
|
|
28813
|
+
}
|
|
28814
|
+
};
|
|
28815
|
+
if (receiver.kind === "global") {
|
|
28816
|
+
result.push(receiver.name);
|
|
28817
|
+
}
|
|
28818
|
+
const typeName = projectSymbolTypeName(receiver);
|
|
28819
|
+
if (typeName) appendTypeAndBases(typeName);
|
|
28820
|
+
return result;
|
|
28821
|
+
}
|
|
28822
|
+
function contextualProjectEnumOptionSymbol(analysis, document, token, candidates, source) {
|
|
28823
|
+
if (!isContextualDot(document.text, token.start)) return null;
|
|
28824
|
+
const expectedTypeName = constructionSiteAt(analysis, document, token.range.start)?.expectedTypeName ?? (source ? parameterDefaultTypeNameAt(source, token.range.start) : null);
|
|
28825
|
+
if (!expectedTypeName) return null;
|
|
28826
|
+
const options = candidates.filter(
|
|
28827
|
+
(symbol) => symbol.kind === "enumOption" && symbol.ownerName === expectedTypeName
|
|
28828
|
+
);
|
|
28829
|
+
return options.length === 1 ? options[0] : null;
|
|
28830
|
+
}
|
|
28831
|
+
function parameterDefaultTypeNameAt(document, position) {
|
|
28832
|
+
const fromParameters = (parameters) => {
|
|
28833
|
+
const parameter4 = parameters?.find(
|
|
28834
|
+
(candidate) => candidate.defaultValue && rangeContains(candidate.defaultValue.range, position)
|
|
28835
|
+
);
|
|
28836
|
+
return parameter4?.type.name ?? null;
|
|
28837
|
+
};
|
|
28838
|
+
for (const declaration of document.declarations) {
|
|
28839
|
+
if (declaration.kind !== "class" && declaration.kind !== "interface") {
|
|
28840
|
+
continue;
|
|
28841
|
+
}
|
|
28842
|
+
if (declaration.kind === "class") {
|
|
28843
|
+
const header = fromParameters(declaration.headerParameters);
|
|
28844
|
+
if (header) return header;
|
|
28845
|
+
for (const constructor2 of declaration.constructors) {
|
|
28846
|
+
const constructorParameter = fromParameters(constructor2.parameters);
|
|
28847
|
+
if (constructorParameter) return constructorParameter;
|
|
28848
|
+
}
|
|
28849
|
+
}
|
|
28850
|
+
for (const member of declaration.members) {
|
|
28851
|
+
if (member.kind !== "function") continue;
|
|
28852
|
+
const functionParameter = fromParameters(member.parameters);
|
|
28853
|
+
if (functionParameter) return functionParameter;
|
|
28854
|
+
}
|
|
28855
|
+
}
|
|
28856
|
+
return null;
|
|
28857
|
+
}
|
|
28669
28858
|
function constructionMemberSymbol(analysis, document, token, candidates) {
|
|
28670
28859
|
const site = constructionSiteAt(analysis, document, token.range.start);
|
|
28671
28860
|
let current = site?.enclosingTypeName ?? null;
|
|
@@ -28702,7 +28891,7 @@ function projectSymbolTypeName(symbol) {
|
|
|
28702
28891
|
}
|
|
28703
28892
|
function declarationContaining(document, position) {
|
|
28704
28893
|
return document.declarations.find(
|
|
28705
|
-
(declaration) =>
|
|
28894
|
+
(declaration) => positionCompare2(declaration.range.start, position) <= 0 && positionCompare2(position, declaration.range.end) <= 0
|
|
28706
28895
|
);
|
|
28707
28896
|
}
|
|
28708
28897
|
function sameProjectSymbol(left, right) {
|
|
@@ -28714,14 +28903,14 @@ function sameProjectSymbol(left, right) {
|
|
|
28714
28903
|
}
|
|
28715
28904
|
function tokensBeforePosition(text, position) {
|
|
28716
28905
|
return lex(text).tokens.filter(
|
|
28717
|
-
(token) => token.kind !== "comment" && token.kind !== "eof" &&
|
|
28906
|
+
(token) => token.kind !== "comment" && token.kind !== "eof" && positionCompare2(token.range.start, position) < 0
|
|
28718
28907
|
);
|
|
28719
28908
|
}
|
|
28720
28909
|
function activeCallOpenIndex(tokens, position) {
|
|
28721
28910
|
let closeDepth = 0;
|
|
28722
28911
|
for (let index = tokens.length - 1; index >= 0; index--) {
|
|
28723
28912
|
const token = tokens[index];
|
|
28724
|
-
if (!token ||
|
|
28913
|
+
if (!token || positionCompare2(token.range.start, position) > 0) continue;
|
|
28725
28914
|
if (token.text === ")") {
|
|
28726
28915
|
closeDepth++;
|
|
28727
28916
|
continue;
|
|
@@ -28740,7 +28929,7 @@ function activeCallParameter(tokens, openIndex, position) {
|
|
|
28740
28929
|
let parameter4 = 0;
|
|
28741
28930
|
for (let index = openIndex + 1; index < tokens.length; index++) {
|
|
28742
28931
|
const token = tokens[index];
|
|
28743
|
-
if (!token ||
|
|
28932
|
+
if (!token || positionCompare2(token.range.start, position) >= 0) break;
|
|
28744
28933
|
if (token.text === "(" || token.text === "[" || token.text === "{") {
|
|
28745
28934
|
depth++;
|
|
28746
28935
|
continue;
|
|
@@ -28823,7 +29012,7 @@ function constructionSiteAt(analysis, document, position) {
|
|
|
28823
29012
|
const root = initializerRootAt(analysis, document, position);
|
|
28824
29013
|
if (!root) return null;
|
|
28825
29014
|
const tokens = projectTokens(document).filter(
|
|
28826
|
-
(token) => token.kind !== "comment" && token.kind !== "eof" && rangeContains(root.range, token.range.start) &&
|
|
29015
|
+
(token) => token.kind !== "comment" && token.kind !== "eof" && rangeContains(root.range, token.range.start) && positionCompare2(token.range.start, position) < 0
|
|
28827
29016
|
);
|
|
28828
29017
|
const stack = [];
|
|
28829
29018
|
const expectedType = () => {
|
|
@@ -32051,6 +32240,154 @@ var init_project_schema_manifest = __esm({
|
|
|
32051
32240
|
}
|
|
32052
32241
|
});
|
|
32053
32242
|
|
|
32243
|
+
// ../packages/neoscript-language/src/spelling-diagnostics.ts
|
|
32244
|
+
function enhanceSpellingDiagnostics(document, diagnostics, completionAt) {
|
|
32245
|
+
return diagnostics.map((diagnostic) => {
|
|
32246
|
+
const misspelling = diagnosticMisspelling(diagnostic);
|
|
32247
|
+
if (!misspelling) return diagnostic;
|
|
32248
|
+
const token = diagnosticIdentifierToken(
|
|
32249
|
+
document,
|
|
32250
|
+
diagnostic,
|
|
32251
|
+
misspelling.name
|
|
32252
|
+
);
|
|
32253
|
+
if (!token) return diagnostic;
|
|
32254
|
+
const candidates = spellingCandidates(
|
|
32255
|
+
misspelling,
|
|
32256
|
+
completionAt(token.range.start)
|
|
32257
|
+
);
|
|
32258
|
+
if (candidates.length === 0) return diagnostic;
|
|
32259
|
+
return {
|
|
32260
|
+
...diagnostic,
|
|
32261
|
+
message: `${diagnostic.message} ${didYouMean(candidates)}`,
|
|
32262
|
+
suggestions: candidates
|
|
32263
|
+
};
|
|
32264
|
+
});
|
|
32265
|
+
}
|
|
32266
|
+
function spellingQuickFixes(document, diagnostic) {
|
|
32267
|
+
const misspelling = diagnosticMisspelling(diagnostic);
|
|
32268
|
+
if (!misspelling || !diagnostic.suggestions) return [];
|
|
32269
|
+
const token = diagnosticIdentifierToken(
|
|
32270
|
+
document,
|
|
32271
|
+
diagnostic,
|
|
32272
|
+
misspelling.name
|
|
32273
|
+
);
|
|
32274
|
+
if (!token) return [];
|
|
32275
|
+
return diagnostic.suggestions.filter((suggestion) => /^[A-Za-z_][A-Za-z0-9_]*$/.test(suggestion)).map((suggestion, index) => ({
|
|
32276
|
+
title: `Change '${misspelling.name}' to '${suggestion}'`,
|
|
32277
|
+
kind: "quickfix",
|
|
32278
|
+
diagnostics: [diagnostic],
|
|
32279
|
+
edit: {
|
|
32280
|
+
changes: {
|
|
32281
|
+
[document.uri]: [{ range: token.range, newText: suggestion }]
|
|
32282
|
+
}
|
|
32283
|
+
},
|
|
32284
|
+
preferred: index === 0
|
|
32285
|
+
}));
|
|
32286
|
+
}
|
|
32287
|
+
function diagnosticMisspelling(diagnostic) {
|
|
32288
|
+
if (/to initialize\b/.test(diagnostic.message)) return null;
|
|
32289
|
+
const unknown = /Unknown (identifier|function) '([^']+)'/.exec(
|
|
32290
|
+
diagnostic.message
|
|
32291
|
+
);
|
|
32292
|
+
if (unknown?.[2]) {
|
|
32293
|
+
return {
|
|
32294
|
+
name: unknown[2],
|
|
32295
|
+
kind: unknown[1] === "function" ? "callable" : "value"
|
|
32296
|
+
};
|
|
32297
|
+
}
|
|
32298
|
+
const member = /has no (?:static )?(?:callable )?member '([^']+)'/.exec(
|
|
32299
|
+
diagnostic.message
|
|
32300
|
+
);
|
|
32301
|
+
if (!member?.[1]) return null;
|
|
32302
|
+
return {
|
|
32303
|
+
name: member[1],
|
|
32304
|
+
kind: /callable member/.test(member[0]) ? "callable" : "member"
|
|
32305
|
+
};
|
|
32306
|
+
}
|
|
32307
|
+
function diagnosticIdentifierToken(document, diagnostic, name) {
|
|
32308
|
+
const candidates = projectTokens(document).filter(
|
|
32309
|
+
(token) => (token.kind === "identifier" || token.kind === "type") && token.text === name
|
|
32310
|
+
);
|
|
32311
|
+
if (candidates.length === 0) return null;
|
|
32312
|
+
const target = positionScore(diagnostic.range.start);
|
|
32313
|
+
return candidates.sort(
|
|
32314
|
+
(left, right) => Math.abs(positionScore(left.range.start) - target) - Math.abs(positionScore(right.range.start) - target)
|
|
32315
|
+
)[0] ?? null;
|
|
32316
|
+
}
|
|
32317
|
+
function positionScore(position) {
|
|
32318
|
+
return position.line * 1e6 + position.character;
|
|
32319
|
+
}
|
|
32320
|
+
function spellingCandidates(misspelling, items) {
|
|
32321
|
+
const allowedKinds = misspelling.kind === "callable" ? /* @__PURE__ */ new Set(["method", "function"]) : misspelling.kind === "member" ? /* @__PURE__ */ new Set(["field", "property", "method", "function", "enumMember"]) : /* @__PURE__ */ new Set([
|
|
32322
|
+
"variable",
|
|
32323
|
+
"parameter",
|
|
32324
|
+
"field",
|
|
32325
|
+
"property",
|
|
32326
|
+
"enumMember",
|
|
32327
|
+
"value"
|
|
32328
|
+
]);
|
|
32329
|
+
const original = misspelling.name.toLocaleLowerCase();
|
|
32330
|
+
const maximumDistance = original.length <= 4 ? 1 : original.length <= 8 ? 2 : 3;
|
|
32331
|
+
const ranked = /* @__PURE__ */ new Map();
|
|
32332
|
+
for (const item of items) {
|
|
32333
|
+
if (!allowedKinds.has(item.kind)) continue;
|
|
32334
|
+
const candidate = item.label.replace(/^\./, "");
|
|
32335
|
+
if (candidate.toLocaleLowerCase() === original) continue;
|
|
32336
|
+
const distance = damerauLevenshtein(
|
|
32337
|
+
original,
|
|
32338
|
+
candidate.toLocaleLowerCase()
|
|
32339
|
+
);
|
|
32340
|
+
if (distance > maximumDistance) continue;
|
|
32341
|
+
const prior = ranked.get(candidate);
|
|
32342
|
+
if (prior === void 0 || distance < prior)
|
|
32343
|
+
ranked.set(candidate, distance);
|
|
32344
|
+
}
|
|
32345
|
+
return [...ranked].sort(
|
|
32346
|
+
([left, leftDistance], [right, rightDistance]) => leftDistance - rightDistance || left.localeCompare(right)
|
|
32347
|
+
).slice(0, 3).map(([candidate]) => candidate);
|
|
32348
|
+
}
|
|
32349
|
+
function damerauLevenshtein(left, right) {
|
|
32350
|
+
const rows = left.length + 1;
|
|
32351
|
+
const columns = right.length + 1;
|
|
32352
|
+
const distance = Array.from(
|
|
32353
|
+
{ length: rows },
|
|
32354
|
+
() => Array(columns).fill(0)
|
|
32355
|
+
);
|
|
32356
|
+
for (let row = 0; row < rows; row++) distance[row][0] = row;
|
|
32357
|
+
for (let column = 0; column < columns; column++) {
|
|
32358
|
+
distance[0][column] = column;
|
|
32359
|
+
}
|
|
32360
|
+
for (let row = 1; row < rows; row++) {
|
|
32361
|
+
for (let column = 1; column < columns; column++) {
|
|
32362
|
+
const substitution = left[row - 1] === right[column - 1] ? 0 : 1;
|
|
32363
|
+
distance[row][column] = Math.min(
|
|
32364
|
+
distance[row - 1][column] + 1,
|
|
32365
|
+
distance[row][column - 1] + 1,
|
|
32366
|
+
distance[row - 1][column - 1] + substitution
|
|
32367
|
+
);
|
|
32368
|
+
if (row > 1 && column > 1 && left[row - 1] === right[column - 2] && left[row - 2] === right[column - 1]) {
|
|
32369
|
+
distance[row][column] = Math.min(
|
|
32370
|
+
distance[row][column],
|
|
32371
|
+
distance[row - 2][column - 2] + 1
|
|
32372
|
+
);
|
|
32373
|
+
}
|
|
32374
|
+
}
|
|
32375
|
+
}
|
|
32376
|
+
return distance[left.length][right.length];
|
|
32377
|
+
}
|
|
32378
|
+
function didYouMean(candidates) {
|
|
32379
|
+
const quoted = candidates.map((candidate) => `'${candidate}'`);
|
|
32380
|
+
if (quoted.length === 1) return `Did you mean ${quoted[0]}?`;
|
|
32381
|
+
if (quoted.length === 2) return `Did you mean ${quoted[0]} or ${quoted[1]}?`;
|
|
32382
|
+
return `Did you mean ${quoted.slice(0, -1).join(", ")}, or ${quoted.at(-1)}?`;
|
|
32383
|
+
}
|
|
32384
|
+
var init_spelling_diagnostics = __esm({
|
|
32385
|
+
"../packages/neoscript-language/src/spelling-diagnostics.ts"() {
|
|
32386
|
+
"use strict";
|
|
32387
|
+
init_project_source_tokens();
|
|
32388
|
+
}
|
|
32389
|
+
});
|
|
32390
|
+
|
|
32054
32391
|
// ../packages/neoscript-language/src/service.ts
|
|
32055
32392
|
function createNeoScriptLanguageService() {
|
|
32056
32393
|
return new LanguageService();
|
|
@@ -32145,6 +32482,7 @@ var init_service = __esm({
|
|
|
32145
32482
|
init_project_source_language_features();
|
|
32146
32483
|
init_project_source_tokens();
|
|
32147
32484
|
init_quick_fixes();
|
|
32485
|
+
init_spelling_diagnostics();
|
|
32148
32486
|
init_syntax();
|
|
32149
32487
|
init_test_prelude();
|
|
32150
32488
|
LanguageService = class {
|
|
@@ -32234,14 +32572,17 @@ var init_service = __esm({
|
|
|
32234
32572
|
if (isProjectDocument(state.document, state.context)) {
|
|
32235
32573
|
const project = this.projectAnalysis();
|
|
32236
32574
|
return {
|
|
32237
|
-
diagnostics:
|
|
32575
|
+
diagnostics: this.enhanceDiagnostics(
|
|
32576
|
+
state,
|
|
32577
|
+
projectDiagnostics(project, uri)
|
|
32578
|
+
),
|
|
32238
32579
|
symbols: projectDocumentSymbols(state.document, project),
|
|
32239
32580
|
semanticTokens: projectSemanticTokens(state.document, project)
|
|
32240
32581
|
};
|
|
32241
32582
|
}
|
|
32242
32583
|
const snapshot = this.scriptSnapshot(state);
|
|
32243
32584
|
return {
|
|
32244
|
-
diagnostics:
|
|
32585
|
+
diagnostics: this.enhanceDiagnostics(state, [
|
|
32245
32586
|
...snapshot.parsed.diagnostics,
|
|
32246
32587
|
...semanticDiagnostics(snapshot)
|
|
32247
32588
|
]),
|
|
@@ -32254,7 +32595,10 @@ var init_service = __esm({
|
|
|
32254
32595
|
if (signal?.aborted) return [];
|
|
32255
32596
|
const generation = ++state.validationGeneration;
|
|
32256
32597
|
if (isProjectDocument(state.document, state.context)) {
|
|
32257
|
-
const diagnostics =
|
|
32598
|
+
const diagnostics = this.enhanceDiagnostics(
|
|
32599
|
+
state,
|
|
32600
|
+
projectDiagnostics(this.projectAnalysis(), uri)
|
|
32601
|
+
);
|
|
32258
32602
|
if (signal?.aborted) return [];
|
|
32259
32603
|
const current2 = this.documents.get(uri);
|
|
32260
32604
|
if (!current2 || current2.validationGeneration !== generation) return [];
|
|
@@ -32272,7 +32616,7 @@ var init_service = __esm({
|
|
|
32272
32616
|
if (signal?.aborted) return [];
|
|
32273
32617
|
const current = this.documents.get(uri);
|
|
32274
32618
|
if (!current || current.validationGeneration !== generation) return [];
|
|
32275
|
-
return
|
|
32619
|
+
return this.enhanceDiagnostics(state, [
|
|
32276
32620
|
...snapshot.parsed.diagnostics,
|
|
32277
32621
|
...strictDiagnostics
|
|
32278
32622
|
]);
|
|
@@ -32385,10 +32729,15 @@ var init_service = __esm({
|
|
|
32385
32729
|
...isProjectDocument(state.document, state.context) ? {} : { kind: options?.kind ?? state.context.kind }
|
|
32386
32730
|
});
|
|
32387
32731
|
}
|
|
32388
|
-
codeActions(uri, diagnostics) {
|
|
32732
|
+
codeActions(uri, diagnostics, range2) {
|
|
32389
32733
|
const state = this.requireState(uri);
|
|
32390
32734
|
const actions = [];
|
|
32391
32735
|
const project = isProjectDocument(state.document, state.context) ? this.projectAnalysis() : null;
|
|
32736
|
+
if (range2) {
|
|
32737
|
+
actions.push(
|
|
32738
|
+
...project ? projectInferredTypeRefactorings(project, state.document, range2) : inferredTypeRefactorings(this.scriptSnapshot(state), range2)
|
|
32739
|
+
);
|
|
32740
|
+
}
|
|
32392
32741
|
for (const diagnostic of finalizeDiagnostics(uri, diagnostics)) {
|
|
32393
32742
|
if (project) {
|
|
32394
32743
|
actions.push(
|
|
@@ -32398,6 +32747,7 @@ var init_service = __esm({
|
|
|
32398
32747
|
...projectConstructionQuickFixes(project, state.document, diagnostic)
|
|
32399
32748
|
);
|
|
32400
32749
|
}
|
|
32750
|
+
actions.push(...spellingQuickFixes(state.document, diagnostic));
|
|
32401
32751
|
const edit = quickFixFor(state.document, diagnostic);
|
|
32402
32752
|
if (!edit) continue;
|
|
32403
32753
|
actions.push({
|
|
@@ -32410,6 +32760,17 @@ var init_service = __esm({
|
|
|
32410
32760
|
}
|
|
32411
32761
|
return deduplicateCodeActions(actions);
|
|
32412
32762
|
}
|
|
32763
|
+
/** Adds conservative, completion-backed spelling suggestions to diagnostics. */
|
|
32764
|
+
enhanceDiagnostics(state, diagnostics) {
|
|
32765
|
+
return finalizeDiagnostics(
|
|
32766
|
+
state.document.uri,
|
|
32767
|
+
enhanceSpellingDiagnostics(
|
|
32768
|
+
state.document,
|
|
32769
|
+
diagnostics,
|
|
32770
|
+
(position) => this.complete(state.document.uri, position).items
|
|
32771
|
+
)
|
|
32772
|
+
);
|
|
32773
|
+
}
|
|
32413
32774
|
projectAnalysis() {
|
|
32414
32775
|
if (this.cachedProjectAnalysis?.generation === this.projectGeneration) {
|
|
32415
32776
|
return this.cachedProjectAnalysis.analysis;
|
|
@@ -110651,7 +111012,7 @@ var init_registry2 = __esm({
|
|
|
110651
111012
|
PROJECT_SCHEMA_CONTRACT = Object.freeze({
|
|
110652
111013
|
formatVersion: 3,
|
|
110653
111014
|
contractVersion: "3.12",
|
|
110654
|
-
cliVersion: "0.31.
|
|
111015
|
+
cliVersion: "0.31.6",
|
|
110655
111016
|
projectFileUploadBatchSize: 32,
|
|
110656
111017
|
documentRecords: {
|
|
110657
111018
|
member: {
|
|
@@ -117246,7 +117607,7 @@ There is no --keep-current: preserving current semantic state defines flatten.
|
|
|
117246
117607
|
async function main() {
|
|
117247
117608
|
const args = parseArgs(process.argv.slice(2));
|
|
117248
117609
|
if (args.command === "--version") {
|
|
117249
|
-
console.log("0.31.
|
|
117610
|
+
console.log("0.31.6");
|
|
117250
117611
|
return;
|
|
117251
117612
|
}
|
|
117252
117613
|
if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {
|
package/package.json
CHANGED
|
@@ -83,7 +83,7 @@ wrappers.
|
|
|
83
83
|
The marker near the top of `SKILL.md` must exactly match the package version:
|
|
84
84
|
|
|
85
85
|
```html
|
|
86
|
-
<!-- reviewed-through-cli: 0.31.
|
|
86
|
+
<!-- reviewed-through-cli: 0.31.6 -->
|
|
87
87
|
```
|
|
88
88
|
|
|
89
89
|
The quoted version above is checked too, so this instruction cannot go stale
|