-
Notifications
You must be signed in to change notification settings - Fork 1
/
parse.js
114 lines (107 loc) · 4.5 KB
/
parse.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
109
110
111
112
113
114
const { getType } = require('./util');
const { deduceType } = require('./type-deduction');
let variableToTypeMap = new Object();
let functionToTypeMap = new Object();
let argumentToTypeMap = new Object();
let functionToArgsMap = new Object();
module.exports = setMaps =>
function(babel) {
const t = babel.types;
return {
visitor: {
VariableDeclarator: function({ node }) {
if (!node.init) return; // we will have to infer this later
// handling closures: don't
if (node.init.type === 'ArrowFunctionExpression') return;
// can't handle destructing props yet
if (node.id.type === 'ObjectPattern') return;
const deduced = deduceType(
node.init,
[
variableToTypeMap,
functionToTypeMap,
argumentToTypeMap
],
null,
t
);
variableToTypeMap[node.id.name] = deduced;
},
AssignmentExpression: function({ node }) {
const deduced = deduceType(
node.right,
[
variableToTypeMap,
functionToTypeMap,
argumentToTypeMap
],
null,
t
);
if (!deduced) return;
if (variableToTypeMap[node.left.name] instanceof Array) {
deduced.forEach(dType =>
variableToTypeMap[node.left.name].push(dType)
);
} else {
variableToTypeMap[node.left.name] = deduced;
}
},
FunctionDeclaration: function({ node }) {
const ret = node.body.body.find(
x => x.type === 'ReturnStatement'
);
if (!ret) return; // // TODO: arguments are []
functionToTypeMap[node.id.name] = [
getType(ret.argument, t)
];
functionToArgsMap[node.id.name] = node.params.map(
x => x.name
);
},
CallExpression: function({ node }) {
// functions may not exist because they were declared as variables
// ...or some other reason. In that case, we want to exit early
if (!functionToArgsMap[node.callee.name]) return;
if (
argumentToTypeMap[
`${node.callee.name}::${
functionToArgsMap[node.callee.name][0]
}`
] instanceof Array
) {
node.arguments.forEach((arg, index) => {
argumentToTypeMap[
`${node.callee.name}::${
functionToArgsMap[node.callee.name][index]
}`
].push(getType(arg, t));
});
} else {
node.arguments.forEach((arg, index) => {
argumentToTypeMap[
`${node.callee.name}::${
functionToArgsMap[node.callee.name][index]
}`
] = [getType(arg, t)];
});
}
},
Program: {
exit: function() {
setMaps([
variableToTypeMap,
functionToTypeMap,
argumentToTypeMap
]);
if (/*VERBOSE*/ false) {
console.log(variableToTypeMap);
console.log(functionToTypeMap);
console.log(argumentToTypeMap);
console.log('\n******************************\n');
}
}
}
}
};
};