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
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
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
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
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()