Skip to content

Commit ebb42a4

Browse files
authored
chore: Unify import management under ImportRequirements for handling required/forbidden symbols (#1843)
chore: Unify import management under ImportRequirements for handling required and forbidden imports
1 parent a3b4717 commit ebb42a4

File tree

11 files changed

+184
-439
lines changed

11 files changed

+184
-439
lines changed

packages/ts-transformers/src/core/assert.ts

Lines changed: 0 additions & 6 deletions
This file was deleted.

packages/ts-transformers/src/core/common-tools-imports.ts

Lines changed: 0 additions & 197 deletions
This file was deleted.
Lines changed: 48 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import ts from "typescript";
2-
import { createImportManager } from "./imports.ts";
3-
import type { ImportManager } from "./imports.ts";
2+
import { ImportRequirements } from "./imports.ts";
43

54
export type TransformMode = "transform" | "error";
65

@@ -9,11 +8,6 @@ export interface TransformationOptions {
98
readonly debug?: boolean;
109
}
1110

12-
export interface TransformationFlags {
13-
jsxExpressionDepth: number;
14-
inJsxAttribute: boolean;
15-
}
16-
1711
export interface TransformationDiagnostic {
1812
readonly type: string;
1913
readonly message: string;
@@ -28,112 +22,61 @@ export interface DiagnosticInput {
2822
readonly node: ts.Node;
2923
}
3024

31-
type FlagValue = TransformationFlags[keyof TransformationFlags];
32-
33-
export interface TransformationContext {
34-
readonly program: ts.Program;
35-
readonly checker: ts.TypeChecker;
36-
readonly factory: ts.NodeFactory;
37-
readonly sourceFile: ts.SourceFile;
38-
readonly options: Required<TransformationOptions>;
39-
readonly imports: ImportManager;
40-
readonly diagnostics: TransformationDiagnostic[];
41-
readonly flags: TransformationFlags;
42-
getType(node: ts.Node): ts.Type;
43-
reportDiagnostic(input: DiagnosticInput): void;
44-
withFlag<T>(
45-
flag: keyof TransformationFlags,
46-
value: FlagValue,
47-
fn: () => T,
48-
): T;
49-
}
50-
5125
const DEFAULT_OPTIONS: Required<TransformationOptions> = {
5226
mode: "transform",
5327
debug: false,
5428
};
5529

56-
function createInitialFlags(): TransformationFlags {
57-
return {
58-
jsxExpressionDepth: 0,
59-
inJsxAttribute: false,
60-
};
30+
export interface TransformationContextConfig {
31+
program: ts.Program;
32+
sourceFile: ts.SourceFile;
33+
transformation: ts.TransformationContext;
34+
options?: TransformationOptions;
35+
imports?: ImportRequirements;
6136
}
6237

63-
export function createTransformationContext(
64-
program: ts.Program,
65-
sourceFile: ts.SourceFile,
66-
transformation: ts.TransformationContext,
67-
options: TransformationOptions = {},
68-
imports: ImportManager = createImportManager(),
69-
): TransformationContext {
70-
const checker = program.getTypeChecker();
71-
const factory = transformation.factory;
72-
const mergedOptions: Required<TransformationOptions> = {
73-
...DEFAULT_OPTIONS,
74-
...options,
75-
};
76-
77-
const typeCache = new Map<ts.Node, ts.Type>();
78-
const diagnostics: TransformationDiagnostic[] = [];
79-
const flags = createInitialFlags();
38+
export class TransformationContext {
39+
readonly program: ts.Program;
40+
readonly checker: ts.TypeChecker;
41+
readonly factory: ts.NodeFactory;
42+
readonly sourceFile: ts.SourceFile;
43+
readonly options: Required<TransformationOptions>;
44+
readonly imports: ImportRequirements;
45+
readonly diagnostics: TransformationDiagnostic[] = [];
46+
#typeCache = new Map<ts.Node, ts.Type>();
8047

81-
const context: TransformationContext = {
82-
program,
83-
checker,
84-
factory,
85-
sourceFile,
86-
options: mergedOptions,
87-
imports,
88-
diagnostics,
89-
flags,
90-
getType(node: ts.Node): ts.Type {
91-
const cached = typeCache.get(node);
92-
if (cached) {
93-
return cached;
94-
}
95-
const type = checker.getTypeAtLocation(node);
96-
typeCache.set(node, type);
97-
return type;
98-
},
99-
reportDiagnostic(input: DiagnosticInput): void {
100-
const location = sourceFile.getLineAndCharacterOfPosition(
101-
input.node.getStart(),
102-
);
103-
diagnostics.push({
104-
type: input.type,
105-
message: input.message,
106-
fileName: sourceFile.fileName,
107-
line: location.line + 1,
108-
column: location.character + 1,
109-
});
110-
},
111-
withFlag<T>(
112-
flag: keyof TransformationFlags,
113-
value: FlagValue,
114-
fn: () => T,
115-
): T {
116-
const key = flag as keyof TransformationFlags;
117-
const previous = flags[key] as FlagValue;
118-
// deno-lint-ignore no-explicit-any
119-
(flags as any)[key] = value;
120-
try {
121-
return fn();
122-
} finally {
123-
// deno-lint-ignore no-explicit-any
124-
(flags as any)[key] = previous;
125-
}
126-
},
127-
};
48+
constructor(config: TransformationContextConfig) {
49+
this.program = config.program;
50+
this.checker = config.program.getTypeChecker();
51+
this.factory = config.transformation.factory;
52+
this.sourceFile = config.sourceFile;
53+
this.imports = config.imports ?? new ImportRequirements();
54+
this.options = {
55+
...DEFAULT_OPTIONS,
56+
...config.options,
57+
};
58+
}
12859

129-
return context;
130-
}
60+
getType(node: ts.Node): ts.Type {
61+
const cached = this.#typeCache.get(node);
62+
if (cached) {
63+
return cached;
64+
}
65+
const type = this.checker.getTypeAtLocation(node);
66+
this.#typeCache.set(node, type);
67+
return type;
68+
}
13169

132-
export function withFlag<T>(
133-
context: TransformationContext,
134-
flag: keyof TransformationFlags,
135-
value: FlagValue,
136-
fn: () => T,
137-
): T {
138-
return context.withFlag(flag, value, fn);
70+
reportDiagnostic(input: DiagnosticInput): void {
71+
const location = this.sourceFile.getLineAndCharacterOfPosition(
72+
input.node.getStart(),
73+
);
74+
this.diagnostics.push({
75+
type: input.type,
76+
message: input.message,
77+
fileName: this.sourceFile.fileName,
78+
line: location.line + 1,
79+
column: location.character + 1,
80+
});
81+
}
13982
}

0 commit comments

Comments
 (0)