Skip to content

Commit b2ded73

Browse files
authored
feat(eslint-rules): add base-hook-no-forbidden-runtime rule (#36253)
1 parent b460b14 commit b2ded73

17 files changed

Lines changed: 1215 additions & 0 deletions

File tree

tools/eslint-rules/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ import {
55
rule as consistentCallbackType,
66
} from './rules/consistent-callback-type';
77
import { RULE_NAME as baseHookSignatureName, rule as baseHookSignature } from './rules/base-hook-signature';
8+
import {
9+
RULE_NAME as baseHookNoForbiddenRuntimeName,
10+
rule as baseHookNoForbiddenRuntime,
11+
} from './rules/base-hook-no-forbidden-runtime';
812

913
/**
1014
* Import your custom workspace rules at the top of this file.
@@ -34,6 +38,7 @@ module.exports = {
3438
rules: {
3539
[consistentCallbackTypeName]: consistentCallbackType,
3640
[baseHookSignatureName]: baseHookSignature,
41+
[baseHookNoForbiddenRuntimeName]: baseHookNoForbiddenRuntime,
3742
[noRestrictedGlobalsName]: noRestrictedGlobals,
3843
[noMissingJsxPragmaName]: noMissingJsxPragma,
3944
},
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// Placeholder so the tsconfig has an actual file to anchor the project.
2+
// RuleTester test cases reference filenames inside this directory but their
3+
// content comes from the inline `code` field.
4+
export const dummy = 1;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// Placeholder anchor for typed RuleTester cases. The actual code being linted
2+
// comes from each test's inline `code` field; this file just needs to exist so
3+
// that the fixture tsconfig's Program contains the filename used by tests.
4+
export {};
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { useB } from './b';
2+
import { runHeavy } from 'heavy-runtime';
3+
4+
export function useA(): number {
5+
runHeavy();
6+
return useB() + 1;
7+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { useA } from './a';
2+
3+
export function useB(): number {
4+
// Keep the static import cycle while avoiding direct execution recursion.
5+
return (useA as unknown as () => number).length;
6+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// Cyclic graph where `a` imports a forbidden runtime and `b` reaches it only transitively.
2+
export { useA } from './a';
3+
export { useB } from './b';
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { useB } from './b';
2+
3+
export function useA(): number {
4+
return useB() + 1;
5+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { useA } from './a';
2+
3+
export function useB(): number {
4+
// Pretend lazy ref to break true cycle at runtime; the static graph is cyclic.
5+
return (useA as unknown as () => number).length;
6+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// Cyclic re-export — exercises the cycle-safety of the transitive walk.
2+
export { useA } from './a';
3+
export { useB } from './b';
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export function runHeavy(): { tag: 'heavy' } {
2+
return { tag: 'heavy' };
3+
}
4+
5+
export type HeavyOptions = { kind: 'heavy' };

0 commit comments

Comments
 (0)