Exemple #1
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
Exemple #2
0
def emit(classes: t.List[t.Type[t.Any]], *, name: str = "main") -> Module:
    m = gofile(name)
    r = get_resolver(m)

    for item in walk(classes):
        if item.is_union:
            emit_union(m, item, resolver=r)
            m.sep()
        else:
            emit_struct(m, item, resolver=r)
            m.sep()
            if item.fields:
                emit_unmarshalJSON(m, item, resolver=r)
            m.sep()

    with m.func("main"):
        pass

    return m
Exemple #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
Exemple #4
0
def emit(classes: t.List[t.Type[t.Any]]) -> Module:
    m = gofile("main")
    r = get_resolver(m)

    for item in walk(classes):
        this = m.symbol(f"{item.type_.__name__[0].lower()}")
        this_type = f"{r.resolve_gotype(item.type_)}"
        this_type_pointer = f"*{this_type}"

        # func (ob *Ob) UnmarshalJSON(b []byte) error {
        b = m.symbol("b")
        m.stmt(
            f"func ({this} {this_type_pointer}) UnmarshalJSON({b} []byte) error {{"
        )
        with m.scope():

            # var err *maperr.Error
            err = m.symbol("err")
            maperr_pkg = m.import_("github.com/podhmo/maperr")
            m.stmt(f"var {err} *{maperr_pkg}.Error")
            m.sep()

            # var inner struct {
            #   ...
            # }
            m.stmt("// loading internal data")
            inner = m.symbol("inner")
            m.stmt(f"var {inner} struct {{")
            with m.scope():
                for name, typeinfo, metadata in item.fields:
                    if name.startswith("_"):
                        continue  # xxx:

                    gotype: str = r.resolve_gotype(typeinfo.raw)
                    m.append(f'{goname(name)} *{gotype} `json:"{name}"`')
                    m.stmt("// required" if metadata["required"] else "")
            m.stmt("}")

            # if rawErr := json.Unmarshal(b, &inner); rawErr != nil {
            # ...
            # }
            json_pkg = m.import_("encoding/json")
            raw_err = m.symbol("rawErr")
            with m.if_(
                    f"{raw_err} := {json_pkg}.Unmarshal(b, &{inner}); {raw_err} != nil"
            ):
                m.return_(err.addSummary(raw_err.Error()))
            m.sep()

            # if <field> != nil {
            #     ob.<field> = *<field>
            # } else {
            #     m.add(<field>, "required")
            # }
            m.stmt("// binding field value and required check")
            for name, typeinfo, metadata in item.fields:
                field = m.symbol(goname(name))
                with m.if_(f"{inner}.{field} != nil"):
                    m.stmt(f"{this}.{field} = *{inner}.{field}")
                if metadata["required"]:
                    with m.else_():
                        m.stmt(f'{err} = err.Add("{name}", "required")')
            m.sep()

            # return err.Untyped()
            m.return_(err.Untyped())
        m.stmt("}")
    return m
Exemple #5
0
import typing as t
from prestring.go.codeobject import gofile
from egoist.go.resolver import get_resolver
from emit import emit_enums

Op = t.Literal["add", "sub", "mul"]
Op.__name__ = "Op"

m = gofile("main")
resolver = get_resolver(m)
emit_enums(m, Op, resolver=resolver, name="op")

print(m)