/
TSESTreeNode.ts
51 lines (44 loc) · 1.36 KB
/
TSESTreeNode.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
import { AST_NODE_TYPES, TSESTree } from '@typescript-eslint/types';
import { NewPlugin } from 'pretty-format';
import { createIdGenerator } from '../../../src/ID';
const EXCLUDED_KEYS = new Set([
// prevent cycles
'parent',
// type is printed in front of the object
'type',
// locations are just noise
'range',
'loc',
]);
const generator = createIdGenerator();
type Node = Record<string, unknown> & { type: AST_NODE_TYPES };
type Identifier = Node & { name: string; type: AST_NODE_TYPES.Identifier };
const SEEN_NODES = new Map<Node, number>();
const serializer: NewPlugin = {
test(val): boolean {
return !!(
val &&
typeof val === 'object' &&
// make sure it's not one of the classes from the package
Object.getPrototypeOf(val) === Object.prototype &&
'type' in val &&
(val as TSESTree.Node).type in AST_NODE_TYPES
);
},
serialize(node: Node): string {
if (node.type === AST_NODE_TYPES.Identifier) {
return `Identifier<"${(node as Identifier).name}">`;
}
const keys = Object.keys(node).filter(k => !EXCLUDED_KEYS.has(k));
if (keys.length === 0) {
return `${node.type}`;
}
if (SEEN_NODES.has(node)) {
return `${node.type}$${SEEN_NODES.get(node)}`;
}
const id = generator();
SEEN_NODES.set(node, id);
return `${node.type}$${id}`;
},
};
export { serializer };