corsa-oxlint 0.36.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 (56) hide show
  1. package/dist/_virtual/_rolldown/runtime.js +1 -0
  2. package/dist/checker.js +12 -2
  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/parser_services.js +9 -60
  8. package/dist/parser_services.js.map +1 -1
  9. package/dist/plugin.js +7 -4
  10. package/dist/plugin.js.map +1 -1
  11. package/dist/rules/await_thenable.js +1 -8
  12. package/dist/rules/await_thenable.js.map +1 -1
  13. package/dist/rules/native_bridge.js +131 -268
  14. package/dist/rules/native_bridge.js.map +1 -1
  15. package/dist/rules/no_array_delete.js +1 -6
  16. package/dist/rules/no_array_delete.js.map +1 -1
  17. package/dist/rules/no_base_to_string.js +1 -6
  18. package/dist/rules/no_base_to_string.js.map +1 -1
  19. package/dist/rules/no_floating_promises.js +1 -8
  20. package/dist/rules/no_floating_promises.js.map +1 -1
  21. package/dist/rules/no_for_in_array.js +1 -5
  22. package/dist/rules/no_for_in_array.js.map +1 -1
  23. package/dist/rules/no_implied_eval.js +1 -6
  24. package/dist/rules/no_implied_eval.js.map +1 -1
  25. package/dist/rules/no_meaningless_void_operator.js +1 -6
  26. package/dist/rules/no_meaningless_void_operator.js.map +1 -1
  27. package/dist/rules/no_unsafe_assignment.js +1 -6
  28. package/dist/rules/no_unsafe_assignment.js.map +1 -1
  29. package/dist/rules/no_unsafe_call.js +1 -6
  30. package/dist/rules/no_unsafe_call.js.map +1 -1
  31. package/dist/rules/no_unsafe_member_access.js +1 -6
  32. package/dist/rules/no_unsafe_member_access.js.map +1 -1
  33. package/dist/rules/no_unsafe_return.js +1 -6
  34. package/dist/rules/no_unsafe_return.js.map +1 -1
  35. package/dist/rules/no_unsafe_type_assertion.js +1 -6
  36. package/dist/rules/no_unsafe_type_assertion.js.map +1 -1
  37. package/dist/rules/no_unsafe_unary_minus.js +1 -6
  38. package/dist/rules/no_unsafe_unary_minus.js.map +1 -1
  39. package/dist/rules/only_throw_error.js +1 -9
  40. package/dist/rules/only_throw_error.js.map +1 -1
  41. package/dist/rules/pending_parity.js +34 -60
  42. package/dist/rules/pending_parity.js.map +1 -1
  43. package/dist/rules/prefer_promise_reject_errors.js +1 -9
  44. package/dist/rules/prefer_promise_reject_errors.js.map +1 -1
  45. package/dist/rules/prefer_reduce_type_parameter.js +1 -6
  46. package/dist/rules/prefer_reduce_type_parameter.js.map +1 -1
  47. package/dist/rules/require_array_sort_compare.js +1 -6
  48. package/dist/rules/require_array_sort_compare.js.map +1 -1
  49. package/dist/rules/restrict_plus_operands.js +1 -6
  50. package/dist/rules/restrict_plus_operands.js.map +1 -1
  51. package/dist/session.d.ts +7 -5
  52. package/dist/session.js +66 -239
  53. package/dist/session.js.map +1 -1
  54. package/dist/types.d.ts +14 -1
  55. package/dist/types.js.map +1 -1
  56. 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
@@ -57,9 +57,15 @@ function createTypeChecker(context) {
57
57
  getTypeOfSymbol(symbol) {
58
58
  return sessionForContext(context).session.getTypeOfSymbol(symbol);
59
59
  },
60
+ getTypeOfSymbolById(id) {
61
+ return sessionForContext(context).session.getTypeOfSymbolById(id);
62
+ },
60
63
  getDeclaredTypeOfSymbol(symbol) {
61
64
  return sessionForContext(context).session.getDeclaredTypeOfSymbol(symbol);
62
65
  },
66
+ getDeclaredTypeOfSymbolById(id) {
67
+ return sessionForContext(context).session.getDeclaredTypeOfSymbolById(id);
68
+ },
63
69
  getTypeOfSymbolAtLocation(symbol, node) {
64
70
  return this.getTypeOfSymbol(symbol) ?? this.getDeclaredTypeOfSymbol(symbol) ?? this.getTypeAtLocation(node);
65
71
  },
@@ -75,6 +81,9 @@ function createTypeChecker(context) {
75
81
  getSignaturesOfType(type, kind) {
76
82
  return sessionForContext(context).session.getSignaturesOfType(type, kind);
77
83
  },
84
+ getCallSignatureFacts(type, kind, argumentTypeTexts, explicitTypeArgumentTexts) {
85
+ return sessionForContext(context).session.getCallSignatureFacts(type, kind, argumentTypeTexts, explicitTypeArgumentTexts);
86
+ },
78
87
  getReturnTypeOfSignature(signature) {
79
88
  return sessionForContext(context).session.getReturnTypeOfSignature(signature);
80
89
  },
@@ -263,7 +272,6 @@ function implementedTypesFromSourceText(context, node, sourceText, checker) {
263
272
  const headerText = classText.slice(headerStart, bodyOpen >= 0 ? bodyOpen : classText.length);
264
273
  const implementsIndex = findKeywordOutsideTrivia(headerText, "implements");
265
274
  if (implementsIndex < 0) return [];
266
- const session = sessionForContext(context).session;
267
275
  const clauseText = headerText.slice(implementsIndex + 10);
268
276
  const clauseStart = node.pos + headerStart + implementsIndex + 10;
269
277
  return splitTopLevelRanges(clauseText, ",").map((range) => {
@@ -282,7 +290,9 @@ function implementedTypesFromSourceText(context, node, sourceText, checker) {
282
290
  const nameNode = implementedClauseNameNode(lookupNode, raw);
283
291
  const symbol = checker.getSymbolAtLocation(nameNode) ?? checker.getSymbolAtLocation(lookupNode);
284
292
  const type = symbol ? checker.getDeclaredTypeOfSymbol(symbol) ?? checker.getTypeOfSymbol(symbol) : checker.getTypeAtLocation(nameNode) ?? checker.getTypeAtLocation(lookupNode);
285
- if (type) session.rememberTypeText(type.id, raw.slice(leading, raw.length - trailing));
293
+ if (type) try {
294
+ checker.typeToString(type);
295
+ } catch {}
286
296
  return type;
287
297
  }).filter((type) => type !== void 0);
288
298
  }
@@ -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 { 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 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, 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 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 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 // 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 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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"}
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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"}
@@ -103,14 +103,16 @@ function createEslintTypeChecker(checker, esTreeNodeToTSNodeMap) {
103
103
  getTypeOfSymbol(symbol) {
104
104
  return callChecker(source, "getTypeOfSymbol", symbol);
105
105
  },
106
+ getTypeOfSymbolById() {},
106
107
  getDeclaredTypeOfSymbol(symbol) {
107
108
  return callChecker(source, "getDeclaredTypeOfSymbol", symbol);
108
109
  },
110
+ getDeclaredTypeOfSymbolById() {},
109
111
  getTypeOfSymbolAtLocation(symbol, node) {
110
112
  return callChecker(source, "getTypeOfSymbolAtLocation", symbol, tsNodeFor(node, esTreeNodeToTSNodeMap)) ?? this.getTypeOfSymbol(symbol) ?? this.getDeclaredTypeOfSymbol(symbol);
111
113
  },
112
114
  typeToString(type, enclosingDeclaration, flags) {
113
- 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) ?? "";
114
116
  },
115
117
  getBaseTypeOfLiteralType(type) {
116
118
  return callChecker(source, "getBaseTypeOfLiteralType", type) ?? type;
@@ -121,6 +123,9 @@ function createEslintTypeChecker(checker, esTreeNodeToTSNodeMap) {
121
123
  getSignaturesOfType(type, kind) {
122
124
  return asReadonlyArray(callChecker(source, "getSignaturesOfType", type, kind));
123
125
  },
126
+ getCallSignatureFacts() {
127
+ return {};
128
+ },
124
129
  getReturnTypeOfSignature(signature) {
125
130
  return callChecker(source, "getReturnTypeOfSignature", signature);
126
131
  },
@@ -128,14 +133,13 @@ function createEslintTypeChecker(checker, esTreeNodeToTSNodeMap) {
128
133
  return callChecker(source, "getTypePredicateOfSignature", signature);
129
134
  },
130
135
  getBaseTypes(type) {
131
- const baseTypes = asReadonlyArray(callChecker(source, "getBaseTypes", type));
132
- return baseTypes.length > 0 ? baseTypes : heritageTypes(type, source, "extends");
136
+ return asReadonlyArray(callChecker(source, "getBaseTypes", type));
133
137
  },
134
138
  getImplementedTypes(node) {
135
- return heritageTypesFromDeclaration(tsNodeFor(node, esTreeNodeToTSNodeMap), source, "implements");
139
+ return asReadonlyArray(callChecker(source, "getImplementedTypes", tsNodeFor(node, esTreeNodeToTSNodeMap)));
136
140
  },
137
141
  getImplementedTypesOfType(type) {
138
- return implementedTypesIncludingBases(type, source);
142
+ return asReadonlyArray(callChecker(source, "getImplementedTypesOfType", type));
139
143
  },
140
144
  getTypeArguments(type) {
141
145
  return asReadonlyArray(callChecker(source, "getTypeArguments", type));
@@ -196,61 +200,6 @@ function tsNodeFor(node, esTreeNodeToTSNodeMap) {
196
200
  function hasNode(esTreeNodeToTSNodeMap, node) {
197
201
  return typeof node === "object" && node !== null && esTreeNodeToTSNodeMap.has(node);
198
202
  }
199
- function fallbackTypeText(type) {
200
- const name = type.name;
201
- return typeof name === "string" || typeof name === "number" || typeof name === "boolean" ? String(name) : "";
202
- }
203
- function heritageTypes(type, checker, keyword) {
204
- return asReadonlyArray(type.symbol?.declarations).flatMap((declaration) => heritageTypesFromDeclaration(declaration, checker, keyword));
205
- }
206
- /**
207
- * Mirrors the tsgo-backed `getImplementedTypesOfType` behaviour by walking the
208
- * base-type chain so a class that implements an interface only through a base
209
- * class still reports that interface. Without this, a rule shared between
210
- * oxlint (tsgo) and ESLint (this `@typescript-eslint` fallback checker) would
211
- * see different implemented types for the same source (GH#207).
212
- *
213
- * The traversal is a DFS so we can use `pop()` (O(1)) instead of a queue with
214
- * `shift()` (O(n)) — visit order doesn't matter because we dedupe implemented
215
- * types by identity. We also `continue` on already-visited bases before
216
- * touching `Set.add`, so a deep diamond hierarchy never quadruples work.
217
- */
218
- function implementedTypesIncludingBases(type, checker) {
219
- if (type === void 0 || type === null) return [];
220
- const visited = /* @__PURE__ */ new Set();
221
- const seenImplemented = /* @__PURE__ */ new Set();
222
- const implemented = [];
223
- const stack = [type];
224
- while (stack.length > 0) {
225
- const current = stack.pop();
226
- if (current === void 0 || current === null || visited.has(current)) continue;
227
- visited.add(current);
228
- const ownImplemented = heritageTypes(current, checker, "implements");
229
- for (let index = 0; index < ownImplemented.length; index += 1) {
230
- const ownType = ownImplemented[index];
231
- if (seenImplemented.has(ownType)) continue;
232
- seenImplemented.add(ownType);
233
- implemented.push(ownType);
234
- }
235
- const directBases = asReadonlyArray(callChecker(checker, "getBaseTypes", current));
236
- const bases = directBases.length > 0 ? directBases : heritageTypes(current, checker, "extends");
237
- for (let index = bases.length - 1; index >= 0; index -= 1) {
238
- const baseType = bases[index];
239
- if (baseType === void 0 || baseType === null || visited.has(baseType)) continue;
240
- stack.push(baseType);
241
- }
242
- }
243
- return implemented;
244
- }
245
- function heritageTypesFromDeclaration(declaration, checker, keyword) {
246
- return asReadonlyArray(declaration.heritageClauses).filter((clause) => heritageClauseText(clause).trimStart().startsWith(keyword)).flatMap((clause) => asReadonlyArray(clause.types)).map((node) => {
247
- return callChecker(checker, "getTypeAtLocation", node.expression ?? node);
248
- }).filter((type) => type !== void 0);
249
- }
250
- function heritageClauseText(clause) {
251
- const getText = clause.getText;
252
- return typeof getText === "function" ? String(getText.call(clause)) : "";
253
- }
254
203
  function resolveEslintParserServices(context) {
255
204
  const candidates = [context.parserServices, context.sourceCode.parserServices];
256
205
  for (const candidate of candidates) if (hasEslintParserServices(candidate)) return candidate;
@@ -1 +1 @@
1
- {"version":3,"file":"parser_services.js","names":[],"sources":["../ts/parser_services.ts"],"sourcesContent":["import { createProgram, createTypeChecker } from \"./checker\";\nimport { resolveTypeAwareParserOptions } from \"./context\";\nimport { createNodeMaps } from \"./node_map\";\nimport type {\n ContextWithParserOptions,\n CorsaTypeCheckerShape,\n ParserServices,\n ParserServicesWithTypeInformation,\n} from \"./types\";\n\nconst parserServices = new WeakMap<object, ParserServices>();\n\n/**\n * Returns type-aware parser services backed by Corsa.\n *\n * @example\n * ```ts\n * const services = getParserServices(context);\n * const checker = services.program.getTypeChecker();\n * ```\n */\nexport function getParserServices(\n context: ContextWithParserOptions,\n allowWithoutFullTypeInformation = false,\n): ParserServices {\n const current = parserServices.get(context);\n if (current) {\n return current;\n }\n const parserOptions = resolveTypeAwareParserOptions(context);\n const eslintParserServices = resolveEslintParserServices(context);\n if (!parserOptions.corsa && eslintParserServices) {\n const services = createEslintParserServices(eslintParserServices);\n parserServices.set(context, services);\n return services;\n }\n try {\n const maps = createNodeMaps(context);\n const program = createProgram(context);\n const services: ParserServicesWithTypeInformation = {\n program,\n ...maps,\n hasFullTypeInformation: true,\n getTypeAtLocation(node) {\n return createTypeChecker(context).getTypeAtLocation(node);\n },\n getSymbolAtLocation(node) {\n return createTypeChecker(context).getSymbolAtLocation(node);\n },\n };\n parserServices.set(context, services);\n return services;\n } catch (error) {\n if (!allowWithoutFullTypeInformation) {\n throw error;\n }\n const fallback: ParserServices = {\n program: createProgram(context),\n ...createNodeMaps(context),\n hasFullTypeInformation: false,\n getTypeAtLocation() {\n return undefined;\n },\n getSymbolAtLocation() {\n return undefined;\n },\n };\n parserServices.set(context, fallback);\n return fallback;\n }\n}\n\nfunction createEslintParserServices(\n parserServices: ParserServices,\n): ParserServicesWithTypeInformation {\n const checker = createEslintTypeChecker(\n parserServices.program.getTypeChecker(),\n parserServices.esTreeNodeToTSNodeMap,\n );\n return {\n program: createEslintProgram(parserServices.program, checker),\n esTreeNodeToTSNodeMap: parserServices.esTreeNodeToTSNodeMap,\n tsNodeToESTreeNodeMap: parserServices.tsNodeToESTreeNodeMap,\n hasFullTypeInformation: true,\n getTypeAtLocation(node) {\n const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node);\n return tsNode ? checker.getTypeAtLocation(tsNode) : undefined;\n },\n getSymbolAtLocation(node) {\n const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node);\n return tsNode ? checker.getSymbolAtLocation(tsNode) : undefined;\n },\n };\n}\n\nfunction createEslintProgram(\n program: ParserServices[\"program\"],\n checker: CorsaTypeCheckerShape,\n): ParserServices[\"program\"] {\n return Object.assign(Object.create(program), {\n getTypeChecker() {\n return checker;\n },\n });\n}\n\nfunction createEslintTypeChecker(\n checker: CorsaTypeCheckerShape,\n esTreeNodeToTSNodeMap: ParserServices[\"esTreeNodeToTSNodeMap\"],\n): CorsaTypeCheckerShape {\n const source = checker as unknown as Record<string, unknown>;\n return {\n ...checker,\n getTypeAtLocation(node) {\n return callChecker(source, \"getTypeAtLocation\", tsNodeFor(node, esTreeNodeToTSNodeMap));\n },\n getContextualType(node) {\n return (\n callChecker(source, \"getContextualType\", tsNodeFor(node, esTreeNodeToTSNodeMap)) ??\n this.getTypeAtLocation(node)\n );\n },\n getSymbolAtLocation(node) {\n return callChecker(source, \"getSymbolAtLocation\", tsNodeFor(node, esTreeNodeToTSNodeMap));\n },\n getSymbol(symbol) {\n return typeof symbol === \"object\" ? symbol : undefined;\n },\n getSymbolById(id) {\n return typeof id === \"object\" ? id : undefined;\n },\n getSymbolOfType(type) {\n return (\n callChecker(source, \"getSymbolOfType\", type) ??\n ((type as { readonly symbol?: unknown }).symbol as never)\n );\n },\n getNode(node) {\n return typeof node === \"object\" ? node : undefined;\n },\n getNodeById(id) {\n return typeof id === \"object\" ? id : undefined;\n },\n getTypeOfSymbol(symbol) {\n return callChecker(source, \"getTypeOfSymbol\", symbol);\n },\n getDeclaredTypeOfSymbol(symbol) {\n return callChecker(source, \"getDeclaredTypeOfSymbol\", symbol);\n },\n getTypeOfSymbolAtLocation(symbol, node) {\n return (\n callChecker(\n source,\n \"getTypeOfSymbolAtLocation\",\n symbol,\n tsNodeFor(node, esTreeNodeToTSNodeMap),\n ) ??\n this.getTypeOfSymbol(symbol) ??\n this.getDeclaredTypeOfSymbol(symbol)\n );\n },\n typeToString(type, enclosingDeclaration, flags) {\n return (\n callChecker(\n source,\n \"typeToString\",\n type,\n enclosingDeclaration ? tsNodeFor(enclosingDeclaration, esTreeNodeToTSNodeMap) : undefined,\n flags,\n ) ?? fallbackTypeText(type)\n );\n },\n getBaseTypeOfLiteralType(type) {\n return callChecker(source, \"getBaseTypeOfLiteralType\", type) ?? type;\n },\n getPropertiesOfType(type) {\n return asReadonlyArray(callChecker(source, \"getPropertiesOfType\", type));\n },\n getSignaturesOfType(type, kind) {\n return asReadonlyArray(callChecker(source, \"getSignaturesOfType\", type, kind));\n },\n getReturnTypeOfSignature(signature) {\n return callChecker(source, \"getReturnTypeOfSignature\", signature);\n },\n getTypePredicateOfSignature(signature) {\n return callChecker(source, \"getTypePredicateOfSignature\", signature);\n },\n getBaseTypes(type) {\n const baseTypes = asReadonlyArray(callChecker(source, \"getBaseTypes\", type));\n return baseTypes.length > 0 ? baseTypes : heritageTypes(type, source, \"extends\");\n },\n getImplementedTypes(node) {\n return heritageTypesFromDeclaration(\n tsNodeFor(node, esTreeNodeToTSNodeMap),\n source,\n \"implements\",\n );\n },\n getImplementedTypesOfType(type) {\n return implementedTypesIncludingBases(type, source);\n },\n getTypeArguments(type) {\n return asReadonlyArray(callChecker(source, \"getTypeArguments\", type));\n },\n getTypesOfType(type) {\n return asReadonlyArray((type as { readonly types?: unknown }).types);\n },\n getTargetOfType(type) {\n return (type as { readonly target?: unknown }).target as never;\n },\n getTypeParametersOfType(type) {\n return asReadonlyArray((type as { readonly typeParameters?: unknown }).typeParameters);\n },\n getOuterTypeParametersOfType(type) {\n return asReadonlyArray(\n (type as { readonly outerTypeParameters?: unknown }).outerTypeParameters,\n );\n },\n getLocalTypeParametersOfType(type) {\n return asReadonlyArray(\n (type as { readonly localTypeParameters?: unknown }).localTypeParameters,\n );\n },\n getObjectTypeOfType(type) {\n return (type as { readonly objectType?: unknown }).objectType as never;\n },\n getIndexTypeOfType(type) {\n return (type as { readonly indexType?: unknown }).indexType as never;\n },\n getCheckTypeOfType(type) {\n return (type as { readonly checkType?: unknown }).checkType as never;\n },\n getExtendsTypeOfType(type) {\n return (type as { readonly extendsType?: unknown }).extendsType as never;\n },\n getBaseTypeOfType(type) {\n return (type as { readonly baseType?: unknown }).baseType as never;\n },\n getConstraintOfType(type) {\n return callChecker(source, \"getBaseConstraintOfType\", type);\n },\n isUnionType(type) {\n const value = type as { readonly isUnion?: unknown };\n return typeof value.isUnion === \"function\" ? Boolean(value.isUnion()) : false;\n },\n isIntersectionType(type) {\n const value = type as { readonly isIntersection?: unknown };\n return typeof value.isIntersection === \"function\" ? Boolean(value.isIntersection()) : false;\n },\n } as CorsaTypeCheckerShape;\n}\n\nfunction callChecker(\n checker: Record<string, unknown>,\n method: string,\n ...args: readonly unknown[]\n): never | undefined {\n const candidate = checker[method];\n return typeof candidate === \"function\" ? candidate.apply(checker, args) : undefined;\n}\n\nfunction asReadonlyArray<T>(value: unknown): readonly T[] {\n return Array.isArray(value) ? value : [];\n}\n\nfunction tsNodeFor(\n node: unknown,\n esTreeNodeToTSNodeMap: ParserServices[\"esTreeNodeToTSNodeMap\"],\n): unknown {\n return hasNode(esTreeNodeToTSNodeMap, node) ? esTreeNodeToTSNodeMap.get(node as never) : node;\n}\n\nfunction hasNode(\n esTreeNodeToTSNodeMap: ParserServices[\"esTreeNodeToTSNodeMap\"],\n node: unknown,\n): boolean {\n return typeof node === \"object\" && node !== null && esTreeNodeToTSNodeMap.has(node as never);\n}\n\nfunction fallbackTypeText(type: unknown): string {\n const name = (type as { readonly name?: unknown }).name;\n return typeof name === \"string\" || typeof name === \"number\" || typeof name === \"boolean\"\n ? String(name)\n : \"\";\n}\n\nfunction heritageTypes(\n type: unknown,\n checker: Record<string, unknown>,\n keyword: \"extends\" | \"implements\",\n): readonly never[] {\n const declarations = asReadonlyArray(\n (type as { readonly symbol?: { readonly declarations?: unknown } }).symbol?.declarations,\n );\n return declarations.flatMap((declaration) =>\n heritageTypesFromDeclaration(declaration, checker, keyword),\n );\n}\n\n/**\n * Mirrors the tsgo-backed `getImplementedTypesOfType` behaviour by walking the\n * base-type chain so a class that implements an interface only through a base\n * class still reports that interface. Without this, a rule shared between\n * oxlint (tsgo) and ESLint (this `@typescript-eslint` fallback checker) would\n * see different implemented types for the same source (GH#207).\n *\n * The traversal is a DFS so we can use `pop()` (O(1)) instead of a queue with\n * `shift()` (O(n)) — visit order doesn't matter because we dedupe implemented\n * types by identity. We also `continue` on already-visited bases before\n * touching `Set.add`, so a deep diamond hierarchy never quadruples work.\n */\nfunction implementedTypesIncludingBases(\n type: unknown,\n checker: Record<string, unknown>,\n): readonly never[] {\n if (type === undefined || type === null) {\n return [];\n }\n const visited = new Set<unknown>();\n const seenImplemented = new Set<unknown>();\n const implemented: never[] = [];\n const stack: unknown[] = [type];\n while (stack.length > 0) {\n const current = stack.pop();\n if (current === undefined || current === null || visited.has(current)) {\n continue;\n }\n visited.add(current);\n const ownImplemented = heritageTypes(current, checker, \"implements\");\n for (let index = 0; index < ownImplemented.length; index += 1) {\n const ownType = ownImplemented[index];\n if (seenImplemented.has(ownType)) {\n continue;\n }\n seenImplemented.add(ownType);\n implemented.push(ownType);\n }\n const directBases = asReadonlyArray(callChecker(checker, \"getBaseTypes\", current));\n const bases = directBases.length > 0 ? directBases : heritageTypes(current, checker, \"extends\");\n for (let index = bases.length - 1; index >= 0; index -= 1) {\n const baseType = bases[index];\n if (baseType === undefined || baseType === null || visited.has(baseType)) {\n continue;\n }\n stack.push(baseType);\n }\n }\n return implemented;\n}\n\nfunction heritageTypesFromDeclaration(\n declaration: unknown,\n checker: Record<string, unknown>,\n keyword: \"extends\" | \"implements\",\n): readonly never[] {\n const clauses = asReadonlyArray(\n (declaration as { readonly heritageClauses?: unknown }).heritageClauses,\n );\n return clauses\n .filter((clause) => heritageClauseText(clause).trimStart().startsWith(keyword))\n .flatMap((clause) => asReadonlyArray((clause as { readonly types?: unknown }).types))\n .map((node) => {\n const expression = (node as { readonly expression?: unknown }).expression ?? node;\n return callChecker(checker, \"getTypeAtLocation\", expression);\n })\n .filter((type): type is never => type !== undefined);\n}\n\nfunction heritageClauseText(clause: unknown): string {\n const getText = (clause as { readonly getText?: unknown }).getText;\n return typeof getText === \"function\" ? String(getText.call(clause)) : \"\";\n}\n\nfunction resolveEslintParserServices(\n context: ContextWithParserOptions,\n): ParserServices | undefined {\n const candidates = [context.parserServices, context.sourceCode.parserServices] as const;\n for (const candidate of candidates) {\n if (hasEslintParserServices(candidate)) {\n return candidate;\n }\n }\n return undefined;\n}\n\nfunction hasEslintParserServices(value: unknown): value is ParserServices {\n return Boolean(\n value &&\n typeof value === \"object\" &&\n \"program\" in value &&\n \"esTreeNodeToTSNodeMap\" in value &&\n \"tsNodeToESTreeNodeMap\" in value,\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"parser_services.js","names":[],"sources":["../ts/parser_services.ts"],"sourcesContent":["import { createProgram, createTypeChecker } from \"./checker\";\nimport { resolveTypeAwareParserOptions } from \"./context\";\nimport { createNodeMaps } from \"./node_map\";\nimport type {\n ContextWithParserOptions,\n CorsaTypeCheckerShape,\n ParserServices,\n ParserServicesWithTypeInformation,\n} from \"./types\";\n\nconst parserServices = new WeakMap<object, ParserServices>();\n\n/**\n * Returns type-aware parser services backed by Corsa.\n *\n * @example\n * ```ts\n * const services = getParserServices(context);\n * const checker = services.program.getTypeChecker();\n * ```\n */\nexport function getParserServices(\n context: ContextWithParserOptions,\n allowWithoutFullTypeInformation = false,\n): ParserServices {\n const current = parserServices.get(context);\n if (current) {\n return current;\n }\n const parserOptions = resolveTypeAwareParserOptions(context);\n const eslintParserServices = resolveEslintParserServices(context);\n if (!parserOptions.corsa && eslintParserServices) {\n const services = createEslintParserServices(eslintParserServices);\n parserServices.set(context, services);\n return services;\n }\n try {\n const maps = createNodeMaps(context);\n const program = createProgram(context);\n const services: ParserServicesWithTypeInformation = {\n program,\n ...maps,\n hasFullTypeInformation: true,\n getTypeAtLocation(node) {\n return createTypeChecker(context).getTypeAtLocation(node);\n },\n getSymbolAtLocation(node) {\n return createTypeChecker(context).getSymbolAtLocation(node);\n },\n };\n parserServices.set(context, services);\n return services;\n } catch (error) {\n if (!allowWithoutFullTypeInformation) {\n throw error;\n }\n const fallback: ParserServices = {\n program: createProgram(context),\n ...createNodeMaps(context),\n hasFullTypeInformation: false,\n getTypeAtLocation() {\n return undefined;\n },\n getSymbolAtLocation() {\n return undefined;\n },\n };\n parserServices.set(context, fallback);\n return fallback;\n }\n}\n\nfunction createEslintParserServices(\n parserServices: ParserServices,\n): ParserServicesWithTypeInformation {\n const checker = createEslintTypeChecker(\n parserServices.program.getTypeChecker(),\n parserServices.esTreeNodeToTSNodeMap,\n );\n return {\n program: createEslintProgram(parserServices.program, checker),\n esTreeNodeToTSNodeMap: parserServices.esTreeNodeToTSNodeMap,\n tsNodeToESTreeNodeMap: parserServices.tsNodeToESTreeNodeMap,\n hasFullTypeInformation: true,\n getTypeAtLocation(node) {\n const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node);\n return tsNode ? checker.getTypeAtLocation(tsNode) : undefined;\n },\n getSymbolAtLocation(node) {\n const tsNode = parserServices.esTreeNodeToTSNodeMap.get(node);\n return tsNode ? checker.getSymbolAtLocation(tsNode) : undefined;\n },\n };\n}\n\nfunction createEslintProgram(\n program: ParserServices[\"program\"],\n checker: CorsaTypeCheckerShape,\n): ParserServices[\"program\"] {\n return Object.assign(Object.create(program), {\n getTypeChecker() {\n return checker;\n },\n });\n}\n\nfunction createEslintTypeChecker(\n checker: CorsaTypeCheckerShape,\n esTreeNodeToTSNodeMap: ParserServices[\"esTreeNodeToTSNodeMap\"],\n): CorsaTypeCheckerShape {\n const source = checker as unknown as Record<string, unknown>;\n return {\n ...checker,\n getTypeAtLocation(node) {\n return callChecker(source, \"getTypeAtLocation\", tsNodeFor(node, esTreeNodeToTSNodeMap));\n },\n getContextualType(node) {\n return (\n callChecker(source, \"getContextualType\", tsNodeFor(node, esTreeNodeToTSNodeMap)) ??\n this.getTypeAtLocation(node)\n );\n },\n getSymbolAtLocation(node) {\n return callChecker(source, \"getSymbolAtLocation\", tsNodeFor(node, esTreeNodeToTSNodeMap));\n },\n getSymbol(symbol) {\n return typeof symbol === \"object\" ? symbol : undefined;\n },\n getSymbolById(id) {\n return typeof id === \"object\" ? id : undefined;\n },\n getSymbolOfType(type) {\n return (\n callChecker(source, \"getSymbolOfType\", type) ??\n ((type as { readonly symbol?: unknown }).symbol as never)\n );\n },\n getNode(node) {\n return typeof node === \"object\" ? node : undefined;\n },\n getNodeById(id) {\n return typeof id === \"object\" ? id : undefined;\n },\n getTypeOfSymbol(symbol) {\n return callChecker(source, \"getTypeOfSymbol\", symbol);\n },\n getTypeOfSymbolById() {\n return undefined;\n },\n getDeclaredTypeOfSymbol(symbol) {\n return callChecker(source, \"getDeclaredTypeOfSymbol\", symbol);\n },\n getDeclaredTypeOfSymbolById() {\n return undefined;\n },\n getTypeOfSymbolAtLocation(symbol, node) {\n return (\n callChecker(\n source,\n \"getTypeOfSymbolAtLocation\",\n symbol,\n tsNodeFor(node, esTreeNodeToTSNodeMap),\n ) ??\n this.getTypeOfSymbol(symbol) ??\n this.getDeclaredTypeOfSymbol(symbol)\n );\n },\n typeToString(type, enclosingDeclaration, flags) {\n return (\n callChecker(\n source,\n \"typeToString\",\n type,\n enclosingDeclaration ? tsNodeFor(enclosingDeclaration, esTreeNodeToTSNodeMap) : undefined,\n flags,\n ) ?? \"\"\n );\n },\n getBaseTypeOfLiteralType(type) {\n return callChecker(source, \"getBaseTypeOfLiteralType\", type) ?? type;\n },\n getPropertiesOfType(type) {\n return asReadonlyArray(callChecker(source, \"getPropertiesOfType\", type));\n },\n getSignaturesOfType(type, kind) {\n return asReadonlyArray(callChecker(source, \"getSignaturesOfType\", type, kind));\n },\n getCallSignatureFacts() {\n return {};\n },\n getReturnTypeOfSignature(signature) {\n return callChecker(source, \"getReturnTypeOfSignature\", signature);\n },\n getTypePredicateOfSignature(signature) {\n return callChecker(source, \"getTypePredicateOfSignature\", signature);\n },\n getBaseTypes(type) {\n return asReadonlyArray(callChecker(source, \"getBaseTypes\", type));\n },\n getImplementedTypes(node) {\n return asReadonlyArray(\n callChecker(source, \"getImplementedTypes\", tsNodeFor(node, esTreeNodeToTSNodeMap)),\n );\n },\n getImplementedTypesOfType(type) {\n return asReadonlyArray(callChecker(source, \"getImplementedTypesOfType\", type));\n },\n getTypeArguments(type) {\n return asReadonlyArray(callChecker(source, \"getTypeArguments\", type));\n },\n getTypesOfType(type) {\n return asReadonlyArray((type as { readonly types?: unknown }).types);\n },\n getTargetOfType(type) {\n return (type as { readonly target?: unknown }).target as never;\n },\n getTypeParametersOfType(type) {\n return asReadonlyArray((type as { readonly typeParameters?: unknown }).typeParameters);\n },\n getOuterTypeParametersOfType(type) {\n return asReadonlyArray(\n (type as { readonly outerTypeParameters?: unknown }).outerTypeParameters,\n );\n },\n getLocalTypeParametersOfType(type) {\n return asReadonlyArray(\n (type as { readonly localTypeParameters?: unknown }).localTypeParameters,\n );\n },\n getObjectTypeOfType(type) {\n return (type as { readonly objectType?: unknown }).objectType as never;\n },\n getIndexTypeOfType(type) {\n return (type as { readonly indexType?: unknown }).indexType as never;\n },\n getCheckTypeOfType(type) {\n return (type as { readonly checkType?: unknown }).checkType as never;\n },\n getExtendsTypeOfType(type) {\n return (type as { readonly extendsType?: unknown }).extendsType as never;\n },\n getBaseTypeOfType(type) {\n return (type as { readonly baseType?: unknown }).baseType as never;\n },\n getConstraintOfType(type) {\n return callChecker(source, \"getBaseConstraintOfType\", type);\n },\n isUnionType(type) {\n const value = type as { readonly isUnion?: unknown };\n return typeof value.isUnion === \"function\" ? Boolean(value.isUnion()) : false;\n },\n isIntersectionType(type) {\n const value = type as { readonly isIntersection?: unknown };\n return typeof value.isIntersection === \"function\" ? Boolean(value.isIntersection()) : false;\n },\n } as CorsaTypeCheckerShape;\n}\n\nfunction callChecker(\n checker: Record<string, unknown>,\n method: string,\n ...args: readonly unknown[]\n): never | undefined {\n const candidate = checker[method];\n return typeof candidate === \"function\" ? candidate.apply(checker, args) : undefined;\n}\n\nfunction asReadonlyArray<T>(value: unknown): readonly T[] {\n return Array.isArray(value) ? value : [];\n}\n\nfunction tsNodeFor(\n node: unknown,\n esTreeNodeToTSNodeMap: ParserServices[\"esTreeNodeToTSNodeMap\"],\n): unknown {\n return hasNode(esTreeNodeToTSNodeMap, node) ? esTreeNodeToTSNodeMap.get(node as never) : node;\n}\n\nfunction hasNode(\n esTreeNodeToTSNodeMap: ParserServices[\"esTreeNodeToTSNodeMap\"],\n node: unknown,\n): boolean {\n return typeof node === \"object\" && node !== null && esTreeNodeToTSNodeMap.has(node as never);\n}\n\nfunction resolveEslintParserServices(\n context: ContextWithParserOptions,\n): ParserServices | undefined {\n const candidates = [context.parserServices, context.sourceCode.parserServices] as const;\n for (const candidate of candidates) {\n if (hasEslintParserServices(candidate)) {\n return candidate;\n }\n }\n return undefined;\n}\n\nfunction hasEslintParserServices(value: unknown): value is ParserServices {\n return Boolean(\n value &&\n typeof value === \"object\" &&\n \"program\" in value &&\n \"esTreeNodeToTSNodeMap\" in value &&\n \"tsNodeToESTreeNodeMap\" in value,\n );\n}\n"],"mappings":"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"}
package/dist/plugin.js CHANGED
@@ -35,13 +35,13 @@ function decorateRule(rule) {
35
35
  if (rule.create) return {
36
36
  ...rule,
37
37
  create(context) {
38
- return rule.create(decorateContext(context));
38
+ return rule.create(decorateContext(context, rule));
39
39
  }
40
40
  };
41
41
  if ("createOnce" in rule && typeof rule.createOnce === "function") return {
42
42
  ...rule,
43
43
  createOnce(context) {
44
- return rule.createOnce(decorateContext(context));
44
+ return rule.createOnce(decorateContext(context, rule));
45
45
  }
46
46
  };
47
47
  return rule;
@@ -49,8 +49,8 @@ function decorateRule(rule) {
49
49
  function wrapRules(rules) {
50
50
  return Object.fromEntries(Object.entries(rules).map(([name, rule]) => [name, decorateRule(rule)]));
51
51
  }
52
- function decorateContext(context) {
53
- const parserOptions = Object.freeze(resolveTypeAwareParserOptions(context));
52
+ function decorateContext(context, rule) {
53
+ const parserOptions = Object.freeze(resolveTypeAwareParserOptions(context, { projectService: requiresTypeChecking(rule) }));
54
54
  const baseLanguageOptions = context.languageOptions;
55
55
  const languageOptions = Object.freeze({
56
56
  ...baseLanguageOptions,
@@ -80,6 +80,9 @@ function decorateContext(context) {
80
80
  }
81
81
  });
82
82
  }
83
+ function requiresTypeChecking(rule) {
84
+ return rule.meta?.docs?.requiresTypeChecking === true;
85
+ }
83
86
  //#endregion
84
87
  export { compatPlugin, decorateRule, definePlugin, defineRule };
85
88
 
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","names":[],"sources":["../ts/plugin.ts"],"sourcesContent":["import * as oxlintPluginApi from \"@oxlint/plugins\";\nimport type {\n Context as OxlintContext,\n Plugin as OxlintPlugin,\n Rule as OxlintRule,\n} from \"@oxlint/plugins\";\n\nimport { resolveTypeAwareParserOptions } from \"./context\";\nimport { getParserServices } from \"./parser_services\";\nimport type { ContextWithParserOptions, ParserServices } from \"./types\";\n\nexport type Plugin = Omit<OxlintPlugin, \"rules\"> & {\n readonly rules: Record<string, Rule>;\n} & Record<string, unknown>;\nexport type Rule = OxlintRule & Record<string, unknown>;\n\nconst defineOxlintPlugin = oxlintPluginApi.definePlugin;\nconst defineOxlintRule = oxlintPluginApi.defineRule;\nconst baseCompatPlugin = Reflect.get(\n oxlintPluginApi as object,\n [\"es\", \"lintCompatPlugin\"].join(\"\"),\n) as typeof oxlintPluginApi.definePlugin;\n\nexport function definePlugin(plugin: Plugin): Plugin {\n return defineOxlintPlugin({\n ...plugin,\n rules: wrapRules(plugin.rules ?? {}),\n } as OxlintPlugin) as Plugin;\n}\n\n/**\n * Defines a single Oxlint rule with type-aware parser services.\n *\n * @example\n * ```ts\n * export default defineRule({\n * meta: { schema: [], messages: { demo: \"demo\" } },\n * create(context) {\n * const services = context.parserServices;\n * return {};\n * },\n * });\n * ```\n */\nexport function defineRule(rule: Rule): Rule {\n return defineOxlintRule(decorateRule(rule) as OxlintRule) as Rule;\n}\n\nexport function compatPlugin(plugin: Plugin): Plugin {\n return baseCompatPlugin(definePlugin(plugin)) as Plugin;\n}\n\nexport function decorateRule(rule: Rule): Rule {\n if (rule.create) {\n return {\n ...rule,\n create(context) {\n return rule.create!(decorateContext(context));\n },\n } as Rule;\n }\n if (\"createOnce\" in rule && typeof (rule as any).createOnce === \"function\") {\n return {\n ...rule,\n createOnce(context) {\n return (rule as any).createOnce(decorateContext(context));\n },\n } as Rule;\n }\n return rule;\n}\n\nfunction wrapRules(rules: Record<string, Rule>): Record<string, Rule> {\n return Object.fromEntries(\n Object.entries(rules).map(([name, rule]) => [name, decorateRule(rule)]),\n );\n}\n\nfunction decorateContext(context: ContextWithParserOptions): ContextWithParserOptions {\n const parserOptions = Object.freeze(resolveTypeAwareParserOptions(context));\n const baseLanguageOptions = context.languageOptions;\n const languageOptions = Object.freeze({\n ...baseLanguageOptions,\n parserOptions,\n });\n return Object.create(context as OxlintContext, {\n languageOptions: {\n configurable: true,\n enumerable: true,\n get() {\n return languageOptions;\n },\n },\n parserOptions: {\n configurable: true,\n enumerable: false,\n get() {\n return parserOptions;\n },\n },\n parserServices: {\n configurable: true,\n enumerable: false,\n get(): ParserServices {\n return getParserServices(context);\n },\n },\n }) as ContextWithParserOptions;\n}\n"],"mappings":";;;;AAgBA,MAAM,qBAAqB,gBAAgB;AAC3C,MAAM,mBAAmB,gBAAgB;AACzC,MAAM,mBAAmB,QAAQ,IAC/B,iBACA,CAAC,MAAM,mBAAmB,CAAC,KAAK,GAAG,CACpC;AAED,SAAgB,aAAa,QAAwB;CACnD,OAAO,mBAAmB;EACxB,GAAG;EACH,OAAO,UAAU,OAAO,SAAS,EAAE,CAAC;EACrC,CAAiB;;;;;;;;;;;;;;;;AAiBpB,SAAgB,WAAW,MAAkB;CAC3C,OAAO,iBAAiB,aAAa,KAAK,CAAe;;AAG3D,SAAgB,aAAa,QAAwB;CACnD,OAAO,iBAAiB,aAAa,OAAO,CAAC;;AAG/C,SAAgB,aAAa,MAAkB;CAC7C,IAAI,KAAK,QACP,OAAO;EACL,GAAG;EACH,OAAO,SAAS;GACd,OAAO,KAAK,OAAQ,gBAAgB,QAAQ,CAAC;;EAEhD;CAEH,IAAI,gBAAgB,QAAQ,OAAQ,KAAa,eAAe,YAC9D,OAAO;EACL,GAAG;EACH,WAAW,SAAS;GAClB,OAAQ,KAAa,WAAW,gBAAgB,QAAQ,CAAC;;EAE5D;CAEH,OAAO;;AAGT,SAAS,UAAU,OAAmD;CACpE,OAAO,OAAO,YACZ,OAAO,QAAQ,MAAM,CAAC,KAAK,CAAC,MAAM,UAAU,CAAC,MAAM,aAAa,KAAK,CAAC,CAAC,CACxE;;AAGH,SAAS,gBAAgB,SAA6D;CACpF,MAAM,gBAAgB,OAAO,OAAO,8BAA8B,QAAQ,CAAC;CAC3E,MAAM,sBAAsB,QAAQ;CACpC,MAAM,kBAAkB,OAAO,OAAO;EACpC,GAAG;EACH;EACD,CAAC;CACF,OAAO,OAAO,OAAO,SAA0B;EAC7C,iBAAiB;GACf,cAAc;GACd,YAAY;GACZ,MAAM;IACJ,OAAO;;GAEV;EACD,eAAe;GACb,cAAc;GACd,YAAY;GACZ,MAAM;IACJ,OAAO;;GAEV;EACD,gBAAgB;GACd,cAAc;GACd,YAAY;GACZ,MAAsB;IACpB,OAAO,kBAAkB,QAAQ;;GAEpC;EACF,CAAC"}
1
+ {"version":3,"file":"plugin.js","names":[],"sources":["../ts/plugin.ts"],"sourcesContent":["import * as oxlintPluginApi from \"@oxlint/plugins\";\nimport type {\n Context as OxlintContext,\n Plugin as OxlintPlugin,\n Rule as OxlintRule,\n} from \"@oxlint/plugins\";\n\nimport { resolveTypeAwareParserOptions } from \"./context\";\nimport { getParserServices } from \"./parser_services\";\nimport type { ContextWithParserOptions, ParserServices } from \"./types\";\n\nexport type Plugin = Omit<OxlintPlugin, \"rules\"> & {\n readonly rules: Record<string, Rule>;\n} & Record<string, unknown>;\nexport type Rule = OxlintRule & Record<string, unknown>;\n\nconst defineOxlintPlugin = oxlintPluginApi.definePlugin;\nconst defineOxlintRule = oxlintPluginApi.defineRule;\nconst baseCompatPlugin = Reflect.get(\n oxlintPluginApi as object,\n [\"es\", \"lintCompatPlugin\"].join(\"\"),\n) as typeof oxlintPluginApi.definePlugin;\n\nexport function definePlugin(plugin: Plugin): Plugin {\n return defineOxlintPlugin({\n ...plugin,\n rules: wrapRules(plugin.rules ?? {}),\n } as OxlintPlugin) as Plugin;\n}\n\n/**\n * Defines a single Oxlint rule with type-aware parser services.\n *\n * @example\n * ```ts\n * export default defineRule({\n * meta: { schema: [], messages: { demo: \"demo\" } },\n * create(context) {\n * const services = context.parserServices;\n * return {};\n * },\n * });\n * ```\n */\nexport function defineRule(rule: Rule): Rule {\n return defineOxlintRule(decorateRule(rule) as OxlintRule) as Rule;\n}\n\nexport function compatPlugin(plugin: Plugin): Plugin {\n return baseCompatPlugin(definePlugin(plugin)) as Plugin;\n}\n\nexport function decorateRule(rule: Rule): Rule {\n if (rule.create) {\n return {\n ...rule,\n create(context) {\n return rule.create!(decorateContext(context, rule));\n },\n } as Rule;\n }\n if (\"createOnce\" in rule && typeof (rule as any).createOnce === \"function\") {\n return {\n ...rule,\n createOnce(context) {\n return (rule as any).createOnce(decorateContext(context, rule));\n },\n } as Rule;\n }\n return rule;\n}\n\nfunction wrapRules(rules: Record<string, Rule>): Record<string, Rule> {\n return Object.fromEntries(\n Object.entries(rules).map(([name, rule]) => [name, decorateRule(rule)]),\n );\n}\n\nfunction decorateContext(context: ContextWithParserOptions, rule: Rule): ContextWithParserOptions {\n const parserOptions = Object.freeze(\n resolveTypeAwareParserOptions(context, {\n projectService: requiresTypeChecking(rule),\n }),\n );\n const baseLanguageOptions = context.languageOptions;\n const languageOptions = Object.freeze({\n ...baseLanguageOptions,\n parserOptions,\n });\n return Object.create(context as OxlintContext, {\n languageOptions: {\n configurable: true,\n enumerable: true,\n get() {\n return languageOptions;\n },\n },\n parserOptions: {\n configurable: true,\n enumerable: false,\n get() {\n return parserOptions;\n },\n },\n parserServices: {\n configurable: true,\n enumerable: false,\n get(): ParserServices {\n return getParserServices(context);\n },\n },\n }) as ContextWithParserOptions;\n}\n\nfunction requiresTypeChecking(rule: Rule): boolean {\n return (\n (rule.meta as { readonly docs?: { readonly requiresTypeChecking?: unknown } } | undefined)?.docs\n ?.requiresTypeChecking === true\n );\n}\n"],"mappings":";;;;AAgBA,MAAM,qBAAqB,gBAAgB;AAC3C,MAAM,mBAAmB,gBAAgB;AACzC,MAAM,mBAAmB,QAAQ,IAC/B,iBACA,CAAC,MAAM,mBAAmB,CAAC,KAAK,GAAG,CACpC;AAED,SAAgB,aAAa,QAAwB;CACnD,OAAO,mBAAmB;EACxB,GAAG;EACH,OAAO,UAAU,OAAO,SAAS,EAAE,CAAC;EACrC,CAAiB;;;;;;;;;;;;;;;;AAiBpB,SAAgB,WAAW,MAAkB;CAC3C,OAAO,iBAAiB,aAAa,KAAK,CAAe;;AAG3D,SAAgB,aAAa,QAAwB;CACnD,OAAO,iBAAiB,aAAa,OAAO,CAAC;;AAG/C,SAAgB,aAAa,MAAkB;CAC7C,IAAI,KAAK,QACP,OAAO;EACL,GAAG;EACH,OAAO,SAAS;GACd,OAAO,KAAK,OAAQ,gBAAgB,SAAS,KAAK,CAAC;;EAEtD;CAEH,IAAI,gBAAgB,QAAQ,OAAQ,KAAa,eAAe,YAC9D,OAAO;EACL,GAAG;EACH,WAAW,SAAS;GAClB,OAAQ,KAAa,WAAW,gBAAgB,SAAS,KAAK,CAAC;;EAElE;CAEH,OAAO;;AAGT,SAAS,UAAU,OAAmD;CACpE,OAAO,OAAO,YACZ,OAAO,QAAQ,MAAM,CAAC,KAAK,CAAC,MAAM,UAAU,CAAC,MAAM,aAAa,KAAK,CAAC,CAAC,CACxE;;AAGH,SAAS,gBAAgB,SAAmC,MAAsC;CAChG,MAAM,gBAAgB,OAAO,OAC3B,8BAA8B,SAAS,EACrC,gBAAgB,qBAAqB,KAAK,EAC3C,CAAC,CACH;CACD,MAAM,sBAAsB,QAAQ;CACpC,MAAM,kBAAkB,OAAO,OAAO;EACpC,GAAG;EACH;EACD,CAAC;CACF,OAAO,OAAO,OAAO,SAA0B;EAC7C,iBAAiB;GACf,cAAc;GACd,YAAY;GACZ,MAAM;IACJ,OAAO;;GAEV;EACD,eAAe;GACb,cAAc;GACd,YAAY;GACZ,MAAM;IACJ,OAAO;;GAEV;EACD,gBAAgB;GACd,cAAc;GACd,YAAY;GACZ,MAAsB;IACpB,OAAO,kBAAkB,QAAQ;;GAEpC;EACF,CAAC;;AAGJ,SAAS,qBAAqB,MAAqB;CACjD,OACG,KAAK,MAAsF,MACxF,yBAAyB"}
@@ -1,13 +1,6 @@
1
1
  import { createRustNativeRule } from "./native_bridge.js";
2
2
  //#region src/bindings/nodejs/corsa_oxlint/ts/rules/await_thenable.ts
3
- const awaitThenableRule = createRustNativeRule("await-thenable", {}, {
4
- includePropertyNames: includeAwaitTypeMetadata,
5
- includeTypeTexts: includeAwaitTypeMetadata,
6
- maxDepth: 3
7
- });
8
- function includeAwaitTypeMetadata(_node, depth) {
9
- return depth === 1 || depth === 2;
10
- }
3
+ const awaitThenableRule = createRustNativeRule("await-thenable");
11
4
  //#endregion
12
5
  export { awaitThenableRule };
13
6