luaut-language-server 1.1.0 → 1.1.1
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/{chunk-HK7PKBDB.js → chunk-OQWE7ISD.js} +46 -9
- package/dist/chunk-OQWE7ISD.js.map +1 -0
- package/dist/cli.cjs +45 -8
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/index.cjs +45 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +2 -2
- package/dist/chunk-HK7PKBDB.js.map +0 -1
|
@@ -843,6 +843,8 @@ var IDENTIFIER_CHAR = /[A-Za-z0-9_]/;
|
|
|
843
843
|
function completion(analyzer, document, position) {
|
|
844
844
|
const inImport = importCompletion(analyzer, document, position);
|
|
845
845
|
if (inImport) return inImport;
|
|
846
|
+
const inString = stringCompletion(analyzer, document, position);
|
|
847
|
+
if (inString) return inString;
|
|
846
848
|
const source = document.getText();
|
|
847
849
|
const offset = document.offsetAt(position);
|
|
848
850
|
let start = offset;
|
|
@@ -883,6 +885,43 @@ function completion(analyzer, document, position) {
|
|
|
883
885
|
}
|
|
884
886
|
return valueItems(first.analysis, at);
|
|
885
887
|
}
|
|
888
|
+
function stringCompletion(analyzer, document, position) {
|
|
889
|
+
const analysis = analyzer.get(document);
|
|
890
|
+
const path = pathAt(analysis.program, position, false);
|
|
891
|
+
const literal = [...path].reverse().find((n) => n.type === "StringLiteral");
|
|
892
|
+
if (!literal) return void 0;
|
|
893
|
+
const expected = analysis.types.expectedTypeOf.get(literal);
|
|
894
|
+
const values = stringLiterals(expected, analysis.types.aliases);
|
|
895
|
+
if (!values.length) return [];
|
|
896
|
+
const line = literal.line.start - 1;
|
|
897
|
+
const range = literal.line.start === literal.line.end ? {
|
|
898
|
+
start: { line, character: literal.column.start },
|
|
899
|
+
end: { line, character: literal.column.end - 2 }
|
|
900
|
+
} : void 0;
|
|
901
|
+
return values.map((value) => ({
|
|
902
|
+
label: value,
|
|
903
|
+
kind: CompletionItemKind2.Constant,
|
|
904
|
+
...range ? { textEdit: { range, newText: value } } : {}
|
|
905
|
+
}));
|
|
906
|
+
}
|
|
907
|
+
function stringLiterals(type, aliases, seen = /* @__PURE__ */ new Set()) {
|
|
908
|
+
if (!type || seen.has(type)) return [];
|
|
909
|
+
seen.add(type);
|
|
910
|
+
switch (type.kind) {
|
|
911
|
+
case "literal":
|
|
912
|
+
return typeof type.value === "string" ? [type.value] : [];
|
|
913
|
+
case "union":
|
|
914
|
+
return [...new Set(type.types.flatMap((t) => stringLiterals(t, aliases, seen)))];
|
|
915
|
+
case "genericRef": {
|
|
916
|
+
const alias = aliases.get(type.name);
|
|
917
|
+
return alias ? stringLiterals(alias, aliases, seen) : [];
|
|
918
|
+
}
|
|
919
|
+
case "typeParam":
|
|
920
|
+
return stringLiterals(type.constraint, aliases, seen);
|
|
921
|
+
default:
|
|
922
|
+
return [];
|
|
923
|
+
}
|
|
924
|
+
}
|
|
886
925
|
function memberOperator(source, wordStart) {
|
|
887
926
|
const ch = source[wordStart - 1];
|
|
888
927
|
if (ch === ":") return source[wordStart - 2] === ":" ? void 0 : ":";
|
|
@@ -1157,7 +1196,7 @@ var TOKEN_TYPES = [
|
|
|
1157
1196
|
"method",
|
|
1158
1197
|
"keyword"
|
|
1159
1198
|
];
|
|
1160
|
-
var TOKEN_MODIFIERS = ["declaration", "readonly", "defaultLibrary"];
|
|
1199
|
+
var TOKEN_MODIFIERS = ["declaration", "readonly", "defaultLibrary", "control"];
|
|
1161
1200
|
var semanticTokensLegend = {
|
|
1162
1201
|
tokenTypes: [...TOKEN_TYPES],
|
|
1163
1202
|
tokenModifiers: [...TOKEN_MODIFIERS]
|
|
@@ -1172,8 +1211,10 @@ var SOFT_KEYWORDS = /* @__PURE__ */ new Set([
|
|
|
1172
1211
|
"is",
|
|
1173
1212
|
"asserts",
|
|
1174
1213
|
"satisfies",
|
|
1175
|
-
"typeof"
|
|
1214
|
+
"typeof",
|
|
1215
|
+
"default"
|
|
1176
1216
|
]);
|
|
1217
|
+
var CONTROL_KEYWORDS = /* @__PURE__ */ new Set(["default"]);
|
|
1177
1218
|
var PRIMITIVES3 = /* @__PURE__ */ new Set(["any", "unknown", "never", "nil", "boolean", "number", "string", "thread", "buffer"]);
|
|
1178
1219
|
function semanticTokens(analysis) {
|
|
1179
1220
|
const entries = /* @__PURE__ */ new Map();
|
|
@@ -1199,12 +1240,8 @@ function semanticTokens(analysis) {
|
|
|
1199
1240
|
walk2(analysis.program);
|
|
1200
1241
|
for (const token of tokens) {
|
|
1201
1242
|
const value = token.value;
|
|
1202
|
-
if (typeof value !== "string") continue;
|
|
1203
|
-
|
|
1204
|
-
add(token, value.length, "keyword");
|
|
1205
|
-
} else if (token.type === "Identifier" && SOFT_KEYWORDS.has(value)) {
|
|
1206
|
-
add(token, value.length, "keyword");
|
|
1207
|
-
}
|
|
1243
|
+
if (token.type !== "Identifier" || typeof value !== "string" || !SOFT_KEYWORDS.has(value)) continue;
|
|
1244
|
+
add(token, value.length, "keyword", CONTROL_KEYWORDS.has(value) ? ["control"] : []);
|
|
1208
1245
|
}
|
|
1209
1246
|
return { data: encode([...entries.values()]) };
|
|
1210
1247
|
}
|
|
@@ -1532,4 +1569,4 @@ export {
|
|
|
1532
1569
|
createServer,
|
|
1533
1570
|
startServer
|
|
1534
1571
|
};
|
|
1535
|
-
//# sourceMappingURL=chunk-
|
|
1572
|
+
//# sourceMappingURL=chunk-OQWE7ISD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/analysis.ts","../src/ast-utils.ts","../src/features/members.ts","../src/features/imports.ts","../src/features/diagnostics.ts","../src/features/hover.ts","../src/features/navigation.ts","../src/features/completion.ts","../src/features/signatureHelp.ts","../src/features/symbols.ts","../src/features/semanticTokens.ts","../src/server.ts"],"sourcesContent":["/**\n * Analysis cache, and the module graph behind `import`.\n *\n * The three parser passes are cheap (single-digit milliseconds for a normal\n * file) but not free, and every LSP request wants the same result for the same\n * document version — so each document is analyzed once per version and the\n * result is reused by hover, definition, completion and the rest.\n *\n * An import is resolved to a file, that file is analyzed the same way, and its\n * exports become the importing file's types. Open documents are read in\n * preference to disk, so an import sees unsaved edits. A cached result is only\n * reused while every module it imported — and everything those import — still\n * has the text it was analyzed against.\n */\nimport { readFileSync, statSync } from \"node:fs\"\nimport { dirname, join, resolve } from \"node:path\"\nimport { fileURLToPath, pathToFileURL } from \"node:url\"\nimport {\n parseWithRecovery, analyzeScopes, analyzeTypes, moduleExports, defaultLibs, getBinding,\n type Program, type ScopeAnalysis, type TypeAnalysis, type ParseError, type ModuleExports,\n type DeclareStatement, type Statement, type Binding, type Identifier,\n} from \"luaut-parser\"\nimport type { TextDocument } from \"vscode-languageserver-textdocument\"\n\nexport interface Analysis {\n readonly uri: string\n readonly version: number\n readonly source: string\n readonly program: Program\n readonly parseErrors: readonly ParseError[]\n readonly scopes: ScopeAnalysis\n readonly types: TypeAnalysis\n /** Every file this analysis read for an import, with the text it read —\n * or `undefined` for a file it looked for and did not find. How a cached\n * result tells that an import changed, appeared or vanished under it. */\n readonly dependencies: ReadonlyMap<string, string | undefined>\n}\n\nexport interface AnalyzerOptions {\n /** Definitions to analyze against. Defaults to core Luau + Roblox. */\n libs?: readonly Program[]\n /** The open document for a file path, if there is one. */\n openDocument?: (path: string) => TextDocument | undefined\n}\n\n/** Names every file may use undeclared: whatever the definitions declare.\n * Derived rather than hard-coded, so adding a `declare` to a `.d.luaut` is\n * all it takes for the name to stop looking undefined. */\nfunction globalsOf(libs: readonly Program[]): string[] {\n const names = new Set<string>()\n for (const lib of libs) collect(lib.body.statements, names)\n return [...names]\n}\n\nfunction collect(statements: readonly Statement[], into: Set<string>): void {\n for (const statement of statements) {\n if (statement.type === \"DeclareStatement\") into.add((statement as DeclareStatement).name)\n }\n}\n\n/** The binding a node names, whether it *uses* the binding or *declares* it.\n *\n * Scope analysis indexes the two differently: every use is in `bindingOf`,\n * but a declaration only appears as its binding's `declarationNode`. Asking\n * `bindingOf` alone is why hovering `const x` — as opposed to a later `x` —\n * used to show nothing. */\nexport function bindingOfNode(analysis: Analysis, node: object): Binding | undefined {\n const used = getBinding(analysis.scopes, node as Identifier)\n if (used) return used\n return declarationIndex(analysis).get(node)\n}\n\nconst declarationIndexes = new WeakMap<Analysis, Map<object, Binding>>()\n\nfunction declarationIndex(analysis: Analysis): Map<object, Binding> {\n let index = declarationIndexes.get(analysis)\n if (!index) {\n index = new Map()\n for (const binding of analysis.scopes.bindings.values()) {\n if (binding.declarationNode) index.set(binding.declarationNode, binding)\n }\n declarationIndexes.set(analysis, index)\n }\n return index\n}\n\n// --------------------------------------------------------------------------\n// Paths\n// --------------------------------------------------------------------------\n\n/** A file URI's path, or `undefined` for anything that is not a file. */\nexport function pathOfUri(uri: string): string | undefined {\n if (!uri.startsWith(\"file:\")) return undefined\n try {\n return fileURLToPath(uri)\n } catch {\n return undefined\n }\n}\n\nexport function uriOfPath(path: string): string {\n return pathToFileURL(path).href\n}\n\n/** Paths compare case-insensitively on Windows, where editors and the file\n * system disagree about drive-letter case. */\nexport function samePath(a: string, b: string): boolean {\n return pathKey(a) === pathKey(b)\n}\n\nfunction pathKey(path: string): string {\n const normalized = resolve(path)\n return process.platform === \"win32\" ? normalized.toLowerCase() : normalized\n}\n\n/** What an import of a module still being analyzed up the chain sees. */\nconst CYCLE: ModuleExports = { values: new Map(), types: new Map(), partial: true }\n\n// --------------------------------------------------------------------------\n// Analyzer\n// --------------------------------------------------------------------------\n\ninterface Module {\n analysis: Analysis\n exports: ModuleExports\n}\n\nexport class Analyzer {\n private readonly libs: readonly Program[]\n private readonly builtinGlobals: string[]\n private readonly openDocument?: (path: string) => TextDocument | undefined\n private readonly cache = new Map<string, Analysis>()\n /** Imported modules, by path key. */\n private readonly modules = new Map<string, Module>()\n\n constructor(options: AnalyzerOptions = {}) {\n this.libs = options.libs ?? defaultLibs\n this.builtinGlobals = globalsOf(this.libs)\n this.openDocument = options.openDocument\n }\n\n /** Analyze `document`, reusing the previous result while neither it nor\n * anything it imports has changed. */\n get(document: TextDocument): Analysis {\n const cached = this.cache.get(document.uri)\n const source = document.getText()\n if (cached && cached.version === document.version && cached.source === source && this.isFresh(cached)) {\n return cached\n }\n const analysis = this.analyze(document.uri, document.version, source)\n this.cache.set(document.uri, analysis)\n return analysis\n }\n\n /** Analyze source text that is not a tracked document — used by\n * completion, which analyzes a speculatively edited copy of the file. */\n analyze(uri: string, version: number, source: string): Analysis {\n const path = pathOfUri(uri)\n return this.analyzeModule(uri, version, source, new Set(path ? [pathKey(path)] : []))\n }\n\n forget(uri: string): void {\n this.cache.delete(uri)\n }\n\n /** The file an import in `fromUri` names. Relative paths only (`./x`,\n * `../x`); the extension may be left off, and a folder means its\n * `index.luaut`. */\n resolveModulePath(fromUri: string, specifier: string): string | undefined {\n return this.moduleCandidates(fromUri, specifier).find(candidate => this.sourceOf(candidate) !== undefined)\n }\n\n /** Every file an import could mean, in the order they are tried. */\n private moduleCandidates(fromUri: string, specifier: string): string[] {\n const from = pathOfUri(fromUri)\n if (!from || !(specifier.startsWith(\"./\") || specifier.startsWith(\"../\"))) return []\n const base = resolve(dirname(from), specifier)\n return specifier.endsWith(\".luaut\")\n ? [base]\n : [`${base}.luaut`, `${base}.d.luaut`, join(base, \"index.luaut\")]\n }\n\n /** What the module at `path` exports, analyzing it if need be. */\n exportsAt(path: string): ModuleExports | undefined {\n return this.exportsOf(path, new Set())\n }\n\n /** The analysis of the module at `path`, analyzing it if need be. */\n moduleAt(path: string): Analysis | undefined {\n this.exportsOf(path, new Set())\n return this.modules.get(pathKey(path))?.analysis\n }\n\n private sourceOf(path: string): string | undefined {\n const open = this.openDocument?.(path)\n if (open) return open.getText()\n try {\n return statSync(path).isFile() ? readFileSync(path, \"utf8\") : undefined\n } catch {\n return undefined\n }\n }\n\n /** `importing` holds every module on the current import chain, so an\n * import back into one of them is recognized as a cycle. */\n private analyzeModule(uri: string, version: number, source: string, importing: Set<string>): Analysis {\n const { program, errors } = parseWithRecovery(source)\n const scopes = analyzeScopes(program, { builtinGlobals: this.builtinGlobals })\n const dependencies = new Map<string, string | undefined>()\n const types = analyzeTypes(program, scopes, {\n libs: this.libs,\n resolveModule: specifier => {\n const target = this.resolveModulePath(uri, specifier)\n if (!target) {\n // Remember where it was looked for. Otherwise creating the\n // file later would leave this module's \"Cannot find module\"\n // — and its unresolved types — cached until its own text\n // changed.\n for (const candidate of this.moduleCandidates(uri, specifier)) dependencies.set(candidate, undefined)\n return undefined\n }\n const exports = this.exportsOf(target, importing)\n dependencies.set(target, this.sourceOf(target))\n return exports\n },\n })\n return { uri, version, source, program, parseErrors: errors, scopes, types, dependencies }\n }\n\n private exportsOf(path: string, importing: Set<string>): ModuleExports | undefined {\n const key = pathKey(path)\n if (importing.has(key)) return CYCLE\n const source = this.sourceOf(path)\n if (source === undefined) return undefined\n const cached = this.modules.get(key)\n if (cached && cached.analysis.source === source && this.isFresh(cached.analysis)) return cached.exports\n importing.add(key)\n try {\n const analysis = this.analyzeModule(uriOfPath(path), -1, source, importing)\n // Re-exports (`export ... from`) resolve relative to this module.\n const exports = moduleExports(analysis.program, analysis.scopes, analysis.types, specifier => {\n const next = this.resolveModulePath(analysis.uri, specifier)\n return next ? this.exportsOf(next, importing) : undefined\n })\n this.modules.set(key, { analysis, exports })\n return exports\n } finally {\n importing.delete(key)\n }\n }\n\n /** Does every module `analysis` imported — and everything those import —\n * still have the text it was analyzed against? */\n private isFresh(analysis: Analysis, seen = new Set<Analysis>()): boolean {\n if (seen.has(analysis)) return true\n seen.add(analysis)\n for (const [path, source] of analysis.dependencies) {\n if (this.sourceOf(path) !== source) return false\n const module = this.modules.get(pathKey(path))\n if (module && !this.isFresh(module.analysis, seen)) return false\n }\n return true\n }\n}\n","/**\n * Position mapping and AST lookup.\n *\n * luaut spans are 1-based with an exclusive end column; LSP positions are\n * 0-based. Every conversion between the two lives here so the features never\n * do the arithmetic themselves.\n */\nimport type { Position, Range } from \"vscode-languageserver\"\n\n/** The shape every luaut AST node shares. */\nexport interface Spanned {\n type?: string\n line: { start: number; end: number }\n column: { start: number; end: number }\n}\n\nexport function isSpanned(v: unknown): v is Spanned {\n if (!v || typeof v !== \"object\") return false\n const n = v as Record<string, unknown>\n return typeof n.line === \"object\" && n.line !== null && typeof n.column === \"object\" && n.column !== null\n}\n\nexport function toRange(node: Spanned): Range {\n return {\n start: { line: node.line.start - 1, character: node.column.start - 1 },\n end: { line: node.line.end - 1, character: node.column.end - 1 },\n }\n}\n\n/** A one-character range, for a diagnostic on a node with a collapsed span. */\nexport function toPosition(line: number, column: number): Position {\n return { line: line - 1, character: column - 1 }\n}\n\n/** Is `pos` inside `node`'s span? The end is exclusive, except that `inclusive`\n * admits a cursor sitting immediately after the node — which is where it is\n * while you are still typing the identifier under it. */\nexport function containsPosition(node: Spanned, pos: Position, inclusive = false): boolean {\n const startLine = node.line.start - 1\n const endLine = node.line.end - 1\n if (pos.line < startLine || pos.line > endLine) return false\n if (pos.line === startLine && pos.character < node.column.start - 1) return false\n if (pos.line === endLine) {\n const end = node.column.end - 1\n if (inclusive ? pos.character > end : pos.character >= end) return false\n }\n return true\n}\n\n/** Every child node of `node`, in source order-ish (declaration order of the\n * fields). Generic on purpose: it walks the object graph rather than knowing\n * the node types, so a new node kind in the parser needs no change here.\n *\n * Some nodes carry no span — the field wrappers of object literals\n * (`TableFieldNamed`) and type literals (`TableTypeProperty`). They are\n * walked *through*: their own children are returned in their place. Skipping\n * them would hide everything inside, which is how hovering an object key used\n * to land on the whole object. */\nexport function children(node: Spanned): Spanned[] {\n const out: Spanned[] = []\n collect(node, out)\n return out\n}\n\nfunction collect(container: object, out: Spanned[]): void {\n for (const key of Object.keys(container)) {\n if (key === \"line\" || key === \"column\") continue\n const value = (container as Record<string, unknown>)[key]\n for (const item of Array.isArray(value) ? value : [value]) {\n if (isSpanned(item)) out.push(item)\n else if (isSpanlessNode(item)) collect(item, out)\n }\n }\n}\n\n/** A node-shaped object (it has a `type` tag) that has no span of its own. */\nfunction isSpanlessNode(v: unknown): v is object {\n return !!v && typeof v === \"object\" && typeof (v as { type?: unknown }).type === \"string\"\n}\n\n/** The chain of nodes containing `pos`, outermost first — the last entry is\n * the innermost node at the cursor and the ones before it are its ancestors.\n *\n * It descends through every child rather than only children that contain\n * `pos`, because a parent's span does not always cover its child's: a\n * binding's span is the name alone, while its type annotation sits after it.\n * So an ancestor in this path is a real ancestor, but not necessarily one\n * whose own span contains the cursor. */\nexport function pathAt(root: Spanned, pos: Position, inclusive = false): Spanned[] {\n let best: Spanned[] | undefined\n\n const descend = (node: Spanned, ancestors: Spanned[]): void => {\n const here = [...ancestors, node]\n if (containsPosition(node, pos, inclusive)) {\n // Prefer the narrowest hit, and among equals the deepest — that is\n // the node the cursor is really \"on\".\n const incumbent = best?.[best.length - 1]\n if (!incumbent\n || spanLength(node) < spanLength(incumbent)\n || (spanLength(node) === spanLength(incumbent) && here.length > best!.length)) {\n best = here\n }\n }\n for (const child of children(node)) descend(child, here)\n }\n\n descend(root, [])\n return best ?? []\n}\n\n/** The innermost node containing `pos`. */\nexport function nodeAt(root: Spanned, pos: Position, inclusive = false): Spanned | undefined {\n const path = pathAt(root, pos, inclusive)\n return path[path.length - 1]\n}\n\n/** The innermost node of one of `types` containing `pos`. */\nexport function enclosing<T extends Spanned>(\n root: Spanned,\n pos: Position,\n types: readonly string[],\n inclusive = false,\n): T | undefined {\n const path = pathAt(root, pos, inclusive)\n for (let i = path.length - 1; i >= 0; i--) {\n if (path[i].type && types.includes(path[i].type as string)) return path[i] as T\n }\n return undefined\n}\n\nfunction spanLength(node: Spanned): number {\n // Line count dominates: a node spanning fewer lines is nested deeper.\n return (node.line.end - node.line.start) * 10000 + (node.column.end - node.column.start)\n}\n\n/** Walk every node under `root`, depth first. */\nexport function walk(root: Spanned, visit: (node: Spanned, parent?: Spanned) => void, parent?: Spanned): void {\n visit(root, parent)\n for (const child of children(root)) walk(child, visit, root)\n}\n","/** What members a type has — shared by completion and signature help. */\nimport { formatType, type FunctionType, type ObjectProperty, type Type } from \"luaut-parser\"\n\nexport interface Member {\n name: string\n property: ObjectProperty\n /** True when the member is a function whose first parameter is `self` —\n * i.e. it is meant to be called with `:`. */\n isMethod: boolean\n}\n\n/** The members of `type`, following aliases, merging intersections and keeping\n * only what every member of a union has (you can only reach a property that\n * is there whichever way the union went). */\nexport function membersOf(\n type: Type | undefined,\n aliases: ReadonlyMap<string, Type>,\n seen = new Set<Type>(),\n): Member[] {\n if (!type || seen.has(type)) return []\n seen.add(type)\n\n switch (type.kind) {\n case \"object\": {\n const out: Member[] = []\n for (const [name, property] of type.properties) {\n out.push({ name, property, isMethod: takesSelf(property.type) })\n }\n return out\n }\n case \"intersection\": {\n // Overload sets are intersections of functions and have no\n // members of their own; a `A & B` object contributes both sides.\n const merged = new Map<string, Member>()\n for (const part of type.types) {\n for (const member of membersOf(part, aliases, seen)) merged.set(member.name, member)\n }\n return [...merged.values()]\n }\n case \"union\": {\n const perBranch = type.types.map(part => membersOf(part, aliases, seen))\n if (!perBranch.length) return []\n const [first, ...rest] = perBranch\n return first.filter(member => rest.every(other => other.some(m => m.name === member.name)))\n }\n case \"genericRef\": {\n const alias = aliases.get(type.name)\n return alias ? membersOf(alias, aliases, seen) : []\n }\n case \"typeParam\":\n return membersOf(type.constraint, aliases, seen)\n default:\n return []\n }\n}\n\nexport function takesSelf(type: Type): boolean {\n for (const signature of signaturesOf(type)) {\n if (signature.params[0]?.name === \"self\") return true\n }\n return false\n}\n\n/** Every call signature of `type` — one for a function, several for an\n * overload set (which is an intersection of function types). */\nexport function signaturesOf(type: Type | undefined, aliases?: ReadonlyMap<string, Type>): FunctionType[] {\n if (!type) return []\n if (type.kind === \"function\") return [type]\n if (type.kind === \"intersection\") return type.types.flatMap(t => signaturesOf(t, aliases))\n if (type.kind === \"genericRef\" && aliases) {\n const alias = aliases.get(type.name)\n return alias ? signaturesOf(alias, aliases) : []\n }\n return []\n}\n\n/** `(a: number, b?: string) -> boolean`, and the pieces of it, for signature\n * help — which needs each parameter's own label to highlight the active one. */\nexport function signatureLabel(signature: FunctionType): { label: string; parameters: string[] } {\n const parameters = signature.params.map((p, i) => {\n const name = p.name ?? `arg${i + 1}`\n return `${name}${p.optional ? \"?\" : \"\"}: ${formatType(p.type)}`\n })\n const generics = signature.typeParams?.length ? `<${signature.typeParams.join(\", \")}>` : \"\"\n const varargs = signature.varargs ? [`...: ${formatType(signature.varargs)}`] : []\n const label = `${generics}(${[...parameters, ...varargs].join(\", \")}) -> ${formatType(signature.returns)}`\n return { label, parameters }\n}\n","/**\n * Modules, across files: completing module paths and the names they export,\n * and jumping from an `import` (or `export ... from`) to the declaration.\n *\n * Completion works on the line's text rather than the AST — a statement that\n * is being typed does not parse yet, and those are exactly the moments\n * completion is asked for.\n */\nimport { readdirSync } from \"node:fs\"\nimport { dirname, resolve } from \"node:path\"\nimport {\n CompletionItemKind,\n type Command, type CompletionItem, type Location, type Position, type Range,\n} from \"vscode-languageserver\"\nimport type { TextDocument } from \"vscode-languageserver-textdocument\"\nimport {\n formatType,\n type BindingTarget, type ExportAllStatement, type ExportNamedStatement, type Identifier, type ImportStatement,\n} from \"luaut-parser\"\nimport { bindingOfNode, pathOfUri, samePath, uriOfPath, type Analysis, type Analyzer } from \"../analysis.js\"\nimport { pathAt, toRange, type Spanned } from \"../ast-utils.js\"\nimport { signaturesOf } from \"./members.js\"\n\n/** Keep the suggestion list open after picking a folder, to go one level in. */\nconst SUGGEST_AGAIN: Command = { title: \"Suggest\", command: \"editor.action.triggerSuggest\" }\n\n/** Completion inside an `import` or `export ... from`, or `undefined` when the\n * cursor is not in one. */\nexport function importCompletion(\n analyzer: Analyzer,\n document: TextDocument,\n position: Position,\n): CompletionItem[] | undefined {\n const text = document.getText()\n const cursor = document.offsetAt(position)\n const lineStart = document.offsetAt({ line: position.line, character: 0 })\n const lineEnd = document.offsetAt({ line: position.line + 1, character: 0 })\n const before = text.slice(lineStart, cursor)\n const after = text.slice(cursor, lineEnd)\n if (!/^\\s*(?:import|export)\\b/.test(before)) return undefined\n\n // In the module path: `from \"./sha|\"`.\n const path = /\\bfrom\\s*([\"'])([^\"']*)$/.exec(before)\n if (path) return pathItems(document.uri, position, path[2])\n\n // In the braces: `import { a, | } from \"./x\"`.\n const braces = /^\\s*(import|export)\\s+(?:[A-Za-z_][A-Za-z0-9_]*\\s*,\\s*)?\\{[^}]*$/.exec(before)\n if (braces) {\n const module = /\\}\\s*from\\s*([\"'])([^\"']+)\\1/.exec(after)\n if (module) return nameItems(analyzer, document.uri, module[2], before)\n // `export { | }` with no `from` names this file's own declarations:\n // ordinary completion answers that.\n return braces[1] === \"import\" ? [] : undefined\n }\n return undefined\n}\n\nfunction pathItems(fromUri: string, position: Position, typed: string): CompletionItem[] {\n const from = pathOfUri(fromUri)\n if (!from) return []\n\n // Only relative paths resolve; until one is started, offer the ways in.\n if (!typed.startsWith(\"./\") && !typed.startsWith(\"../\")) {\n const range = rangeBack(position, typed.length)\n return [\"./\", \"../\"].map(label => ({\n label,\n kind: CompletionItemKind.Folder,\n textEdit: { range, newText: label },\n command: SUGGEST_AGAIN,\n }))\n }\n\n const slash = typed.lastIndexOf(\"/\")\n const directory = resolve(dirname(from), typed.slice(0, slash + 1))\n const range = rangeBack(position, typed.length - slash - 1)\n let entries\n try {\n entries = readdirSync(directory, { withFileTypes: true })\n } catch {\n return []\n }\n\n const items: CompletionItem[] = []\n for (const entry of entries) {\n if (entry.name.startsWith(\".\") || entry.name === \"node_modules\") continue\n if (entry.isDirectory()) {\n items.push({\n label: `${entry.name}/`,\n kind: CompletionItemKind.Folder,\n textEdit: { range, newText: `${entry.name}/` },\n command: SUGGEST_AGAIN,\n })\n } else if (entry.name.endsWith(\".luaut\")) {\n // A file does not import itself.\n if (samePath(resolve(directory, entry.name), from)) continue\n const name = entry.name.replace(/(\\.d)?\\.luaut$/, \"\")\n items.push({\n label: name,\n kind: CompletionItemKind.File,\n detail: entry.name,\n textEdit: { range, newText: name },\n })\n }\n }\n return items\n}\n\nfunction nameItems(analyzer: Analyzer, fromUri: string, specifier: string, before: string): CompletionItem[] {\n const target = analyzer.resolveModulePath(fromUri, specifier)\n const exports = target ? analyzer.exportsAt(target) : undefined\n if (!exports) return []\n\n // Names already in the braces are not offered again.\n const braces = before.slice(before.indexOf(\"{\") + 1)\n const listed = new Set(braces.split(\",\").map(part => part.trim().split(/\\s+/)[0]).filter(Boolean))\n\n const items: CompletionItem[] = []\n for (const [name, type] of exports.values) {\n if (listed.has(name)) continue\n items.push({\n label: name,\n kind: signaturesOf(type).length ? CompletionItemKind.Function : CompletionItemKind.Variable,\n detail: formatType(type),\n })\n }\n for (const [name, exported] of exports.types) {\n if (listed.has(name) || exports.values.has(name)) continue\n items.push({\n label: name,\n kind: CompletionItemKind.Interface,\n detail: `type ${name} = ${formatType(exported.type)}`,\n })\n }\n return items\n}\n\nfunction rangeBack(position: Position, length: number): Range {\n return { start: { line: position.line, character: position.character - length }, end: position }\n}\n\n// --------------------------------------------------------------------------\n// Definition\n// --------------------------------------------------------------------------\n\n/** A statement that names another module. */\ntype ModuleReference = ImportStatement | ExportNamedStatement | ExportAllStatement\n\n/** Go-to-definition inside a statement that names another module: the module\n * string opens the module, a name jumps to where it is really declared —\n * through any `export { } from` and `export *` in between. `undefined` when\n * the cursor is not in such a statement, so the caller can fall back to\n * ordinary definition. */\nexport function importDefinition(\n analyzer: Analyzer,\n analysis: Analysis,\n position: Position,\n): Location | null | undefined {\n const path = pathAt(analysis.program, position, true)\n const statement = path.find(isModuleReference) as unknown as ModuleReference | undefined\n if (!statement?.source) return undefined\n\n const target = analyzer.resolveModulePath(analysis.uri, statement.source.value)\n if (!target) return null\n const fileStart: Location = {\n uri: uriOfPath(target),\n range: { start: { line: 0, character: 0 }, end: { line: 0, character: 0 } },\n }\n\n const name = referencedName(statement, path[path.length - 1] as unknown)\n if (!name) return fileStart\n const module = analyzer.moduleAt(target)\n const found = module && exportDeclaration(analyzer, module, name)\n return found ? { uri: found.uri, range: toRange(found.node) } : fileStart\n}\n\nfunction isModuleReference(node: Spanned): boolean {\n return node.type === \"ImportStatement\"\n || node.type === \"ExportAllStatement\"\n || (node.type === \"ExportNamedStatement\" && !!(node as unknown as ExportNamedStatement).source)\n}\n\n/** The name, as the other module exports it, that `node` stands for. */\nfunction referencedName(statement: ModuleReference, node: unknown): string | undefined {\n switch (statement.type) {\n case \"ImportStatement\":\n if (node === statement.defaultImport) return \"default\"\n return statement.specifiers.find(s => node === s.imported || node === s.local)?.imported.name\n case \"ExportNamedStatement\":\n return statement.specifiers.find(s => node === s.local || node === s.exported)?.local.name\n case \"ExportAllStatement\":\n return undefined\n }\n}\n\nexport interface Declaration {\n uri: string\n node: Spanned\n}\n\n/** Where the export `name` (`\"default\"` for the default) of `module` is\n * declared — following re-exports into the module that declares it. */\nexport function exportDeclaration(\n analyzer: Analyzer,\n module: Analysis,\n name: string,\n seen = new Set<string>(),\n): Declaration | undefined {\n // Re-exports can form a cycle; each (module, name) is visited once.\n const key = `${module.uri}#${name}`\n if (seen.has(key)) return undefined\n seen.add(key)\n\n const here = (node: unknown): Declaration => ({ uri: module.uri, node: node as Spanned })\n const stars: string[] = []\n\n for (const statement of module.program.body.statements) {\n switch (statement.type) {\n case \"ExportDefaultStatement\":\n if (name === \"default\") return here(statement)\n break\n case \"ExportTypeAliasStatement\":\n if (statement.alias.name.name === name) return here(statement.alias.name)\n break\n case \"ExportStatement\": {\n const declaration = statement.declaration\n if (declaration.type === \"FunctionDeclaration\") {\n if (declaration.name.name === name) return here(declaration.name)\n } else {\n for (const target of declaration.names) {\n const found = patternNamed(target, name)\n if (found) return here(found)\n }\n }\n break\n }\n case \"ExportNamedStatement\": {\n const specifier = statement.specifiers.find(s => s.exported.name === name)\n if (!specifier) break\n if (statement.source) {\n const next = moduleFrom(analyzer, module, statement.source.value)\n return next && exportDeclaration(analyzer, next, specifier.local.name, seen)\n }\n return here(localDeclaration(module, specifier.local) ?? specifier.local)\n }\n case \"ExportAllStatement\":\n stars.push(statement.source.value)\n break\n }\n }\n\n // `export *` never carries the default, and a name declared here wins.\n if (name === \"default\") return undefined\n for (const specifier of stars) {\n const next = moduleFrom(analyzer, module, specifier)\n const found = next && exportDeclaration(analyzer, next, name, seen)\n if (found) return found\n }\n return undefined\n}\n\nfunction moduleFrom(analyzer: Analyzer, module: Analysis, specifier: string): Analysis | undefined {\n const target = analyzer.resolveModulePath(module.uri, specifier)\n return target ? analyzer.moduleAt(target) : undefined\n}\n\n/** The declaration of a top-level value or type that `export { x }` names. */\nfunction localDeclaration(module: Analysis, local: Identifier): unknown {\n const binding = bindingOfNode(module, local)\n if (binding?.declarationNode) return binding.declarationNode\n for (const statement of module.program.body.statements) {\n const alias = statement.type === \"TypeAliasStatement\" ? statement\n : statement.type === \"ExportTypeAliasStatement\" ? statement.alias\n : undefined\n if (alias?.name.name === local.name) return alias.name\n }\n return undefined\n}\n\nfunction patternNamed(target: BindingTarget, name: string): Spanned | undefined {\n switch (target.type) {\n case \"IdentifierPattern\":\n return target.name === name ? (target as unknown as Spanned) : undefined\n case \"ObjectPattern\":\n for (const property of target.properties) {\n const found = patternNamed(property.value, name)\n if (found) return found\n }\n return target.rest && patternNamed(target.rest, name)\n case \"ArrayPattern\":\n for (const element of target.elements) {\n const found = element && patternNamed(element.value, name)\n if (found) return found\n }\n return target.rest && patternNamed(target.rest, name)\n }\n}\n","/** Syntax errors, scope errors and type errors, as one list. */\nimport { DiagnosticSeverity, type Diagnostic } from \"vscode-languageserver\"\nimport type { Analysis } from \"../analysis.js\"\nimport { toRange, toPosition } from \"../ast-utils.js\"\n\nexport function diagnostics(analysis: Analysis): Diagnostic[] {\n const out: Diagnostic[] = []\n\n for (const error of analysis.parseErrors) {\n // A parse error points at a token, not a span; highlight to the end of\n // the word under it so the squiggle is visible.\n const start = toPosition(error.line, error.column)\n out.push({\n range: { start, end: { line: start.line, character: start.character + 1 } },\n severity: DiagnosticSeverity.Error,\n source: \"luaut\",\n code: \"syntax\",\n // The parser appends `(line:column)`; the range already says that.\n message: error.message.replace(/\\s*\\(\\d+:\\d+\\)$/, \"\"),\n })\n }\n\n for (const d of analysis.scopes.diagnostics) {\n out.push({\n range: toRange(d.node),\n severity: DiagnosticSeverity.Error,\n source: \"luaut\",\n code: d.kind,\n message: d.message,\n })\n }\n\n for (const d of analysis.types.diagnostics) {\n out.push({\n range: toRange(d.node),\n severity: DiagnosticSeverity.Error,\n source: \"luaut\",\n code: \"type\",\n message: d.message,\n })\n }\n\n return out\n}\n","/**\n * Hover: what the thing under the cursor is, as luaut would write it.\n *\n * Every answer comes from the parser's own tables — binding types, the type of\n * each expression, the resolved type of each type annotation — and every name\n * has a node of its own to point at. Nothing is recovered from the source\n * text.\n */\nimport type { Hover, Position } from \"vscode-languageserver\"\nimport {\n formatType,\n type Binding, type Expression, type Identifier, type Type, type TypeNode,\n} from \"luaut-parser\"\nimport { bindingOfNode, type Analysis } from \"../analysis.js\"\nimport { pathAt, toRange, type Spanned } from \"../ast-utils.js\"\nimport { signaturesOf } from \"./members.js\"\n\nexport function hover(analysis: Analysis, position: Position): Hover | null {\n const path = pathAt(analysis.program, position, true)\n for (let i = path.length - 1; i >= 0; i--) {\n const text = describe(analysis, path, i)\n if (text) return { contents: { kind: \"markdown\", value: code(text) }, range: toRange(path[i]) }\n }\n return null\n}\n\ntype AnyNode = Spanned & Record<string, unknown>\n\nconst PRIMITIVES = new Set([\"any\", \"unknown\", \"never\", \"nil\", \"boolean\", \"number\", \"string\", \"thread\", \"buffer\"])\n\nfunction describe(analysis: Analysis, path: readonly Spanned[], index: number): string | undefined {\n const { types } = analysis\n const node = path[index] as AnyNode\n const parent = path[index - 1] as AnyNode | undefined\n const typeOfNode = (n: unknown): Type | undefined => types.typeOfTypeNode.get(n as TypeNode)\n\n switch (node.type) {\n case \"Identifier\": {\n const identifier = node as unknown as Identifier\n const name = identifier.name\n\n switch (parent?.type) {\n // `{ name: \"n\" }` — read the property off the object's type, so\n // it widens the way the object did (`string`, not `\"n\"`).\n case \"TableExpression\": {\n const field = fieldWithKey(parent, node)\n if (!field) break\n const objectType = types.typeOf.get(parent as unknown as Expression)\n const property = objectType?.kind === \"object\" ? objectType.properties.get(name) : undefined\n const type = property?.type ?? types.typeOf.get(field.value)\n return type && `(property) ${name}: ${pretty(type)}`\n }\n case \"ImportSpecifier\": {\n // A type-only import has no value worth showing (`any`);\n // the type it brings in is the answer.\n const alias = types.aliases.get(name)\n const binding = bindingOfNode(analysis, identifier)\n const value = binding && types.bindingType.get(binding.id)\n if (alias && (!value || value.kind === \"any\")) return `type ${name} = ${pretty(alias)}`\n break\n }\n case \"ExportSpecifier\": {\n // `export { Size }` can name a type, which has no binding.\n if (bindingOfNode(analysis, identifier)) break\n const alias = types.aliases.get(name)\n if (alias) return `type ${name} = ${pretty(alias)}`\n break\n }\n case \"TypeAliasStatement\":\n case \"ExportTypeAliasStatement\":\n if (parent.name === node) return aliasText(analysis, parent)\n break\n case \"DeclareStatement\":\n if (parent.id === node) return declareText(analysis, parent)\n break\n case \"TableTypeProperty\":\n if (parent.key === node) {\n const type = typeOfNode(parent.valueType)\n const readonly = parent.readonly ? \"readonly \" : \"\"\n return type && `(property) ${readonly}${name}${parent.optional ? \"?\" : \"\"}: ${pretty(type)}`\n }\n break\n case \"FunctionTypeParameter\":\n if (parent.id === node) {\n const type = typeOfNode(parent.typeAnnotation)\n return type && `(parameter) ${name}${parent.optional ? \"?\" : \"\"}: ${pretty(type)}`\n }\n break\n case \"GenericTypeParameter\":\n if (parent.id === node) return typeParameterText(analysis, parent)\n break\n case \"InferTypeNode\":\n if (parent.id === node) return `(type parameter) infer ${name}`\n break\n case \"MappedTypeNode\":\n if (parent.parameterId === node) {\n const keys = typeOfNode(parent.constraint)\n return `(type parameter) ${name}${keys ? ` in ${formatType(keys)}` : \"\"}`\n }\n break\n }\n\n // A reference: prefer the narrowed type — what the code sees here,\n // and the whole reason for narrowing.\n const narrowed = types.narrowedTypeOf.get(identifier)\n if (narrowed) return `${name}: ${pretty(narrowed)}`\n const binding = bindingOfNode(analysis, identifier)\n if (binding) {\n const type = types.bindingType.get(binding.id)\n if (type) return `${keyword(binding)} ${binding.name}: ${pretty(type)}`\n }\n // `x.foo` / `x:foo()` — the member's own type.\n if (parent?.type === \"MemberExpression\" || parent?.type === \"MethodCallExpression\") {\n const type = types.typeOf.get(parent as unknown as Expression)\n if (type) return `${name}: ${pretty(type)}`\n }\n return undefined\n }\n\n // Declarations: `const x`, a parameter, `const function f`.\n case \"IdentifierPattern\":\n case \"FunctionParameter\":\n case \"TypedIdentifier\": {\n const binding = bindingOfNode(analysis, node)\n const type = binding && types.bindingType.get(binding.id)\n return type ? `${keyword(binding)} ${binding.name}: ${pretty(type)}` : undefined\n }\n\n // A type written by name: `number`, `Shape`, `Partial<User>`, or a type\n // parameter in scope.\n case \"TypeReference\": {\n const base = node.base as string\n if (!node.namespace) {\n const parameter = typeParameterInScope(path, index, base)\n if (parameter) return typeParameterText(analysis, parameter)\n if (PRIMITIVES.has(base)) return `type ${base}`\n }\n // A plain alias: its definition. The resolved type carries the\n // alias's name, so printing that would read `type Shape = Shape`.\n if (!node.namespace && !(node.typeArguments as unknown[]).length) {\n const alias = types.aliases.get(base)\n if (alias) return `type ${base} = ${pretty(alias)}`\n }\n const type = typeOfNode(node)\n return type && `type ${referenceText(analysis, node)} = ${pretty(type)}`\n }\n }\n\n // Any other part of a type — `typeof x`, `keyof T`, a union — reads as what\n // it resolves to; any expression as its type.\n const annotated = typeOfNode(node)\n if (annotated) return pretty(annotated)\n const type = types.typeOf.get(node as unknown as Expression)\n return type ? pretty(type) : undefined\n}\n\n/** `type Name<T extends C> = ...` */\nfunction aliasText(analysis: Analysis, statement: AnyNode): string | undefined {\n const name = (statement.name as Identifier).name\n const alias = analysis.types.aliases.get(name)\n if (!alias) return undefined\n const generics = (statement.generics as AnyNode[] | undefined) ?? []\n const parameters = generics.length\n ? `<${generics.map(g => typeParameterSignature(analysis, g)).join(\", \")}>`\n : \"\"\n return `type ${name}${parameters} = ${pretty(alias)}`\n}\n\n/** `declare math: {...}` / `declare function f(x: number) -> string (+2 overloads)`.\n * A name declared several times is an overload set: show the signature this\n * particular declaration contributes, and how many others there are. */\nfunction declareText(analysis: Analysis, statement: AnyNode): string | undefined {\n const name = statement.name as string\n const own = analysis.types.typeOfTypeNode.get(statement.valueType as TypeNode)\n if (!own) return undefined\n if (own.kind !== \"function\") return `declare ${name}: ${pretty(own)}`\n // Declaring a name more than once makes an overload set. Count what every\n // top-level declaration of the name contributes — read from the AST, since\n // a declared name nothing references has no binding to read it from.\n const total = (analysis.program.body.statements as unknown as AnyNode[])\n .filter(s => s.type === \"DeclareStatement\" && s.name === name)\n .reduce((n, s) => n + signaturesOf(analysis.types.typeOfTypeNode.get(s.valueType as TypeNode)).length, 0)\n const others = total - 1\n const overloads = others > 0 ? ` (+${others} overload${others > 1 ? \"s\" : \"\"})` : \"\"\n return `declare function ${name}${formatType(own)}${overloads}`\n}\n\ninterface TypeParameterNode {\n name: string\n constraint?: unknown\n isConst?: boolean\n infer?: boolean\n}\n\nfunction typeParameterText(analysis: Analysis, parameter: TypeParameterNode | AnyNode): string {\n return `(type parameter) ${typeParameterSignature(analysis, parameter)}`\n}\n\nfunction typeParameterSignature(analysis: Analysis, parameter: TypeParameterNode | AnyNode): string {\n const p = parameter as TypeParameterNode\n if (p.infer) return `infer ${p.name}`\n const constraint = p.constraint ? analysis.types.typeOfTypeNode.get(p.constraint as TypeNode) : undefined\n return `${p.isConst ? \"const \" : \"\"}${p.name}${constraint ? ` extends ${formatType(constraint)}` : \"\"}`\n}\n\n/** The type parameter `name` refers to at this point: from an enclosing\n * generic list, a mapped type's key, or an `infer` in a conditional. */\nfunction typeParameterInScope(path: readonly Spanned[], index: number, name: string): TypeParameterNode | undefined {\n for (let i = index - 1; i >= 0; i--) {\n const a = path[i] as AnyNode\n const generic = (a.generics as TypeParameterNode[] | undefined)?.find(g => g.name === name)\n if (generic) return generic\n if (a.type === \"MappedTypeNode\" && a.parameter === name) return { name }\n if (a.type === \"ConditionalTypeNode\" && bindsInfer(a.extendsType, name)) return { name, infer: true }\n }\n return undefined\n}\n\nfunction bindsInfer(node: unknown, name: string): boolean {\n if (!node || typeof node !== \"object\") return false\n if (Array.isArray(node)) return node.some(n => bindsInfer(n, name))\n const n = node as AnyNode\n if (n.type === \"InferTypeNode\" && n.name === name) return true\n return Object.values(n).some(v => bindsInfer(v, name))\n}\n\n/** `Partial<User>` — the reference with its arguments resolved. */\nfunction referenceText(analysis: Analysis, reference: AnyNode): string {\n const name = reference.namespace ? `${reference.namespace}.${reference.base}` : (reference.base as string)\n const args = (reference.typeArguments as unknown[]) ?? []\n if (!args.length) return name\n const resolved = args.map(a => {\n const t = analysis.types.typeOfTypeNode.get(a as TypeNode)\n return t ? formatType(t) : \"?\"\n })\n return `${name}<${resolved.join(\", \")}>`\n}\n\nfunction fieldWithKey(table: AnyNode, key: AnyNode): { value: Expression } | undefined {\n const fields = table.fields as { type: string; key?: unknown; value: Expression }[]\n return fields.find(f => f.type === \"TableFieldNamed\" && f.key === key)\n}\n\n/** Long object types one member per line, overload sets one signature per\n * line — `math` on a single line is thousands of characters. */\nfunction pretty(type: Type): string {\n const flat = formatType(type)\n if (flat.length <= 80) return flat\n if (type.kind === \"object\") {\n const lines: string[] = []\n if (type.indexer) lines.push(` [${formatType(type.indexer.key)}]: ${formatType(type.indexer.value)},`)\n for (const [name, property] of type.properties) {\n const readonly = property.readonly ? \"readonly \" : \"\"\n lines.push(` ${readonly}${name}${property.optional ? \"?\" : \"\"}: ${formatType(property.type)},`)\n }\n return `{\\n${lines.join(\"\\n\")}\\n}`\n }\n if (type.kind === \"intersection\" && type.types.every(t => t.kind === \"function\")) {\n return type.types.map(formatType).join(\"\\n& \")\n }\n return flat\n}\n\nfunction keyword(binding: Binding): string {\n if (binding.kind === \"param\" || binding.kind === \"self\") return \"(parameter)\"\n if (binding.kind === \"global\") return \"(global)\"\n if (binding.kind.startsWith(\"for-\")) return \"(loop variable)\"\n return binding.isConst ? \"const\" : \"let\"\n}\n\nfunction code(text: string): string {\n // Its own grammar: VS Code colours a hover's code block with TextMate\n // only, and the editor's luaut grammar deliberately leaves names and\n // types to semantic tokens. Hover text is output this server formats,\n // so a grammar for that format is exact rather than a guess.\n return \"```luaut-hover\\n\" + text + \"\\n```\"\n}\n","/**\n * Go-to-definition, find-references, rename and document highlight — all four\n * are the same question (\"which binding is this, and where else does it\n * appear?\") asked with different answers.\n */\nimport {\n DocumentHighlightKind,\n type DocumentHighlight, type Location, type Position, type Range,\n type TextEdit, type WorkspaceEdit,\n} from \"vscode-languageserver\"\nimport type { Binding } from \"luaut-parser\"\nimport { bindingOfNode, type Analysis } from \"../analysis.js\"\nimport { pathAt, toRange, type Spanned } from \"../ast-utils.js\"\n\n/** Nodes that can name a binding — as a use or as its declaration. */\nconst NAMING = new Set([\"Identifier\", \"IdentifierPattern\", \"FunctionParameter\", \"TypedIdentifier\"])\n\n/** The binding referred to at `position`, if the cursor is on a variable —\n * a use of it or its declaration. */\nexport function bindingAt(analysis: Analysis, position: Position): Binding | undefined {\n const path = pathAt(analysis.program, position, true)\n for (let i = path.length - 1; i >= 0; i--) {\n const node = path[i]\n if (!node.type || !NAMING.has(node.type)) continue\n const binding = bindingOfNode(analysis, node)\n if (binding) return binding\n }\n return undefined\n}\n\n/** Every place the binding appears: its declaration plus every reference. */\nfunction sites(binding: Binding): Spanned[] {\n const out: Spanned[] = []\n if (binding.declarationNode) out.push(binding.declarationNode as unknown as Spanned)\n out.push(...(binding.references as unknown as Spanned[]))\n return out\n}\n\nexport function definition(analysis: Analysis, position: Position): Location | null {\n const binding = bindingAt(analysis, position)\n if (!binding?.declarationNode) return null\n return { uri: analysis.uri, range: toRange(binding.declarationNode as unknown as Spanned) }\n}\n\nexport function references(\n analysis: Analysis,\n position: Position,\n includeDeclaration: boolean,\n): Location[] {\n const binding = bindingAt(analysis, position)\n if (!binding) return []\n const nodes = includeDeclaration ? sites(binding) : (binding.references as unknown as Spanned[])\n return nodes.map(node => ({ uri: analysis.uri, range: toRange(node) }))\n}\n\nexport function highlights(analysis: Analysis, position: Position): DocumentHighlight[] {\n const binding = bindingAt(analysis, position)\n if (!binding) return []\n return sites(binding).map(node => ({\n range: toRange(node),\n kind: node === binding.declarationNode\n ? DocumentHighlightKind.Write\n : DocumentHighlightKind.Read,\n }))\n}\n\n/** The range rename would replace, and the current name — so the editor can\n * refuse before it asks for a new one. */\nexport function prepareRename(\n analysis: Analysis,\n position: Position,\n): { range: Range; placeholder: string } | null {\n const binding = bindingAt(analysis, position)\n if (!binding) return null\n // A builtin lives in a definitions file; renaming it here would rename the\n // uses and leave the declaration behind.\n if (binding.isBuiltin || !binding.declarationNode) return null\n const path = pathAt(analysis.program, position, true)\n const identifier = [...path].reverse().find(n => !!n.type && NAMING.has(n.type))\n if (!identifier) return null\n return { range: toRange(identifier), placeholder: binding.name }\n}\n\nexport function rename(analysis: Analysis, position: Position, newName: string): WorkspaceEdit | null {\n if (!isIdentifier(newName)) return null\n const binding = bindingAt(analysis, position)\n if (!binding || binding.isBuiltin || !binding.declarationNode) return null\n const edits: TextEdit[] = sites(binding).map(node => ({ range: toRange(node), newText: newName }))\n return { changes: { [analysis.uri]: edits } }\n}\n\nconst IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/\nfunction isIdentifier(name: string): boolean {\n return IDENTIFIER.test(name)\n}\n","/**\n * Completion.\n *\n * `x.` and `x:` are syntax errors, so the file as typed cannot answer \"what\n * are `x`'s members?\". The trick every language server of this shape uses:\n * substitute a placeholder identifier at the cursor, analyze *that* text, and\n * read the answer off the AST it produces. The user's document is untouched —\n * only the speculative copy is analyzed, and it is never cached.\n */\nimport {\n CompletionItemKind, InsertTextFormat,\n type CompletionItem, type Position,\n} from \"vscode-languageserver\"\nimport type { TextDocument } from \"vscode-languageserver-textdocument\"\nimport { formatType, type Expression, type Type } from \"luaut-parser\"\nimport type { Analysis, Analyzer } from \"../analysis.js\"\nimport { pathAt, type Spanned } from \"../ast-utils.js\"\nimport { importCompletion } from \"./imports.js\"\nimport { membersOf, signaturesOf, signatureLabel } from \"./members.js\"\n\nconst PLACEHOLDER = \"__luautCompletion__\"\nconst IDENTIFIER_CHAR = /[A-Za-z0-9_]/\n\nexport function completion(\n analyzer: Analyzer,\n document: TextDocument,\n position: Position,\n): CompletionItem[] {\n // A module path or imported name: answered from the other module.\n const inImport = importCompletion(analyzer, document, position)\n if (inImport) return inImport\n\n // Inside a string argument: the values its parameter accepts.\n const inString = stringCompletion(analyzer, document, position)\n if (inString) return inString\n\n const source = document.getText()\n const offset = document.offsetAt(position)\n\n // The word being typed, if any — replaced wholesale so a half-written\n // name cannot break the speculative parse.\n let start = offset\n while (start > 0 && IDENTIFIER_CHAR.test(source[start - 1])) start--\n let end = offset\n while (end < source.length && IDENTIFIER_CHAR.test(source[end])) end++\n\n const operator = memberOperator(source, start)\n const alreadyCalled = /^\\s*\\(/.test(source.slice(end))\n\n // A member access on its own is not a statement — `obj.foo` alone on a\n // line is a syntax error, which is exactly where people type `obj.` — so\n // after `.` the placeholder is also tried as a call, which parses wherever\n // the access would and on a line of its own too. A method name after `:`\n // must be called to parse at all.\n const standIns = operator === \":\"\n ? [alreadyCalled ? PLACEHOLDER : `${PLACEHOLDER}()`]\n : operator === \".\" && !alreadyCalled\n ? [PLACEHOLDER, `${PLACEHOLDER}()`]\n : [PLACEHOLDER]\n\n // Where the placeholder sits, in the patched document's coordinates —\n // the same line, since the patch never spans one.\n const at: Position = { line: position.line, character: position.character - (offset - start) }\n\n let first: { analysis: Analysis; path: Spanned[] } | undefined\n for (const standIn of standIns) {\n const patched = source.slice(0, start) + standIn + source.slice(end)\n const analysis = analyzer.analyze(document.uri, -1, patched)\n const path = pathAt(analysis.program, at, true)\n const index = path.findLastIndex(\n n => n.type === \"Identifier\" && (n as unknown as { name: string }).name === PLACEHOLDER,\n )\n const parent = index > 0 ? path[index - 1] : undefined\n if (parent && (parent.type === \"MemberExpression\" || parent.type === \"MethodCallExpression\")) {\n return memberItems(analysis, parent)\n }\n first ??= { analysis, path }\n }\n\n // After `.` or `:` only members make sense. If none could be found, an\n // empty list is honest; the globals are never what was meant there.\n if (operator || !first) return []\n\n // A type position wants type names, not values.\n if (inTypePosition(first.path)) {\n const named: CompletionItem[] = [...first.analysis.types.aliases.keys()].map(name => ({\n label: name,\n kind: CompletionItemKind.Interface,\n detail: \"type\",\n }))\n const primitives: CompletionItem[] = PRIMITIVES.map(name => ({\n label: name,\n kind: CompletionItemKind.Keyword,\n detail: \"type\",\n }))\n return [...named, ...primitives]\n }\n\n return valueItems(first.analysis, at)\n}\n\n/** Completion inside a string literal, or `undefined` when the cursor is not\n * in one. A string that is a call argument offers the string values its\n * parameter accepts — `game:GetService(\"|\")` lists the services. Any other\n * string offers nothing: a variable name is never what goes inside quotes. */\nfunction stringCompletion(\n analyzer: Analyzer,\n document: TextDocument,\n position: Position,\n): CompletionItem[] | undefined {\n const analysis = analyzer.get(document)\n const path = pathAt(analysis.program, position, false)\n const literal = [...path].reverse().find(n => n.type === \"StringLiteral\")\n if (!literal) return undefined\n\n const expected = analysis.types.expectedTypeOf.get(literal as unknown as Expression)\n const values = stringLiterals(expected, analysis.types.aliases)\n if (!values.length) return []\n\n // Replace what is between the quotes. A string spanning lines is left to\n // the editor's own filtering.\n const line = literal.line.start - 1\n const range = literal.line.start === literal.line.end\n ? {\n start: { line, character: literal.column.start },\n end: { line, character: literal.column.end - 2 },\n }\n : undefined\n return values.map(value => ({\n label: value,\n kind: CompletionItemKind.Constant,\n ...(range ? { textEdit: { range, newText: value } } : {}),\n }))\n}\n\n/** The string literal types a type admits — through unions, aliases and a\n * type parameter's constraint. */\nfunction stringLiterals(type: Type | undefined, aliases: ReadonlyMap<string, Type>, seen = new Set<Type>()): string[] {\n if (!type || seen.has(type)) return []\n seen.add(type)\n switch (type.kind) {\n case \"literal\":\n return typeof type.value === \"string\" ? [type.value] : []\n case \"union\":\n return [...new Set(type.types.flatMap(t => stringLiterals(t, aliases, seen)))]\n case \"genericRef\": {\n const alias = aliases.get(type.name)\n return alias ? stringLiterals(alias, aliases, seen) : []\n }\n case \"typeParam\":\n return stringLiterals(type.constraint, aliases, seen)\n default:\n return []\n }\n}\n\n/** The member operator right before the word being typed, if there is one.\n * `..` is concatenation and `1.` is a number, neither of which has members. */\nfunction memberOperator(source: string, wordStart: number): \".\" | \":\" | undefined {\n const ch = source[wordStart - 1]\n if (ch === \":\") return source[wordStart - 2] === \":\" ? undefined : \":\"\n if (ch !== \".\") return undefined\n if (source[wordStart - 2] === \".\") return undefined\n // A run of digits right before the dot, not part of a longer name.\n let i = wordStart - 2\n while (i >= 0 && /[0-9]/.test(source[i])) i--\n const digits = wordStart - 2 - i\n if (digits > 0 && (i < 0 || !/[A-Za-z_]/.test(source[i]))) return undefined\n return \".\"\n}\n\nfunction memberItems(analysis: Analysis, access: Spanned): CompletionItem[] {\n const object = (access as unknown as { object: Expression }).object\n const type = analysis.types.typeOf.get(object)\n const colon = access.type === \"MethodCallExpression\"\n\n // A string has no fields, but `s:upper()` reaches the `string` library\n // through the string metatable — so after `:` offer that library.\n if (isStringLike(type)) {\n if (!colon) return []\n const id = analysis.scopes.globalsByName.get(\"string\")\n const library = id === undefined ? undefined : analysis.types.bindingType.get(id)\n return membersOf(library, analysis.types.aliases)\n .filter(member => signaturesOf(member.property.type).length > 0)\n .map(member => memberItem(member.name, member.property.type, member.property.readonly))\n }\n\n return membersOf(type, analysis.types.aliases)\n .filter(member => (colon ? member.isMethod : true))\n .map(member => memberItem(member.name, member.property.type, member.property.readonly))\n}\n\nfunction isStringLike(type: Type | undefined): boolean {\n if (!type) return false\n switch (type.kind) {\n case \"primitive\": return type.name === \"string\"\n case \"literal\": return typeof type.value === \"string\"\n case \"templateLiteral\": return true\n case \"union\": return type.types.length > 0 && type.types.every(isStringLike)\n default: return false\n }\n}\n\n/** Names in scope at `at`. Scope analysis records where each binding is\n * declared but not the extent of its scope, so this approximates: everything\n * declared earlier in the file, plus the globals, which are visible\n * everywhere. Over-offering is the right failure — a name the editor lists\n * and the file rejects is a diagnostic away from being obvious. */\nfunction valueItems(analysis: Analysis, at: Position): CompletionItem[] {\n const items: CompletionItem[] = []\n const seen = new Set<string>()\n for (const binding of analysis.scopes.bindings.values()) {\n if (binding.name === PLACEHOLDER || seen.has(binding.name)) continue\n const declaration = binding.declarationNode as unknown as Spanned | undefined\n if (declaration && declaration.line.start - 1 > at.line) continue\n seen.add(binding.name)\n const type = analysis.types.bindingType.get(binding.id)\n items.push({\n label: binding.name,\n kind: kindOf(type, binding.kind),\n detail: type ? formatType(type) : undefined,\n // Locals before globals, and globals before library names.\n sortText: `${binding.isBuiltin ? 2 : binding.kind === \"global\" ? 1 : 0}${binding.name}`,\n })\n }\n for (const keyword of KEYWORDS) {\n items.push({ label: keyword, kind: CompletionItemKind.Keyword, sortText: `3${keyword}` })\n }\n return items\n}\n\nfunction memberItem(name: string, type: Type, readonly?: boolean): CompletionItem {\n const signatures = signaturesOf(type)\n if (signatures.length) {\n return {\n label: name,\n kind: CompletionItemKind.Method,\n detail: signatureLabel(signatures[0]).label,\n insertText: `${name}($0)`,\n insertTextFormat: InsertTextFormat.Snippet,\n }\n }\n return {\n label: name,\n kind: CompletionItemKind.Field,\n detail: `${readonly ? \"readonly \" : \"\"}${formatType(type)}`,\n }\n}\n\nfunction kindOf(type: Type | undefined, bindingKind: string): CompletionItemKind {\n if (type && signaturesOf(type).length) return CompletionItemKind.Function\n if (bindingKind === \"param\" || bindingKind === \"self\") return CompletionItemKind.Variable\n return CompletionItemKind.Variable\n}\n\n/** Is the cursor inside a type annotation? Every type node's name ends in\n * `TypeNode`, plus the couple that do not. */\nfunction inTypePosition(path: readonly Spanned[]): boolean {\n return path.some(n =>\n !!n.type && (n.type.endsWith(\"TypeNode\") || n.type === \"TypeReference\"\n || n.type === \"TypeAliasStatement\" || n.type === \"ExportTypeAliasStatement\"),\n )\n}\n\nconst PRIMITIVES = [\n \"any\", \"unknown\", \"never\", \"nil\", \"boolean\", \"number\", \"string\", \"thread\", \"buffer\",\n]\n\nconst KEYWORDS = [\n \"const\", \"let\", \"function\", \"return\", \"if\", \"then\", \"elseif\", \"else\", \"end\",\n \"for\", \"in\", \"while\", \"do\", \"repeat\", \"until\", \"break\", \"continue\",\n \"type\", \"declare\", \"export\", \"import\", \"and\", \"or\", \"not\", \"true\", \"false\", \"nil\",\n]\n","/**\n * Signature help: the parameter list of the call the cursor sits inside.\n *\n * A call being typed is usually not yet a call — `add(1, ` has no argument\n * after the comma and no closing paren, and the parser drops the statement.\n * So, like completion, this analyzes a repaired copy of the text: the fewest\n * characters that make the call parse, tried in order.\n */\nimport type { Position, SignatureHelp, SignatureInformation } from \"vscode-languageserver\"\nimport type { TextDocument } from \"vscode-languageserver-textdocument\"\nimport type { Expression } from \"luaut-parser\"\nimport type { Analyzer, Analysis } from \"../analysis.js\"\nimport { containsPosition, pathAt, type Spanned } from \"../ast-utils.js\"\nimport { signaturesOf, signatureLabel } from \"./members.js\"\n\ninterface CallLike extends Spanned {\n type: \"CallExpression\" | \"MethodCallExpression\"\n arguments: Expression[]\n}\n\nexport function signatureHelp(\n analyzer: Analyzer,\n document: TextDocument,\n position: Position,\n): SignatureHelp | null {\n const source = document.getText()\n const offset = document.offsetAt(position)\n for (const repair of [\"\", \"nil\", \"nil)\", \")\"]) {\n const text = source.slice(0, offset) + repair + source.slice(offset)\n const analysis = analyzer.analyze(document.uri, -1, text)\n const found = helpAt(analysis, position)\n if (found) return found\n }\n return null\n}\n\nfunction helpAt(analysis: Analysis, position: Position): SignatureHelp | null {\n const path = pathAt(analysis.program, position, true)\n const call = [...path].reverse().find(\n n => n.type === \"CallExpression\" || n.type === \"MethodCallExpression\",\n ) as CallLike | undefined\n if (!call) return null\n\n const callee = call.type === \"CallExpression\"\n ? (call as unknown as { callee: Expression }).callee\n : (call as unknown as Expression)\n // For a method call the callee has no node of its own, so read the type of\n // the whole `obj:m` receiver path from the object plus the method name.\n const calleeType = call.type === \"CallExpression\"\n ? analysis.types.typeOf.get(callee)\n : methodType(analysis, call)\n\n const signatures = signaturesOf(calleeType, analysis.types.aliases)\n if (!signatures.length) return null\n\n // `:` supplies `self`, so the first written argument is the second param.\n const selfOffset = call.type === \"MethodCallExpression\" ? 1 : 0\n const written = activeArgument(call, position)\n\n const infos: SignatureInformation[] = signatures.map(signature => {\n const { label, parameters } = signatureLabel(signature)\n return { label, parameters: parameters.map(p => ({ label: p })) }\n })\n\n // Pick the overload that could still accept this many arguments.\n const wanted = written + selfOffset + 1\n let active = signatures.findIndex(s => s.params.length >= wanted || s.varargs)\n if (active < 0) active = 0\n\n return {\n signatures: infos,\n activeSignature: active,\n activeParameter: Math.min(\n written + selfOffset,\n Math.max(0, signatures[active].params.length - 1),\n ),\n }\n}\n\nfunction methodType(analysis: Analysis, call: CallLike): undefined | ReturnType<Analysis[\"types\"][\"typeOf\"][\"get\"]> {\n const object = (call as unknown as { object: Expression }).object\n const method = (call as unknown as { method: { name: string } }).method\n const objectType = analysis.types.typeOf.get(object)\n if (!objectType) return undefined\n return memberType(objectType, method.name, analysis)\n}\n\nfunction memberType(\n type: NonNullable<ReturnType<Analysis[\"types\"][\"typeOf\"][\"get\"]>>,\n name: string,\n analysis: Analysis,\n): ReturnType<Analysis[\"types\"][\"typeOf\"][\"get\"]> {\n if (type.kind === \"object\") return type.properties.get(name)?.type\n if (type.kind === \"intersection\") {\n for (const part of type.types) {\n const found = memberType(part, name, analysis)\n if (found) return found\n }\n }\n if (type.kind === \"genericRef\") {\n const alias = analysis.types.aliases.get(type.name)\n if (alias) return memberType(alias, name, analysis)\n }\n return undefined\n}\n\n/** Which argument the cursor is in — counted by which argument spans it, or\n * by how many end before it when the cursor is in the gap after a comma. */\nfunction activeArgument(call: CallLike, position: Position): number {\n const args = call.arguments\n for (let i = 0; i < args.length; i++) {\n if (containsPosition(args[i] as unknown as Spanned, position, true)) return i\n }\n let count = 0\n for (const arg of args as unknown as Spanned[]) {\n const before = arg.line.end - 1 < position.line\n || (arg.line.end - 1 === position.line && arg.column.end - 1 <= position.character)\n if (before) count++\n }\n return count\n}\n","/** Document symbols: the outline of a file. */\nimport { SymbolKind, type DocumentSymbol } from \"vscode-languageserver\"\nimport { formatType, type Identifier } from \"luaut-parser\"\nimport { bindingOfNode, type Analysis } from \"../analysis.js\"\nimport { toRange, walk, type Spanned } from \"../ast-utils.js\"\n\nexport function documentSymbols(analysis: Analysis): DocumentSymbol[] {\n const out: DocumentSymbol[] = []\n\n walk(analysis.program, node => {\n switch (node.type) {\n case \"FunctionDeclaration\":\n case \"FunctionDeclarationStatement\": {\n const name = functionName(node)\n if (name) out.push(symbol(name, SymbolKind.Function, node, detailOf(analysis, node)))\n break\n }\n case \"TypeAliasStatement\":\n case \"ExportTypeAliasStatement\": {\n // The alias name is an Identifier node here, a bare string on\n // a `declare` — take either.\n const named = (node as unknown as { name?: string | { name?: string } }).name\n const name = typeof named === \"string\" ? named : named?.name\n if (name) {\n const alias = analysis.types.aliases.get(name)\n out.push(symbol(name, SymbolKind.Interface, node, alias ? formatType(alias) : undefined))\n }\n break\n }\n case \"VariableDeclaration\": {\n for (const target of (node as unknown as { names?: Spanned[] }).names ?? []) {\n const name = (target as unknown as { name?: string }).name\n if (name) out.push(symbol(name, SymbolKind.Variable, target))\n }\n break\n }\n }\n })\n\n return out\n}\n\nfunction functionName(node: Spanned): string | undefined {\n const named = node as unknown as {\n name?: string | { name?: string }\n target?: { base?: { name?: string }; path?: { name?: string }[]; method?: { name: string } }\n }\n if (typeof named.name === \"string\") return named.name\n if (named.name && typeof named.name === \"object\") return named.name.name\n if (named.target?.base?.name) {\n const path = (named.target.path ?? []).map(p => p.name).filter(Boolean)\n const dotted = [named.target.base.name, ...path].join(\".\")\n return named.target.method ? `${dotted}:${named.target.method.name}` : dotted\n }\n return undefined\n}\n\n/** A function declaration is a statement, not an expression, so its type\n * comes from the binding it creates rather than from `typeOf`. */\nfunction detailOf(analysis: Analysis, node: Spanned): string | undefined {\n const name = (node as unknown as { name?: Identifier }).name\n if (name && typeof name === \"object\") {\n const binding = bindingOfNode(analysis, name)\n const type = binding && analysis.types.bindingType.get(binding.id)\n if (type) return formatType(type)\n }\n return undefined\n}\n\nfunction symbol(name: string, kind: SymbolKind, node: Spanned, detail?: string): DocumentSymbol {\n const range = toRange(node)\n return { name, kind, detail, range, selectionRange: range }\n}\n","/**\n * Semantic highlighting, from the parser rather than from patterns.\n *\n * A TextMate grammar only sees characters, and in luaut a word's role depends\n * on where it stands: `extends` is a keyword inside a type and a plain name\n * elsewhere, `type Foo = ...` declares an alias while `type(x)` calls a\n * builtin, and `typeof x` in a type is a query while `typeof(v)` in code is a\n * call. Guessing that with regexes is how `extends (` came out coloured as a\n * function call. Here every token is classified from the same lexer and AST\n * the analyzer uses, so the colours cannot disagree with what the file means.\n *\n * The grammar still colours what is unambiguous — comments, strings, numbers,\n * reserved words — so the file looks right before the server answers.\n */\nimport type { SemanticTokens, SemanticTokensLegend } from \"vscode-languageserver\"\nimport { tokenize, type Binding, type Expression, type Identifier, type Token, type Type, type TypeNode } from \"luaut-parser\"\nimport { bindingOfNode, type Analysis } from \"../analysis.js\"\nimport { children, type Spanned } from \"../ast-utils.js\"\nimport { signaturesOf } from \"./members.js\"\n\nconst TOKEN_TYPES = [\n \"namespace\", \"type\", \"typeParameter\", \"parameter\", \"variable\",\n \"property\", \"function\", \"method\", \"keyword\",\n] as const\nconst TOKEN_MODIFIERS = [\"declaration\", \"readonly\", \"defaultLibrary\", \"control\"] as const\n\ntype TokenType = typeof TOKEN_TYPES[number]\ntype TokenModifier = typeof TOKEN_MODIFIERS[number]\n\nexport const semanticTokensLegend: SemanticTokensLegend = {\n tokenTypes: [...TOKEN_TYPES],\n tokenModifiers: [...TOKEN_MODIFIERS],\n}\n\n/** Words the lexer reads as identifiers but the parser treats as keywords\n * where they stand in the right place. A word is only coloured as one if the\n * AST did not already claim it as a name. */\nconst SOFT_KEYWORDS = new Set([\n \"type\", \"declare\", \"extends\", \"keyof\", \"infer\", \"readonly\", \"is\", \"asserts\", \"satisfies\", \"typeof\",\n \"default\",\n])\n\n/** Soft keywords that belong with `export` / `return` rather than with\n * `const` / `type`: marked `control`, which the editor extension maps to the\n * scope themes colour control keywords with. */\nconst CONTROL_KEYWORDS = new Set([\"default\"])\n\nconst PRIMITIVES = new Set([\"any\", \"unknown\", \"never\", \"nil\", \"boolean\", \"number\", \"string\", \"thread\", \"buffer\"])\n\ninterface Entry {\n line: number\n character: number\n length: number\n type: TokenType\n modifiers: readonly TokenModifier[]\n}\n\ntype Add = (at: { line: { start: number }; column: { start: number } }, length: number,\n type: TokenType, modifiers?: readonly TokenModifier[]) => void\n\nexport function semanticTokens(analysis: Analysis): SemanticTokens {\n // Keyed by start position: the first classification of a token wins, so\n // the AST's reading of a word takes precedence over the keyword fallback.\n const entries = new Map<string, Entry>()\n const add: Add = (at, length, type, modifiers = []) => {\n const line = at.line.start - 1\n const character = at.column.start - 1\n const key = `${line}:${character}`\n if (!entries.has(key)) entries.set(key, { line, character, length, type, modifiers })\n }\n\n let tokens: Token[] = []\n try {\n tokens = tokenize(analysis.source)\n } catch {\n // A lex error: only what the (empty) AST knows gets coloured.\n }\n const identifiers = tokens.filter(t => t.type === \"Identifier\")\n\n const ancestors: Spanned[] = []\n const walk = (node: Spanned): void => {\n classify(analysis, node, ancestors, identifiers, add)\n ancestors.push(node)\n for (const child of children(node)) walk(child)\n ancestors.pop()\n }\n walk(analysis.program)\n\n // Reserved words are left to the grammar: it already tells a control\n // keyword (`if`, `export`) from a declaration keyword (`const`), the way\n // themes colour them. Overriding them with one \"keyword\" type flattened\n // that. Only soft keywords need the parser's say-so.\n for (const token of tokens) {\n const value = (token as { value?: unknown }).value\n if (token.type !== \"Identifier\" || typeof value !== \"string\" || !SOFT_KEYWORDS.has(value)) continue\n add(token, value.length, \"keyword\", CONTROL_KEYWORDS.has(value) ? [\"control\"] : [])\n }\n\n return { data: encode([...entries.values()]) }\n}\n\ntype AnyNode = Spanned & Record<string, unknown>\n\nfunction classify(\n analysis: Analysis,\n spanned: Spanned,\n ancestors: readonly Spanned[],\n identifiers: readonly Token[],\n add: Add,\n): void {\n const node = spanned as AnyNode\n switch (node.type) {\n case \"Identifier\":\n identifier(analysis, node, ancestors[ancestors.length - 1] as AnyNode | undefined, add)\n return\n\n // Declarations whose node starts at the name.\n case \"IdentifierPattern\":\n case \"TypedIdentifier\":\n case \"FunctionParameter\": {\n const name = node.name\n // A destructured parameter has no name; its leaves are patterns.\n if (typeof name !== \"string\" || !name) return\n const binding = bindingOfNode(analysis, node)\n add(node, name.length, valueKind(analysis, binding), modifiersOf(binding, true))\n return\n }\n\n case \"TypeReference\": {\n const base = node.base as string\n const namespace = node.namespace as string | undefined\n const names = firstTokensWithin(identifiers, node, namespace ? 2 : 1)\n if (namespace && names[0]) add(names[0], namespace.length, \"namespace\")\n const baseToken = names[namespace ? 1 : 0]\n if (!baseToken) return\n if (!namespace && typeParameterInScope(ancestors, base)) {\n add(baseToken, base.length, \"typeParameter\")\n } else {\n add(baseToken, base.length, \"type\", PRIMITIVES.has(base) ? [\"defaultLibrary\"] : [])\n }\n return\n }\n }\n}\n\nfunction identifier(analysis: Analysis, node: AnyNode, parent: AnyNode | undefined, add: Add): void {\n const name = (node as unknown as Identifier).name\n const as = (type: TokenType, modifiers: readonly TokenModifier[] = []): void => add(node, name.length, type, modifiers)\n const typeOfNode = (n: unknown): Type | undefined => analysis.types.typeOfTypeNode.get(n as TypeNode)\n\n switch (parent?.type) {\n case \"MemberExpression\":\n if (parent.property === node) {\n return as(isFunction(analysis.types.typeOf.get(parent as unknown as Expression)) ? \"method\" : \"property\")\n }\n break\n case \"MethodCallExpression\":\n if (parent.method === node) return as(\"method\")\n break\n case \"TableExpression\":\n if (isFieldKey(parent, node)) return as(\"property\", [\"declaration\"])\n break\n case \"TypeAliasStatement\":\n case \"ExportTypeAliasStatement\":\n if (parent.name === node) return as(\"type\", [\"declaration\"])\n break\n case \"DeclareStatement\":\n if (parent.id === node) return as(isFunction(typeOfNode(parent.valueType)) ? \"function\" : \"variable\", [\"declaration\"])\n break\n case \"TableTypeProperty\":\n if (parent.key === node) {\n return as(\n isFunction(typeOfNode(parent.valueType)) ? \"method\" : \"property\",\n parent.readonly ? [\"declaration\", \"readonly\"] : [\"declaration\"],\n )\n }\n break\n case \"FunctionTypeParameter\":\n if (parent.id === node) return as(\"parameter\", [\"declaration\"])\n break\n case \"GenericTypeParameter\":\n case \"InferTypeNode\":\n if (parent.id === node) return as(\"typeParameter\", [\"declaration\"])\n break\n case \"MappedTypeNode\":\n if (parent.parameterId === node) return as(\"typeParameter\", [\"declaration\"])\n break\n case \"ImportSpecifier\": {\n // A type-only import is a type, not an `any` value.\n const binding = bindingOfNode(analysis, node)\n const value = binding && analysis.types.bindingType.get(binding.id)\n if (analysis.types.aliases.has(name) && (!value || value.kind === \"any\")) return as(\"type\", [\"declaration\"])\n break\n }\n case \"ExportSpecifier\":\n // `export { Size }` can name a type, which has no value binding.\n if (!bindingOfNode(analysis, node) && analysis.types.aliases.has(name)) return as(\"type\")\n break\n case \"FunctionName\":\n // `function a.b.c:d()` — `a` is a variable, `b`/`c` are properties,\n // `d` is the method being defined.\n if ((parent.path as unknown[]).includes(node)) return as(\"property\")\n if (parent.method === node) return as(\"method\", [\"declaration\"])\n break\n }\n\n const binding = bindingOfNode(analysis, node)\n // No binding: a name the analysis has no reading of (inside a syntax\n // error, say). Leave it to the grammar rather than guess.\n if (!binding) return\n as(valueKind(analysis, binding), modifiersOf(binding, binding.declarationNode === (node as unknown)))\n}\n\nfunction valueKind(analysis: Analysis, binding: Binding | undefined): TokenType {\n if (!binding) return \"variable\"\n if (binding.kind === \"param\" || binding.kind === \"self\") return \"parameter\"\n return isFunction(analysis.types.bindingType.get(binding.id)) ? \"function\" : \"variable\"\n}\n\nfunction modifiersOf(binding: Binding | undefined, isDeclaration: boolean): TokenModifier[] {\n const modifiers: TokenModifier[] = []\n if (isDeclaration) modifiers.push(\"declaration\")\n if (binding?.isConst) modifiers.push(\"readonly\")\n if (binding?.isBuiltin) modifiers.push(\"defaultLibrary\")\n return modifiers\n}\n\nfunction isFunction(type: Type | undefined): boolean {\n return signaturesOf(type).length > 0\n}\n\nfunction isFieldKey(table: AnyNode, key: AnyNode): boolean {\n const fields = table.fields as { type: string; key?: unknown }[]\n return fields.some(f => f.type === \"TableFieldNamed\" && f.key === key)\n}\n\n/** Is `name` a type parameter at this point — declared by an enclosing\n * generic list, a mapped type's key, or an `infer` in a conditional? */\nfunction typeParameterInScope(ancestors: readonly Spanned[], name: string): boolean {\n for (let i = ancestors.length - 1; i >= 0; i--) {\n const a = ancestors[i] as AnyNode\n if ((a.generics as { name: string }[] | undefined)?.some(g => g.name === name)) return true\n if (a.type === \"MappedTypeNode\" && a.parameter === name) return true\n if (a.type === \"ConditionalTypeNode\" && bindsInfer(a.extendsType, name)) return true\n }\n return false\n}\n\nfunction bindsInfer(node: unknown, name: string): boolean {\n if (!node || typeof node !== \"object\") return false\n if (Array.isArray(node)) return node.some(n => bindsInfer(n, name))\n const n = node as AnyNode\n if (n.type === \"InferTypeNode\" && n.name === name) return true\n return Object.values(n).some(v => bindsInfer(v, name))\n}\n\n/** The first `count` identifier tokens inside `node`'s span. Tokens are in\n * source order, so binary search to the start and read forward. */\nfunction firstTokensWithin(tokens: readonly Token[], node: Spanned, count: number): Token[] {\n let lo = 0\n let hi = tokens.length\n while (lo < hi) {\n const mid = (lo + hi) >> 1\n const t = tokens[mid]\n const before = t.line.start < node.line.start\n || (t.line.start === node.line.start && t.column.start < node.column.start)\n if (before) lo = mid + 1\n else hi = mid\n }\n const out: Token[] = []\n for (let i = lo; i < tokens.length && out.length < count; i++) {\n const t = tokens[i]\n const after = t.line.start > node.line.end\n || (t.line.start === node.line.end && t.column.start >= node.column.end)\n if (after) break\n out.push(t)\n }\n return out\n}\n\n/** LSP's relative encoding: each token as five integers relative to the\n * previous one. */\nfunction encode(entries: Entry[]): number[] {\n entries.sort((a, b) => a.line - b.line || a.character - b.character)\n const data: number[] = []\n let line = 0\n let character = 0\n for (const e of entries) {\n const deltaLine = e.line - line\n data.push(\n deltaLine,\n deltaLine === 0 ? e.character - character : e.character,\n e.length,\n TOKEN_TYPES.indexOf(e.type),\n e.modifiers.reduce((bits, m) => bits | (1 << TOKEN_MODIFIERS.indexOf(m)), 0),\n )\n line = e.line\n character = e.character\n }\n return data\n}\n","/**\n * The language server: LSP wiring only.\n *\n * Every handler is the same three steps — get the cached analysis for the\n * document, ask one feature module a question, hand back the answer. The\n * thinking lives in `features/`; nothing here knows about luaut.\n */\nimport {\n createConnection, ProposedFeatures, TextDocuments, TextDocumentSyncKind,\n type Connection, type InitializeParams, type InitializeResult,\n} from \"vscode-languageserver/node\"\nimport { TextDocument } from \"vscode-languageserver-textdocument\"\nimport { Analyzer, pathOfUri, samePath, type AnalyzerOptions } from \"./analysis.js\"\nimport { importDefinition } from \"./features/imports.js\"\nimport { diagnostics } from \"./features/diagnostics.js\"\nimport { hover } from \"./features/hover.js\"\nimport { definition, references, highlights, prepareRename, rename } from \"./features/navigation.js\"\nimport { completion } from \"./features/completion.js\"\nimport { signatureHelp } from \"./features/signatureHelp.js\"\nimport { documentSymbols } from \"./features/symbols.js\"\nimport { semanticTokens, semanticTokensLegend } from \"./features/semanticTokens.js\"\n\nexport interface ServerOptions extends AnalyzerOptions {}\n\n/** Attach the luaut language server to a connection. Exported separately from\n * `startServer` so an editor extension can run it in-process over its own\n * transport, and so the tests can drive it without spawning anything. */\nexport function createServer(connection: Connection, options: ServerOptions = {}): void {\n const documents = new TextDocuments(TextDocument)\n // Imports read open documents before disk, so they see unsaved edits.\n const analyzer = new Analyzer({\n ...options,\n openDocument: path => documents.all().find(document => {\n const documentPath = pathOfUri(document.uri)\n return documentPath !== undefined && samePath(documentPath, path)\n }),\n })\n\n connection.onInitialize((_params: InitializeParams): InitializeResult => ({\n capabilities: {\n textDocumentSync: TextDocumentSyncKind.Incremental,\n hoverProvider: true,\n definitionProvider: true,\n referencesProvider: true,\n documentHighlightProvider: true,\n documentSymbolProvider: true,\n renameProvider: { prepareProvider: true },\n completionProvider: {\n // `.` and `:` open a member list; the rest of the time\n // completion is asked for as you type a word.\n // plus the characters that start or extend an import path.\n triggerCharacters: [\".\", \":\", \"\\\"\", \"'\", \"/\"],\n resolveProvider: false,\n },\n signatureHelpProvider: { triggerCharacters: [\"(\", \",\"], retriggerCharacters: [\",\"] },\n // Colours from the parser, not from patterns: whether a word is a\n // keyword, a type or a name depends on where it stands.\n semanticTokensProvider: { legend: semanticTokensLegend, full: true },\n },\n serverInfo: { name: \"luaut-language-server\" },\n }))\n\n // --- semantic highlighting ---------------------------------------------\n connection.languages.semanticTokens.on(p => {\n const document = documents.get(p.textDocument.uri)\n return document ? semanticTokens(analyzer.get(document)) : { data: [] }\n })\n\n // --- diagnostics -------------------------------------------------------\n const publish = (document: TextDocument): void => {\n void connection.sendDiagnostics({\n uri: document.uri,\n version: document.version,\n diagnostics: diagnostics(analyzer.get(document)),\n })\n }\n\n documents.onDidOpen(e => publish(e.document))\n // Any change can affect every open file that imports the changed one, so\n // all of them are re-checked; unchanged ones come straight from the cache.\n const publishAll = (): void => {\n for (const document of documents.all()) publish(document)\n }\n documents.onDidChangeContent(publishAll)\n // A module edited, created or deleted outside the editor.\n connection.onDidChangeWatchedFiles(publishAll)\n documents.onDidClose(e => {\n analyzer.forget(e.document.uri)\n void connection.sendDiagnostics({ uri: e.document.uri, diagnostics: [] })\n })\n\n // --- language features -------------------------------------------------\n const withDocument = <T>(uri: string, f: (document: TextDocument) => T, fallback: T): T => {\n const document = documents.get(uri)\n return document ? f(document) : fallback\n }\n\n connection.onHover(p => withDocument(\n p.textDocument.uri, d => hover(analyzer.get(d), p.position), null,\n ))\n\n connection.onDefinition(p => withDocument(\n p.textDocument.uri,\n d => {\n const analysis = analyzer.get(d)\n // Inside an import, the definition is in the other module.\n const across = importDefinition(analyzer, analysis, p.position)\n return across !== undefined ? across : definition(analysis, p.position)\n },\n null,\n ))\n\n connection.onReferences(p => withDocument(\n p.textDocument.uri,\n d => references(analyzer.get(d), p.position, p.context.includeDeclaration),\n [],\n ))\n\n connection.onDocumentHighlight(p => withDocument(\n p.textDocument.uri, d => highlights(analyzer.get(d), p.position), [],\n ))\n\n connection.onDocumentSymbol(p => withDocument(\n p.textDocument.uri, d => documentSymbols(analyzer.get(d)), [],\n ))\n\n connection.onPrepareRename(p => withDocument(\n p.textDocument.uri,\n d => {\n const prepared = prepareRename(analyzer.get(d), p.position)\n return prepared ? { range: prepared.range, placeholder: prepared.placeholder } : null\n },\n null,\n ))\n\n connection.onRenameRequest(p => withDocument(\n p.textDocument.uri, d => rename(analyzer.get(d), p.position, p.newName), null,\n ))\n\n connection.onCompletion(p => withDocument(\n p.textDocument.uri, d => completion(analyzer, d, p.position), [],\n ))\n\n connection.onSignatureHelp(p => withDocument(\n p.textDocument.uri, d => signatureHelp(analyzer, d, p.position), null,\n ))\n\n documents.listen(connection)\n connection.listen()\n}\n\n/** Run the server over stdio — the transport editors launch it with. */\nexport function startServer(options: ServerOptions = {}): void {\n createServer(createConnection(ProposedFeatures.all), options)\n}\n"],"mappings":"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","names":["collect","dirname","resolve","formatType","range","resolve","dirname","formatType","formatType","identifier","type","binding","formatType","n","identifier","CompletionItemKind","formatType","CompletionItemKind","PRIMITIVES","formatType","keyword","formatType","formatType","PRIMITIVES","walk","typeParameterInScope","binding","bindsInfer","n"]}
|
package/dist/cli.cjs
CHANGED
|
@@ -823,6 +823,8 @@ var IDENTIFIER_CHAR = /[A-Za-z0-9_]/;
|
|
|
823
823
|
function completion(analyzer, document, position) {
|
|
824
824
|
const inImport = importCompletion(analyzer, document, position);
|
|
825
825
|
if (inImport) return inImport;
|
|
826
|
+
const inString = stringCompletion(analyzer, document, position);
|
|
827
|
+
if (inString) return inString;
|
|
826
828
|
const source = document.getText();
|
|
827
829
|
const offset = document.offsetAt(position);
|
|
828
830
|
let start = offset;
|
|
@@ -863,6 +865,43 @@ function completion(analyzer, document, position) {
|
|
|
863
865
|
}
|
|
864
866
|
return valueItems(first.analysis, at);
|
|
865
867
|
}
|
|
868
|
+
function stringCompletion(analyzer, document, position) {
|
|
869
|
+
const analysis = analyzer.get(document);
|
|
870
|
+
const path = pathAt(analysis.program, position, false);
|
|
871
|
+
const literal = [...path].reverse().find((n) => n.type === "StringLiteral");
|
|
872
|
+
if (!literal) return void 0;
|
|
873
|
+
const expected = analysis.types.expectedTypeOf.get(literal);
|
|
874
|
+
const values = stringLiterals(expected, analysis.types.aliases);
|
|
875
|
+
if (!values.length) return [];
|
|
876
|
+
const line = literal.line.start - 1;
|
|
877
|
+
const range = literal.line.start === literal.line.end ? {
|
|
878
|
+
start: { line, character: literal.column.start },
|
|
879
|
+
end: { line, character: literal.column.end - 2 }
|
|
880
|
+
} : void 0;
|
|
881
|
+
return values.map((value) => ({
|
|
882
|
+
label: value,
|
|
883
|
+
kind: import_vscode_languageserver4.CompletionItemKind.Constant,
|
|
884
|
+
...range ? { textEdit: { range, newText: value } } : {}
|
|
885
|
+
}));
|
|
886
|
+
}
|
|
887
|
+
function stringLiterals(type, aliases, seen = /* @__PURE__ */ new Set()) {
|
|
888
|
+
if (!type || seen.has(type)) return [];
|
|
889
|
+
seen.add(type);
|
|
890
|
+
switch (type.kind) {
|
|
891
|
+
case "literal":
|
|
892
|
+
return typeof type.value === "string" ? [type.value] : [];
|
|
893
|
+
case "union":
|
|
894
|
+
return [...new Set(type.types.flatMap((t) => stringLiterals(t, aliases, seen)))];
|
|
895
|
+
case "genericRef": {
|
|
896
|
+
const alias = aliases.get(type.name);
|
|
897
|
+
return alias ? stringLiterals(alias, aliases, seen) : [];
|
|
898
|
+
}
|
|
899
|
+
case "typeParam":
|
|
900
|
+
return stringLiterals(type.constraint, aliases, seen);
|
|
901
|
+
default:
|
|
902
|
+
return [];
|
|
903
|
+
}
|
|
904
|
+
}
|
|
866
905
|
function memberOperator(source, wordStart) {
|
|
867
906
|
const ch = source[wordStart - 1];
|
|
868
907
|
if (ch === ":") return source[wordStart - 2] === ":" ? void 0 : ":";
|
|
@@ -1137,7 +1176,7 @@ var TOKEN_TYPES = [
|
|
|
1137
1176
|
"method",
|
|
1138
1177
|
"keyword"
|
|
1139
1178
|
];
|
|
1140
|
-
var TOKEN_MODIFIERS = ["declaration", "readonly", "defaultLibrary"];
|
|
1179
|
+
var TOKEN_MODIFIERS = ["declaration", "readonly", "defaultLibrary", "control"];
|
|
1141
1180
|
var semanticTokensLegend = {
|
|
1142
1181
|
tokenTypes: [...TOKEN_TYPES],
|
|
1143
1182
|
tokenModifiers: [...TOKEN_MODIFIERS]
|
|
@@ -1152,8 +1191,10 @@ var SOFT_KEYWORDS = /* @__PURE__ */ new Set([
|
|
|
1152
1191
|
"is",
|
|
1153
1192
|
"asserts",
|
|
1154
1193
|
"satisfies",
|
|
1155
|
-
"typeof"
|
|
1194
|
+
"typeof",
|
|
1195
|
+
"default"
|
|
1156
1196
|
]);
|
|
1197
|
+
var CONTROL_KEYWORDS = /* @__PURE__ */ new Set(["default"]);
|
|
1157
1198
|
var PRIMITIVES3 = /* @__PURE__ */ new Set(["any", "unknown", "never", "nil", "boolean", "number", "string", "thread", "buffer"]);
|
|
1158
1199
|
function semanticTokens(analysis) {
|
|
1159
1200
|
const entries = /* @__PURE__ */ new Map();
|
|
@@ -1179,12 +1220,8 @@ function semanticTokens(analysis) {
|
|
|
1179
1220
|
walk2(analysis.program);
|
|
1180
1221
|
for (const token of tokens) {
|
|
1181
1222
|
const value = token.value;
|
|
1182
|
-
if (typeof value !== "string") continue;
|
|
1183
|
-
|
|
1184
|
-
add(token, value.length, "keyword");
|
|
1185
|
-
} else if (token.type === "Identifier" && SOFT_KEYWORDS.has(value)) {
|
|
1186
|
-
add(token, value.length, "keyword");
|
|
1187
|
-
}
|
|
1223
|
+
if (token.type !== "Identifier" || typeof value !== "string" || !SOFT_KEYWORDS.has(value)) continue;
|
|
1224
|
+
add(token, value.length, "keyword", CONTROL_KEYWORDS.has(value) ? ["control"] : []);
|
|
1188
1225
|
}
|
|
1189
1226
|
return { data: encode([...entries.values()]) };
|
|
1190
1227
|
}
|