Exemplo n.º 1
0
def emit(env: runtime.Env, classes: t.List[t.Type[t.Any]],
         dry_run: bool) -> t.Iterator[Module]:
    if dry_run:
        yield env.m
        return

    from egoist.go.types import get_gopackage
    from egoist.go.walker import get_walker
    from egoist.generators.structkit import _emit

    m = env.m
    w = get_walker(classes,
                   m=m,
                   metadata_handler=runtime._default_metadata_handler)

    yield m
    m.import_("")
    m.stmt(f"// this file is generated by *me*")
    m.sep()

    for item in w.walk():
        gopackage = get_gopackage(item.type_)
        if gopackage is not None:
            continue

        # emit only struct
        _emit.emit_struct(w, item)
        m.sep()
    return m
Exemplo n.º 2
0
def run() -> Module:
    r = get_resolver()
    m = gofile("main")

    classes = [Person, Person2]

    for item in walk(classes):
        gopackage = get_gopackage(item.cls)
        if gopackage is not None:
            continue

        m.stmt(f"type {goname(item.cls.__name__)} struct {{")
        with m.scope():
            for name, typeinfo, _metadata in item.fields:
                metadata = t.cast(Metadata, _metadata)
                if metadata.get("default") == MISSING:
                    metadata.pop("default")

                try:
                    gotype = r.resolve_gotype(typeinfo.normalized)  # todo: pointer
                except KeyError:
                    gotype = goname(typeinfo.normalized.__name__)

                gopackage = get_gopackage(typeinfo.normalized)
                if gopackage is not None:
                    gotype = f"{m.import_(gopackage)}.{gotype}"

                if metadata.get("pointer", False):
                    gotype = f"*{gotype}"

                if metadata.get("inline", False):
                    m.append(gotype)
                else:
                    m.append(f"{goname(name)} {gotype}")

                if metadata:
                    m.stmt(f"  // {metadata}")
                else:
                    m.stmt("")

        m.stmt("}")
        m.sep()
    return m
Exemplo n.º 3
0
def emit(classes: t.List[t.Type[t.Any]]) -> Module:
    r = get_resolver()
    m = gofile("main")

    for item in walk(classes):
        gopackage = get_gopackage(item.cls)
        if gopackage is not None:
            continue

        m.stmt(f"type {goname(item.cls.__name__)} struct {{")
        with m.scope():
            for name, typeinfo, _metadata in item.fields:
                metadata = t.cast(Metadata, _metadata)
                if metadata.get("default") == MISSING:
                    metadata.pop("default")

                typ = typeinfo.raw
                if metadata.get("pointer", False):
                    typ = t.Optional[typ]
                gotype: str = r.resolve_gotype(typ)
                gopackage = get_gopackage(
                    typeinfo.normalized)  # todo: support composite

                if gopackage is not None:
                    gotype = f"{m.import_(gopackage)}.{gotype}"

                if metadata.get("inline", False):
                    m.append(gotype)
                else:
                    m.append(f"{goname(name)} {gotype}")

                if metadata:
                    m.stmt(f"  // {metadata}")
                else:
                    m.stmt("")

        m.stmt("}")
        m.sep()

    return m
Exemplo n.º 4
0
def emit_struct(m: Module, item: Item, *, resolver: Resolver) -> Definition:
    gopackage = get_gopackage(item.type_)
    if gopackage is not None:
        return ""

    typename = str(resolver.resolve_gotype(item.type_))

    # // <typename> ...
    doc = inspect.getdoc(item.type_)
    if doc:
        lines = doc.split("\n")
        m.stmt(f"// {typename} {lines[0]}")
        for line in lines[1:]:
            m.stmt(f"// {line}")

    # type <typename> struct {
    # ...
    # }
    m.stmt(f"type {typename} struct {{")
    with m.scope():
        for name, info, metadata in item.fields:
            gotype: str = resolver.resolve_gotype(info.raw)

            # handling field (private field?, embedded?)
            if metadata.get("inline", False):
                m.append(gotype)
            elif name.startswith("_"):
                m.append(f"{untitleize(goname(name))} {gotype}")
            else:
                m.append(f"{goname(name)} {gotype}")

            # todo: handling tags
            if "tags" not in metadata:
                metadata["tags"] = {}
            metadata["tags"] = {"json": [name.rstrip("_")]}
            m.append(f" `{build_gotags(metadata['tags'])}`")

            # handling comments
            if metadata.get("inline", False):
                m.stmt(f"  // {metadata}")
            else:
                comment = metadata.get("comment", "")
                m.stmt(
                    f"  // {comment.split(_NEWLINE, 1)[0]}" if comment else "")

    definition = Definition(name=typename, code_module=None)
    m.stmt("}")
    return definition
Exemplo n.º 5
0
def structkit(
    env: Env,
    classes: t.List[t.Type[t.Any]],
    dry_run: bool,
    *,
    resolver: t.Optional[Resolver] = None,
) -> t.Iterator[Module]:
    if dry_run:
        logger.debug("dry run, %s skipped", __name__)
        yield env.m
        return

    from egoist.go.types import get_gopackage
    from egoist.go.walker import get_walker
    from egoist.generators.structkit import _emit
    from . import runtime

    m = env.m
    w = get_walker(classes,
                   m=m,
                   metadata_handler=runtime._default_metadata_handler)

    yield m
    m.import_("")
    m.stmt(f"// this file is generated by {__name__}")
    m.sep()

    for item in w.walk():
        gopackage = get_gopackage(item.type_)
        if gopackage is not None:
            continue

        if item.is_enums:
            _emit.emit_enums(w, item.type_)
            m.sep()
        elif item.is_union:
            _emit.emit_union(w, item)
            m.sep()
        else:
            _emit.emit_struct(w, item)
            m.sep()
            if item.fields:
                _emit.emit_unmarshalJSON(w, item)
            m.sep()