Tipragot
628be439b8
Cela permet de ne pas avoir de problèmes de compatibilité car python est dans le git.
89 lines
3.1 KiB
Python
89 lines
3.1 KiB
Python
"""Intermediate representation of modules."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import Dict
|
|
|
|
from mypyc.common import JsonDict
|
|
from mypyc.ir.class_ir import ClassIR
|
|
from mypyc.ir.func_ir import FuncDecl, FuncIR
|
|
from mypyc.ir.ops import DeserMaps
|
|
from mypyc.ir.rtypes import RType, deserialize_type
|
|
|
|
|
|
class ModuleIR:
|
|
"""Intermediate representation of a module."""
|
|
|
|
def __init__(
|
|
self,
|
|
fullname: str,
|
|
imports: list[str],
|
|
functions: list[FuncIR],
|
|
classes: list[ClassIR],
|
|
final_names: list[tuple[str, RType]],
|
|
) -> None:
|
|
self.fullname = fullname
|
|
self.imports = imports.copy()
|
|
self.functions = functions
|
|
self.classes = classes
|
|
self.final_names = final_names
|
|
|
|
def serialize(self) -> JsonDict:
|
|
return {
|
|
"fullname": self.fullname,
|
|
"imports": self.imports,
|
|
"functions": [f.serialize() for f in self.functions],
|
|
"classes": [c.serialize() for c in self.classes],
|
|
"final_names": [(k, t.serialize()) for k, t in self.final_names],
|
|
}
|
|
|
|
@classmethod
|
|
def deserialize(cls, data: JsonDict, ctx: DeserMaps) -> ModuleIR:
|
|
return ModuleIR(
|
|
data["fullname"],
|
|
data["imports"],
|
|
[ctx.functions[FuncDecl.get_id_from_json(f)] for f in data["functions"]],
|
|
[ClassIR.deserialize(c, ctx) for c in data["classes"]],
|
|
[(k, deserialize_type(t, ctx)) for k, t in data["final_names"]],
|
|
)
|
|
|
|
|
|
def deserialize_modules(data: dict[str, JsonDict], ctx: DeserMaps) -> dict[str, ModuleIR]:
|
|
"""Deserialize a collection of modules.
|
|
|
|
The modules can contain dependencies on each other.
|
|
|
|
Arguments:
|
|
data: A dict containing the modules to deserialize.
|
|
ctx: The deserialization maps to use and to populate.
|
|
They are populated with information from the deserialized
|
|
modules and as a precondition must have been populated by
|
|
deserializing any dependencies of the modules being deserialized
|
|
(outside of dependencies between the modules themselves).
|
|
|
|
Returns a map containing the deserialized modules.
|
|
"""
|
|
for mod in data.values():
|
|
# First create ClassIRs for every class so that we can construct types and whatnot
|
|
for cls in mod["classes"]:
|
|
ir = ClassIR(cls["name"], cls["module_name"])
|
|
assert ir.fullname not in ctx.classes, "Class %s already in map" % ir.fullname
|
|
ctx.classes[ir.fullname] = ir
|
|
|
|
for mod in data.values():
|
|
# Then deserialize all of the functions so that methods are available
|
|
# to the class deserialization.
|
|
for method in mod["functions"]:
|
|
func = FuncIR.deserialize(method, ctx)
|
|
assert func.decl.id not in ctx.functions, (
|
|
"Method %s already in map" % func.decl.fullname
|
|
)
|
|
ctx.functions[func.decl.id] = func
|
|
|
|
return {k: ModuleIR.deserialize(v, ctx) for k, v in data.items()}
|
|
|
|
|
|
# ModulesIRs should also always be an *OrderedDict*, but if we
|
|
# declared it that way we would need to put it in quotes everywhere...
|
|
ModuleIRs = Dict[str, ModuleIR]
|