Skip to content

Commit 2fdd066

Browse files
authored
Updated documentation (#321)
* chore: Updated package page * chore: Updated main tutorial * chore: Updated support-windows tutorial * chore: Added changeset --------- Co-authored-by: ijlee2 <ijlee2@users.noreply.github.com>
1 parent d119f6d commit 2fdd066

13 files changed

Lines changed: 58 additions & 203 deletions

File tree

.changeset/salty-houses-visit.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"docs-app-for-codemod-utils": minor
3+
---
4+
5+
Addressed breaking changes in @codemod-utils/ast-javascript

docs/src/docs/packages/codemod-utils-ast-javascript.md

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,8 @@ _Utilities for handling `*.{js,ts}` files as abstract syntax tree_
1212
```ts [How to update JavaScript]
1313
import { AST } from '@codemod-utils/ast-javascript';
1414

15-
type Data = {
16-
isTypeScript: boolean;
17-
};
18-
19-
function transform(file: string, data: Data): string {
20-
const traverse = AST.traverse(data.isTypeScript);
15+
function transform(file: string): string {
16+
const traverse = AST.traverse();
2117

2218
const ast = traverse(file, {
2319
/* Use AST.builders to transform the tree */
@@ -43,17 +39,16 @@ In a `traverse` call, you can specify how to visit the nodes of interest ("visit
4339

4440
::: code-group
4541

46-
```ts [Example]{10,21,28}
42+
```ts [Example]{9,20,27}
4743
import { AST } from '@codemod-utils/ast-javascript';
4844

4945
type Data = {
50-
isTypeScript: boolean;
5146
newName: string;
5247
oldName: string;
5348
};
5449

5550
function transform(file: string, data: Data): string {
56-
const traverse = AST.traverse(data.isTypeScript);
51+
const traverse = AST.traverse();
5752

5853
const ast = traverse(file, {
5954
visitCallExpression(path) {
@@ -132,17 +127,16 @@ export default function transformer(code, { recast, parsers }) {
132127
}
133128
```
134129

135-
```ts [Example (Your file)]{13-24}
130+
```ts [Example (Your file)]{12-23}
136131
import { AST } from '@codemod-utils/ast-javascript';
137132

138133
type Data = {
139-
isTypeScript: boolean;
140134
newName: string;
141135
oldName: string;
142136
};
143137

144138
function transform(file: string, data: Data): string {
145-
const traverse = AST.traverse(data.isTypeScript);
139+
const traverse = AST.traverse();
146140

147141
const ast = traverse(file, {
148142
visitCallExpression(path) {

docs/src/docs/tutorials/main-tutorial/05-update-acceptance-tests-part-2.md

Lines changed: 38 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,11 @@ Libraries like [`recast`](https://github.com/benjamn/recast) and [`@glimmer/synt
2828

2929
::: code-group
3030

31-
```ts [How to use @codemod-utils/ast-javascript]{1,8-14}
31+
```ts [How to use @codemod-utils/ast-javascript]{1}
3232
import { AST } from '@codemod-utils/ast-javascript';
3333

34-
type Data = {
35-
isTypeScript: boolean;
36-
};
37-
38-
function transform(file: string, data: Data): string {
39-
const traverse = AST.traverse(data.isTypeScript);
34+
function transform(file: string): string {
35+
const traverse = AST.traverse();
4036

4137
const ast = traverse(file, {
4238
/* Use AST.builders to transform the tree */
@@ -46,7 +42,7 @@ function transform(file: string, data: Data): string {
4642
}
4743
```
4844

49-
```ts [How to use @codemod-utils/ast-template]{1,4-10}
45+
```ts [How to use @codemod-utils/ast-template]{1}
5046
import { AST } from '@codemod-utils/ast-template';
5147

5248
function transform(file: string): string {
@@ -62,7 +58,7 @@ function transform(file: string): string {
6258

6359
:::
6460

65-
Based on the how-to's above, try using `AST` in `renameModule` so that it remains an identity function. That is, define `traverse` (on line 10) so that the input `file` and the returned file have the same value. How will you indicate if the file is written in JavaScript or TypeScript?
61+
Based on the how-to's above, try using `AST` in `renameModule` so that it remains an identity function. That is, define `traverse` (on line 10) so that the input `file` and the returned file have the same value.
6662

6763
<details>
6864

@@ -81,22 +77,16 @@ import { findFiles } from '@codemod-utils/files';
8177

8278
import type { Options } from '../types/index.js';
8379

84-
- function renameModule(file: string): string {
85-
- return file;
86-
- }
87-
+ type Data = {
88-
+ isTypeScript: boolean;
89-
+ };
90-
+
91-
+ function renameModule(file: string, data: Data): string {
92-
+ const traverse = AST.traverse(data.isTypeScript);
80+
function renameModule(file: string): string {
81+
+ const traverse = AST.traverse();
9382
+
9483
+ const ast = traverse(file, {
9584
+ // ...
9685
+ });
9786
+
87+
- return file;
9888
+ return AST.print(ast);
99-
+ }
89+
}
10090

10191
export function renameAcceptanceTests(options: Options): void {
10292
const { projectRoot } = options;
@@ -109,12 +99,7 @@ export function renameAcceptanceTests(options: Options): void {
10999
const oldPath = join(projectRoot, filePath);
110100
const oldFile = readFileSync(oldPath, 'utf8');
111101

112-
- const newFile = renameModule(oldFile);
113-
+ const data = {
114-
+ isTypeScript: filePath.endsWith('.ts'),
115-
+ };
116-
+
117-
+ const newFile = renameModule(oldFile, data);
102+
const newFile = renameModule(oldFile);
118103

119104
writeFileSync(oldPath, newFile, 'utf8');
120105
});
@@ -287,8 +272,6 @@ Use what are highlighted in orange (`path.node.callee` and `path.node.arguments`
287272

288273
<summary>Solution</summary>
289274

290-
An extra check `path.node.arguments[0]!.type !== 'Literal'` is needed for JavaScript files. Apparently, the `type` is `Literal` for JS and `StringLiteral` for TS? 😓
291-
292275
::: code-group
293276

294277
```diff [Transform function]
@@ -309,15 +292,12 @@ export default function transformer(code, { recast, parsers }) {
309292
+ return false;
310293
+ }
311294
+
312-
+ if (
313-
+ path.node.arguments[0]!.type !== 'Literal' &&
314-
+ path.node.arguments[0]!.type !== 'StringLiteral'
315-
+ ) {
316-
+ return false;
295+
- console.log('-- CallExpression --');
296+
- console.log(path.node);
297+
+ if (path.node.arguments[0].type === 'StringLiteral') {
298+
+ console.log('-- CallExpression --');
299+
+ console.log(path.node);
317300
+ }
318-
+
319-
console.log('-- CallExpression --');
320-
console.log(path.node);
321301

322302
return false;
323303
},
@@ -370,16 +350,11 @@ export default function transformer(code, { recast, parsers }) {
370350
return false;
371351
}
372352

373-
if (
374-
path.node.arguments[0]!.type !== 'Literal' &&
375-
path.node.arguments[0]!.type !== 'StringLiteral'
376-
) {
377-
return false;
353+
if (path.node.arguments[0].type === 'StringLiteral') {
354+
- console.log('-- CallExpression --');
355+
- console.log(path.node);
356+
+ path.node.arguments[0] = b.stringLiteral(moduleName);
378357
}
379-
380-
- console.log('-- CallExpression --');
381-
- console.log(path.node);
382-
+ path.node.arguments[0] = b.stringLiteral(moduleName);
383358

384359
return false;
385360
},
@@ -395,77 +370,17 @@ export default function transformer(code, { recast, parsers }) {
395370

396371
</details>
397372

398-
To be precise about types, let's use a `switch` statement and refactor code.
399-
400-
<details>
401-
402-
<summary>Solution</summary>
403-
404-
::: code-group
405-
406-
```diff [Transform function]
407-
export default function transformer(code, { recast, parsers }) {
408-
const ast = recast.parse(code, { parser: parsers.typescript });
409-
const b = recast.types.builders;
410-
411-
const moduleName = 'New name';
412-
413-
recast.visit(ast, {
414-
visitCallExpression(path) {
415-
if (
416-
path.node.callee.type !== 'Identifier' ||
417-
path.node.callee.name !== 'module'
418-
) {
419-
return false;
420-
}
421-
422-
if (path.node.arguments.length !== 2) {
423-
return false;
424-
}
425-
426-
- if (
427-
- path.node.arguments[0]!.type !== 'Literal' &&
428-
- path.node.arguments[0]!.type !== 'StringLiteral'
429-
- ) {
430-
- return false;
431-
- }
432-
-
433-
- path.node.arguments[0] = b.stringLiteral(moduleName);
434-
+ switch (path.node.arguments[0]!.type) {
435-
+ case 'Literal': {
436-
+ path.node.arguments[0] = b.literal(moduleName);
437-
+
438-
+ break;
439-
+ }
440-
+
441-
+ case 'StringLiteral': {
442-
+ path.node.arguments[0] = b.stringLiteral(moduleName);
443-
+
444-
+ break;
445-
+ }
446-
+ }
447-
448-
return false;
449-
},
450-
});
451-
452-
return recast.print(ast).code;
453-
}
454-
```
455-
456-
:::
457-
458-
</details>
459-
460373

461374
## Time to get real
462375

463-
Once you arrive at an implementation in AST Explorer, moving the code to the codemod is trivial. Copy-paste the object with the visit methods, then replace `b.` with `AST.builders.`. (How should we pass `moduleName`?)
376+
Once you arrive at an implementation in AST Explorer, moving the code to the codemod is trivial. Copy-paste the object with the visit methods, then replace `b.` with `AST.builders.`. How should we pass data like `moduleName`?
464377

465378
<details>
466379

467380
<summary>Solution</summary>
468381

382+
To pass data, we use an object. Objects help us maintain and extend code, because they don't create an order dependency among items that don't have a natural order.
383+
469384
::: code-group
470385

471386
```diff [src/steps/rename-acceptance-tests.ts]
@@ -477,13 +392,13 @@ import { findFiles } from '@codemod-utils/files';
477392

478393
import type { Options } from '../types/index.js';
479394

480-
type Data = {
481-
isTypeScript: boolean;
395+
+ type Data = {
482396
+ moduleName: string;
483-
};
484-
485-
function renameModule(file: string, data: Data): string {
486-
const traverse = AST.traverse(data.isTypeScript);
397+
+ };
398+
+
399+
- function renameModule(file: string): string {
400+
+ function renameModule(file: string, data: Data): string {
401+
const traverse = AST.traverse();
487402

488403
const ast = traverse(file, {
489404
- // ...
@@ -494,25 +409,15 @@ function renameModule(file: string, data: Data): string {
494409
+ ) {
495410
+ return false;
496411
+ }
497-
+
412+
+
498413
+ if (path.node.arguments.length !== 2) {
499414
+ return false;
500415
+ }
501-
+
502-
+ switch (path.node.arguments[0]!.type) {
503-
+ case 'Literal': {
504-
+ path.node.arguments[0] = AST.builders.literal(data.moduleName);
505-
+
506-
+ break;
507-
+ }
508-
+
509-
+ case 'StringLiteral': {
510-
+ path.node.arguments[0] = AST.builders.stringLiteral(data.moduleName);
511-
+
512-
+ break;
513-
+ }
416+
+
417+
+ if (path.node.arguments[0]!.type === 'StringLiteral') {
418+
+ path.node.arguments[0] = AST.builders.stringLiteral(data.moduleName);
514419
+ }
515-
+
420+
+
516421
+ return false;
517422
+ },
518423
});
@@ -531,12 +436,12 @@ export function renameAcceptanceTests(options: Options): void {
531436
const oldPath = join(projectRoot, filePath);
532437
const oldFile = readFileSync(oldPath, 'utf8');
533438

534-
const data = {
535-
isTypeScript: filePath.endsWith('.ts'),
439+
+ const data = {
536440
+ moduleName: 'New module',
537-
};
538-
539-
const newFile = renameModule(oldFile, data);
441+
+ };
442+
+
443+
- const newFile = renameModule(oldFile);
444+
+ const newFile = renameModule(oldFile, data);
540445

541446
writeFileSync(oldPath, newFile, 'utf8');
542447
});
@@ -618,7 +523,6 @@ import { AST } from '@codemod-utils/ast-javascript';
618523
import type { Options } from '../types/index.js';
619524
620525
type Data = {
621-
isTypeScript: boolean;
622526
moduleName: string;
623527
};
624528
@@ -650,7 +554,6 @@ export function renameAcceptanceTests(options: Options): void {
650554
const oldFile = readFileSync(oldPath, 'utf8');
651555
652556
const data = {
653-
isTypeScript: filePath.endsWith('.ts'),
654557
- moduleName: 'New module',
655558
+ moduleName: getModuleName(filePath),
656559
};

0 commit comments

Comments
 (0)