mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 16:47:34 +00:00
perf(lint): avoid unnecessary anti-slop scope construction (#28470)
* perf(lint): construct anti-slop scopes only for relevant expressions * fix(ci): resolve extensionless mobile census entries as files
This commit is contained in:
@@ -30,3 +30,49 @@ index af5f08a5002fb26f94414be13f1ad848ae73d522..eb95ebc44fcb4b4760b2afe097a114cb
|
||||
environment = createTypeAliasEnvironment(
|
||||
node,
|
||||
context.sourceCode.visitorKeys,
|
||||
diff --git a/src/rules/no-widen-then-assert.ts b/src/rules/no-widen-then-assert.ts
|
||||
--- a/src/rules/no-widen-then-assert.ts
|
||||
+++ b/src/rules/no-widen-then-assert.ts
|
||||
@@ -325,11 +325,12 @@
|
||||
},
|
||||
},
|
||||
createOnce(context) {
|
||||
- let scopes: Parameters<typeof resolvedVariableForIdentifier>[0] = [];
|
||||
+ let scopes: Parameters<typeof resolvedVariableForIdentifier>[0] | null = null;
|
||||
|
||||
const checkAssertion = (node: ESTree.TSAsExpression | ESTree.TSTypeAssertion) => {
|
||||
const expression = assertedExpression(node);
|
||||
if (expression.type !== "Identifier") return;
|
||||
+ scopes ??= context.sourceCode.scopeManager.scopes;
|
||||
|
||||
const variable = resolvedVariableForIdentifier(scopes, expression);
|
||||
if (variable === null) return;
|
||||
@@ -357,7 +358,7 @@
|
||||
|
||||
return {
|
||||
Program() {
|
||||
- scopes = context.sourceCode.scopeManager.scopes;
|
||||
+ scopes = null;
|
||||
},
|
||||
TSAsExpression: checkAssertion,
|
||||
TSTypeAssertion: checkAssertion,
|
||||
diff --git a/src/rules/no-module-mocking.ts b/src/rules/no-module-mocking.ts
|
||||
--- a/src/rules/no-module-mocking.ts
|
||||
+++ b/src/rules/no-module-mocking.ts
|
||||
@@ -39,7 +39,6 @@
|
||||
|
||||
function moduleMockCall(sourceCode: SourceCode, callee: ESTree.Expression): boolean {
|
||||
if (!("property" in callee) || !("object" in callee) || !("computed" in callee)) return false;
|
||||
- if (!isTestFrameworkObject(sourceCode, callee.object)) return false;
|
||||
const property = callee.property;
|
||||
const method = callee.computed
|
||||
? property.type === "Literal" &&
|
||||
@@ -51,7 +50,7 @@
|
||||
: property.type === "Identifier"
|
||||
? property.name
|
||||
: null;
|
||||
- return method !== null && moduleMockMethods.has(method);
|
||||
+ return method !== null && moduleMockMethods.has(method) && isTestFrameworkObject(sourceCode, callee.object);
|
||||
}
|
||||
|
||||
/** Ban test framework module mocking in favor of real dependency seams. */
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import { cpSync, mkdtempSync, rmSync } from 'node:fs'
|
||||
import { createRequire } from 'node:module'
|
||||
import path from 'node:path'
|
||||
import { afterAll, expect, it } from 'vitest'
|
||||
import { runOxlintPluginOnSource } from './oxlint-plugin-test-runner.mjs'
|
||||
|
||||
const directory = mkdtempSync(path.join(import.meta.dirname, '.anti-slop-scope-'))
|
||||
const source = path.dirname(createRequire(import.meta.url).resolve('oxlint-plugin-anti-slop'))
|
||||
cpSync(source, directory, { recursive: true })
|
||||
afterAll(() => rmSync(directory, { recursive: true, force: true }))
|
||||
|
||||
function lint(source, rule) {
|
||||
return runOxlintPluginOnSource({
|
||||
pluginName: 'anti-slop',
|
||||
pluginPath: path.join(directory, 'index.ts'),
|
||||
rules: { [`anti-slop/${rule}`]: 'error' },
|
||||
source,
|
||||
extension: 'ts'
|
||||
})
|
||||
}
|
||||
|
||||
it.each([
|
||||
['const value = {}; const wide: unknown = value; wide as { id: string };', 1],
|
||||
['const value = {}; const alias = value; const wide: unknown = alias; <{ id: string }>wide;', 1],
|
||||
['function parse(input: unknown) { return input as { id: string }; }', 0],
|
||||
['const value = {}; let wide: unknown = value; wide as { id: string };', 0],
|
||||
['const value = {}; const wide: unknown = value; function read() { return wide as {}; }', 0],
|
||||
[
|
||||
'const value = {}; const wide: unknown = value; function read(wide: unknown) { return wide as {}; }',
|
||||
0
|
||||
],
|
||||
['const value = {}; const wide: unknown = value; wide as unknown;', 0]
|
||||
])('preserves widening evidence and lexical boundaries: %s', (source, count) => {
|
||||
expect(lint(source, 'no-widen-then-assert')).toHaveLength(count)
|
||||
})
|
||||
|
||||
it.each([
|
||||
["import { vi as test } from 'vitest'; test.mock('module');", 1],
|
||||
["import { jest as test } from '@jest/globals'; test['doMock']('module');", 1],
|
||||
["jest.unstable_mockModule('module', () => ({}));", 1],
|
||||
["vi['mock']('module');", 1],
|
||||
["import { vi } from 'vitest'; vi.mocked(value);", 0],
|
||||
["const unrelated = { mock() {} }; unrelated.mock('module');", 0],
|
||||
["const vi = { mock() {} }; vi.mock('module');", 0],
|
||||
["import { vi as test } from 'vitest'; function run(test) { test.mock('module'); }", 0]
|
||||
])('preserves mock method and owner resolution: %s', (source, count) => {
|
||||
expect(lint(source, 'no-module-mocking')).toHaveLength(count)
|
||||
})
|
||||
@@ -0,0 +1,34 @@
|
||||
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'
|
||||
import { tmpdir } from 'node:os'
|
||||
import path from 'node:path'
|
||||
import { expect, it } from 'vitest'
|
||||
import { mobileWebAppModuleClosure } from './build-mobile-web-app-bundle.mjs'
|
||||
|
||||
it.each(['extensionless', 'explicit', 'absolute'])(
|
||||
'resolves %s census entries against their source tree and prefers web siblings',
|
||||
async (form) => {
|
||||
const directory = mkdtempSync(path.join(tmpdir(), 'orca-mobile-entry-'))
|
||||
const modules = ['app/_layout', 'app/h/_layout', 'app/h/[hostId]/index']
|
||||
const webModules = ['app/_layout.web.tsx', 'app/h/_layout.tsx', 'app/h/[hostId]/index.web.tsx']
|
||||
try {
|
||||
for (const file of [...webModules, 'app/_layout.tsx', 'app/h/[hostId]/index.tsx']) {
|
||||
const target = path.join(directory, file)
|
||||
mkdirSync(path.dirname(target), { recursive: true })
|
||||
writeFileSync(target, 'export const entry = 1')
|
||||
}
|
||||
const entries = modules.map((entry) => {
|
||||
if (form === 'explicit') {
|
||||
return `${entry}.tsx`
|
||||
}
|
||||
if (form === 'absolute') {
|
||||
return path.join(directory, `${entry}.tsx`)
|
||||
}
|
||||
return entry
|
||||
})
|
||||
const { local } = await mobileWebAppModuleClosure(entries, { absWorkingDir: directory })
|
||||
expect(local.map((file) => file.replaceAll('\\', '/')).sort()).toEqual(webModules.sort())
|
||||
} finally {
|
||||
rmSync(directory, { recursive: true, force: true })
|
||||
}
|
||||
}
|
||||
)
|
||||
Generated
+3
-3
@@ -177,7 +177,7 @@ patchedDependencies:
|
||||
lint-staged@16.4.0: 7333b3837f80a7fbd045964db6d76ba4fc118e49134bdbabb00585b6b7b60673
|
||||
monaco-editor@0.55.1: 53b71f7d8a7c00b76ffdb73ce83d18e31692f193f5fafa6a390e48f5b3fdd636
|
||||
node-pty@1.1.0: c2fe19cde7aef223738a7503ae429dd9b03432130b064aa64a601900b33c151f
|
||||
oxlint-plugin-anti-slop@0.1.2: c442be3f300c2d47e98af4c6347fc18cad8c13cc18913c4ee50b3720dad85753
|
||||
oxlint-plugin-anti-slop@0.1.2: c10c871702365a0c2c59e9f1c5fb92df97cae5755d534c0a3d83c6368f6feafe
|
||||
ws@8.22.0: 9393e04dd9a90b01eb7aa35fcd5b1431b5038ce999fbbd82651136193ba51f14
|
||||
|
||||
importers:
|
||||
@@ -514,7 +514,7 @@ importers:
|
||||
version: 1.86.0(oxlint-tsgolint@7.0.2003)
|
||||
oxlint-plugin-anti-slop:
|
||||
specifier: github:dmmulroy/anti-slop#c44ef22ca116d0ba62a3ff663a0bd13a3f3fa40b
|
||||
version: https://codeload.github.com/dmmulroy/anti-slop/tar.gz/c44ef22ca116d0ba62a3ff663a0bd13a3f3fa40b(patch_hash=c442be3f300c2d47e98af4c6347fc18cad8c13cc18913c4ee50b3720dad85753)
|
||||
version: https://codeload.github.com/dmmulroy/anti-slop/tar.gz/c44ef22ca116d0ba62a3ff663a0bd13a3f3fa40b(patch_hash=c10c871702365a0c2c59e9f1c5fb92df97cae5755d534c0a3d83c6368f6feafe)
|
||||
oxlint-plugin-react-doctor:
|
||||
specifier: 0.9.14
|
||||
version: 0.9.14
|
||||
@@ -14171,7 +14171,7 @@ snapshots:
|
||||
'@oxfmt/binding-win32-ia32-msvc': 0.71.0
|
||||
'@oxfmt/binding-win32-x64-msvc': 0.71.0
|
||||
|
||||
oxlint-plugin-anti-slop@https://codeload.github.com/dmmulroy/anti-slop/tar.gz/c44ef22ca116d0ba62a3ff663a0bd13a3f3fa40b(patch_hash=c442be3f300c2d47e98af4c6347fc18cad8c13cc18913c4ee50b3720dad85753):
|
||||
oxlint-plugin-anti-slop@https://codeload.github.com/dmmulroy/anti-slop/tar.gz/c44ef22ca116d0ba62a3ff663a0bd13a3f3fa40b(patch_hash=c10c871702365a0c2c59e9f1c5fb92df97cae5755d534c0a3d83c6368f6feafe):
|
||||
dependencies:
|
||||
'@oxlint/plugins': 1.78.0
|
||||
|
||||
|
||||
Reference in New Issue
Block a user