-
Notifications
You must be signed in to change notification settings - Fork 220
/
example-plugin-ts.ts
66 lines (57 loc) · 2.42 KB
/
example-plugin-ts.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import ts from 'typescript';
import { Plugin } from 'ts-migrate-server';
import { updateSourceText, SourceTextUpdate } from 'ts-migrate-plugins';
type Options = { shouldReplaceText?: boolean };
const examplePluginTs: Plugin<Options> = {
name: 'example-plugin-ts',
async run({ sourceFile, text, options }) {
// array with source text updates
const updates: SourceTextUpdate[] = [];
const printer = ts.createPrinter();
// get all function decladations from the source file
const functionDeclarations = sourceFile.statements.filter(ts.isFunctionDeclaration);
functionDeclarations.forEach((functionDeclaration) => {
const hasTwoParams = functionDeclaration.parameters.length === 2;
// check if return statement of the function is "x*y"
const multiplierReturn =
functionDeclaration.body &&
functionDeclaration.body.statements.find(
(statement) =>
ts.isReturnStatement(statement) &&
statement.expression &&
ts.isBinaryExpression(statement.expression) &&
statement.expression.operatorToken.kind === ts.SyntaxKind.AsteriskToken,
);
if (options.shouldReplaceText && hasTwoParams && multiplierReturn) {
// create a new function declaration with a new type
const newFunctionDeclaration = ts.createFunctionDeclaration(
functionDeclaration.decorators,
functionDeclaration.modifiers,
functionDeclaration.asteriskToken,
functionDeclaration.name,
functionDeclaration.typeParameters,
functionDeclaration.parameters.map((x) =>
ts.createParameter(
x.decorators,
x.modifiers,
x.dotDotDotToken,
x.name,
x.questionToken,
ts.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword),
x.initializer,
),
),
ts.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword),
functionDeclaration.body,
);
const start = functionDeclaration.pos;
const { end } = functionDeclaration;
// generate a new source text for the function declaration
const text = printer.printNode(ts.EmitHint.Unspecified, newFunctionDeclaration, sourceFile);
updates.push({ kind: 'replace', index: start, length: end - start, text });
}
});
return updateSourceText(text, updates);
},
};
export default examplePluginTs;