Skip to content

Commit 7ce86b2

Browse files
committed
add s/const/var jest transformer
1 parent 1130c1c commit 7ce86b2

File tree

1 file changed

+84
-0
lines changed

1 file changed

+84
-0
lines changed

jest/transformers/constReplacer.ts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/**
2+
* This is a transformer which `ts-jest` applies during the compilation process, which switches all of the `const`s out
3+
* for `var`s. Unlike in our package builds, where we do the same substiution for bundle size reasons, here we do it
4+
* because otherwise `const global = getGlobalObject()` throws an error about redifining `global`. (This didn't used to
5+
* be a problem because our down-compilation did the `const`-`var` substitution for us, but now that we're ES6-only, we
6+
* have to do it ourselves.)
7+
*
8+
* Note: If you ever have to change this, and are testing it locally in the process, be sure to call
9+
* `yarn jest --clearCache`
10+
* before each test run, as transformation results are cached between runs.
11+
*/
12+
13+
import {
14+
createVariableDeclarationList,
15+
getCombinedNodeFlags,
16+
isVariableDeclarationList,
17+
Node,
18+
NodeFlags,
19+
SourceFile,
20+
TransformationContext,
21+
Transformer,
22+
TransformerFactory,
23+
visitEachChild,
24+
visitNode,
25+
VisitResult,
26+
} from 'typescript';
27+
28+
// These can be anything - they're just used to construct a cache key for the transformer returned by the factory below.
29+
// This really only matters when you're testing the transformer itself, as changing these values gives you a quick way
30+
// to invalidate the cache and ensure that changes you've made to the code here are immediately picked up on and used.
31+
export const name = 'const-to-var';
32+
export const version = '1.0';
33+
34+
/**
35+
* Check whether the given AST node represents a `const` token.
36+
*
37+
* This function comes from the TS compiler, and is copied here to get around the fact that it's not exported by the
38+
* `typescript` package.
39+
*
40+
* @param node The node to check
41+
* @returns A boolean indicating if the node is a `const` token.
42+
*/
43+
function isVarConst(node: Node): boolean {
44+
// eslint-disable-next-line no-bitwise
45+
return !!(getCombinedNodeFlags(node) & NodeFlags.Const);
46+
}
47+
48+
/**
49+
* Return a set of nested factory functions, which ultimately creates an AST-node visitor function, which can modify
50+
* each visited node as it sees fit, and uses it to walk the AST, returning the results.
51+
*
52+
* In our case, we're modifying all `const` variable declarations to use `var` instead.
53+
*/
54+
export function factory(): TransformerFactory<SourceFile> {
55+
// Create the transformer
56+
function transformerFactory(context: TransformationContext): Transformer<SourceFile> {
57+
// Create a visitor function and use it to walk the AST
58+
function transformer(sourceFile: SourceFile): SourceFile {
59+
// This visitor function can either return a node, in which case the subtree rooted at the returned node is
60+
// substituted for the subtree rooted at the visited node, or can use the recursive `visitEachChild` function
61+
// provided by TS to continue traversing the tree.
62+
function visitor(node: Node): VisitResult<Node> {
63+
// If we've found a `const` declaration, return a `var` declaration in its place
64+
if (isVariableDeclarationList(node) && isVarConst(node)) {
65+
// A declaration list with a `None` flag defaults to using `var`
66+
return createVariableDeclarationList(node.declarations, NodeFlags.None);
67+
}
68+
69+
// This wasn't a node we're interested in, so keep walking down the tree.
70+
return visitEachChild(node, visitor, context);
71+
}
72+
73+
// Having defined our visitor, pass it to the TS-provided `visitNode` function, which will use it to walk the AST,
74+
// and return the results of that walk.
75+
return visitNode(sourceFile, visitor);
76+
}
77+
78+
// Back in the transformer factory, return the transformer we just created
79+
return transformer;
80+
}
81+
82+
// Finally, we're back in `factory`, and can return the whole nested system
83+
return transformerFactory;
84+
}

0 commit comments

Comments
 (0)