-
Notifications
You must be signed in to change notification settings - Fork 478
/
Copy pathFlowTreeBuilder.js
108 lines (87 loc) · 2.96 KB
/
FlowTreeBuilder.js
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
import traverse from '@babel/traverse';
import { DefinitionsList } from './entryDefinitionsMap';
import { parseCodeToAST, buildVisitor } from './astBuilder';
import {
ABSTRACTION_LEVELS,
rebuildConfigForAbstractionLevel
} from './abstractionLevelsConfigurator';
import FlowTreeModifier from './FlowTreeModifier';
import {
DEFINED_MODIFIERS,
MODIFIER_PRESETS,
destructionModifier,
expressionCallbacksModifier,
arrowFunctionReturnModifier
} from './modifiers/modifiersFactory';
import { TOKEN_TYPES } from 'shared/constants';
import { logError } from 'shared/utils/logger';
const buildFlowTree = (astTree, astVisitorConfig) => {
const treeNodes = [];
traverse(astTree, buildVisitor(astVisitorConfig, treeNodes));
const root = (treeNodes.length && treeNodes[0]) || {};
return root.type === TOKEN_TYPES.PROGRAM
? root
: { name: 'Root', type: TOKEN_TYPES.PROGRAM, body: treeNodes };
};
//TODO: seems redundant abstraction, refactor
export const createFlowTreeModifier = () => {
const modifiers = FlowTreeModifier();
return {
setModifier(modifier) {
modifiers.addModifier(modifier);
},
registerNewModifier(test, updates) {
modifiers.create(test, updates);
},
destructNodeTree(test, newNameFn) {
this.setModifier(destructionModifier(test, newNameFn));
},
applyToFlowTree(flowTree) {
modifiers.applyTo(flowTree);
return flowTree;
}
};
};
export default ({ astParser = {}, astVisitor = {} } = {}) => {
const astParserConfig = {
...astParser
};
const astVisitorConfig = {
definitionsMap: [...DefinitionsList],
globalIgnore: null,
...astVisitor
};
const defaultModifier = createFlowTreeModifier();
defaultModifier.setModifier(expressionCallbacksModifier());
defaultModifier.setModifier(arrowFunctionReturnModifier());
return {
setAbstractionLevel(level) {
astVisitorConfig.definitionsMap = rebuildConfigForAbstractionLevel(level);
},
resetAbstractionLevelToNormal() {
astVisitorConfig.definitionsMap = [...DefinitionsList];
},
setIgnoreFilter(fn) {
astVisitorConfig.globalIgnore = fn;
},
build(code) {
const ast = this.buildAst(code);
return this.buildFlowTreeFromAst(ast);
},
buildAst(code) {
return parseCodeToAST(code, astParserConfig);
},
buildFlowTreeFromAst(ast) {
let flowTree = [];
try {
flowTree = buildFlowTree(ast, astVisitorConfig);
defaultModifier.applyToFlowTree(flowTree);
} catch (e) {
logError('Error at buildFlowTreeFromAst' + e.message, e.stack);
throw e;
}
return flowTree;
}
};
};
export { DEFINED_MODIFIERS, MODIFIER_PRESETS, ABSTRACTION_LEVELS };