diff --git a/apps/oxlint/conformance/src/rule_tester.ts b/apps/oxlint/conformance/src/rule_tester.ts index e7e32d133944c..43f744718fd31 100644 --- a/apps/oxlint/conformance/src/rule_tester.ts +++ b/apps/oxlint/conformance/src/rule_tester.ts @@ -104,7 +104,8 @@ function addBeforeHook(test: T): T { const clonedTest = { ...test }; if (Object.hasOwn(test, "before")) { - const originalBefore = test.before; + // oxlint-disable-next-line typescript/unbound-method - called with `.call` + const originalBefore = test.before as () => void; test.before = function (this) { setCurrentTest(clonedTest); originalBefore!.call(this); diff --git a/apps/oxlint/src-js/cli.ts b/apps/oxlint/src-js/cli.ts index 6474b56057d25..57765bf4ebf83 100644 --- a/apps/oxlint/src-js/cli.ts +++ b/apps/oxlint/src-js/cli.ts @@ -25,19 +25,19 @@ let loadJsConfigs: typeof import("./js_config.ts").loadJsConfigs | null = null; */ function loadPluginWrapper( path: string, - pluginName: string | null, + pluginName: string | null | undefined, pluginNameIsAlias: boolean, - workspaceUri: string | null, + workspaceUri: string | null | undefined, ): Promise { if (loadPlugin === null) { // Use promises here instead of making `loadPluginWrapper` an async function, // to avoid a micro-tick and extra wrapper `Promise` in all later calls to `loadPluginWrapper` return import("./plugins/index.ts").then((mod) => { ({ loadPlugin, lintFile, setupRuleConfigs } = mod); - return loadPlugin(path, pluginName, pluginNameIsAlias, workspaceUri); + return loadPlugin(path, pluginName ?? null, pluginNameIsAlias, workspaceUri ?? null); }); } - return loadPlugin(path, pluginName, pluginNameIsAlias, workspaceUri); + return loadPlugin(path, pluginName ?? null, pluginNameIsAlias, workspaceUri ?? null); } /** @@ -71,12 +71,12 @@ function setupRuleConfigsWrapper(optionsJSON: string): string | null { function lintFileWrapper( filePath: string, bufferId: number, - buffer: Uint8Array | null, + buffer: Uint8Array | null | undefined, ruleIds: number[], optionsIds: number[], settingsJSON: string, globalsJSON: string, - workspaceUri: string | null, + workspaceUri: string | null | undefined, ): string | null { // `lintFileWrapper` is never called without `loadPluginWrapper` being called first, // so `lintFile` must be defined here @@ -84,12 +84,12 @@ function lintFileWrapper( return lintFile( filePath, bufferId, - buffer, + buffer ?? null, ruleIds, optionsIds, settingsJSON, globalsJSON, - workspaceUri, + workspaceUri ?? null, ); } diff --git a/apps/oxlint/src-js/generated/deserialize.d.ts b/apps/oxlint/src-js/generated/deserialize.d.ts index d2815decb03cd..7473511fa3e1a 100644 --- a/apps/oxlint/src-js/generated/deserialize.d.ts +++ b/apps/oxlint/src-js/generated/deserialize.d.ts @@ -2,10 +2,11 @@ // To edit this generated file you have to edit `tasks/ast_tools/src/generators/raw_transfer.rs`. import type { Program } from "./types.d.ts"; +import type { Node, Comment } from "../plugins/types.ts"; import type { Location as SourceLocation } from "../plugins/location.ts"; type BufferWithArrays = Uint8Array & { uint32: Uint32Array; float64: Float64Array }; -type GetLoc = (node: { range: [number, number] }) => SourceLocation; +type GetLoc = (node: Node | Comment) => SourceLocation; export declare function deserializeProgramOnly( buffer: BufferWithArrays, diff --git a/apps/oxlint/src-js/package/rule_tester.ts b/apps/oxlint/src-js/package/rule_tester.ts index f1fe135e314b6..f86c03c783473 100644 --- a/apps/oxlint/src-js/package/rule_tester.ts +++ b/apps/oxlint/src-js/package/rule_tester.ts @@ -41,7 +41,7 @@ type ItFn = ((text: string, fn: () => void) => void) & { only?: ItFn }; * @param method - Test case logic * @returns Returned value of `method` */ -function defaultDescribe(text: string, method: () => R): R { +function defaultDescribe(this: T, text: string, method: (this: T) => R): R { return method.call(this); } @@ -58,7 +58,7 @@ let describe: DescribeFn = * @throws {Error} Any error upon execution of `method` * @returns Returned value of `method` */ -function defaultIt(text: string, method: () => R): R { +function defaultIt(this: T, text: string, method: (this: T) => R): R { try { return method.call(this); } catch (err) { @@ -320,8 +320,8 @@ interface TestCase extends Config { filename?: string; options?: Options; settings?: Settings; - before?: (this: this) => void; - after?: (this: this) => void; + before?(this: this): void; + after?(this: this): void; } /** @@ -1566,6 +1566,7 @@ function getTestName(test: TestCase): string { * @throws {*} - Value thrown by the hook function */ function runBeforeHook(test: TestCase): void { + // oxlint-disable-next-line typescript/unbound-method - bound in `runHook` if (Object.hasOwn(test, "before")) runHook(test, test.before, "before"); } @@ -1576,6 +1577,7 @@ function runBeforeHook(test: TestCase): void { * @throws {*} - Value thrown by the hook function */ function runAfterHook(test: TestCase): void { + // oxlint-disable-next-line typescript/unbound-method - bound in `runHook` if (Object.hasOwn(test, "after")) runHook(test, test.after, "after"); } diff --git a/apps/oxlint/src-js/plugins/cfg.ts b/apps/oxlint/src-js/plugins/cfg.ts index cabc979a8d30c..6ecbe7c1c643d 100644 --- a/apps/oxlint/src-js/plugins/cfg.ts +++ b/apps/oxlint/src-js/plugins/cfg.ts @@ -17,7 +17,7 @@ import { import { ancestors } from "../generated/walk.js"; import { debugAssert, debugAssertIsFunction } from "../utils/asserts.ts"; -import type { EnterExit } from "./visitor.ts"; +import type { CfgVisitFn, EnterExit } from "./visitor.ts"; import type { Node, Program } from "../generated/types.d.ts"; import type { CompiledVisitors } from "../generated/walk.js"; @@ -139,10 +139,10 @@ export function walkProgramWithCfg(ast: Program, visitors: CompiledVisitors): vo // Call method (CFG event). `typeId` is event type ID. debugAssert(Array.isArray(stepData[i]), "`stepData` should contain an array for CFG events"); - const visit = visitors[typeId]; + const visit = visitors[typeId] as CfgVisitFn; if (visit !== null) { debugAssertIsFunction(visit); - visit.apply(undefined, stepData[i]); + visit.apply(undefined, stepData[i] as unknown[]); } } } diff --git a/apps/oxlint/src-js/plugins/visitor.ts b/apps/oxlint/src-js/plugins/visitor.ts index 667ef069b861f..003356eb947e1 100644 --- a/apps/oxlint/src-js/plugins/visitor.ts +++ b/apps/oxlint/src-js/plugins/visitor.ts @@ -98,7 +98,7 @@ import type { Node, Visitor } from "./types.ts"; export type VisitFn = (node: Node) => void; // Visit function for a specific CFG event. -type CfgVisitFn = (...args: unknown[]) => void; +export type CfgVisitFn = (...args: unknown[]) => void; // Enter+exit pair, for non-leaf nodes in compiled visitor. export interface EnterExit { @@ -268,7 +268,7 @@ export function addVisitorToCompiled(visitor: Visitor): void { for (let i = 0; i < keysLen; i++) { let name = keys[i]; - const visitFn = visitor[name]; + const visitFn = visitor[name] as VisitFn; if (typeof visitFn !== "function") { throw new TypeError(`'${name}' property of visitor object is not a function`); } @@ -649,7 +649,7 @@ function mergeCfgVisitFns(visitProps: VisitProp[]): CfgVisitFn { if (numVisitFns === 1) { // Only 1 visit function, so no need to merge debugAssertIsNonNull(visitProps[0].fn); - mergedFn = visitProps[0].fn; + mergedFn = visitProps[0].fn as CfgVisitFn; } else { // No need to sort in order of specificity, because each rule can only have 1 handler for each CFG event @@ -675,7 +675,7 @@ function mergeCfgVisitFns(visitProps: VisitProp[]): CfgVisitFn { debugAssertIsNonNull(visitProps[i].fn); visitFns.push(visitProps[i].fn!); } - mergedFn = merger(...visitFns); + mergedFn = merger(...(visitFns as CfgVisitFn[])); visitFns.length = 0; } diff --git a/apps/oxlint/test/tokens.type_test.ts b/apps/oxlint/test/tokens.type_test.ts index 0a988d3fd03e8..07d491f8af928 100644 --- a/apps/oxlint/test/tokens.type_test.ts +++ b/apps/oxlint/test/tokens.type_test.ts @@ -125,7 +125,7 @@ declare const node: Node; // Options with `filter` only -> `Token[]` { - const opts = { filter: (token: Token) => token.type === "Keyword" }; + const opts = { filter: (token: TokenOrComment) => token.type === "Keyword" }; const result = getTokens(node, opts); true satisfies IsExact; } @@ -277,7 +277,7 @@ declare const node: Node; // Options with `filter` only -> `Token | null` { - const opts = { filter: (token: Token) => token.type === "Keyword" }; + const opts = { filter: (token: TokenOrComment) => token.type === "Keyword" }; const result = getFirstToken(node, opts); true satisfies IsExact; } diff --git a/apps/oxlint/tsconfig.json b/apps/oxlint/tsconfig.json index eebc3169ba29f..295145f4b589c 100644 --- a/apps/oxlint/tsconfig.json +++ b/apps/oxlint/tsconfig.json @@ -6,12 +6,9 @@ "noEmit": true, "target": "ESNext", "allowImportingTsExtensions": true, - "strict": false, - "noImplicitAny": true, - "strictNullChecks": true, + "strict": true, "skipLibCheck": true, - "noUnusedLocals": true, - "useUnknownInCatchVariables": true + "noUnusedLocals": true }, "exclude": ["node_modules", "fixtures", "test/fixtures/*/files", "conformance/submodules"] } diff --git a/tasks/ast_tools/src/generators/raw_transfer.rs b/tasks/ast_tools/src/generators/raw_transfer.rs index 460d826f98cc2..8b05b90f74d0e 100644 --- a/tasks/ast_tools/src/generators/raw_transfer.rs +++ b/tasks/ast_tools/src/generators/raw_transfer.rs @@ -208,10 +208,11 @@ fn generate_deserializers( #[rustfmt::skip] let code_type_definition_linter = " import type { Program } from './types.d.ts'; + import type { Node, Comment } from '../plugins/types.ts'; import type { Location as SourceLocation } from '../plugins/location.ts'; type BufferWithArrays = Uint8Array & { uint32: Uint32Array; float64: Float64Array }; - type GetLoc = (node: { range: [number, number] }) => SourceLocation; + type GetLoc = (node: Node | Comment) => SourceLocation; export declare function deserializeProgramOnly( buffer: BufferWithArrays,