def resolve_FuncCall(node, parent, symbols, is_global, is_check, cand, hlist): global_var, local_var = symbols go_flag = True callee_type = get_node_type(node['callee']) if callee_type == 'Identifier': name = node['callee']['name'] if (name in builtin.FUNCS or name in builtin.OBJS or name in builtin.ARRAYS): expr = None elif name in ID_HARNESS_MAP: if not is_duplicate(hlist, name): fname = pick_one(ID_HARNESS_MAP[name]) hlist.append(fname) expr = None else: symbol = find_symbol(node['callee'], symbols) if symbol == None: symbol = change_id(node['callee'], [JSType.js_func], symbols, cand) expr = symbol.expr go_flag = symbol.get_flag() symbol.set_flag(False) elif callee_type in ['FunctionExpression', 'ArrowFunctionExpression']: expr = node['callee'] elif callee_type in ['MemberExpression', 'CallExpression', 'SequenceExpression']: resolve_id(node['callee'], node, symbols, is_global, is_check, cand, hlist) expr = None elif callee_type == 'NewExpression': node['callee']['callee']['name'] = 'Function' return symbols elif callee_type == 'BlockStatement': resolve_list(node['body'], node, symbols, is_global, is_check, cand, hlist) expr = None else: error('resolve_id FunctionCall fail') expr = None resolve_list(node['arguments'], node, symbols, is_global, is_check, cand, hlist) if (go_flag and expr != None and 'params' in expr and 'body' in expr): l1 = [] for arg in expr['params']: if get_node_type(arg) == 'Identifier': l1.append(Symbol(arg, arg)) l1.append(Symbol('arguments', None, JSType.js_array)) symbols = global_var, l1 symbols = hoisting(expr['body'], symbols, False) resolve_id(expr['body'], node, symbols, False, False, cand, hlist) return global_var, local_var
def resolve_ClassDecl(node, parent, symbols, is_global, is_check, cand, hlist): if (node['id'] != None and get_node_type(node['id']) == 'Identifier'): if is_check: return symbols ty = JSType.js_object sym = Symbol(node['id'], None, ty) symbols[0].append(sym) return symbols
def func_hoisting(node, sym_list): if node == None: return node_type = get_node_type(node) for key in PROP_DICT[node_type]: if key not in node: continue child = node[key] if is_single_node(child): if get_node_type(child) == 'FunctionDeclaration': sym_list.append(Symbol(child['id'], child, JSType.js_func)) elif get_node_type(child) == 'BlockStatement': func_hoisting(child, sym_list) elif is_node_list(child): for _child in child: if _child == None: continue if get_node_type(_child) == 'FunctionDeclaration': sym_list.append(Symbol(_child['id'], _child, JSType.js_func)) elif get_node_type(_child) == 'BlockStatement': func_hoisting(_child, sym_list)
def resolve_ForIn(node, parent, symbols, is_global, is_check, cand, hlist): # TODO: let.. global_var, local_var = symbols if node['left'] == 'Identifier': global_var.append(Symbol(node['left'], node)) else: symbols = resolve_id(node['left'], node, symbols, is_global, is_check, cand, hlist) symbols = resolve_id(node['right'], node, symbols, is_global, is_check, cand, hlist) func_hoisting(node['body'], symbols[1]) return resolve_id(node['body'], node, symbols, is_global, is_check, cand, hlist)
def update_builtins(self, eng_path): globs = exec_eng(eng_path, 'utils/global_getter.js') globs = self.process_out(globs) self.OBJS = [x for x in self.OBJS if x in globs] self.FUNCS = [x for x in self.FUNCS if x in globs] for x in self.OBJS + self.ARRAYS: self.BUILTINS[x] = JSType.js_object for x in self.FUNCS: self.BUILTINS[x] = JSType.js_func for sym, ty in self.BUILTINS.items(): self.SYMS.append(Symbol(sym, None, ty))
def resolve_Try(node, parent, symbols, is_global, is_check, cand, hlist): global_var, local_var = symbols length = len(local_var) ret = ([], []) for x in [node['block'], node['handler'], node['finalizer']]: g1, l1 = global_var[::], local_var[::] func_hoisting(x, l1) if (x != None and x == node['handler'] and get_node_type(x['param']) == 'Identifier'): l1.append(Symbol(x['param'], None, JSType.js_object)) g1, l1 = resolve_id(x, node, (g1, l1), is_global, is_check, cand, hlist) ret = merge_symbols(ret, (g1, l1[:length])) return symbols
def help_Assign(pattern, parent, init, symbols, is_global, is_VarDecl, is_check, cand, hlist): if pattern == None: return symbols pattern_type = get_node_type(pattern) if pattern_type == 'Identifier': if is_check: return symbols ty = get_type(init, symbols) if is_VarDecl: sym = find_symbol(pattern, symbols) if sym == None: error('help_VarDecl fail') sym.update_type(ty) else: sym = Symbol(pattern, None, ty) symbols[0].append(sym) return symbols elif pattern_type == 'ArrayPattern': items = pattern['elements'] for idx in range(len(items)): item = items[idx] item_init = get_Array_item(init, idx) symbols = help_Assign(item, pattern, item_init, symbols, is_global, is_VarDecl, is_check, cand, hlist) return symbols elif pattern_type == 'ObjectPattern': for prop in pattern['properties']: prop_init = get_Object_prop(init, prop['key']) symbols = help_Assign(prop['value'], pattern, prop_init, symbols, is_global, is_VarDecl, is_check, cand, hlist) return symbols elif pattern_type == 'MemberExpression': return resolve_id(pattern, parent, symbols, is_global, is_check, cand, hlist) elif pattern_type == 'AssignmentPattern': # TODO: Check return symbols else: error('Unknown branch in help assign') return symbols
def pattern_hoisting(pattern, node): if pattern == None: return [] pattern_type = get_node_type(pattern) if pattern_type == 'Identifier': return [Symbol(pattern, node, JSType.undefined)] elif pattern_type == 'ArrayPattern': ret = [] for item in pattern['elements']: ret += pattern_hoisting(item, pattern) return ret elif pattern_type == 'ObjectPattern': ret = [] for prop in pattern['properties']: ret += pattern_hoisting(prop, pattern) return ret elif pattern_type == 'AssignmentPattern': return pattern_hoisting(pattern['left'], pattern) elif pattern_type == 'Property': return pattern_hoisting(pattern['value'], pattern) elif pattern_type == 'RestElement': return pattern_hoisting(pattern['argument'], pattern) else: error('pattern_hoisting: %s %s' % (pattern['type'], node['type'])) return []