0
# Transformer Utilities
1
2
Core utilities for AST manipulation and transformation support, including helper functions for working with TypeScript nodes, creating Closure-compatible constructs, and managing comments during transformation.
3
4
## Capabilities
5
6
### AST Node Utilities
7
8
Functions for checking node properties and extracting information from TypeScript AST nodes.
9
10
```typescript { .api }
11
/**
12
* Checks if declaration has specified modifier flag
13
*/
14
function hasModifierFlag(declaration: ts.Declaration, flag: ts.ModifierFlags): boolean;
15
16
/**
17
* Checks if node is an ambient declaration
18
*/
19
function isAmbient(node: ts.Node): boolean;
20
21
/**
22
* Checks if filename is a TypeScript declaration file
23
*/
24
function isDtsFileName(fileName: string): boolean;
25
26
/**
27
* Gets identifier text from identifier node
28
*/
29
function getIdentifierText(identifier: ts.Identifier): string;
30
31
/**
32
* Gets full text from entity name
33
*/
34
function getEntityNameText(name: ts.EntityName): string;
35
36
/**
37
* Checks if symbol represents a value (not just a type)
38
*/
39
function symbolIsValue(tc: ts.TypeChecker, sym: ts.Symbol): boolean;
40
41
/**
42
* Unescapes TypeScript internal string representation
43
*/
44
function unescapeName(name: ts.__String): string;
45
```
46
47
**Usage Examples:**
48
49
```typescript
50
import { hasModifierFlag, isAmbient, getIdentifierText } from "tsickle";
51
52
// Check if class is exported
53
if (hasModifierFlag(classDecl, ts.ModifierFlags.Export)) {
54
console.log("Class is exported");
55
}
56
57
// Check if declaration is ambient
58
if (isAmbient(node)) {
59
// Handle ambient declaration
60
console.log("Ambient declaration found");
61
}
62
63
// Extract identifier text
64
const name = getIdentifierText(identifier);
65
console.log(`Identifier: ${name}`);
66
```
67
68
### Comment Management
69
70
Functions for creating and managing comments during transformation.
71
72
```typescript { .api }
73
/**
74
* Creates not emitted statement with comments
75
*/
76
function createNotEmittedStatementWithComments(
77
sourceFile: ts.SourceFile,
78
original: ts.Node
79
): ts.Statement;
80
81
/**
82
* Synthesizes comment ranges from parsed comments
83
*/
84
function synthesizeCommentRanges(
85
sourceFile: ts.SourceFile,
86
parsedComments: ts.CommentRange[]
87
): ts.SynthesizedComment[];
88
89
/**
90
* Gets all leading comments for a node
91
*/
92
function getAllLeadingComments(
93
node: ts.Node
94
): ReadonlyArray<Readonly<ts.CommentRange & {text: string}>>;
95
96
/**
97
* Creates single line comment
98
*/
99
function createSingleLineComment(text: string): ts.SynthesizedComment;
100
101
/**
102
* Creates multi line comment
103
*/
104
function createMultiLineComment(text: string): ts.SynthesizedComment;
105
```
106
107
**Usage Examples:**
108
109
```typescript
110
import { createSingleLineComment, getAllLeadingComments } from "tsickle";
111
112
// Create a single line comment
113
const comment = createSingleLineComment("Generated by tsickle");
114
115
// Get all comments from a node
116
const comments = getAllLeadingComments(functionDecl);
117
console.log(`Found ${comments.length} comments`);
118
```
119
120
### String and Literal Utilities
121
122
Functions for creating string literals and handling string representations.
123
124
```typescript { .api }
125
/**
126
* Creates single-quoted string literal
127
*/
128
function createSingleQuoteStringLiteral(text: string): ts.StringLiteral;
129
```
130
131
**Usage Example:**
132
133
```typescript
134
import { createSingleQuoteStringLiteral } from "tsickle";
135
136
// Create a single-quoted string literal
137
const literal = createSingleQuoteStringLiteral("my-module");
138
// Results in: 'my-module'
139
```
140
141
### Google Closure Utilities
142
143
Functions for creating and managing Google Closure-specific constructs.
144
145
```typescript { .api }
146
/**
147
* Creates goog function call expression
148
*/
149
function createGoogCall(
150
fn: string,
151
args?: ts.Expression[]
152
): ts.CallExpression;
153
154
/**
155
* Gets Google Closure function name from call
156
*/
157
function getGoogFunctionName(call: ts.CallExpression): string | undefined;
158
```
159
160
**Usage Examples:**
161
162
```typescript
163
import { createGoogCall, getGoogFunctionName } from "tsickle";
164
165
// Create goog.require call
166
const requireCall = createGoogCall('require', [
167
ts.factory.createStringLiteral('my.module')
168
]);
169
170
// Extract function name from goog call
171
const fnName = getGoogFunctionName(callExpression);
172
if (fnName === 'require') {
173
console.log('Found goog.require call');
174
}
175
```
176
177
### Diagnostic Utilities
178
179
Functions for reporting diagnostics and warnings during transformation.
180
181
```typescript { .api }
182
/**
183
* Reports debug warning
184
*/
185
function reportDebugWarning(
186
host: AnnotatorHost,
187
node: ts.Node,
188
message: string
189
): void;
190
191
/**
192
* Reports diagnostic
193
*/
194
function reportDiagnostic(
195
diagnostics: ts.Diagnostic[],
196
node: ts.Node,
197
message: string,
198
category?: ts.DiagnosticCategory
199
): void;
200
```
201
202
**Usage Examples:**
203
204
```typescript
205
import { reportDebugWarning, reportDiagnostic } from "tsickle";
206
207
// Report a debug warning
208
reportDebugWarning(host, node, "Unsupported TypeScript feature detected");
209
210
// Report an error diagnostic
211
reportDiagnostic(
212
diagnostics,
213
node,
214
"Invalid module syntax",
215
ts.DiagnosticCategory.Error
216
);
217
```
218
219
## Integration with Transformers
220
221
These utilities are designed to work seamlessly with TypeScript's transformer API:
222
223
```typescript
224
// Example transformer using utilities
225
function myTransformer(context: ts.TransformationContext): ts.Transformer<ts.SourceFile> {
226
return (sourceFile: ts.SourceFile) => {
227
function visit(node: ts.Node): ts.Node {
228
// Use utilities for node inspection
229
if (ts.isClassDeclaration(node) && hasModifierFlag(node, ts.ModifierFlags.Export)) {
230
// Add comment to exported classes
231
const comment = createSingleLineComment("Exported class processed by tsickle");
232
// ... transform logic
233
}
234
return ts.visitEachChild(node, visit, context);
235
}
236
return ts.visitNode(sourceFile, visit);
237
};
238
}
239
```
240
241
## Error Handling
242
243
The transformer utilities include robust error handling:
244
245
- **Node validation**: Functions validate input nodes before processing
246
- **Diagnostic reporting**: Built-in diagnostic reporting for transformation issues
247
- **Graceful degradation**: Utilities handle edge cases and malformed AST nodes
248
- **Debug support**: Debug utilities help identify transformation issues
249
250
## Performance Considerations
251
252
These utilities are optimized for performance in large codebases:
253
254
- **Lazy evaluation**: Node properties are computed only when needed
255
- **Caching**: Frequently accessed properties are cached appropriately
256
- **Memory efficiency**: Minimal memory allocation for temporary objects
257
- **TypeScript AST integration**: Direct integration with TypeScript's internal APIs
258
259
## Common Patterns
260
261
### Checking Declaration Types
262
263
```typescript
264
import { hasModifierFlag, isAmbient } from "tsickle";
265
266
function processDeclaration(decl: ts.Declaration) {
267
if (isAmbient(decl)) {
268
// Handle ambient declarations differently
269
return processAmbientDeclaration(decl);
270
}
271
272
if (hasModifierFlag(decl, ts.ModifierFlags.Export)) {
273
// Process exported declarations
274
return processExportedDeclaration(decl);
275
}
276
277
// Handle regular declarations
278
return processRegularDeclaration(decl);
279
}
280
```
281
282
### Working with Identifiers
283
284
```typescript
285
import { getIdentifierText, getEntityNameText } from "tsickle";
286
287
function processIdentifiers(node: ts.Node) {
288
if (ts.isIdentifier(node)) {
289
const name = getIdentifierText(node);
290
console.log(`Processing identifier: ${name}`);
291
} else if (ts.isQualifiedName(node)) {
292
const fullName = getEntityNameText(node);
293
console.log(`Processing qualified name: ${fullName}`);
294
}
295
}
296
```
297
298
### Comment Preservation
299
300
```typescript
301
import { getAllLeadingComments, createMultiLineComment } from "tsickle";
302
303
function preserveComments(originalNode: ts.Node, transformedNode: ts.Node): ts.Node {
304
const comments = getAllLeadingComments(originalNode);
305
if (comments.length > 0) {
306
// Preserve original comments on transformed node
307
const preservedComment = createMultiLineComment(
308
"Original comments preserved during transformation"
309
);
310
// Attach to transformed node...
311
}
312
return transformedNode;
313
}
314
```