luaut-language-server 2.1.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -771,11 +771,28 @@ import {
771
771
  function hover(analysis, position) {
772
772
  const path = pathAt(analysis.program, position, true);
773
773
  for (let i = path.length - 1; i >= 0; i--) {
774
+ if (UNNAMED.has(path[i].type)) return null;
774
775
  const text = describe(analysis, path, i);
775
776
  if (text) return { contents: { kind: "markdown", value: code(text) }, range: toRange(path[i]) };
776
777
  }
777
778
  return null;
778
779
  }
780
+ var UNNAMED = /* @__PURE__ */ new Set([
781
+ "BinaryExpression",
782
+ "UnaryExpression",
783
+ "CallExpression",
784
+ "MethodCallExpression",
785
+ "MemberExpression",
786
+ "IndexExpression",
787
+ "ParenthesizedExpression",
788
+ "IfElseExpression",
789
+ "TableExpression",
790
+ "ArrayExpression",
791
+ "TypeAssertionExpression",
792
+ "SatisfiesExpression",
793
+ "AsConstExpression",
794
+ "InterpolatedStringExpression"
795
+ ]);
779
796
  var PRIMITIVES = /* @__PURE__ */ new Set(["any", "unknown", "never", "nil", "boolean", "number", "string", "thread", "buffer"]);
780
797
  function describe(analysis, path, index) {
781
798
  const { types } = analysis;
@@ -851,7 +868,7 @@ function describe(analysis, path, index) {
851
868
  const binding = bindingOfNode(analysis, identifier2);
852
869
  if (binding) {
853
870
  const type2 = types.bindingType.get(binding.id);
854
- if (type2) return `${keyword(binding)} ${binding.name}: ${pretty(type2)}`;
871
+ if (type2) return bindingText(binding, type2);
855
872
  }
856
873
  if (parent?.type === "MemberExpression" || parent?.type === "MethodCallExpression") {
857
874
  const type2 = types.typeOf.get(parent);
@@ -859,13 +876,13 @@ function describe(analysis, path, index) {
859
876
  }
860
877
  return void 0;
861
878
  }
862
- // Declarations: `const x`, a parameter, `const function f`.
879
+ // Declarations: `const x`, a parameter.
863
880
  case "IdentifierPattern":
864
881
  case "FunctionParameter":
865
882
  case "TypedIdentifier": {
866
883
  const binding = bindingOfNode(analysis, node);
867
884
  const type2 = binding && types.bindingType.get(binding.id);
868
- return type2 ? `${keyword(binding)} ${binding.name}: ${pretty(type2)}` : void 0;
885
+ return type2 ? bindingText(binding, type2) : void 0;
869
886
  }
870
887
  // A type written by name: `number`, `Shape`, `Partial<User>`, or a type
871
888
  // parameter in scope.
@@ -981,10 +998,19 @@ ${lines.join("\n")}
981
998
  }
982
999
  return flat;
983
1000
  }
1001
+ function bindingText(binding, type) {
1002
+ if (binding.declaredBy === "function" && type.kind === "function") {
1003
+ return `function ${binding.name}${formatType3(type)}`;
1004
+ }
1005
+ return `${keyword(binding)} ${binding.name}: ${pretty(type)}`;
1006
+ }
984
1007
  function keyword(binding) {
985
1008
  if (binding.kind === "param" || binding.kind === "self") return "(parameter)";
986
1009
  if (binding.kind === "global") return "(global)";
987
1010
  if (binding.kind.startsWith("for-")) return "(loop variable)";
1011
+ if (binding.declaredBy === "import" || binding.declaredBy === "namespace") return "(import)";
1012
+ if (binding.declaredBy === "type") return "(type import)";
1013
+ if (binding.declaredBy === "function") return "function";
988
1014
  return binding.isConst ? "const" : "let";
989
1015
  }
990
1016
  function code(text) {
@@ -1185,6 +1211,7 @@ function valueItems(analysis, at) {
1185
1211
  const seen = /* @__PURE__ */ new Set();
1186
1212
  for (const binding of analysis.scopes.bindings.values()) {
1187
1213
  if (binding.name === PLACEHOLDER || seen.has(binding.name)) continue;
1214
+ if (binding.declaredBy === "type") continue;
1188
1215
  const declaration = binding.declarationNode;
1189
1216
  if (declaration && declaration.line.start - 1 > at.line) continue;
1190
1217
  seen.add(binding.name);
@@ -1553,10 +1580,14 @@ function identifier(analysis, node, parent, add) {
1553
1580
  break;
1554
1581
  case "ImportSpecifier": {
1555
1582
  const binding2 = bindingOfNode(analysis, node);
1583
+ if (binding2?.declaredBy === "type") return as("type", ["declaration"]);
1556
1584
  const value = binding2 && analysis.types.bindingType.get(binding2.id);
1557
1585
  if (analysis.types.aliases.has(name) && (!value || value.kind === "any")) return as("type", ["declaration"]);
1558
1586
  break;
1559
1587
  }
1588
+ case "ImportStatement":
1589
+ if (parent.namespaceImport === node) return as("namespace", ["declaration"]);
1590
+ break;
1560
1591
  case "ExportSpecifier":
1561
1592
  if (!bindingOfNode(analysis, node) && analysis.types.aliases.has(name)) return as("type");
1562
1593
  break;
@@ -1572,6 +1603,7 @@ function identifier(analysis, node, parent, add) {
1572
1603
  function valueKind(analysis, binding) {
1573
1604
  if (!binding) return "variable";
1574
1605
  if (binding.kind === "param" || binding.kind === "self") return "parameter";
1606
+ if (binding.declaredBy === "namespace") return "namespace";
1575
1607
  return isFunction(analysis.types.bindingType.get(binding.id)) ? "function" : "variable";
1576
1608
  }
1577
1609
  function modifiersOf(binding, isDeclaration) {
@@ -1842,4 +1874,4 @@ export {
1842
1874
  createServer,
1843
1875
  startServer
1844
1876
  };
1845
- //# sourceMappingURL=chunk-HJ2C3OFZ.js.map
1877
+ //# sourceMappingURL=chunk-X2GHHRWT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/features/members.ts","../src/analysis.ts","../src/ast-utils.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":["/** 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 * Analysis cache, projects, 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 * Nothing is built in. A file belongs to the project of the nearest\n * `luaut.config.json`: the type libraries it names, its `paths` aliases, and\n * its sourcemap's instance tree. A file no config covers gets no types at all.\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 file it read — the modules it imports, its config, type\n * libraries and sourcemap — still has the text it was analyzed against.\n */\nimport { readFileSync, statSync } from \"node:fs\"\nimport { dirname, resolve } from \"node:path\"\nimport { fileURLToPath, pathToFileURL } from \"node:url\"\nimport {\n parse, parseWithRecovery, analyzeScopes, analyzeTypes, moduleExports, getBinding,\n findConfig, resolveTypeLibraries, moduleCandidates, sourceMapTypes,\n type Program, type ScopeAnalysis, type TypeAnalysis, type ParseError, type ModuleExports,\n type Binding, type Identifier, type Type, type LuautConfig, type ConfigProblem, type ProjectHost,\n type SourceMapTypes,\n} from \"luaut-parser\"\nimport type { TextDocument } from \"vscode-languageserver-textdocument\"\nimport { membersOf } from \"./features/members.js\"\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 — imported modules, its config, type\n * libraries, sourcemap — with the text it read, or `undefined` for a file\n * it looked for and did not find. How a cached result tells that something\n * changed, appeared or vanished under it. */\n readonly dependencies: ReadonlyMap<string, string | undefined>\n /** The project the file belongs to. */\n readonly project: Project\n}\n\nexport interface Project {\n /** The config that applies to the file, or `undefined` when none does. */\n readonly config?: LuautConfig\n /** The types came from `AnalyzerOptions.libs`, not from a config. */\n readonly fixed: boolean\n /** What is wrong with the config, a type library it names, or its sourcemap. */\n readonly problems: readonly ConfigProblem[]\n}\n\nexport interface AnalyzerOptions {\n /** Analyze every file against these definitions instead of the ones its\n * `luaut.config.json` names — for tests and for embedding the server. */\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 a file may use undeclared: whatever the definitions declare. */\nfunction globalsOf(libs: readonly Program[]): string[] {\n const names = new Set<string>()\n for (const lib of libs) {\n for (const statement of lib.body.statements) {\n if (statement.type === \"DeclareStatement\") names.add(statement.name)\n }\n }\n return [...names]\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, when\n * there is nothing better yet: its names read as `any`. */\nconst CYCLE: ModuleExports = { values: new Map(), types: new Map(), partial: true }\n\n/**\n * One analysis of a module and everything it imports.\n *\n * An import cycle can only be broken by letting one side see the other before\n * it is finished — as `any`. A value exported from the far side and inferred\n * from the near side then comes back as `any` too. So a run that met a cycle\n * goes once more: the modules it analyzed are redone, and where an import\n * meets a module mid-analysis it reads that module's exports from the first\n * pass instead of `any`.\n */\ninterface Run {\n /** Modules an import reached while they were still being analyzed. */\n readonly cycles: Set<string>\n /** Modules analyzed in this run — the ones a second pass redoes. */\n readonly analyzed: Set<string>\n /** Exports from the first pass, read in place of `any` in the second. */\n readonly provisional: Map<string, ModuleExports>\n}\n\n// --------------------------------------------------------------------------\n// Analyzer\n// --------------------------------------------------------------------------\n\ninterface Module {\n analysis: Analysis\n exports: ModuleExports\n}\n\n/** Everything a folder's files are analyzed with. */\ninterface Context {\n readonly project: Project\n /** The type libraries, then the sourcemap's tree. */\n readonly libs: readonly Program[]\n readonly globals: readonly string[]\n readonly sourceMap?: SourceMapTypes\n /** Every file read to build this, with what it held. */\n readonly reads: ReadonlyMap<string, string | undefined>\n}\n\nconst NO_PROJECT: Context = { project: { fixed: false, problems: [] }, libs: [], globals: [], reads: new Map() }\n\nexport class Analyzer {\n private readonly fixed?: Context\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 /** Project contexts, by folder. */\n private readonly contexts = new Map<string, Context>()\n /** Parsed type libraries, by path — reparsed only when the text changes. */\n private readonly libraries = new Map<string, { source: string; program?: Program; problem?: ConfigProblem }>()\n /** Sourcemaps turned into types, by path, with what they were built from. */\n private readonly sourceMaps = new Map<string, { text: string; libraries: string; result: ReturnType<typeof sourceMapTypes> }>()\n /** The analysis run in progress, if any. */\n private run: Run | undefined\n\n constructor(options: AnalyzerOptions = {}) {\n this.openDocument = options.openDocument\n if (options.libs) {\n this.fixed = {\n project: { fixed: true, problems: [] },\n libs: options.libs,\n globals: globalsOf(options.libs),\n reads: new Map(),\n }\n }\n }\n\n /** Analyze `document`, reusing the previous result while neither it nor\n * anything it read 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 if (!path) return this.analyzeModule(uri, version, source, new Set())\n const key = pathKey(path)\n return this.resolvingCycles(key, () => {\n const analysis = this.analyzeModule(uri, version, source, new Set([key]))\n return { result: analysis, exports: () => this.exportsFrom(analysis, new Set([key])) }\n })\n }\n\n forget(uri: string): void {\n this.cache.delete(uri)\n }\n\n /** The project a file belongs to. */\n projectOf(uri: string): Project {\n return this.contextFor(pathOfUri(uri)).project\n }\n\n /** The file an import in `fromUri` names: a relative path, or a `paths`\n * alias from the file's config. */\n resolveModulePath(fromUri: string, specifier: string): string | undefined {\n const from = pathOfUri(fromUri)\n if (!from) return undefined\n return this.candidatesFor(from, specifier).find(candidate => this.readFile(candidate) !== undefined)\n }\n\n /** What the module at `path` exports, analyzing it if need be. */\n exportsAt(path: string): ModuleExports | undefined {\n return this.resolvingCycles(pathKey(path), () => {\n const exports = this.exportsOf(path, new Set())\n return { result: exports, exports: () => exports }\n })\n }\n\n /** The analysis of the module at `path`, analyzing it if need be. */\n moduleAt(path: string): Analysis | undefined {\n this.exportsAt(path)\n return this.modules.get(pathKey(path))?.analysis\n }\n\n /** A file's text: the open document if there is one, else the disk. */\n readFile(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 private candidatesFor(from: string, specifier: string): string[] {\n return moduleCandidates(from, specifier, this.contextFor(from).project.config)\n }\n\n // ---------------------------------------------------------------- projects\n\n private contextFor(path: string | undefined): Context {\n if (this.fixed) return this.fixed\n if (!path) return NO_PROJECT\n const key = pathKey(dirname(path))\n const cached = this.contexts.get(key)\n if (cached && this.unchanged(cached.reads)) return cached\n const context = this.buildContext(path)\n this.contexts.set(key, context)\n return context\n }\n\n private buildContext(path: string): Context {\n const reads = new Map<string, string | undefined>()\n const host: ProjectHost = {\n readFile: file => {\n const text = this.readFile(file)\n reads.set(file, text)\n return text\n },\n }\n\n const lookup = findConfig(path, host)\n const problems: ConfigProblem[] = [...lookup.problems]\n const config = lookup.config\n if (!config) return { project: { fixed: false, problems }, libs: [], globals: [], reads }\n\n const libraries = resolveTypeLibraries(config, host)\n problems.push(...libraries.problems)\n const libs: Program[] = []\n for (const file of libraries.files) {\n const program = this.library(file, host, problems)\n if (program) libs.push(program)\n }\n\n let sourceMap: SourceMapTypes | undefined\n if (config.sourceMap) {\n const text = host.readFile(config.sourceMap)\n if (text === undefined) {\n problems.push({\n file: config.path,\n message: `Cannot find the sourceMap file ${config.sourceMap}`,\n ...optionPosition(config, \"sourceMap\"),\n })\n } else {\n const result = this.sourceMap(config.sourceMap, text, libs, libraries.files)\n if (result.problem) problems.push({ file: config.sourceMap, message: result.problem, line: 1, column: 1 })\n sourceMap = result.types\n if (sourceMap) libs.push(sourceMap.program)\n }\n }\n\n return { project: { config, fixed: false, problems }, libs, globals: globalsOf(libs), sourceMap, reads }\n }\n\n /** A type library's definitions, parsed once per text. */\n private library(file: string, host: ProjectHost, problems: ConfigProblem[]): Program | undefined {\n const source = host.readFile(file)\n if (source === undefined) return undefined\n const key = pathKey(file)\n let entry = this.libraries.get(key)\n if (!entry || entry.source !== source) {\n try {\n entry = { source, program: parse(source) }\n } catch (error) {\n const { message, line, column } = error as { message: string; line?: number; column?: number }\n entry = {\n source,\n problem: { file, message: `Syntax error in type library: ${message.replace(/\\s*\\(\\d+:\\d+\\)$/, \"\")}`, line, column },\n }\n }\n this.libraries.set(key, entry)\n }\n if (entry.problem) problems.push(entry.problem)\n return entry.program\n }\n\n /** A sourcemap's types, rebuilt only when it or the libraries change. */\n private sourceMap(path: string, text: string, libs: readonly Program[], files: readonly string[]): ReturnType<typeof sourceMapTypes> {\n const key = pathKey(path)\n const libraries = files.join(\"\\n\")\n const cached = this.sourceMaps.get(key)\n if (cached && cached.text === text && cached.libraries === libraries) return cached.result\n\n const aliases = aliasesOf(libs)\n const members = new Map<string, ReadonlySet<string>>()\n const result = sourceMapTypes(text, path, {\n classes: new Set(aliases.keys()),\n membersOf: className => {\n let names = members.get(className)\n if (!names) {\n names = new Set(membersOf(aliases.get(className), aliases).map(member => member.name))\n members.set(className, names)\n }\n return names\n },\n })\n this.sourceMaps.set(key, { text, libraries, result })\n return result\n }\n\n private unchanged(reads: ReadonlyMap<string, string | undefined>): boolean {\n for (const [file, text] of reads) if (this.readFile(file) !== text) return false\n return true\n }\n\n // ----------------------------------------------------------------- modules\n\n /** Run one analysis of `root` and everything it imports; if that met an\n * import cycle, run it once more with the first pass's exports standing\n * in for the `any` the cycle left (see `Run`). A call made while a run is\n * already going is part of that run. */\n private resolvingCycles<T>(\n root: string,\n analyzeRoot: () => { result: T; exports: () => ModuleExports | undefined },\n ): T {\n if (this.run) return analyzeRoot().result\n const run: Run = { cycles: new Set(), analyzed: new Set(), provisional: new Map() }\n this.run = run\n try {\n const first = analyzeRoot()\n if (!run.cycles.size) return first.result\n\n for (const key of run.cycles) {\n const exports = key === root ? first.exports() : this.modules.get(key)?.exports\n if (exports && !exports.partial) run.provisional.set(key, exports)\n }\n // Anything the first pass analyzed may have read `any` through the\n // cycle, so all of it is redone.\n for (const key of run.analyzed) this.modules.delete(key)\n return analyzeRoot().result\n } finally {\n this.run = undefined\n }\n }\n\n /** A module's exports, from its analysis. */\n private exportsFrom(analysis: Analysis, importing: Set<string>): ModuleExports {\n // Re-exports (`export ... from`) resolve relative to this module.\n return 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 }\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 path = pathOfUri(uri)\n const context = this.contextFor(path)\n // A file the sourcemap maps has its own `script`.\n const script = path ? context.sourceMap?.scriptFor(path) : undefined\n const libs = script ? [...context.libs, script] : context.libs\n const globals = script ? [...context.globals, \"script\"] : context.globals\n\n const { program, errors } = parseWithRecovery(source)\n const scopes = analyzeScopes(program, { builtinGlobals: [...globals] })\n const dependencies = new Map(context.reads)\n const types = analyzeTypes(program, scopes, {\n libs,\n resolveModule: specifier => {\n if (!path) return undefined\n const candidates = this.candidatesFor(path, specifier)\n const target = candidates.find(candidate => this.readFile(candidate) !== undefined)\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 candidates) dependencies.set(candidate, undefined)\n return undefined\n }\n const exports = this.exportsOf(target, importing)\n dependencies.set(target, this.readFile(target))\n return exports\n },\n })\n return { uri, version, source, program, parseErrors: errors, scopes, types, dependencies, project: context.project }\n }\n\n private exportsOf(path: string, importing: Set<string>): ModuleExports | undefined {\n const key = pathKey(path)\n if (importing.has(key)) {\n this.run?.cycles.add(key)\n return this.run?.provisional.get(key) ?? CYCLE\n }\n const source = this.readFile(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 const exports = this.exportsFrom(analysis, importing)\n this.modules.set(key, { analysis, exports })\n this.run?.analyzed.add(key)\n return exports\n } finally {\n importing.delete(key)\n }\n }\n\n /** Does every file `analysis` read — and everything the modules it\n * imported read — 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.readFile(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/** The type aliases a set of libraries defines, resolved. */\nfunction aliasesOf(libs: readonly Program[]): ReadonlyMap<string, Type> {\n const empty = parse(\"\")\n return analyzeTypes(empty, analyzeScopes(empty, {}), { libs, diagnostics: false }).aliases\n}\n\n/** Where an option is written in a config, to point a problem at it. */\nexport function optionPosition(config: LuautConfig, key: string): { line?: number; column?: number } {\n const offset = config.source.indexOf(JSON.stringify(key))\n if (offset < 0) return { line: 1, column: 1 }\n const before = config.source.slice(0, offset)\n return { line: before.split(\"\\n\").length, column: offset - before.lastIndexOf(\"\\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","/**\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(analyzer, 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(analyzer: Analyzer, fromUri: string, position: Position, typed: string): CompletionItem[] {\n const from = pathOfUri(fromUri)\n if (!from) return []\n\n if (typed.startsWith(\"./\") || typed.startsWith(\"../\")) {\n const slash = typed.lastIndexOf(\"/\")\n return entryItems(resolve(dirname(from), typed.slice(0, slash + 1)), rangeBack(position, typed.length - slash - 1), from)\n }\n\n // Not started yet, or an alias: offer the ways in — `./`, `../` and each\n // `paths` alias — and inside an alias, what its targets hold.\n const items = new Map<string, CompletionItem>()\n const whole = rangeBack(position, typed.length)\n const offer = (label: string, folder: boolean): void => {\n if (!label.startsWith(typed) || label === typed) return\n items.set(label, {\n label,\n kind: folder ? CompletionItemKind.Folder : CompletionItemKind.File,\n textEdit: { range: whole, newText: label },\n command: folder ? SUGGEST_AGAIN : undefined,\n })\n }\n offer(\"./\", true)\n offer(\"../\", true)\n\n const config = analyzer.projectOf(fromUri).config\n for (const [pattern, targets] of Object.entries(config?.paths ?? {})) {\n const star = pattern.indexOf(\"*\")\n if (star < 0) {\n offer(pattern, false)\n continue\n }\n const prefix = pattern.slice(0, star)\n if (!typed.startsWith(prefix)) {\n offer(prefix, true)\n continue\n }\n const rest = typed.slice(prefix.length)\n const slash = rest.lastIndexOf(\"/\")\n const range = rangeBack(position, rest.length - slash - 1)\n for (const target of targets) {\n const cut = target.indexOf(\"*\")\n const head = cut < 0 ? target : target.slice(0, cut)\n for (const item of entryItems(resolve(config!.baseUrl, head + rest.slice(0, slash + 1)), range, from)) {\n items.set(item.label, item)\n }\n }\n }\n return [...items.values()]\n}\n\n/** The luaut files and folders in `directory`, as import path completions. */\nfunction entryItems(directory: string, range: Range, from: string): CompletionItem[] {\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, isClassType,\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 // On an operator, a parenthesis or a dot the cursor is on no name:\n // nothing to say, as in TypeScript — not the type of the whole\n // expression around it.\n if (UNNAMED.has(path[i].type as string)) return null\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\n/** Expressions made of other expressions plus operators or punctuation. The\n * names inside them have hovers of their own. */\nconst UNNAMED = new Set([\n \"BinaryExpression\", \"UnaryExpression\", \"CallExpression\", \"MethodCallExpression\",\n \"MemberExpression\", \"IndexExpression\", \"ParenthesizedExpression\", \"IfElseExpression\",\n \"TableExpression\", \"ArrayExpression\", \"TypeAssertionExpression\", \"SatisfiesExpression\",\n \"AsConstExpression\", \"InterpolatedStringExpression\",\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 \"DeclareClassStatement\":\n if (parent.name === node) return classText(analysis, name)\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 bindingText(binding, 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.\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 ? bindingText(binding, 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.typeArguments as unknown[]).length) {\n // `Enum.Material` is declared under its qualified name.\n const qualified = node.namespace ? `${node.namespace}.${base}` : base\n const alias = types.aliases.get(qualified)\n if (alias && isClassType(alias)) return classText(analysis, qualified)\n if (alias) return `type ${qualified} = ${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\n/** `declare class Part extends BasePart { ... }` — the members this class\n * adds. What it inherits is a hover away, on the superclass. */\nfunction classText(analysis: Analysis, name: string): string | undefined {\n const type = analysis.types.aliases.get(name)\n if (!type || !isClassType(type)) return undefined\n const superclass = type.class.superclass\n const inherited = superclass ? analysis.types.aliases.get(superclass) : undefined\n const own = [...type.properties].filter(([key, property]) =>\n inherited?.kind !== \"object\" || inherited.properties.get(key) !== property)\n const head = `declare class ${name}${superclass ? ` extends ${superclass}` : \"\"}`\n if (!own.length) return `${head} {}`\n const lines = own.map(([key, property]) =>\n ` ${property.readonly ? \"readonly \" : \"\"}${key}${property.optional ? \"?\" : \"\"}: ${formatType(property.type)},`)\n return `${head} {\\n${lines.join(\"\\n\")}\\n}`\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\n/** `const x: number`, `function f(a: string) -> number`, `(import) util: {...}`. */\nfunction bindingText(binding: Binding, type: Type): string {\n if (binding.declaredBy === \"function\" && type.kind === \"function\") {\n return `function ${binding.name}${formatType(type)}`\n }\n return `${keyword(binding)} ${binding.name}: ${pretty(type)}`\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 if (binding.declaredBy === \"import\" || binding.declaredBy === \"namespace\") return \"(import)\"\n if (binding.declaredBy === \"type\") return \"(type import)\"\n if (binding.declaredBy === \"function\") return \"function\"\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, isClassType, 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].map(([name, type]) => ({\n label: name,\n kind: isClassType(type) ? CompletionItemKind.Class : CompletionItemKind.Interface,\n detail: isClassType(type) ? \"class\" : \"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 // `import type` names are not values.\n if (binding.declaredBy === \"type\") 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.type === \"DeclareClassStatement\"),\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 \"DeclareClassStatement\": {\n const name = (node as unknown as { name: Identifier }).name.name\n const superclass = (node as unknown as { superclass?: { base: string } }).superclass?.base\n out.push(symbol(name, SymbolKind.Class, node, superclass && `extends ${superclass}`))\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, isClassType, unknownType, 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\", \"class\", \"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\", \"class\", \"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 if (isClassType(analysis.types.aliases.get(namespace ? `${namespace}.${base}` : base) ?? unknownType)) {\n add(baseToken, base.length, \"class\")\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 \"DeclareClassStatement\":\n if (parent.name === node) return as(\"class\", [\"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 if (binding?.declaredBy === \"type\") return as(\"type\", [\"declaration\"])\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 \"ImportStatement\":\n // `import * as Module`\n if (parent.namespaceImport === node) return as(\"namespace\", [\"declaration\"])\n break\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 if (binding.declaredBy === \"namespace\") return \"namespace\"\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, DiagnosticSeverity, ProposedFeatures, TextDocuments, TextDocumentSyncKind,\n type Connection, type Diagnostic, type InitializeParams, type InitializeResult,\n} from \"vscode-languageserver/node\"\nimport { TextDocument } from \"vscode-languageserver-textdocument\"\nimport type { ConfigProblem } from \"luaut-parser\"\nimport { Analyzer, pathOfUri, samePath, uriOfPath, type Analysis, 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 and configs read open documents before disk, so they see\n // 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 /** Config files currently showing problems, so fixed ones get cleared. */\n let configUris = new Set<string>()\n\n const publishAll = (): void => {\n const problems = new Map<string, ConfigProblem[]>()\n for (const document of documents.all()) {\n const analysis = analyzer.get(document)\n void connection.sendDiagnostics({\n uri: document.uri,\n version: document.version,\n diagnostics: [...diagnostics(analysis), ...projectHint(analysis)],\n })\n // A problem is shown on the config (or sourcemap) it is about, once\n // however many files share that config.\n for (const problem of analysis.project.problems) {\n const uri = uriOfPath(problem.file)\n const list = problems.get(uri) ?? []\n if (!list.some(p => p.message === problem.message && p.line === problem.line)) list.push(problem)\n problems.set(uri, list)\n }\n }\n for (const [uri, list] of problems) {\n void connection.sendDiagnostics({ uri, diagnostics: list.map(problemDiagnostic) })\n }\n for (const uri of configUris) {\n if (!problems.has(uri)) void connection.sendDiagnostics({ uri, diagnostics: [] })\n }\n configUris = new Set(problems.keys())\n }\n\n const problemDiagnostic = (problem: ConfigProblem): Diagnostic => {\n const line = Math.max((problem.line ?? 1) - 1, 0)\n const character = Math.max((problem.column ?? 1) - 1, 0)\n // Underline to the end of the line: the option or entry the problem is about.\n const text = analyzer.readFile(problem.file)?.split(\"\\n\")[line] ?? \"\"\n const end = Math.max(text.replace(/\\r$/, \"\").trimEnd().length, character + 1)\n return {\n range: { start: { line, character }, end: { line, character: end } },\n severity: DiagnosticSeverity.Error,\n source: \"luaut\",\n code: \"config\",\n message: problem.message,\n }\n }\n\n /** A file no config covers gets no types at all, which is easy to miss —\n * so say so, once, at the top of the file. */\n const projectHint = (analysis: Analysis): Diagnostic[] => {\n const { project } = analysis\n if (project.fixed || project.config || !pathOfUri(analysis.uri)) return []\n return [{\n range: { start: { line: 0, character: 0 }, end: { line: 0, character: 0 } },\n severity: DiagnosticSeverity.Information,\n source: \"luaut\",\n code: \"no-config\",\n message: \"No luaut.config.json applies to this file, so no types are loaded — not even `print`. \"\n + \"Add one to this folder or a folder above, such as \"\n + \"{ \\\"types\\\": [\\\"luau\\\"], \\\"paths\\\": {}, \\\"sourceMap\\\": null }\",\n }]\n }\n\n // Any change can affect every open file that imports the changed one, or\n // shares its config, so all of them are re-checked; unchanged ones come\n // straight from the cache.\n documents.onDidOpen(publishAll)\n documents.onDidChangeContent(publishAll)\n // A module, config, type library or sourcemap changed 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":["dirname","resolve","formatType","resolve","dirname","formatType","formatType","identifier","type","binding","formatType","n","identifier","CompletionItemKind","formatType","isClassType","isClassType","CompletionItemKind","PRIMITIVES","formatType","keyword","formatType","formatType","isClassType","PRIMITIVES","walk","typeParameterInScope","isClassType","binding","bindsInfer","n","DiagnosticSeverity","DiagnosticSeverity"]}
package/dist/cli.cjs CHANGED
@@ -753,11 +753,28 @@ var import_luaut_parser4 = require("luaut-parser");
753
753
  function hover(analysis, position) {
754
754
  const path = pathAt(analysis.program, position, true);
755
755
  for (let i = path.length - 1; i >= 0; i--) {
756
+ if (UNNAMED.has(path[i].type)) return null;
756
757
  const text = describe(analysis, path, i);
757
758
  if (text) return { contents: { kind: "markdown", value: code(text) }, range: toRange(path[i]) };
758
759
  }
759
760
  return null;
760
761
  }
762
+ var UNNAMED = /* @__PURE__ */ new Set([
763
+ "BinaryExpression",
764
+ "UnaryExpression",
765
+ "CallExpression",
766
+ "MethodCallExpression",
767
+ "MemberExpression",
768
+ "IndexExpression",
769
+ "ParenthesizedExpression",
770
+ "IfElseExpression",
771
+ "TableExpression",
772
+ "ArrayExpression",
773
+ "TypeAssertionExpression",
774
+ "SatisfiesExpression",
775
+ "AsConstExpression",
776
+ "InterpolatedStringExpression"
777
+ ]);
761
778
  var PRIMITIVES = /* @__PURE__ */ new Set(["any", "unknown", "never", "nil", "boolean", "number", "string", "thread", "buffer"]);
762
779
  function describe(analysis, path, index) {
763
780
  const { types } = analysis;
@@ -833,7 +850,7 @@ function describe(analysis, path, index) {
833
850
  const binding = bindingOfNode(analysis, identifier2);
834
851
  if (binding) {
835
852
  const type2 = types.bindingType.get(binding.id);
836
- if (type2) return `${keyword(binding)} ${binding.name}: ${pretty(type2)}`;
853
+ if (type2) return bindingText(binding, type2);
837
854
  }
838
855
  if (parent?.type === "MemberExpression" || parent?.type === "MethodCallExpression") {
839
856
  const type2 = types.typeOf.get(parent);
@@ -841,13 +858,13 @@ function describe(analysis, path, index) {
841
858
  }
842
859
  return void 0;
843
860
  }
844
- // Declarations: `const x`, a parameter, `const function f`.
861
+ // Declarations: `const x`, a parameter.
845
862
  case "IdentifierPattern":
846
863
  case "FunctionParameter":
847
864
  case "TypedIdentifier": {
848
865
  const binding = bindingOfNode(analysis, node);
849
866
  const type2 = binding && types.bindingType.get(binding.id);
850
- return type2 ? `${keyword(binding)} ${binding.name}: ${pretty(type2)}` : void 0;
867
+ return type2 ? bindingText(binding, type2) : void 0;
851
868
  }
852
869
  // A type written by name: `number`, `Shape`, `Partial<User>`, or a type
853
870
  // parameter in scope.
@@ -963,10 +980,19 @@ ${lines.join("\n")}
963
980
  }
964
981
  return flat;
965
982
  }
983
+ function bindingText(binding, type) {
984
+ if (binding.declaredBy === "function" && type.kind === "function") {
985
+ return `function ${binding.name}${(0, import_luaut_parser4.formatType)(type)}`;
986
+ }
987
+ return `${keyword(binding)} ${binding.name}: ${pretty(type)}`;
988
+ }
966
989
  function keyword(binding) {
967
990
  if (binding.kind === "param" || binding.kind === "self") return "(parameter)";
968
991
  if (binding.kind === "global") return "(global)";
969
992
  if (binding.kind.startsWith("for-")) return "(loop variable)";
993
+ if (binding.declaredBy === "import" || binding.declaredBy === "namespace") return "(import)";
994
+ if (binding.declaredBy === "type") return "(type import)";
995
+ if (binding.declaredBy === "function") return "function";
970
996
  return binding.isConst ? "const" : "let";
971
997
  }
972
998
  function code(text) {
@@ -1162,6 +1188,7 @@ function valueItems(analysis, at) {
1162
1188
  const seen = /* @__PURE__ */ new Set();
1163
1189
  for (const binding of analysis.scopes.bindings.values()) {
1164
1190
  if (binding.name === PLACEHOLDER || seen.has(binding.name)) continue;
1191
+ if (binding.declaredBy === "type") continue;
1165
1192
  const declaration = binding.declarationNode;
1166
1193
  if (declaration && declaration.line.start - 1 > at.line) continue;
1167
1194
  seen.add(binding.name);
@@ -1530,10 +1557,14 @@ function identifier(analysis, node, parent, add) {
1530
1557
  break;
1531
1558
  case "ImportSpecifier": {
1532
1559
  const binding2 = bindingOfNode(analysis, node);
1560
+ if (binding2?.declaredBy === "type") return as("type", ["declaration"]);
1533
1561
  const value = binding2 && analysis.types.bindingType.get(binding2.id);
1534
1562
  if (analysis.types.aliases.has(name) && (!value || value.kind === "any")) return as("type", ["declaration"]);
1535
1563
  break;
1536
1564
  }
1565
+ case "ImportStatement":
1566
+ if (parent.namespaceImport === node) return as("namespace", ["declaration"]);
1567
+ break;
1537
1568
  case "ExportSpecifier":
1538
1569
  if (!bindingOfNode(analysis, node) && analysis.types.aliases.has(name)) return as("type");
1539
1570
  break;
@@ -1549,6 +1580,7 @@ function identifier(analysis, node, parent, add) {
1549
1580
  function valueKind(analysis, binding) {
1550
1581
  if (!binding) return "variable";
1551
1582
  if (binding.kind === "param" || binding.kind === "self") return "parameter";
1583
+ if (binding.declaredBy === "namespace") return "namespace";
1552
1584
  return isFunction(analysis.types.bindingType.get(binding.id)) ? "function" : "variable";
1553
1585
  }
1554
1586
  function modifiersOf(binding, isDeclaration) {