forked from javascript-obfuscator/javascript-obfuscator
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTransformersRunner.ts
More file actions
123 lines (97 loc) · 4.09 KB
/
Copy pathTransformersRunner.ts
File metadata and controls
123 lines (97 loc) · 4.09 KB
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import { inject, injectable } from 'inversify';
import { ServiceIdentifiers } from '../container/ServiceIdentifiers';
import * as estraverse from 'estraverse';
import * as ESTree from 'estree';
import { TNodeTransformerFactory } from '../types/container/node-transformers/TNodeTransformerFactory';
import { TVisitorDirection } from '../types/node-transformers/TVisitorDirection';
import { TVisitorFunction } from '../types/node-transformers/TVisitorFunction';
import { TVisitorResult } from '../types/node-transformers/TVisitorResult';
import { ITransformersRunner } from '../interfaces/node-transformers/ITransformersRunner';
import { IVisitor } from '../interfaces/node-transformers/IVisitor';
import { NodeTransformer } from '../enums/node-transformers/NodeTransformer';
import { TransformationStage } from '../enums/node-transformers/TransformationStage';
import { VisitorDirection } from '../enums/node-transformers/VisitorDirection';
import { NodeGuards } from '../node/NodeGuards';
import { NodeMetadata } from '../node/NodeMetadata';
@injectable()
export class TransformersRunner implements ITransformersRunner {
/**
* @type {TNodeTransformerFactory}
*/
private readonly nodeTransformerFactory: TNodeTransformerFactory;
/**
* @param {TNodeTransformerFactory} nodeTransformerFactory
*/
constructor (
@inject(ServiceIdentifiers.Factory__INodeTransformer) nodeTransformerFactory: TNodeTransformerFactory,
) {
this.nodeTransformerFactory = nodeTransformerFactory;
}
/**
* @param {T} astTree
* @param {NodeTransformer[]} nodeTransformers
* @param {TransformationStage} transformationStage
* @returns {T}
*/
public transform <T extends ESTree.Node = ESTree.Program> (
astTree: T,
nodeTransformers: NodeTransformer[],
transformationStage: TransformationStage
): T {
if (!nodeTransformers.length) {
return astTree;
}
const enterVisitors: IVisitor[] = [];
const leaveVisitors: IVisitor[] = [];
const nodeTransformersLength: number = nodeTransformers.length;
let visitor: IVisitor | null;
for (let i: number = 0; i < nodeTransformersLength; i++) {
visitor = this.nodeTransformerFactory(nodeTransformers[i]).getVisitor(transformationStage);
if (!visitor) {
continue;
}
if (visitor.enter) {
enterVisitors.push({ enter: visitor.enter });
}
if (visitor.leave) {
leaveVisitors.push({ leave: visitor.leave });
}
}
if (!enterVisitors.length && !leaveVisitors.length) {
return astTree;
}
estraverse.replace(astTree, {
enter: this.mergeVisitorsForDirection(enterVisitors, VisitorDirection.Enter),
leave: this.mergeVisitorsForDirection(leaveVisitors, VisitorDirection.Leave)
});
return astTree;
}
/**
* @param {IVisitor[]} visitors
* @param {TVisitorDirection} direction
* @returns {TVisitorFunction}
*/
private mergeVisitorsForDirection (visitors: IVisitor[], direction: TVisitorDirection): TVisitorFunction {
const visitorsLength: number = visitors.length;
if (!visitorsLength) {
return (node: ESTree.Node, parentNode: ESTree.Node | null) => node;
}
return (node: ESTree.Node, parentNode: ESTree.Node | null) => {
if (NodeMetadata.isIgnoredNode(node)) {
return estraverse.VisitorOption.Skip;
}
for (let i: number = 0; i < visitorsLength; i++) {
const visitorFunction: TVisitorFunction | undefined = visitors[i][direction];
if (!visitorFunction) {
continue;
}
const visitorResult: TVisitorResult = visitorFunction(node, parentNode);
if (!visitorResult || !NodeGuards.isNode(visitorResult)) {
continue;
}
node = visitorResult;
}
return node;
};
}
}