예제 #1
0
def resolve_type(library, repo, parser_module, tag):
    if '(' in tag:
        # has modifiers.
        mod, args = parse_tag(tag)
        if mod in ('pointer', 'reference'):
            # pointer and reference have the same handling
            return ctypes.POINTER(resolve_type(library, repo, parser_module, args[0]))
        elif mod == 'Func':
            return library.types.Closure # TODO: specialized funcs!
        else:
            raise SorryError('Unknown tag: %r' % tag)
    else:
        # just a name.
        module = library.get_module(parser_module.path)
        # search in current module
        if hasattr(module, tag):
            # yay!
            return getattr(module, tag)
        else:
            # nay.
            # types? Since lang/* modules are imported automatically anyway,
            # it's no problem to look through them before looking through
            # explicitly imported modules. Right? (TODO)
            # The other way round, it will cause problems because we'd have
            # `String` defined multiple times. TODO anyway.
            if hasattr(library.types, tag):
                return getattr(library.types, tag)
            # TODO: namespaced imports
            for import_path in parser_module.global_imports:
                if hasattr(library.get_module(import_path), tag):
                    return getattr(library.get_module(import_path), tag)
            raise SorryError('Unknown type: %r' % tag)
예제 #2
0
 def resolve_tag(self, tag, cb=lambda x:x):
     if '(' in tag:
         mod, args = parse_tag(tag)
         if mod == 'pointer':
             return self.resolve_tag(translate(args[0]), cb) + '*'
         elif mod == 'reference':
             return self.resolve_tag(translate(args[0]), cb) + '@'
         elif mod == 'multi':
             return '(' + ', '.join(self.resolve_tag(translate(arg), cb) for arg in args) + ')'
         elif mod == 'Func':
             return cb('Func') # TODO: specialized functions
         else:
             return 'dunno'
     else:
         return cb(tag)
예제 #3
0
def analyze_function(library, repo, parser_module, cls_entity, entity):
    # arguments.
    arguments = []
    for arg in entity.arguments:
        if (arg.tag in entity.generic_types or (cls_entity and arg.tag in cls_entity.generic_types)):
            # generic.
            arguments.append(arg.tag)
        else:
            arguments.append(resolve_type(library, repo, parser_module, arg.tag))
    # return type.
    if entity.return_type is None:
        return_type = None
    elif entity.return_type.startswith('multi('):
        # multi-return ...
        return_type = []
        for rtype in parse_tag(entity.return_type)[1]:
            if (rtype in entity.generic_types or (cls_entity and rtype in cls_entity.generic_types)):
                return_type.append(rtype)
            else:
                return_type.append(resolve_type(library, repo, parser_module, rtype))
        return_type = tuple(return_type)
    elif (entity.return_type in entity.generic_types or (cls_entity and entity.return_type in cls_entity.generic_types)):
        return_type = entity.return_type
    else:
        return_type = resolve_type(library, repo, parser_module, entity.return_type)
    # modifiers.
    # well, i think only `static` has any effect here. right?
    static = 'static' in entity.modifiers
    return {
        'name': entity.name,
        'arguments': arguments,
        'generic_types': entity.generic_types,
        'return_type': return_type,
        'generic_return_type': isinstance(return_type, basestring),
        'static': static,
    }