Exemple #1
0
def _get_full_name(cls):
    if not inspect.isclass(cls):
        raise CodegenError("Base type has to be a class")
    module = inspect.getmodule(cls)
    if not module:
        raise CodegenError("Base type has to be inside a module")
    modulename = module.__name__

    if PY33:
        name = cls.__qualname__
    else:
        name = cls.__name__

    # Try to reference the class
    try:
        idents = name.split('.')
        _cls = getattr(module, idents[0])
        for ident in idents[1:]:
            _cls = getattr(_cls, ident)

        assert _cls == cls
    except AttributeError:
        raise CodegenError("Couldn't find base type, it has to be importable")

    return modulename, name
Exemple #2
0
    def _find_renderer_class(self, item):
        if not isinstance(item, Node):
            return None

        name = item.__class__.__name__
        renderer = globals().get(name)
        if not renderer or not issubclass(renderer, ModelRenderer):
            raise CodegenError('Renderer for %s not found' % name)
        return renderer
Exemple #3
0
    def _find_renderer_class(self, node):
        if not isinstance(node, Node):
            return None

        name = node.__class__.__name__
        renderer = globals().get(name)
        if not renderer or not issubclass(renderer, Base):
            raise CodegenError('Renderer for %s not found' % name)
        return renderer
Exemple #4
0
    def get_renderer(self, item):
        if not isinstance(item, Node):
            return None

        renderer_class = self._find_renderer_class(item)
        if renderer_class is None:
            raise CodegenError('Renderer not found for %s' % type(item).__name__)
        try:
            assert issubclass(renderer_class, ModelRenderer)
            return renderer_class(self, item)
        except Exception as e:
            raise type(e)(str(e), renderer_class.__name__)
Exemple #5
0
    def _find_renderer_class(self, node):
        if not isinstance(node, Node):
            return None

        node_class_name = node.__class__.__name__
        classes = [node.__class__]
        while classes:
            cls = classes.pop()

            name = cls.__name__
            if name in self._renderers:
                renderer = self._renderers[name]
                self._renderers[node_class_name] = renderer
                return renderer

            for base in cls.__bases__:
                if base not in classes:
                    classes.append(base)

        raise CodegenError('Renderer for %s not found' % node_class_name)
Exemple #6
0
 def render(self, **fields):
     if {()} in self.node.exp.lookahead():
         raise CodegenError('may repeat empty sequence')
     return '\n' + super().render(**fields)
Exemple #7
0
 def render(self, **fields):
     try:
         return super().render(**fields)
     except CodegenError as e:
         raise CodegenError(f'{self.node.name}={e}') from e
Exemple #8
0
def codegen(model, target='python'):
    if target.lower() == 'python':
        from tatsu.codegen import python
        return python.codegen(model)
    else:
        raise CodegenError('Unknown target language: %s' % target)
Exemple #9
0
 def render(self, **fields):
     if {()} in self.node.exp.firstset:
         raise CodegenError('may repeat empty sequence')
     return '\n' + super(Join, self).render(**fields)