Esempio n. 1
0
def resolve_local_type(var, node):
    """Resolve the var in any nodes before `node`
    Will search for `decl_stmt` or `params`
    Return type name if found.
    """
    while node and node.previousSibling:
        node = node.previousSibling
        if domutil.is_element(node):
            # won't search beyond function. That will resolved as global variable
            if node.tagName == 'function':
                return None
            if node.tagName == 'decl_stmt':
                type_name,var_name,_ = syntaxutil.parse_decl_stmt(node)
                if var == var_name:
                    return type_name
            elif node.tagName == 'parameter_list':
                # if reach function's parameter list, search params, if fail, then stop
                params = syntaxutil.parse_parameter_list(node)
                for type_name,var_name in params:
                    if var == var_name:
                        return type_name
    if node and node.parentNode:
        return resolve_local_type(var, node.parentNode)
    else:
        return None
Esempio n. 2
0
def resolve_alive_vars(node, resolved):
    """Resolve all alive vars at this node.
    :return {var: type}
    """
    result = {}
    if node.previousSibling:
        node = node.previousSibling
        if domutil.is_element(node):
            if node.tagName == 'decl_stmt':
                type_name,var_name,_ = syntaxutil.parse_decl_stmt(node)
                if var_name not in result:
                    result[var_name] = type_name
            elif node.tagName == 'parameter_list':
                params = syntaxutil.parse_parameter_list(node)
                for type_name,var_name in params:
                    if var_name not in result:
                        result[var_name] = type_name
    elif node.parentNode:
        node = node.parentNode
    else:
        return {}
    more = resolve_alive_vars(node, resolved | result.keys())
    for key in more:
        if key not in result:
            result[key] = more[key]
    return result
Esempio n. 3
0
def get_undefined_vars(nodes, resolved):
    """Get undefined variable.
    :param nodes: a list of dom nodes
    :param resolved: a set of names as strings that is assumed to be defined
    :return a set of names
    """
    result = set()
    for node in nodes:
        if domutil.is_element(node):
            if node.tagName == 'decl_stmt':
                _,var_name,_ = syntaxutil.parse_decl_stmt(node)
                resolved.add(var_name)
            elif node.tagName == 'expr':
                # in #ifdef, there may be `#elif defined(__sun)`
                if domutil.in_node(node, 'cpp:ifdef', level=2) or\
                    domutil.in_node(node, 'cpp:elif', level=2) or\
                    domutil.in_node(node, 'cpp:ifndef', level=2):
                    continue
                name_set = syntaxutil.parse_expr(node)
                for name in name_set:
                    # uint8_t, false, true, NULL
                    if sys.resolve_single(name):
                        continue
                    # here we find the undefined variable
                    if name not in resolved and name not in result:
                        result.add(name)
            elif node.tagName == 'for':
                init_node = domutil.get_first_child_by_tagname(node, 'init')
                if init_node:
                    _, var = syntaxutil.parse_for_init(init_node)
                    if var:
                        resolved.add(var)
            elif node.tagName == 'parameter_list':
                params = syntaxutil.parse_parameter_list(node)
                for _,name in params:
                    resolved.add(name)
            elif node.tagName == 'cpp:define':
                value_node = domutil.get_first_child_by_tagname(node, 'cpp:value')
                text = domutil.get_text_content(value_node)
                match = re.findall(r'([A-Z_]{2,})', text)
                for m in match:
                    if m not in resolved:
                        result.add(m)
            new_result = get_undefined_vars(node.childNodes, resolved | result)
            result.update(new_result)
    return result