Ejemplo n.º 1
0
def resolve_reference(ref, rel):
    """Looks up an interrogate symbol to its canonical name.  The second
    argument is the fully qualified name it should be seen relative to, which
    may be a module name, or a module name followed by an object name.

    If found, returns a 2-tuple (type, fqname), else None."""

    # Find out which module we should be looking in.
    modname = None
    relpath = None
    rel_parts = rel.split('.')
    for i in range(len(rel_parts), 0, -1):
        try_modname = '.'.join(rel_parts[:i])
        if idb.has_module(try_modname):
            modname = try_modname
            relpath = rel_parts[i:]
            break

    if not modname:
        return None

    refpath = ref.replace('::', '.').split('.')

    # Say `rel` is "panda3d.core.NodePath.node",
    # and `ref` is "PandaNode.final", then we will try these in this order:
    # - panda3d.core::NodePath.node.PandaNode.final
    # - panda3d.core::NodePath.PandaNode.final
    # - panda3d.core::PandaNode.final

    for i in range(len(relpath), -1, -1):
        search = relpath[:i] + refpath
        ifunc = idb.lookup_function(modname, search)
        if ifunc:
            # Grab the mangled function name.
            func_name = idb.get_function_name(ifunc, mangle=True)
            return ('meth', '.'.join(relpath[:i] + refpath[:-1] + [func_name]))

        itype = idb.lookup_type(modname, search)
        if itype:
            # Grab the original type name.
            type_name = idb.get_type_name(itype, mangle=False, scoped=True)
            return ('class', type_name)
Ejemplo n.º 2
0
def resolve_reference(ref, rel, domain='py'):
    """Looks up an interrogate symbol to its canonical name.  The second
    argument is the fully qualified name it should be seen relative to, which
    may be a module name, or a module name followed by an object name.

    If found, returns a 2-tuple (type, fqname), else None."""

    # Find out which module we should be looking in.
    modname = None
    relpath = None
    rel_parts = rel.replace('::', '.').split('.')
    for i in range(len(rel_parts), 0, -1):
        try_modname = '.'.join(rel_parts[:i])
        if idb.has_module(try_modname):
            modname = try_modname
            relpath = rel_parts[i:]
            break

    if not modname:
        return None

    refpath = ref.replace('::', '.').split('.')

    # Say `rel` is "panda3d.core.NodePath.node",
    # and `ref` is "PandaNode.final", then we will try these in this order:
    # - panda3d.core::NodePath.node.PandaNode.final
    # - panda3d.core::NodePath.PandaNode.final
    # - panda3d.core::PandaNode.final

    for i in range(len(relpath), -1, -1):
        search = relpath[:i] + refpath

        if len(refpath) == 1 and i > 0 and refpath[0] == relpath[i - 1]:
            # If we are looking for a name equal to the parent scope, we are
            # probably referencing a class name from within that very class.
            # We don't want to find the constructor, so skip this.
            continue

        ifunc = idb.lookup_function(modname, search)
        if ifunc:
            if domain == 'cpp':
                func_name = interrogate_function_scoped_name(ifunc)
                return ('func', func_name)
            elif domain == 'py':
                # Grab the mangled function name.
                func_name = idb.get_function_name(ifunc, mangle=True)
                if len(search) == 1:
                    return ('func', func_name)
                else:
                    return ('meth',
                            '.'.join(relpath[:i] + refpath[:-1] + [func_name]))

        itype = idb.lookup_type(modname, search)
        if itype:
            # Grab the original type name.
            if domain == 'cpp':
                type_name = interrogate_type_scoped_name(itype)
                if interrogate_type_is_typedef(itype):
                    return ('type', type_name)
                elif interrogate_type_is_enum(itype):
                    return ('enum', type_name)
                elif interrogate_type_is_struct(itype):
                    return ('struct', type_name)
                elif interrogate_type_is_class(itype):
                    return ('class', type_name)
                elif interrogate_type_is_union(itype):
                    return ('union', type_name)
            elif domain == 'py':
                type_name = idb.get_type_name(itype, mangle=False, scoped=True)
                return ('class', type_name)

    if len(rel_parts
           ) >= 2 and rel_parts[0] == 'panda3d' and rel_parts[1] != 'core':
        # Look in panda3d.core instead, prefix the result with the module name.
        rel_parts[1] = 'core'
        resolved = resolve_reference(ref, '.'.join(rel_parts), domain=domain)
        if resolved and domain == 'py':
            return (resolved[0], 'panda3d.core.' + resolved[1])
        else:
            return resolved