corsa-oxlint 0.35.0 → 0.37.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.
Files changed (59) hide show
  1. package/dist/_virtual/_rolldown/runtime.js +1 -0
  2. package/dist/checker.js +57 -5
  3. package/dist/checker.js.map +1 -1
  4. package/dist/context.d.ts +3 -1
  5. package/dist/context.js +38 -4
  6. package/dist/context.js.map +1 -1
  7. package/dist/index.d.ts +2 -2
  8. package/dist/index.js +2 -1
  9. package/dist/parser_services.js +12 -60
  10. package/dist/parser_services.js.map +1 -1
  11. package/dist/plugin.js +7 -4
  12. package/dist/plugin.js.map +1 -1
  13. package/dist/rules/await_thenable.js +1 -8
  14. package/dist/rules/await_thenable.js.map +1 -1
  15. package/dist/rules/native_bridge.js +131 -268
  16. package/dist/rules/native_bridge.js.map +1 -1
  17. package/dist/rules/no_array_delete.js +1 -6
  18. package/dist/rules/no_array_delete.js.map +1 -1
  19. package/dist/rules/no_base_to_string.js +1 -6
  20. package/dist/rules/no_base_to_string.js.map +1 -1
  21. package/dist/rules/no_floating_promises.js +1 -8
  22. package/dist/rules/no_floating_promises.js.map +1 -1
  23. package/dist/rules/no_for_in_array.js +1 -5
  24. package/dist/rules/no_for_in_array.js.map +1 -1
  25. package/dist/rules/no_implied_eval.js +1 -6
  26. package/dist/rules/no_implied_eval.js.map +1 -1
  27. package/dist/rules/no_meaningless_void_operator.js +1 -6
  28. package/dist/rules/no_meaningless_void_operator.js.map +1 -1
  29. package/dist/rules/no_unsafe_assignment.js +1 -6
  30. package/dist/rules/no_unsafe_assignment.js.map +1 -1
  31. package/dist/rules/no_unsafe_call.js +1 -6
  32. package/dist/rules/no_unsafe_call.js.map +1 -1
  33. package/dist/rules/no_unsafe_member_access.js +1 -6
  34. package/dist/rules/no_unsafe_member_access.js.map +1 -1
  35. package/dist/rules/no_unsafe_return.js +1 -6
  36. package/dist/rules/no_unsafe_return.js.map +1 -1
  37. package/dist/rules/no_unsafe_type_assertion.js +1 -6
  38. package/dist/rules/no_unsafe_type_assertion.js.map +1 -1
  39. package/dist/rules/no_unsafe_unary_minus.js +1 -6
  40. package/dist/rules/no_unsafe_unary_minus.js.map +1 -1
  41. package/dist/rules/only_throw_error.js +1 -9
  42. package/dist/rules/only_throw_error.js.map +1 -1
  43. package/dist/rules/pending_parity.js +34 -60
  44. package/dist/rules/pending_parity.js.map +1 -1
  45. package/dist/rules/prefer_promise_reject_errors.js +1 -9
  46. package/dist/rules/prefer_promise_reject_errors.js.map +1 -1
  47. package/dist/rules/prefer_reduce_type_parameter.js +1 -6
  48. package/dist/rules/prefer_reduce_type_parameter.js.map +1 -1
  49. package/dist/rules/require_array_sort_compare.js +1 -6
  50. package/dist/rules/require_array_sort_compare.js.map +1 -1
  51. package/dist/rules/restrict_plus_operands.js +1 -6
  52. package/dist/rules/restrict_plus_operands.js.map +1 -1
  53. package/dist/session.d.ts +9 -5
  54. package/dist/session.js +99 -247
  55. package/dist/session.js.map +1 -1
  56. package/dist/types.d.ts +20 -2
  57. package/dist/types.js +10 -1
  58. package/dist/types.js.map +1 -0
  59. package/package.json +2 -2
@@ -1,3 +1,4 @@
1
+ import "node:module";
1
2
  //#region \0rolldown/runtime.js
2
3
  var __defProp = Object.defineProperty;
3
4
  var __exportAll = (all, no_symbols) => {
package/dist/checker.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { createNodeMaps, toPosition } from "./node_map.js";
2
2
  import { sessionForContext } from "./registry.js";
3
+ import "./types.js";
3
4
  //#region src/bindings/nodejs/corsa_oxlint/ts/checker.ts
4
5
  function createProgram(context) {
5
6
  return {
@@ -44,6 +45,9 @@ function createTypeChecker(context) {
44
45
  getSymbolById(id) {
45
46
  return sessionForContext(context).session.getSymbol(id);
46
47
  },
48
+ getSymbolOfType(type) {
49
+ return sessionForContext(context).session.getSymbolOfType(type);
50
+ },
47
51
  getNode(node) {
48
52
  return sessionForContext(context).session.getNode(node);
49
53
  },
@@ -53,9 +57,15 @@ function createTypeChecker(context) {
53
57
  getTypeOfSymbol(symbol) {
54
58
  return sessionForContext(context).session.getTypeOfSymbol(symbol);
55
59
  },
60
+ getTypeOfSymbolById(id) {
61
+ return sessionForContext(context).session.getTypeOfSymbolById(id);
62
+ },
56
63
  getDeclaredTypeOfSymbol(symbol) {
57
64
  return sessionForContext(context).session.getDeclaredTypeOfSymbol(symbol);
58
65
  },
66
+ getDeclaredTypeOfSymbolById(id) {
67
+ return sessionForContext(context).session.getDeclaredTypeOfSymbolById(id);
68
+ },
59
69
  getTypeOfSymbolAtLocation(symbol, node) {
60
70
  return this.getTypeOfSymbol(symbol) ?? this.getDeclaredTypeOfSymbol(symbol) ?? this.getTypeAtLocation(node);
61
71
  },
@@ -71,6 +81,9 @@ function createTypeChecker(context) {
71
81
  getSignaturesOfType(type, kind) {
72
82
  return sessionForContext(context).session.getSignaturesOfType(type, kind);
73
83
  },
84
+ getCallSignatureFacts(type, kind, argumentTypeTexts, explicitTypeArgumentTexts) {
85
+ return sessionForContext(context).session.getCallSignatureFacts(type, kind, argumentTypeTexts, explicitTypeArgumentTexts);
86
+ },
74
87
  getReturnTypeOfSignature(signature) {
75
88
  return sessionForContext(context).session.getReturnTypeOfSignature(signature);
76
89
  },
@@ -259,7 +272,6 @@ function implementedTypesFromSourceText(context, node, sourceText, checker) {
259
272
  const headerText = classText.slice(headerStart, bodyOpen >= 0 ? bodyOpen : classText.length);
260
273
  const implementsIndex = findKeywordOutsideTrivia(headerText, "implements");
261
274
  if (implementsIndex < 0) return [];
262
- const session = sessionForContext(context).session;
263
275
  const clauseText = headerText.slice(implementsIndex + 10);
264
276
  const clauseStart = node.pos + headerStart + implementsIndex + 10;
265
277
  return splitTopLevelRanges(clauseText, ",").map((range) => {
@@ -275,12 +287,49 @@ function implementedTypesFromSourceText(context, node, sourceText, checker) {
275
287
  end,
276
288
  range: [pos, end]
277
289
  };
278
- const symbol = checker.getSymbolAtLocation(lookupNode);
279
- const type = symbol ? checker.getDeclaredTypeOfSymbol(symbol) ?? checker.getTypeOfSymbol(symbol) : checker.getTypeAtLocation(lookupNode);
280
- if (type) session.rememberTypeText(type.id, raw.slice(leading, raw.length - trailing));
290
+ const nameNode = implementedClauseNameNode(lookupNode, raw);
291
+ const symbol = checker.getSymbolAtLocation(nameNode) ?? checker.getSymbolAtLocation(lookupNode);
292
+ const type = symbol ? checker.getDeclaredTypeOfSymbol(symbol) ?? checker.getTypeOfSymbol(symbol) : checker.getTypeAtLocation(nameNode) ?? checker.getTypeAtLocation(lookupNode);
293
+ if (type) try {
294
+ checker.typeToString(type);
295
+ } catch {}
281
296
  return type;
282
297
  }).filter((type) => type !== void 0);
283
298
  }
299
+ function implementedClauseNameNode(node, raw) {
300
+ const range = lastTypeNameIdentifierRange(raw);
301
+ if (!range) return node;
302
+ const pos = node.pos + range.start;
303
+ const end = node.pos + range.end;
304
+ return {
305
+ fileName: node.fileName,
306
+ pos,
307
+ end,
308
+ range: [pos, end]
309
+ };
310
+ }
311
+ function lastTypeNameIdentifierRange(text) {
312
+ let last;
313
+ const scanner = createScanner();
314
+ for (let index = 0; index < text.length; index += 1) {
315
+ const nextIndex = scanner.skip(text, index);
316
+ if (nextIndex > index) {
317
+ index = nextIndex - 1;
318
+ continue;
319
+ }
320
+ const char = text[index];
321
+ if (char === "<") break;
322
+ if (!isIdentifierStart(char)) continue;
323
+ let end = index + 1;
324
+ while (isIdentifierPart(text[end])) end += 1;
325
+ last = {
326
+ start: index,
327
+ end
328
+ };
329
+ index = end - 1;
330
+ }
331
+ return last;
332
+ }
284
333
  function findClassBodyOpen(text, start) {
285
334
  const scanner = createScanner();
286
335
  let angleDepth = 0;
@@ -322,7 +371,10 @@ function matchesKeyword(text, keyword, index) {
322
371
  return text.startsWith(keyword, index) && !isIdentifierPart(text[index - 1]) && !isIdentifierPart(text[index + keyword.length]);
323
372
  }
324
373
  function isIdentifierPart(char) {
325
- return char !== void 0 && /[A-Za-z0-9_$]/.test(char);
374
+ return char !== void 0 && (isIdentifierStart(char) || /[0-9]/.test(char));
375
+ }
376
+ function isIdentifierStart(char) {
377
+ return char !== void 0 && /[A-Za-z_$]/.test(char);
326
378
  }
327
379
  function splitTopLevelRanges(text, delimiter) {
328
380
  const ranges = [];
@@ -1 +1 @@
1
- {"version":3,"file":"checker.js","names":[],"sources":["../ts/checker.ts"],"sourcesContent":["import type { Node } from \"@oxlint/plugins\";\n\nimport { createNodeMaps, toPosition } from \"./node_map\";\nimport { sessionForContext } from \"./registry\";\nimport type {\n ContextWithParserOptions,\n CorsaNode,\n CorsaProgramShape,\n CorsaSignature,\n CorsaSymbol,\n CorsaType,\n CorsaTypeCheckerShape,\n} from \"./types\";\n\nexport function createProgram(\n context: ContextWithParserOptions,\n): CorsaProgramShape & { readonly nodeMaps: ReturnType<typeof createNodeMaps> } {\n const nodeMaps = createNodeMaps(context);\n return {\n nodeMaps,\n getCompilerOptions() {\n return sessionForContext(context).session.getCompilerOptions();\n },\n getCurrentDirectory() {\n return sessionForContext(context).project.rootDir;\n },\n getRootFileNames() {\n return sessionForContext(context).session.getRootFileNames();\n },\n getSourceFile(fileName = context.filename) {\n return { fileName, text: context.sourceCode.text };\n },\n getTypeChecker() {\n return createTypeChecker(context);\n },\n };\n}\n\nexport function createTypeChecker(context: ContextWithParserOptions): CorsaTypeCheckerShape {\n return {\n getTypeAtLocation(node) {\n if ((node as { readonly type?: string }).type === \"NewExpression\") {\n return typeOfNewExpression(node as Node, this);\n }\n const lookupNode = nodeForTypeLookup(node);\n return sessionForContext(context).session.getTypeAtSourceRange(\n filenameFor(context, lookupNode),\n toPosition(lookupNode),\n endPosition(lookupNode),\n sourceTextFor(context, lookupNode),\n nodeKind(lookupNode),\n );\n },\n getContextualType(node) {\n return this.getTypeAtLocation(node);\n },\n getSymbolAtLocation(node) {\n const lookupNode = nodeForTypeLookup(node);\n return sessionForContext(context).session.getSymbolAtPosition(\n filenameFor(context, lookupNode),\n toPosition(lookupNode),\n sourceTextFor(context, lookupNode),\n );\n },\n getSymbol(symbol) {\n return sessionForContext(context).session.getSymbol(symbol);\n },\n getSymbolById(id) {\n return sessionForContext(context).session.getSymbol(id);\n },\n getNode(node) {\n return sessionForContext(context).session.getNode(node);\n },\n getNodeById(id) {\n return sessionForContext(context).session.getNode(id);\n },\n getTypeOfSymbol(symbol) {\n return sessionForContext(context).session.getTypeOfSymbol(symbol);\n },\n getDeclaredTypeOfSymbol(symbol) {\n return sessionForContext(context).session.getDeclaredTypeOfSymbol(symbol);\n },\n getTypeOfSymbolAtLocation(symbol, node) {\n return (\n this.getTypeOfSymbol(symbol) ??\n this.getDeclaredTypeOfSymbol(symbol) ??\n this.getTypeAtLocation(node)\n );\n },\n typeToString(type, enclosingDeclaration, flags) {\n void enclosingDeclaration;\n return sessionForContext(context).session.typeToString(type, flags);\n },\n getBaseTypeOfLiteralType(type) {\n return sessionForContext(context).session.getBaseTypeOfLiteralType(type);\n },\n getPropertiesOfType(type) {\n return sessionForContext(context).session.getPropertiesOfType(type);\n },\n getSignaturesOfType(type, kind) {\n return sessionForContext(context).session.getSignaturesOfType(type, kind);\n },\n getReturnTypeOfSignature(signature) {\n return sessionForContext(context).session.getReturnTypeOfSignature(signature);\n },\n getTypePredicateOfSignature(signature) {\n return sessionForContext(context).session.getTypePredicateOfSignature(signature);\n },\n getBaseTypes(type) {\n return sessionForContext(context).session.getBaseTypes(type);\n },\n getImplementedTypes(node) {\n if (\"pos\" in node) {\n return implementedTypesFromCorsaNode(context, node, this);\n }\n const sourceText = sourceTextFor(context, node);\n const sourceNode = sourceText ? corsaNodeFromEstree(context, node) : undefined;\n if (sourceText && sourceNode) {\n const implemented = implementedTypesFromSourceText(context, sourceNode, sourceText, this);\n if (implemented.length > 0) {\n return implemented;\n }\n }\n return implementedClauseNodes(node)\n .map((clause) => {\n const expression = implementedClauseChildNode(clause, \"expression\") ?? clause;\n const symbol = this.getSymbolAtLocation(expression) ?? this.getSymbolAtLocation(clause);\n return symbol\n ? (this.getDeclaredTypeOfSymbol(symbol) ?? this.getTypeOfSymbol(symbol))\n : (this.getTypeAtLocation(expression) ?? this.getTypeAtLocation(clause));\n })\n .filter((type): type is CorsaType => type !== undefined);\n },\n getImplementedTypesOfType(type) {\n return implementedTypesFromTypeAndBases(context, type, this);\n },\n getTypeArguments(type) {\n return sessionForContext(context).session.getTypeArguments(type);\n },\n getTypesOfType(type) {\n return sessionForContext(context).session.getTypesOfType(type);\n },\n getTargetOfType(type) {\n return sessionForContext(context).session.getTargetOfType(type);\n },\n getTypeParametersOfType(type) {\n return sessionForContext(context).session.getTypeParametersOfType(type);\n },\n getOuterTypeParametersOfType(type) {\n return sessionForContext(context).session.getOuterTypeParametersOfType(type);\n },\n getLocalTypeParametersOfType(type) {\n return sessionForContext(context).session.getLocalTypeParametersOfType(type);\n },\n getObjectTypeOfType(type) {\n return sessionForContext(context).session.getObjectTypeOfType(type);\n },\n getIndexTypeOfType(type) {\n return sessionForContext(context).session.getIndexTypeOfType(type);\n },\n getCheckTypeOfType(type) {\n return sessionForContext(context).session.getCheckTypeOfType(type);\n },\n getExtendsTypeOfType(type) {\n return sessionForContext(context).session.getExtendsTypeOfType(type);\n },\n getBaseTypeOfType(type) {\n return sessionForContext(context).session.getBaseTypeOfType(type);\n },\n getConstraintOfType(type) {\n return sessionForContext(context).session.getConstraintOfType(type);\n },\n isUnionType(type) {\n return (type.flags & typeFlags.union) !== 0;\n },\n isIntersectionType(type) {\n return (type.flags & typeFlags.intersection) !== 0;\n },\n };\n}\n\nconst typeFlags = {\n union: 1 << 27,\n intersection: 1 << 28,\n} as const;\n\nfunction sourceTextFor(\n context: ContextWithParserOptions,\n node: Node | CorsaNode | CorsaType | CorsaSymbol | CorsaSignature,\n): string | undefined {\n return sourceTextForPath(context, filenameFor(context, node));\n}\n\nfunction sourceTextForPath(\n context: ContextWithParserOptions,\n fileName: string,\n): string | undefined {\n const normalizedFileName = fileName.toLowerCase();\n const normalizedContextFilename = context.filename.toLowerCase();\n return normalizedFileName === normalizedContextFilename ||\n normalizedFileName.endsWith(normalizedContextFilename) ||\n normalizedContextFilename.endsWith(normalizedFileName)\n ? context.sourceCode.text\n : sessionForContext(context).session.getSourceTextForPath(fileName);\n}\n\nfunction typeOfNewExpression(node: Node, checker: CorsaTypeCheckerShape): CorsaType | undefined {\n const callee = childNode(node, \"callee\");\n if (!callee) {\n return undefined;\n }\n const calleeType = checker.getTypeAtLocation(callee);\n if (!calleeType) {\n return undefined;\n }\n const constructSignature = checker.getSignaturesOfType(calleeType, 1)[0];\n return constructSignature\n ? (checker.getReturnTypeOfSignature(constructSignature) ?? calleeType)\n : calleeType;\n}\n\nfunction nodeForTypeLookup(node: Node | CorsaNode): Node | CorsaNode {\n if (\"pos\" in node) {\n return node;\n }\n switch ((node as { readonly type?: string }).type) {\n case \"ClassDeclaration\":\n case \"ClassExpression\":\n return childNode(node, \"id\") ?? node;\n case \"TSPropertySignature\":\n return childNode(node, \"key\") ?? node;\n default:\n return node;\n }\n}\n\nfunction endPosition(node: Node | CorsaNode): number {\n if (\"end\" in node) {\n return node.end;\n }\n const range = (node as Node & { readonly range?: readonly [number, number] }).range;\n if (!range) {\n throw new Error(\"corsa oxlint requires ESTree nodes with range data\");\n }\n return range[1];\n}\n\nfunction nodeKind(node: Node | CorsaNode): string | undefined {\n return \"pos\" in node ? undefined : (node as { readonly type?: string }).type;\n}\n\nfunction childNode(node: Node, key: string): Node | undefined {\n const value = (node as unknown as Record<string, unknown>)[key];\n if (isNode(value)) {\n return value;\n }\n return undefined;\n}\n\nfunction implementedClauseNodes(node: Node | CorsaNode): readonly Node[] {\n if (\"pos\" in node) {\n return [];\n }\n const clauses = (node as unknown as { readonly implements?: unknown }).implements;\n if (!Array.isArray(clauses)) {\n return [];\n }\n return clauses.filter(isNode);\n}\n\nfunction implementedClauseChildNode(node: Node, key: string): Node | undefined {\n const value = (node as unknown as Record<string, unknown>)[key];\n if (isNode(value)) {\n return value;\n }\n return undefined;\n}\n\nfunction implementedTypesFromCorsaNode(\n context: ContextWithParserOptions,\n node: CorsaNode,\n checker: CorsaTypeCheckerShape,\n): readonly CorsaType[] {\n const symbol = checker.getSymbolAtLocation(node);\n if (symbol) {\n const declaredType = checker.getDeclaredTypeOfSymbol(symbol) ?? checker.getTypeOfSymbol(symbol);\n if (declaredType) {\n const implemented = checker.getImplementedTypesOfType(declaredType);\n if (implemented.length > 0) {\n return implemented;\n }\n }\n }\n const sourceText = sourceTextFor(context, node);\n if (sourceText) {\n return implementedTypesFromSourceText(context, node, sourceText, checker);\n }\n const type = checker.getTypeAtLocation(node);\n return type ? checker.getImplementedTypesOfType(type) : [];\n}\n\nfunction corsaNodeFromEstree(context: ContextWithParserOptions, node: Node): CorsaNode | undefined {\n const range = (node as { readonly range?: unknown }).range;\n if (\n !Array.isArray(range) ||\n range.length < 2 ||\n typeof range[0] !== \"number\" ||\n typeof range[1] !== \"number\"\n ) {\n return undefined;\n }\n return {\n fileName: context.filename,\n pos: range[0],\n end: range[1],\n range: [range[0], range[1]] as const,\n };\n}\n\nfunction implementedTypesFromTypeAndBases(\n context: ContextWithParserOptions,\n type: CorsaType,\n checker: CorsaTypeCheckerShape,\n): readonly CorsaType[] {\n // Iterative DFS over the base chain so we don't pay for one closure call\n // and one `push(...subResult)` spread per base (each spread used to copy\n // the entire growing accumulator). Visit order doesn't matter because we\n // dedupe by `type.id`.\n const seenTypes = new Set<string>();\n const seenImplementedTypes = new Set<string>();\n const implemented: CorsaType[] = [];\n const stack: CorsaType[] = [type];\n while (stack.length > 0) {\n const current = stack.pop()!;\n if (seenTypes.has(current.id)) {\n continue;\n }\n seenTypes.add(current.id);\n\n const ownImplemented = implementedTypesFromTypeDeclaration(context, current, checker);\n for (let index = 0; index < ownImplemented.length; index += 1) {\n const ownType = ownImplemented[index]!;\n if (seenImplementedTypes.has(ownType.id)) {\n continue;\n }\n seenImplementedTypes.add(ownType.id);\n implemented.push(ownType);\n }\n\n const bases = checker.getBaseTypes(current);\n // Push in reverse so the natural visit order matches the recursive form.\n for (let index = bases.length - 1; index >= 0; index -= 1) {\n const baseType = bases[index]!;\n if (seenTypes.has(baseType.id)) {\n continue;\n }\n stack.push(baseType);\n }\n }\n return implemented;\n}\n\nfunction implementedTypesFromTypeDeclaration(\n context: ContextWithParserOptions,\n type: CorsaType,\n checker: CorsaTypeCheckerShape,\n): readonly CorsaType[] {\n const session = sessionForContext(context).session;\n const symbol = type.symbol ? session.getSymbol(type.symbol) : undefined;\n const declaration = symbol?.valueDeclaration ?? symbol?.declarations?.[0];\n const declarationNode = declaration ? session.getNode(declaration) : undefined;\n const sourceText = declarationNode\n ? sourceTextForPath(context, declarationNode.fileName)\n : undefined;\n return declarationNode && sourceText\n ? implementedTypesFromSourceText(context, declarationNode, sourceText, checker)\n : [];\n}\n\nfunction implementedTypesFromSourceText(\n context: ContextWithParserOptions,\n node: CorsaNode,\n sourceText: string,\n checker: CorsaTypeCheckerShape,\n): readonly CorsaType[] {\n if (node.pos < 0 || node.end > sourceText.length || node.pos >= node.end) {\n return [];\n }\n const classText = sourceText.slice(node.pos, node.end);\n const classStart = findKeywordOutsideTrivia(classText, \"class\");\n const headerStart = classStart >= 0 ? classStart : 0;\n const bodyOpen = findClassBodyOpen(classText, headerStart);\n const headerText = classText.slice(headerStart, bodyOpen >= 0 ? bodyOpen : classText.length);\n const implementsIndex = findKeywordOutsideTrivia(headerText, \"implements\");\n if (implementsIndex < 0) {\n return [];\n }\n const session = sessionForContext(context).session;\n const clauseText = headerText.slice(implementsIndex + \"implements\".length);\n const clauseStart = node.pos + headerStart + implementsIndex + \"implements\".length;\n return splitTopLevelRanges(clauseText, \",\")\n .map((range) => {\n const raw = clauseText.slice(range.start, range.end);\n const leading = raw.search(/\\S/);\n if (leading < 0) {\n return undefined;\n }\n const trailing = raw.match(/\\s*$/)?.[0].length ?? 0;\n const pos = clauseStart + range.start + leading;\n const end = clauseStart + range.end - trailing;\n const lookupNode: CorsaNode = {\n fileName: node.fileName,\n pos,\n end,\n range: [pos, end] as const,\n };\n const symbol = checker.getSymbolAtLocation(lookupNode);\n const type = symbol\n ? (checker.getDeclaredTypeOfSymbol(symbol) ?? checker.getTypeOfSymbol(symbol))\n : checker.getTypeAtLocation(lookupNode);\n if (type) {\n // Implemented-interface handles come back with empty `texts`, so warm\n // the type-text cache with the `implements` identifier. If upstream\n // later evicts the handle, `typeToString` falls back to this name\n // instead of throwing (GH#211).\n session.rememberTypeText(type.id, raw.slice(leading, raw.length - trailing));\n }\n return type;\n })\n .filter((type): type is CorsaType => type !== undefined);\n}\n\nfunction findClassBodyOpen(text: string, start: number): number {\n const scanner = createScanner();\n let angleDepth = 0;\n let parenDepth = 0;\n let bracketDepth = 0;\n let braceDepth = 0;\n for (let index = start; index < text.length; index += 1) {\n const nextIndex = scanner.skip(text, index);\n if (nextIndex > index) {\n index = nextIndex - 1;\n continue;\n }\n const char = text[index];\n if (char === \"<\") angleDepth += 1;\n else if (char === \">\") angleDepth = Math.max(0, angleDepth - 1);\n else if (char === \"(\") parenDepth += 1;\n else if (char === \")\") parenDepth = Math.max(0, parenDepth - 1);\n else if (char === \"[\") bracketDepth += 1;\n else if (char === \"]\") bracketDepth = Math.max(0, bracketDepth - 1);\n else if (\n char === \"{\" &&\n angleDepth === 0 &&\n parenDepth === 0 &&\n bracketDepth === 0 &&\n braceDepth === 0\n ) {\n return index;\n } else if (char === \"{\") braceDepth += 1;\n else if (char === \"}\") braceDepth = Math.max(0, braceDepth - 1);\n }\n return -1;\n}\n\nfunction findKeywordOutsideTrivia(text: string, keyword: string): number {\n const scanner = createScanner();\n for (let index = 0; index < text.length; index += 1) {\n const nextIndex = scanner.skip(text, index);\n if (nextIndex > index) {\n index = nextIndex - 1;\n continue;\n }\n if (matchesKeyword(text, keyword, index)) {\n return index;\n }\n }\n return -1;\n}\n\nfunction matchesKeyword(text: string, keyword: string, index: number): boolean {\n return (\n text.startsWith(keyword, index) &&\n !isIdentifierPart(text[index - 1]) &&\n !isIdentifierPart(text[index + keyword.length])\n );\n}\n\nfunction isIdentifierPart(char: string | undefined): boolean {\n return char !== undefined && /[A-Za-z0-9_$]/.test(char);\n}\n\nfunction splitTopLevelRanges(\n text: string,\n delimiter: string,\n): readonly { readonly start: number; readonly end: number }[] {\n const ranges: { start: number; end: number }[] = [];\n const scanner = createScanner();\n let start = 0;\n let angleDepth = 0;\n let parenDepth = 0;\n let bracketDepth = 0;\n let braceDepth = 0;\n for (let index = 0; index < text.length; index += 1) {\n const char = text[index];\n const nextIndex = scanner.skip(text, index);\n if (nextIndex > index) {\n index = nextIndex - 1;\n continue;\n }\n if (char === \"<\") angleDepth += 1;\n else if (char === \">\") angleDepth = Math.max(0, angleDepth - 1);\n else if (char === \"(\") parenDepth += 1;\n else if (char === \")\") parenDepth = Math.max(0, parenDepth - 1);\n else if (char === \"[\") bracketDepth += 1;\n else if (char === \"]\") bracketDepth = Math.max(0, bracketDepth - 1);\n else if (char === \"{\") braceDepth += 1;\n else if (char === \"}\") braceDepth = Math.max(0, braceDepth - 1);\n else if (\n char === delimiter &&\n angleDepth === 0 &&\n parenDepth === 0 &&\n bracketDepth === 0 &&\n braceDepth === 0\n ) {\n ranges.push({ start, end: index });\n start = index + 1;\n }\n }\n ranges.push({ start, end: text.length });\n return ranges;\n}\n\nfunction createScanner(): {\n skip(text: string, index: number): number;\n} {\n let quote: string | undefined;\n let escaped = false;\n let inLineComment = false;\n let inBlockComment = false;\n return {\n skip(text, index) {\n const char = text[index];\n const next = text[index + 1];\n if (inLineComment) {\n if (char === \"\\n\" || char === \"\\r\") {\n inLineComment = false;\n }\n return index + 1;\n }\n if (inBlockComment) {\n if (char === \"*\" && next === \"/\") {\n inBlockComment = false;\n return index + 2;\n }\n return index + 1;\n }\n if (quote) {\n if (escaped) {\n escaped = false;\n } else if (char === \"\\\\\") {\n escaped = true;\n } else if (char === quote) {\n quote = undefined;\n }\n return index + 1;\n }\n if (char === \"/\" && next === \"/\") {\n inLineComment = true;\n return index + 2;\n }\n if (char === \"/\" && next === \"*\") {\n inBlockComment = true;\n return index + 2;\n }\n if (char === '\"' || char === \"'\" || char === \"`\") {\n quote = char;\n return index + 1;\n }\n return index;\n },\n };\n}\n\nfunction isNode(value: unknown): value is Node {\n return typeof value === \"object\" && value !== null && \"type\" in value && \"range\" in value;\n}\n\nfunction filenameFor(\n context: ContextWithParserOptions,\n node: Node | CorsaNode | CorsaType | CorsaSymbol | CorsaSignature,\n): string {\n if (\"fileName\" in node) {\n return node.fileName;\n }\n return context.filename;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"checker.js","names":[],"sources":["../ts/checker.ts"],"sourcesContent":["import type { Node } from \"@oxlint/plugins\";\n\nimport { createNodeMaps, toPosition } from \"./node_map\";\nimport { sessionForContext } from \"./registry\";\nimport { SignatureKind } from \"./types\";\nimport type {\n ContextWithParserOptions,\n CorsaNode,\n CorsaProgramShape,\n CorsaSignature,\n CorsaSymbol,\n CorsaType,\n CorsaTypeCheckerShape,\n} from \"./types\";\n\nexport function createProgram(\n context: ContextWithParserOptions,\n): CorsaProgramShape & { readonly nodeMaps: ReturnType<typeof createNodeMaps> } {\n const nodeMaps = createNodeMaps(context);\n return {\n nodeMaps,\n getCompilerOptions() {\n return sessionForContext(context).session.getCompilerOptions();\n },\n getCurrentDirectory() {\n return sessionForContext(context).project.rootDir;\n },\n getRootFileNames() {\n return sessionForContext(context).session.getRootFileNames();\n },\n getSourceFile(fileName = context.filename) {\n return { fileName, text: context.sourceCode.text };\n },\n getTypeChecker() {\n return createTypeChecker(context);\n },\n };\n}\n\nexport function createTypeChecker(context: ContextWithParserOptions): CorsaTypeCheckerShape {\n return {\n getTypeAtLocation(node) {\n if ((node as { readonly type?: string }).type === \"NewExpression\") {\n return typeOfNewExpression(node as Node, this);\n }\n const lookupNode = nodeForTypeLookup(node);\n return sessionForContext(context).session.getTypeAtSourceRange(\n filenameFor(context, lookupNode),\n toPosition(lookupNode),\n endPosition(lookupNode),\n sourceTextFor(context, lookupNode),\n nodeKind(lookupNode),\n );\n },\n getContextualType(node) {\n return this.getTypeAtLocation(node);\n },\n getSymbolAtLocation(node) {\n const lookupNode = nodeForTypeLookup(node);\n return sessionForContext(context).session.getSymbolAtPosition(\n filenameFor(context, lookupNode),\n toPosition(lookupNode),\n sourceTextFor(context, lookupNode),\n );\n },\n getSymbol(symbol) {\n return sessionForContext(context).session.getSymbol(symbol);\n },\n getSymbolById(id) {\n return sessionForContext(context).session.getSymbol(id);\n },\n getSymbolOfType(type) {\n return sessionForContext(context).session.getSymbolOfType(type);\n },\n getNode(node) {\n return sessionForContext(context).session.getNode(node);\n },\n getNodeById(id) {\n return sessionForContext(context).session.getNode(id);\n },\n getTypeOfSymbol(symbol) {\n return sessionForContext(context).session.getTypeOfSymbol(symbol);\n },\n getTypeOfSymbolById(id) {\n return sessionForContext(context).session.getTypeOfSymbolById(id);\n },\n getDeclaredTypeOfSymbol(symbol) {\n return sessionForContext(context).session.getDeclaredTypeOfSymbol(symbol);\n },\n getDeclaredTypeOfSymbolById(id) {\n return sessionForContext(context).session.getDeclaredTypeOfSymbolById(id);\n },\n getTypeOfSymbolAtLocation(symbol, node) {\n return (\n this.getTypeOfSymbol(symbol) ??\n this.getDeclaredTypeOfSymbol(symbol) ??\n this.getTypeAtLocation(node)\n );\n },\n typeToString(type, enclosingDeclaration, flags) {\n void enclosingDeclaration;\n return sessionForContext(context).session.typeToString(type, flags);\n },\n getBaseTypeOfLiteralType(type) {\n return sessionForContext(context).session.getBaseTypeOfLiteralType(type);\n },\n getPropertiesOfType(type) {\n return sessionForContext(context).session.getPropertiesOfType(type);\n },\n getSignaturesOfType(type, kind) {\n return sessionForContext(context).session.getSignaturesOfType(type, kind);\n },\n getCallSignatureFacts(type, kind, argumentTypeTexts, explicitTypeArgumentTexts) {\n return sessionForContext(context).session.getCallSignatureFacts(\n type,\n kind,\n argumentTypeTexts,\n explicitTypeArgumentTexts,\n );\n },\n getReturnTypeOfSignature(signature) {\n return sessionForContext(context).session.getReturnTypeOfSignature(signature);\n },\n getTypePredicateOfSignature(signature) {\n return sessionForContext(context).session.getTypePredicateOfSignature(signature);\n },\n getBaseTypes(type) {\n return sessionForContext(context).session.getBaseTypes(type);\n },\n getImplementedTypes(node) {\n if (\"pos\" in node) {\n return implementedTypesFromCorsaNode(context, node, this);\n }\n const sourceText = sourceTextFor(context, node);\n const sourceNode = sourceText ? corsaNodeFromEstree(context, node) : undefined;\n if (sourceText && sourceNode) {\n const implemented = implementedTypesFromSourceText(context, sourceNode, sourceText, this);\n if (implemented.length > 0) {\n return implemented;\n }\n }\n return implementedClauseNodes(node)\n .map((clause) => {\n const expression = implementedClauseChildNode(clause, \"expression\") ?? clause;\n const symbol = this.getSymbolAtLocation(expression) ?? this.getSymbolAtLocation(clause);\n return symbol\n ? (this.getDeclaredTypeOfSymbol(symbol) ?? this.getTypeOfSymbol(symbol))\n : (this.getTypeAtLocation(expression) ?? this.getTypeAtLocation(clause));\n })\n .filter((type): type is CorsaType => type !== undefined);\n },\n getImplementedTypesOfType(type) {\n return implementedTypesFromTypeAndBases(context, type, this);\n },\n getTypeArguments(type) {\n return sessionForContext(context).session.getTypeArguments(type);\n },\n getTypesOfType(type) {\n return sessionForContext(context).session.getTypesOfType(type);\n },\n getTargetOfType(type) {\n return sessionForContext(context).session.getTargetOfType(type);\n },\n getTypeParametersOfType(type) {\n return sessionForContext(context).session.getTypeParametersOfType(type);\n },\n getOuterTypeParametersOfType(type) {\n return sessionForContext(context).session.getOuterTypeParametersOfType(type);\n },\n getLocalTypeParametersOfType(type) {\n return sessionForContext(context).session.getLocalTypeParametersOfType(type);\n },\n getObjectTypeOfType(type) {\n return sessionForContext(context).session.getObjectTypeOfType(type);\n },\n getIndexTypeOfType(type) {\n return sessionForContext(context).session.getIndexTypeOfType(type);\n },\n getCheckTypeOfType(type) {\n return sessionForContext(context).session.getCheckTypeOfType(type);\n },\n getExtendsTypeOfType(type) {\n return sessionForContext(context).session.getExtendsTypeOfType(type);\n },\n getBaseTypeOfType(type) {\n return sessionForContext(context).session.getBaseTypeOfType(type);\n },\n getConstraintOfType(type) {\n return sessionForContext(context).session.getConstraintOfType(type);\n },\n isUnionType(type) {\n return (type.flags & typeFlags.union) !== 0;\n },\n isIntersectionType(type) {\n return (type.flags & typeFlags.intersection) !== 0;\n },\n };\n}\n\nconst typeFlags = {\n union: 1 << 27,\n intersection: 1 << 28,\n} as const;\n\nfunction sourceTextFor(\n context: ContextWithParserOptions,\n node: Node | CorsaNode | CorsaType | CorsaSymbol | CorsaSignature,\n): string | undefined {\n return sourceTextForPath(context, filenameFor(context, node));\n}\n\nfunction sourceTextForPath(\n context: ContextWithParserOptions,\n fileName: string,\n): string | undefined {\n const normalizedFileName = fileName.toLowerCase();\n const normalizedContextFilename = context.filename.toLowerCase();\n return normalizedFileName === normalizedContextFilename ||\n normalizedFileName.endsWith(normalizedContextFilename) ||\n normalizedContextFilename.endsWith(normalizedFileName)\n ? context.sourceCode.text\n : sessionForContext(context).session.getSourceTextForPath(fileName);\n}\n\nfunction typeOfNewExpression(node: Node, checker: CorsaTypeCheckerShape): CorsaType | undefined {\n const callee = childNode(node, \"callee\");\n if (!callee) {\n return undefined;\n }\n const calleeType = checker.getTypeAtLocation(callee);\n if (!calleeType) {\n return undefined;\n }\n const constructSignature = checker.getSignaturesOfType(calleeType, SignatureKind.Construct)[0];\n return constructSignature\n ? (checker.getReturnTypeOfSignature(constructSignature) ?? calleeType)\n : calleeType;\n}\n\nfunction nodeForTypeLookup(node: Node | CorsaNode): Node | CorsaNode {\n if (\"pos\" in node) {\n return node;\n }\n switch ((node as { readonly type?: string }).type) {\n case \"ClassDeclaration\":\n case \"ClassExpression\":\n return childNode(node, \"id\") ?? node;\n case \"TSPropertySignature\":\n return childNode(node, \"key\") ?? node;\n default:\n return node;\n }\n}\n\nfunction endPosition(node: Node | CorsaNode): number {\n if (\"end\" in node) {\n return node.end;\n }\n const range = (node as Node & { readonly range?: readonly [number, number] }).range;\n if (!range) {\n throw new Error(\"corsa oxlint requires ESTree nodes with range data\");\n }\n return range[1];\n}\n\nfunction nodeKind(node: Node | CorsaNode): string | undefined {\n return \"pos\" in node ? undefined : (node as { readonly type?: string }).type;\n}\n\nfunction childNode(node: Node, key: string): Node | undefined {\n const value = (node as unknown as Record<string, unknown>)[key];\n if (isNode(value)) {\n return value;\n }\n return undefined;\n}\n\nfunction implementedClauseNodes(node: Node | CorsaNode): readonly Node[] {\n if (\"pos\" in node) {\n return [];\n }\n const clauses = (node as unknown as { readonly implements?: unknown }).implements;\n if (!Array.isArray(clauses)) {\n return [];\n }\n return clauses.filter(isNode);\n}\n\nfunction implementedClauseChildNode(node: Node, key: string): Node | undefined {\n const value = (node as unknown as Record<string, unknown>)[key];\n if (isNode(value)) {\n return value;\n }\n return undefined;\n}\n\nfunction implementedTypesFromCorsaNode(\n context: ContextWithParserOptions,\n node: CorsaNode,\n checker: CorsaTypeCheckerShape,\n): readonly CorsaType[] {\n const symbol = checker.getSymbolAtLocation(node);\n if (symbol) {\n const declaredType = checker.getDeclaredTypeOfSymbol(symbol) ?? checker.getTypeOfSymbol(symbol);\n if (declaredType) {\n const implemented = checker.getImplementedTypesOfType(declaredType);\n if (implemented.length > 0) {\n return implemented;\n }\n }\n }\n const sourceText = sourceTextFor(context, node);\n if (sourceText) {\n return implementedTypesFromSourceText(context, node, sourceText, checker);\n }\n const type = checker.getTypeAtLocation(node);\n return type ? checker.getImplementedTypesOfType(type) : [];\n}\n\nfunction corsaNodeFromEstree(context: ContextWithParserOptions, node: Node): CorsaNode | undefined {\n const range = (node as { readonly range?: unknown }).range;\n if (\n !Array.isArray(range) ||\n range.length < 2 ||\n typeof range[0] !== \"number\" ||\n typeof range[1] !== \"number\"\n ) {\n return undefined;\n }\n return {\n fileName: context.filename,\n pos: range[0],\n end: range[1],\n range: [range[0], range[1]] as const,\n };\n}\n\nfunction implementedTypesFromTypeAndBases(\n context: ContextWithParserOptions,\n type: CorsaType,\n checker: CorsaTypeCheckerShape,\n): readonly CorsaType[] {\n // Iterative DFS over the base chain so we don't pay for one closure call\n // and one `push(...subResult)` spread per base (each spread used to copy\n // the entire growing accumulator). Visit order doesn't matter because we\n // dedupe by `type.id`.\n const seenTypes = new Set<string>();\n const seenImplementedTypes = new Set<string>();\n const implemented: CorsaType[] = [];\n const stack: CorsaType[] = [type];\n while (stack.length > 0) {\n const current = stack.pop()!;\n if (seenTypes.has(current.id)) {\n continue;\n }\n seenTypes.add(current.id);\n\n const ownImplemented = implementedTypesFromTypeDeclaration(context, current, checker);\n for (let index = 0; index < ownImplemented.length; index += 1) {\n const ownType = ownImplemented[index]!;\n if (seenImplementedTypes.has(ownType.id)) {\n continue;\n }\n seenImplementedTypes.add(ownType.id);\n implemented.push(ownType);\n }\n\n const bases = checker.getBaseTypes(current);\n // Push in reverse so the natural visit order matches the recursive form.\n for (let index = bases.length - 1; index >= 0; index -= 1) {\n const baseType = bases[index]!;\n if (seenTypes.has(baseType.id)) {\n continue;\n }\n stack.push(baseType);\n }\n }\n return implemented;\n}\n\nfunction implementedTypesFromTypeDeclaration(\n context: ContextWithParserOptions,\n type: CorsaType,\n checker: CorsaTypeCheckerShape,\n): readonly CorsaType[] {\n const session = sessionForContext(context).session;\n const symbol = type.symbol ? session.getSymbol(type.symbol) : undefined;\n const declaration = symbol?.valueDeclaration ?? symbol?.declarations?.[0];\n const declarationNode = declaration ? session.getNode(declaration) : undefined;\n const sourceText = declarationNode\n ? sourceTextForPath(context, declarationNode.fileName)\n : undefined;\n return declarationNode && sourceText\n ? implementedTypesFromSourceText(context, declarationNode, sourceText, checker)\n : [];\n}\n\nfunction implementedTypesFromSourceText(\n context: ContextWithParserOptions,\n node: CorsaNode,\n sourceText: string,\n checker: CorsaTypeCheckerShape,\n): readonly CorsaType[] {\n if (node.pos < 0 || node.end > sourceText.length || node.pos >= node.end) {\n return [];\n }\n const classText = sourceText.slice(node.pos, node.end);\n const classStart = findKeywordOutsideTrivia(classText, \"class\");\n const headerStart = classStart >= 0 ? classStart : 0;\n const bodyOpen = findClassBodyOpen(classText, headerStart);\n const headerText = classText.slice(headerStart, bodyOpen >= 0 ? bodyOpen : classText.length);\n const implementsIndex = findKeywordOutsideTrivia(headerText, \"implements\");\n if (implementsIndex < 0) {\n return [];\n }\n const clauseText = headerText.slice(implementsIndex + \"implements\".length);\n const clauseStart = node.pos + headerStart + implementsIndex + \"implements\".length;\n return splitTopLevelRanges(clauseText, \",\")\n .map((range) => {\n const raw = clauseText.slice(range.start, range.end);\n const leading = raw.search(/\\S/);\n if (leading < 0) {\n return undefined;\n }\n const trailing = raw.match(/\\s*$/)?.[0].length ?? 0;\n const pos = clauseStart + range.start + leading;\n const end = clauseStart + range.end - trailing;\n const lookupNode: CorsaNode = {\n fileName: node.fileName,\n pos,\n end,\n range: [pos, end] as const,\n };\n const nameNode = implementedClauseNameNode(lookupNode, raw);\n const symbol =\n checker.getSymbolAtLocation(nameNode) ?? checker.getSymbolAtLocation(lookupNode);\n const type = symbol\n ? (checker.getDeclaredTypeOfSymbol(symbol) ?? checker.getTypeOfSymbol(symbol))\n : (checker.getTypeAtLocation(nameNode) ?? checker.getTypeAtLocation(lookupNode));\n if (type) {\n try {\n checker.typeToString(type);\n } catch {\n // Corsa-side relation fallbacks handle stale type handles; avoid\n // deriving replacement text from source names in the JS bridge.\n }\n }\n return type;\n })\n .filter((type): type is CorsaType => type !== undefined);\n}\n\nfunction implementedClauseNameNode(node: CorsaNode, raw: string): CorsaNode {\n const range = lastTypeNameIdentifierRange(raw);\n if (!range) {\n return node;\n }\n const pos = node.pos + range.start;\n const end = node.pos + range.end;\n return {\n fileName: node.fileName,\n pos,\n end,\n range: [pos, end] as const,\n };\n}\n\nfunction lastTypeNameIdentifierRange(\n text: string,\n): { readonly start: number; readonly end: number } | undefined {\n let last: { start: number; end: number } | undefined;\n const scanner = createScanner();\n for (let index = 0; index < text.length; index += 1) {\n const nextIndex = scanner.skip(text, index);\n if (nextIndex > index) {\n index = nextIndex - 1;\n continue;\n }\n const char = text[index];\n if (char === \"<\") {\n break;\n }\n if (!isIdentifierStart(char)) {\n continue;\n }\n let end = index + 1;\n while (isIdentifierPart(text[end])) {\n end += 1;\n }\n last = { start: index, end };\n index = end - 1;\n }\n return last;\n}\n\nfunction findClassBodyOpen(text: string, start: number): number {\n const scanner = createScanner();\n let angleDepth = 0;\n let parenDepth = 0;\n let bracketDepth = 0;\n let braceDepth = 0;\n for (let index = start; index < text.length; index += 1) {\n const nextIndex = scanner.skip(text, index);\n if (nextIndex > index) {\n index = nextIndex - 1;\n continue;\n }\n const char = text[index];\n if (char === \"<\") angleDepth += 1;\n else if (char === \">\") angleDepth = Math.max(0, angleDepth - 1);\n else if (char === \"(\") parenDepth += 1;\n else if (char === \")\") parenDepth = Math.max(0, parenDepth - 1);\n else if (char === \"[\") bracketDepth += 1;\n else if (char === \"]\") bracketDepth = Math.max(0, bracketDepth - 1);\n else if (\n char === \"{\" &&\n angleDepth === 0 &&\n parenDepth === 0 &&\n bracketDepth === 0 &&\n braceDepth === 0\n ) {\n return index;\n } else if (char === \"{\") braceDepth += 1;\n else if (char === \"}\") braceDepth = Math.max(0, braceDepth - 1);\n }\n return -1;\n}\n\nfunction findKeywordOutsideTrivia(text: string, keyword: string): number {\n const scanner = createScanner();\n for (let index = 0; index < text.length; index += 1) {\n const nextIndex = scanner.skip(text, index);\n if (nextIndex > index) {\n index = nextIndex - 1;\n continue;\n }\n if (matchesKeyword(text, keyword, index)) {\n return index;\n }\n }\n return -1;\n}\n\nfunction matchesKeyword(text: string, keyword: string, index: number): boolean {\n return (\n text.startsWith(keyword, index) &&\n !isIdentifierPart(text[index - 1]) &&\n !isIdentifierPart(text[index + keyword.length])\n );\n}\n\nfunction isIdentifierPart(char: string | undefined): boolean {\n return char !== undefined && (isIdentifierStart(char) || /[0-9]/.test(char));\n}\n\nfunction isIdentifierStart(char: string | undefined): boolean {\n return char !== undefined && /[A-Za-z_$]/.test(char);\n}\n\nfunction splitTopLevelRanges(\n text: string,\n delimiter: string,\n): readonly { readonly start: number; readonly end: number }[] {\n const ranges: { start: number; end: number }[] = [];\n const scanner = createScanner();\n let start = 0;\n let angleDepth = 0;\n let parenDepth = 0;\n let bracketDepth = 0;\n let braceDepth = 0;\n for (let index = 0; index < text.length; index += 1) {\n const char = text[index];\n const nextIndex = scanner.skip(text, index);\n if (nextIndex > index) {\n index = nextIndex - 1;\n continue;\n }\n if (char === \"<\") angleDepth += 1;\n else if (char === \">\") angleDepth = Math.max(0, angleDepth - 1);\n else if (char === \"(\") parenDepth += 1;\n else if (char === \")\") parenDepth = Math.max(0, parenDepth - 1);\n else if (char === \"[\") bracketDepth += 1;\n else if (char === \"]\") bracketDepth = Math.max(0, bracketDepth - 1);\n else if (char === \"{\") braceDepth += 1;\n else if (char === \"}\") braceDepth = Math.max(0, braceDepth - 1);\n else if (\n char === delimiter &&\n angleDepth === 0 &&\n parenDepth === 0 &&\n bracketDepth === 0 &&\n braceDepth === 0\n ) {\n ranges.push({ start, end: index });\n start = index + 1;\n }\n }\n ranges.push({ start, end: text.length });\n return ranges;\n}\n\nfunction createScanner(): {\n skip(text: string, index: number): number;\n} {\n let quote: string | undefined;\n let escaped = false;\n let inLineComment = false;\n let inBlockComment = false;\n return {\n skip(text, index) {\n const char = text[index];\n const next = text[index + 1];\n if (inLineComment) {\n if (char === \"\\n\" || char === \"\\r\") {\n inLineComment = false;\n }\n return index + 1;\n }\n if (inBlockComment) {\n if (char === \"*\" && next === \"/\") {\n inBlockComment = false;\n return index + 2;\n }\n return index + 1;\n }\n if (quote) {\n if (escaped) {\n escaped = false;\n } else if (char === \"\\\\\") {\n escaped = true;\n } else if (char === quote) {\n quote = undefined;\n }\n return index + 1;\n }\n if (char === \"/\" && next === \"/\") {\n inLineComment = true;\n return index + 2;\n }\n if (char === \"/\" && next === \"*\") {\n inBlockComment = true;\n return index + 2;\n }\n if (char === '\"' || char === \"'\" || char === \"`\") {\n quote = char;\n return index + 1;\n }\n return index;\n },\n };\n}\n\nfunction isNode(value: unknown): value is Node {\n return typeof value === \"object\" && value !== null && \"type\" in value && \"range\" in value;\n}\n\nfunction filenameFor(\n context: ContextWithParserOptions,\n node: Node | CorsaNode | CorsaType | CorsaSymbol | CorsaSignature,\n): string {\n if (\"fileName\" in node) {\n return node.fileName;\n }\n return context.filename;\n}\n"],"mappings":"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"}
package/dist/context.d.ts CHANGED
@@ -17,7 +17,9 @@ declare function resolveProjectConfig(context: ContextWithParserOptions): Resolv
17
17
  * parserOptions.corsa?.mode;
18
18
  * ```
19
19
  */
20
- declare function resolveTypeAwareParserOptions(context: ContextWithParserOptions): TypeAwareParserOptions;
20
+ declare function resolveTypeAwareParserOptions(context: ContextWithParserOptions, defaults?: {
21
+ readonly projectService?: boolean;
22
+ }): TypeAwareParserOptions;
21
23
  declare function mergeTypeAwareParserOptions(base: TypeAwareParserOptions | undefined, override: TypeAwareParserOptions | undefined): TypeAwareParserOptions;
22
24
  //#endregion
23
25
  export { defaultCorsaExecutable, mergeTypeAwareParserOptions, resolveProjectConfig, resolveTypeAwareParserOptions };
package/dist/context.js CHANGED
@@ -1,4 +1,5 @@
1
- import { existsSync, mkdirSync, writeFileSync } from "node:fs";
1
+ import { createRequire } from "node:module";
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
3
  import { dirname, resolve } from "node:path";
3
4
  //#region src/bindings/nodejs/corsa_oxlint/ts/context.ts
4
5
  const DEFAULT_CACHE_LIFETIME_MS = 250;
@@ -14,7 +15,7 @@ const DEFAULT_TS_CONFIG = { compilerOptions: {
14
15
  strict: true
15
16
  } };
16
17
  function defaultCorsaExecutable(rootDir, platform = process.platform) {
17
- return resolve(rootDir, platform === "win32" ? ".cache/corsa.exe" : ".cache/corsa");
18
+ return resolveNativePreviewExecutable(rootDir) ?? resolve(rootDir, platform === "win32" ? ".cache/corsa.exe" : ".cache/corsa");
18
19
  }
19
20
  function resolveProjectConfig(context) {
20
21
  const filename = resolve(context.filename);
@@ -44,8 +45,8 @@ function resolveProjectConfig(context) {
44
45
  * parserOptions.corsa?.mode;
45
46
  * ```
46
47
  */
47
- function resolveTypeAwareParserOptions(context) {
48
- return mergeTypeAwareParserOptions(resolveSettingsParserOptions(context.settings?.corsaOxlint), mergeTypeAwareParserOptions(context.parserOptions, context.languageOptions?.parserOptions));
48
+ function resolveTypeAwareParserOptions(context, defaults = {}) {
49
+ return applyTypeAwareParserOptionDefaults(mergeTypeAwareParserOptions(resolveSettingsParserOptions(context.settings?.corsaOxlint), mergeTypeAwareParserOptions(context.parserOptions, context.languageOptions?.parserOptions)), defaults);
49
50
  }
50
51
  function resolveRuntimeOptions(rootDir, parserOptions) {
51
52
  const runtime = parserOptions.corsa;
@@ -98,11 +99,44 @@ function globMatch(value, pattern) {
98
99
  function asArray(value) {
99
100
  return value ? Array.isArray(value) ? value : [value] : [];
100
101
  }
102
+ function resolveNativePreviewExecutable(rootDir) {
103
+ const requireFromRoot = createRequire(resolve(rootDir, "package.json"));
104
+ const packageJsonPath = resolveOptional(requireFromRoot, "@typescript/native-preview/package.json");
105
+ if (packageJsonPath) {
106
+ const binPath = nativePreviewBinPath(packageJsonPath);
107
+ if (binPath && existsSync(binPath)) return binPath;
108
+ }
109
+ const packageEntry = resolveOptional(requireFromRoot, "@typescript/native-preview");
110
+ return packageEntry && existsSync(packageEntry) ? packageEntry : void 0;
111
+ }
112
+ function resolveOptional(requireFromRoot, specifier) {
113
+ try {
114
+ return requireFromRoot.resolve(specifier);
115
+ } catch {
116
+ return;
117
+ }
118
+ }
119
+ function nativePreviewBinPath(packageJsonPath) {
120
+ try {
121
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
122
+ const bin = typeof packageJson.bin === "string" ? packageJson.bin : packageJson.bin?.tsgo ?? Object.values(packageJson.bin ?? {})[0];
123
+ return bin ? resolve(dirname(packageJsonPath), bin) : void 0;
124
+ } catch {
125
+ return;
126
+ }
127
+ }
101
128
  function resolveSettingsParserOptions(settings) {
102
129
  if (!settings) return {};
103
130
  const { parserOptions, ...inline } = settings;
104
131
  return mergeTypeAwareParserOptions(inline, parserOptions);
105
132
  }
133
+ function applyTypeAwareParserOptionDefaults(parserOptions, defaults) {
134
+ if (defaults.projectService !== true || parserOptions.projectService !== void 0 || parserOptions.project !== void 0) return parserOptions;
135
+ return {
136
+ ...parserOptions,
137
+ projectService: true
138
+ };
139
+ }
106
140
  function mergeTypeAwareParserOptions(base, override) {
107
141
  if (!base) return normalizeTypeAwareParserOptions(override ?? {});
108
142
  if (!override) return normalizeTypeAwareParserOptions(base);
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","names":[],"sources":["../ts/context.ts"],"sourcesContent":["import { existsSync, mkdirSync, writeFileSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\n\nimport type {\n ContextWithParserOptions,\n CorsaOxlintSettings,\n ProjectServiceOptions,\n ResolvedProjectConfig,\n ResolvedRuntimeOptions,\n TypeAwareParserOptions,\n} from \"./types\";\n\nconst DEFAULT_CACHE_LIFETIME_MS = 250;\nconst DEFAULT_PROJECT_PATTERNS = [\"*.ts\", \"*.tsx\", \"*.js\", \"*.jsx\"];\nconst DEFAULT_TS_CONFIG = {\n compilerOptions: {\n module: \"esnext\",\n target: \"es2022\",\n strict: true,\n },\n};\n\nexport function defaultCorsaExecutable(rootDir: string, platform = process.platform): string {\n return resolve(rootDir, platform === \"win32\" ? \".cache/corsa.exe\" : \".cache/corsa\");\n}\n\nexport function resolveProjectConfig(context: ContextWithParserOptions): ResolvedProjectConfig {\n const filename = resolve(context.filename);\n const parserOptions = resolveTypeAwareParserOptions(context);\n const rootDir = resolve(parserOptions.tsconfigRootDir ?? context.cwd);\n const runtime = resolveRuntimeOptions(rootDir, parserOptions);\n const configPath =\n resolveExplicitProject(rootDir, parserOptions) ??\n discoverTsconfig(filename, rootDir) ??\n resolveDefaultProject(rootDir, filename, parserOptions.projectService);\n if (!configPath) {\n throw new Error(`corsa oxlint could not resolve a tsconfig for ${filename}`);\n }\n return { filename, rootDir, configPath, runtime };\n}\n\n/**\n * Resolves the type-aware parser options visible to a rule.\n *\n * Oxlint exposes a fixed `context.languageOptions.parserOptions` object at\n * runtime, so `corsa oxlint` stores its richer configuration under\n * `settings.corsaOxlint` and rehydrates the rule-facing parser options\n * shape from there.\n *\n * @example\n * ```ts\n * const parserOptions = resolveTypeAwareParserOptions(context);\n * parserOptions.corsa?.mode;\n * ```\n */\nexport function resolveTypeAwareParserOptions(\n context: ContextWithParserOptions,\n): TypeAwareParserOptions {\n return mergeTypeAwareParserOptions(\n resolveSettingsParserOptions(context.settings?.corsaOxlint),\n mergeTypeAwareParserOptions(context.parserOptions, context.languageOptions?.parserOptions),\n );\n}\n\nfunction resolveRuntimeOptions(\n rootDir: string,\n parserOptions: TypeAwareParserOptions,\n): ResolvedRuntimeOptions {\n const runtime = parserOptions.corsa;\n return {\n executable: resolve(\n runtime?.executable ?? process.env.CORSA_EXECUTABLE ?? defaultCorsaExecutable(rootDir),\n ),\n cwd: resolve(runtime?.cwd ?? rootDir),\n mode: runtime?.mode ?? \"msgpack\",\n cacheLifetimeMs: runtime?.cacheLifetimeMs ?? DEFAULT_CACHE_LIFETIME_MS,\n };\n}\n\nfunction resolveExplicitProject(\n rootDir: string,\n parserOptions: TypeAwareParserOptions,\n): string | undefined {\n const projects = asArray(parserOptions.project).map((project) => {\n return resolve(rootDir, project);\n });\n return projects.find(existsSync);\n}\n\nfunction discoverTsconfig(filename: string, rootDir: string): string | undefined {\n let current = dirname(filename);\n const boundary = resolve(rootDir);\n while (current.startsWith(boundary)) {\n const candidate = resolve(current, \"tsconfig.json\");\n if (existsSync(candidate)) {\n return candidate;\n }\n const parent = dirname(current);\n if (parent === current) {\n break;\n }\n current = parent;\n }\n return undefined;\n}\n\nfunction resolveDefaultProject(\n rootDir: string,\n filename: string,\n projectService: boolean | ProjectServiceOptions | undefined,\n): string | undefined {\n if (!projectService) {\n return undefined;\n }\n if (projectService !== true && projectService.defaultProject) {\n return resolve(rootDir, projectService.defaultProject);\n }\n if (!matchesDefaultProject(filename, projectService as true | ProjectServiceOptions)) {\n return undefined;\n }\n const id = Buffer.from(filename).toString(\"hex\").slice(0, 24);\n const cacheDir = resolve(rootDir, \".cache/corsa_oxlint/default\");\n const configPath = resolve(cacheDir, `${id}.tsconfig.json`);\n if (!existsSync(configPath)) {\n mkdirSync(cacheDir, { recursive: true });\n writeFileSync(\n configPath,\n JSON.stringify(\n {\n ...DEFAULT_TS_CONFIG,\n files: [filename],\n },\n null,\n 2,\n ),\n );\n }\n return configPath;\n}\n\nfunction matchesDefaultProject(\n filename: string,\n projectService: true | ProjectServiceOptions,\n): boolean {\n const patterns =\n (projectService === true ? undefined : projectService.allowDefaultProject) ??\n DEFAULT_PROJECT_PATTERNS;\n return patterns.some((pattern: string) => globMatch(filename, pattern));\n}\n\nfunction globMatch(value: string, pattern: string): boolean {\n const escaped = pattern.replaceAll(\".\", \"\\\\.\").replaceAll(\"*\", \".*\");\n return new RegExp(`${escaped}$`).test(value);\n}\n\nfunction asArray(value: string | string[] | undefined): string[] {\n return value ? (Array.isArray(value) ? value : [value]) : [];\n}\n\nfunction resolveSettingsParserOptions(\n settings: CorsaOxlintSettings | undefined,\n): TypeAwareParserOptions {\n if (!settings) {\n return {};\n }\n const { parserOptions, ...inline } = settings;\n return mergeTypeAwareParserOptions(inline, parserOptions);\n}\n\nexport function mergeTypeAwareParserOptions(\n base: TypeAwareParserOptions | undefined,\n override: TypeAwareParserOptions | undefined,\n): TypeAwareParserOptions {\n if (!base) {\n return normalizeTypeAwareParserOptions(override ?? {});\n }\n if (!override) {\n return normalizeTypeAwareParserOptions(base);\n }\n const runtime = {\n ...base.corsa,\n ...override.corsa,\n };\n return {\n ...base,\n ...override,\n project: override.project ?? base.project,\n projectService: mergeProjectService(base.projectService, override.projectService),\n tsconfigRootDir: override.tsconfigRootDir ?? base.tsconfigRootDir,\n ...(Object.keys(runtime).length > 0 ? { corsa: runtime } : {}),\n };\n}\n\nfunction normalizeTypeAwareParserOptions(options: TypeAwareParserOptions): TypeAwareParserOptions {\n const runtime = options.corsa;\n if (!runtime) {\n return options;\n }\n return {\n ...options,\n corsa: runtime,\n };\n}\n\nfunction mergeProjectService(\n base: boolean | ProjectServiceOptions | undefined,\n override: boolean | ProjectServiceOptions | undefined,\n): boolean | ProjectServiceOptions | undefined {\n if (override === undefined) {\n return base;\n }\n if (typeof override === \"boolean\") {\n return override;\n }\n if (base === undefined || typeof base === \"boolean\") {\n return override;\n }\n return {\n ...base,\n ...override,\n allowDefaultProject: override.allowDefaultProject ?? base.allowDefaultProject,\n defaultProject: override.defaultProject ?? base.defaultProject,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"context.js","names":[],"sources":["../ts/context.ts"],"sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { dirname, resolve } from \"node:path\";\n\nimport type {\n ContextWithParserOptions,\n CorsaOxlintSettings,\n ProjectServiceOptions,\n ResolvedProjectConfig,\n ResolvedRuntimeOptions,\n TypeAwareParserOptions,\n} from \"./types\";\n\nconst DEFAULT_CACHE_LIFETIME_MS = 250;\nconst DEFAULT_PROJECT_PATTERNS = [\"*.ts\", \"*.tsx\", \"*.js\", \"*.jsx\"];\nconst DEFAULT_TS_CONFIG = {\n compilerOptions: {\n module: \"esnext\",\n target: \"es2022\",\n strict: true,\n },\n};\n\nexport function defaultCorsaExecutable(rootDir: string, platform = process.platform): string {\n return (\n resolveNativePreviewExecutable(rootDir) ??\n resolve(rootDir, platform === \"win32\" ? \".cache/corsa.exe\" : \".cache/corsa\")\n );\n}\n\nexport function resolveProjectConfig(context: ContextWithParserOptions): ResolvedProjectConfig {\n const filename = resolve(context.filename);\n const parserOptions = resolveTypeAwareParserOptions(context);\n const rootDir = resolve(parserOptions.tsconfigRootDir ?? context.cwd);\n const runtime = resolveRuntimeOptions(rootDir, parserOptions);\n const configPath =\n resolveExplicitProject(rootDir, parserOptions) ??\n discoverTsconfig(filename, rootDir) ??\n resolveDefaultProject(rootDir, filename, parserOptions.projectService);\n if (!configPath) {\n throw new Error(`corsa oxlint could not resolve a tsconfig for ${filename}`);\n }\n return { filename, rootDir, configPath, runtime };\n}\n\n/**\n * Resolves the type-aware parser options visible to a rule.\n *\n * Oxlint exposes a fixed `context.languageOptions.parserOptions` object at\n * runtime, so `corsa oxlint` stores its richer configuration under\n * `settings.corsaOxlint` and rehydrates the rule-facing parser options\n * shape from there.\n *\n * @example\n * ```ts\n * const parserOptions = resolveTypeAwareParserOptions(context);\n * parserOptions.corsa?.mode;\n * ```\n */\nexport function resolveTypeAwareParserOptions(\n context: ContextWithParserOptions,\n defaults: { readonly projectService?: boolean } = {},\n): TypeAwareParserOptions {\n const parserOptions = mergeTypeAwareParserOptions(\n resolveSettingsParserOptions(context.settings?.corsaOxlint),\n mergeTypeAwareParserOptions(context.parserOptions, context.languageOptions?.parserOptions),\n );\n return applyTypeAwareParserOptionDefaults(parserOptions, defaults);\n}\n\nfunction resolveRuntimeOptions(\n rootDir: string,\n parserOptions: TypeAwareParserOptions,\n): ResolvedRuntimeOptions {\n const runtime = parserOptions.corsa;\n return {\n executable: resolve(\n runtime?.executable ?? process.env.CORSA_EXECUTABLE ?? defaultCorsaExecutable(rootDir),\n ),\n cwd: resolve(runtime?.cwd ?? rootDir),\n mode: runtime?.mode ?? \"msgpack\",\n cacheLifetimeMs: runtime?.cacheLifetimeMs ?? DEFAULT_CACHE_LIFETIME_MS,\n };\n}\n\nfunction resolveExplicitProject(\n rootDir: string,\n parserOptions: TypeAwareParserOptions,\n): string | undefined {\n const projects = asArray(parserOptions.project).map((project) => {\n return resolve(rootDir, project);\n });\n return projects.find(existsSync);\n}\n\nfunction discoverTsconfig(filename: string, rootDir: string): string | undefined {\n let current = dirname(filename);\n const boundary = resolve(rootDir);\n while (current.startsWith(boundary)) {\n const candidate = resolve(current, \"tsconfig.json\");\n if (existsSync(candidate)) {\n return candidate;\n }\n const parent = dirname(current);\n if (parent === current) {\n break;\n }\n current = parent;\n }\n return undefined;\n}\n\nfunction resolveDefaultProject(\n rootDir: string,\n filename: string,\n projectService: boolean | ProjectServiceOptions | undefined,\n): string | undefined {\n if (!projectService) {\n return undefined;\n }\n if (projectService !== true && projectService.defaultProject) {\n return resolve(rootDir, projectService.defaultProject);\n }\n if (!matchesDefaultProject(filename, projectService as true | ProjectServiceOptions)) {\n return undefined;\n }\n const id = Buffer.from(filename).toString(\"hex\").slice(0, 24);\n const cacheDir = resolve(rootDir, \".cache/corsa_oxlint/default\");\n const configPath = resolve(cacheDir, `${id}.tsconfig.json`);\n if (!existsSync(configPath)) {\n mkdirSync(cacheDir, { recursive: true });\n writeFileSync(\n configPath,\n JSON.stringify(\n {\n ...DEFAULT_TS_CONFIG,\n files: [filename],\n },\n null,\n 2,\n ),\n );\n }\n return configPath;\n}\n\nfunction matchesDefaultProject(\n filename: string,\n projectService: true | ProjectServiceOptions,\n): boolean {\n const patterns =\n (projectService === true ? undefined : projectService.allowDefaultProject) ??\n DEFAULT_PROJECT_PATTERNS;\n return patterns.some((pattern: string) => globMatch(filename, pattern));\n}\n\nfunction globMatch(value: string, pattern: string): boolean {\n const escaped = pattern.replaceAll(\".\", \"\\\\.\").replaceAll(\"*\", \".*\");\n return new RegExp(`${escaped}$`).test(value);\n}\n\nfunction asArray(value: string | string[] | undefined): string[] {\n return value ? (Array.isArray(value) ? value : [value]) : [];\n}\n\nfunction resolveNativePreviewExecutable(rootDir: string): string | undefined {\n const requireFromRoot = createRequire(resolve(rootDir, \"package.json\"));\n const packageJsonPath = resolveOptional(\n requireFromRoot,\n \"@typescript/native-preview/package.json\",\n );\n if (packageJsonPath) {\n const binPath = nativePreviewBinPath(packageJsonPath);\n if (binPath && existsSync(binPath)) {\n return binPath;\n }\n }\n const packageEntry = resolveOptional(requireFromRoot, \"@typescript/native-preview\");\n return packageEntry && existsSync(packageEntry) ? packageEntry : undefined;\n}\n\nfunction resolveOptional(requireFromRoot: NodeJS.Require, specifier: string): string | undefined {\n try {\n return requireFromRoot.resolve(specifier);\n } catch {\n return undefined;\n }\n}\n\nfunction nativePreviewBinPath(packageJsonPath: string): string | undefined {\n try {\n const packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf8\")) as {\n readonly bin?: string | Record<string, string>;\n };\n const bin =\n typeof packageJson.bin === \"string\"\n ? packageJson.bin\n : (packageJson.bin?.tsgo ?? Object.values(packageJson.bin ?? {})[0]);\n return bin ? resolve(dirname(packageJsonPath), bin) : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction resolveSettingsParserOptions(\n settings: CorsaOxlintSettings | undefined,\n): TypeAwareParserOptions {\n if (!settings) {\n return {};\n }\n const { parserOptions, ...inline } = settings;\n return mergeTypeAwareParserOptions(inline, parserOptions);\n}\n\nfunction applyTypeAwareParserOptionDefaults(\n parserOptions: TypeAwareParserOptions,\n defaults: { readonly projectService?: boolean },\n): TypeAwareParserOptions {\n if (\n defaults.projectService !== true ||\n parserOptions.projectService !== undefined ||\n parserOptions.project !== undefined\n ) {\n return parserOptions;\n }\n return {\n ...parserOptions,\n projectService: true,\n };\n}\n\nexport function mergeTypeAwareParserOptions(\n base: TypeAwareParserOptions | undefined,\n override: TypeAwareParserOptions | undefined,\n): TypeAwareParserOptions {\n if (!base) {\n return normalizeTypeAwareParserOptions(override ?? {});\n }\n if (!override) {\n return normalizeTypeAwareParserOptions(base);\n }\n const runtime = {\n ...base.corsa,\n ...override.corsa,\n };\n return {\n ...base,\n ...override,\n project: override.project ?? base.project,\n projectService: mergeProjectService(base.projectService, override.projectService),\n tsconfigRootDir: override.tsconfigRootDir ?? base.tsconfigRootDir,\n ...(Object.keys(runtime).length > 0 ? { corsa: runtime } : {}),\n };\n}\n\nfunction normalizeTypeAwareParserOptions(options: TypeAwareParserOptions): TypeAwareParserOptions {\n const runtime = options.corsa;\n if (!runtime) {\n return options;\n }\n return {\n ...options,\n corsa: runtime,\n };\n}\n\nfunction mergeProjectService(\n base: boolean | ProjectServiceOptions | undefined,\n override: boolean | ProjectServiceOptions | undefined,\n): boolean | ProjectServiceOptions | undefined {\n if (override === undefined) {\n return base;\n }\n if (typeof override === \"boolean\") {\n return override;\n }\n if (base === undefined || typeof base === \"boolean\") {\n return override;\n }\n return {\n ...base,\n ...override,\n allowDefaultProject: override.allowDefaultProject ?? base.allowDefaultProject,\n defaultProject: override.defaultProject ?? base.defaultProject,\n };\n}\n"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { ast_utils_d_exports } from "./ast_utils.js";
2
- import { ContextWithParserOptions, CorsaNode, CorsaOxlintSettings, CorsaProgramShape, CorsaRuntimeOptions, CorsaSignature, CorsaStylisticSettings, CorsaSymbol, CorsaType, CorsaTypeCheckerShape, ParserServices, ParserServicesWithTypeInformation, ProjectServiceOptions, TypeAwareParserOptions } from "./types.js";
2
+ import { ContextWithParserOptions, CorsaNode, CorsaOxlintSettings, CorsaProgramShape, CorsaRuntimeOptions, CorsaSignature, CorsaStylisticSettings, CorsaSymbol, CorsaType, CorsaTypeCheckerShape, ParserServices, ParserServicesWithTypeInformation, ProjectServiceOptions, SignatureKind, TypeAwareParserOptions } from "./types.js";
3
3
  import { AST_NODE_TYPES, AST_TOKEN_TYPES, TSESTree } from "./compat.js";
4
4
  import { json_schema_d_exports } from "./json_schema.js";
5
5
  import { oxlintCompat, oxlint_compat_d_exports } from "./oxlint_compat.js";
@@ -24,5 +24,5 @@ type ESTree = {
24
24
  [key: string]: unknown;
25
25
  };
26
26
  //#endregion
27
- export { ast_utils_d_exports as ASTUtils, AST_NODE_TYPES, AST_TOKEN_TYPES, type ContextWithParserOptions, type CorsaNode, type CorsaOxlintSettings, type CorsaProgramShape, type CorsaRuntimeOptions, type CorsaSignature, type CorsaStylisticSettings, type CorsaSymbol, type CorsaType, type CorsaTypeCheckerShape, ESLintUtils, ESTree, json_schema_d_exports as JSONSchema, oxlint_compat_d_exports as OxlintCompat, OxlintUtils, type ParserServices, type ParserServicesWithTypeInformation, type Plugin, type ProjectServiceOptions, type Rule, RuleCreator, RuleTester, type RuleTesterConfig, TSESLint, TSESTree, ts_utils_d_exports as TSUtils, type TypeAwareParserOptions, utils_d_exports as Utils, compatPlugin, definePlugin, defineRule, getParserServices, oxlintCompat, index_d_exports as rules, stylistic_d_exports as stylistic };
27
+ export { ast_utils_d_exports as ASTUtils, AST_NODE_TYPES, AST_TOKEN_TYPES, type ContextWithParserOptions, type CorsaNode, type CorsaOxlintSettings, type CorsaProgramShape, type CorsaRuntimeOptions, type CorsaSignature, type CorsaStylisticSettings, type CorsaSymbol, type CorsaType, type CorsaTypeCheckerShape, ESLintUtils, ESTree, json_schema_d_exports as JSONSchema, oxlint_compat_d_exports as OxlintCompat, OxlintUtils, type ParserServices, type ParserServicesWithTypeInformation, type Plugin, type ProjectServiceOptions, type Rule, RuleCreator, RuleTester, type RuleTesterConfig, SignatureKind, TSESLint, TSESTree, ts_utils_d_exports as TSUtils, type TypeAwareParserOptions, utils_d_exports as Utils, compatPlugin, definePlugin, defineRule, getParserServices, oxlintCompat, index_d_exports as rules, stylistic_d_exports as stylistic };
28
28
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { ast_utils_exports } from "./ast_utils.js";
2
+ import { SignatureKind } from "./types.js";
2
3
  import { AST_NODE_TYPES, AST_TOKEN_TYPES, TSESTree } from "./compat.js";
3
4
  import { json_schema_exports } from "./json_schema.js";
4
5
  import { oxlintCompat, oxlint_compat_exports } from "./oxlint_compat.js";
@@ -11,4 +12,4 @@ import { RuleTester } from "./rule_tester.js";
11
12
  import { TSESLint } from "./ts_eslint.js";
12
13
  import { rules_exports } from "./rules/index.js";
13
14
  import { stylistic_exports } from "./stylistic.js";
14
- export { ast_utils_exports as ASTUtils, AST_NODE_TYPES, AST_TOKEN_TYPES, ESLintUtils, json_schema_exports as JSONSchema, oxlint_compat_exports as OxlintCompat, OxlintUtils, RuleCreator, RuleTester, TSESLint, TSESTree, ts_utils_exports as TSUtils, utils_exports as Utils, compatPlugin, definePlugin, defineRule, getParserServices, oxlintCompat, rules_exports as rules, stylistic_exports as stylistic };
15
+ export { ast_utils_exports as ASTUtils, AST_NODE_TYPES, AST_TOKEN_TYPES, ESLintUtils, json_schema_exports as JSONSchema, oxlint_compat_exports as OxlintCompat, OxlintUtils, RuleCreator, RuleTester, SignatureKind, TSESLint, TSESTree, ts_utils_exports as TSUtils, utils_exports as Utils, compatPlugin, definePlugin, defineRule, getParserServices, oxlintCompat, rules_exports as rules, stylistic_exports as stylistic };
@@ -91,6 +91,9 @@ function createEslintTypeChecker(checker, esTreeNodeToTSNodeMap) {
91
91
  getSymbolById(id) {
92
92
  return typeof id === "object" ? id : void 0;
93
93
  },
94
+ getSymbolOfType(type) {
95
+ return callChecker(source, "getSymbolOfType", type) ?? type.symbol;
96
+ },
94
97
  getNode(node) {
95
98
  return typeof node === "object" ? node : void 0;
96
99
  },
@@ -100,14 +103,16 @@ function createEslintTypeChecker(checker, esTreeNodeToTSNodeMap) {
100
103
  getTypeOfSymbol(symbol) {
101
104
  return callChecker(source, "getTypeOfSymbol", symbol);
102
105
  },
106
+ getTypeOfSymbolById() {},
103
107
  getDeclaredTypeOfSymbol(symbol) {
104
108
  return callChecker(source, "getDeclaredTypeOfSymbol", symbol);
105
109
  },
110
+ getDeclaredTypeOfSymbolById() {},
106
111
  getTypeOfSymbolAtLocation(symbol, node) {
107
112
  return callChecker(source, "getTypeOfSymbolAtLocation", symbol, tsNodeFor(node, esTreeNodeToTSNodeMap)) ?? this.getTypeOfSymbol(symbol) ?? this.getDeclaredTypeOfSymbol(symbol);
108
113
  },
109
114
  typeToString(type, enclosingDeclaration, flags) {
110
- return callChecker(source, "typeToString", type, enclosingDeclaration ? tsNodeFor(enclosingDeclaration, esTreeNodeToTSNodeMap) : void 0, flags) ?? fallbackTypeText(type);
115
+ return callChecker(source, "typeToString", type, enclosingDeclaration ? tsNodeFor(enclosingDeclaration, esTreeNodeToTSNodeMap) : void 0, flags) ?? "";
111
116
  },
112
117
  getBaseTypeOfLiteralType(type) {
113
118
  return callChecker(source, "getBaseTypeOfLiteralType", type) ?? type;
@@ -118,6 +123,9 @@ function createEslintTypeChecker(checker, esTreeNodeToTSNodeMap) {
118
123
  getSignaturesOfType(type, kind) {
119
124
  return asReadonlyArray(callChecker(source, "getSignaturesOfType", type, kind));
120
125
  },
126
+ getCallSignatureFacts() {
127
+ return {};
128
+ },
121
129
  getReturnTypeOfSignature(signature) {
122
130
  return callChecker(source, "getReturnTypeOfSignature", signature);
123
131
  },
@@ -125,14 +133,13 @@ function createEslintTypeChecker(checker, esTreeNodeToTSNodeMap) {
125
133
  return callChecker(source, "getTypePredicateOfSignature", signature);
126
134
  },
127
135
  getBaseTypes(type) {
128
- const baseTypes = asReadonlyArray(callChecker(source, "getBaseTypes", type));
129
- return baseTypes.length > 0 ? baseTypes : heritageTypes(type, source, "extends");
136
+ return asReadonlyArray(callChecker(source, "getBaseTypes", type));
130
137
  },
131
138
  getImplementedTypes(node) {
132
- return heritageTypesFromDeclaration(tsNodeFor(node, esTreeNodeToTSNodeMap), source, "implements");
139
+ return asReadonlyArray(callChecker(source, "getImplementedTypes", tsNodeFor(node, esTreeNodeToTSNodeMap)));
133
140
  },
134
141
  getImplementedTypesOfType(type) {
135
- return implementedTypesIncludingBases(type, source);
142
+ return asReadonlyArray(callChecker(source, "getImplementedTypesOfType", type));
136
143
  },
137
144
  getTypeArguments(type) {
138
145
  return asReadonlyArray(callChecker(source, "getTypeArguments", type));
@@ -193,61 +200,6 @@ function tsNodeFor(node, esTreeNodeToTSNodeMap) {
193
200
  function hasNode(esTreeNodeToTSNodeMap, node) {
194
201
  return typeof node === "object" && node !== null && esTreeNodeToTSNodeMap.has(node);
195
202
  }
196
- function fallbackTypeText(type) {
197
- const name = type.name;
198
- return typeof name === "string" || typeof name === "number" || typeof name === "boolean" ? String(name) : "";
199
- }
200
- function heritageTypes(type, checker, keyword) {
201
- return asReadonlyArray(type.symbol?.declarations).flatMap((declaration) => heritageTypesFromDeclaration(declaration, checker, keyword));
202
- }
203
- /**
204
- * Mirrors the tsgo-backed `getImplementedTypesOfType` behaviour by walking the
205
- * base-type chain so a class that implements an interface only through a base
206
- * class still reports that interface. Without this, a rule shared between
207
- * oxlint (tsgo) and ESLint (this `@typescript-eslint` fallback checker) would
208
- * see different implemented types for the same source (GH#207).
209
- *
210
- * The traversal is a DFS so we can use `pop()` (O(1)) instead of a queue with
211
- * `shift()` (O(n)) — visit order doesn't matter because we dedupe implemented
212
- * types by identity. We also `continue` on already-visited bases before
213
- * touching `Set.add`, so a deep diamond hierarchy never quadruples work.
214
- */
215
- function implementedTypesIncludingBases(type, checker) {
216
- if (type === void 0 || type === null) return [];
217
- const visited = /* @__PURE__ */ new Set();
218
- const seenImplemented = /* @__PURE__ */ new Set();
219
- const implemented = [];
220
- const stack = [type];
221
- while (stack.length > 0) {
222
- const current = stack.pop();
223
- if (current === void 0 || current === null || visited.has(current)) continue;
224
- visited.add(current);
225
- const ownImplemented = heritageTypes(current, checker, "implements");
226
- for (let index = 0; index < ownImplemented.length; index += 1) {
227
- const ownType = ownImplemented[index];
228
- if (seenImplemented.has(ownType)) continue;
229
- seenImplemented.add(ownType);
230
- implemented.push(ownType);
231
- }
232
- const directBases = asReadonlyArray(callChecker(checker, "getBaseTypes", current));
233
- const bases = directBases.length > 0 ? directBases : heritageTypes(current, checker, "extends");
234
- for (let index = bases.length - 1; index >= 0; index -= 1) {
235
- const baseType = bases[index];
236
- if (baseType === void 0 || baseType === null || visited.has(baseType)) continue;
237
- stack.push(baseType);
238
- }
239
- }
240
- return implemented;
241
- }
242
- function heritageTypesFromDeclaration(declaration, checker, keyword) {
243
- return asReadonlyArray(declaration.heritageClauses).filter((clause) => heritageClauseText(clause).trimStart().startsWith(keyword)).flatMap((clause) => asReadonlyArray(clause.types)).map((node) => {
244
- return callChecker(checker, "getTypeAtLocation", node.expression ?? node);
245
- }).filter((type) => type !== void 0);
246
- }
247
- function heritageClauseText(clause) {
248
- const getText = clause.getText;
249
- return typeof getText === "function" ? String(getText.call(clause)) : "";
250
- }
251
203
  function resolveEslintParserServices(context) {
252
204
  const candidates = [context.parserServices, context.sourceCode.parserServices];
253
205
  for (const candidate of candidates) if (hasEslintParserServices(candidate)) return candidate;