module_ir.py 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. """Intermediate representation of modules."""
  2. from __future__ import annotations
  3. from typing import Dict
  4. from mypyc.common import JsonDict
  5. from mypyc.ir.class_ir import ClassIR
  6. from mypyc.ir.func_ir import FuncDecl, FuncIR
  7. from mypyc.ir.ops import DeserMaps
  8. from mypyc.ir.rtypes import RType, deserialize_type
  9. class ModuleIR:
  10. """Intermediate representation of a module."""
  11. def __init__(
  12. self,
  13. fullname: str,
  14. imports: list[str],
  15. functions: list[FuncIR],
  16. classes: list[ClassIR],
  17. final_names: list[tuple[str, RType]],
  18. ) -> None:
  19. self.fullname = fullname
  20. self.imports = imports.copy()
  21. self.functions = functions
  22. self.classes = classes
  23. self.final_names = final_names
  24. def serialize(self) -> JsonDict:
  25. return {
  26. "fullname": self.fullname,
  27. "imports": self.imports,
  28. "functions": [f.serialize() for f in self.functions],
  29. "classes": [c.serialize() for c in self.classes],
  30. "final_names": [(k, t.serialize()) for k, t in self.final_names],
  31. }
  32. @classmethod
  33. def deserialize(cls, data: JsonDict, ctx: DeserMaps) -> ModuleIR:
  34. return ModuleIR(
  35. data["fullname"],
  36. data["imports"],
  37. [ctx.functions[FuncDecl.get_id_from_json(f)] for f in data["functions"]],
  38. [ClassIR.deserialize(c, ctx) for c in data["classes"]],
  39. [(k, deserialize_type(t, ctx)) for k, t in data["final_names"]],
  40. )
  41. def deserialize_modules(data: dict[str, JsonDict], ctx: DeserMaps) -> dict[str, ModuleIR]:
  42. """Deserialize a collection of modules.
  43. The modules can contain dependencies on each other.
  44. Arguments:
  45. data: A dict containing the modules to deserialize.
  46. ctx: The deserialization maps to use and to populate.
  47. They are populated with information from the deserialized
  48. modules and as a precondition must have been populated by
  49. deserializing any dependencies of the modules being deserialized
  50. (outside of dependencies between the modules themselves).
  51. Returns a map containing the deserialized modules.
  52. """
  53. for mod in data.values():
  54. # First create ClassIRs for every class so that we can construct types and whatnot
  55. for cls in mod["classes"]:
  56. ir = ClassIR(cls["name"], cls["module_name"])
  57. assert ir.fullname not in ctx.classes, "Class %s already in map" % ir.fullname
  58. ctx.classes[ir.fullname] = ir
  59. for mod in data.values():
  60. # Then deserialize all of the functions so that methods are available
  61. # to the class deserialization.
  62. for method in mod["functions"]:
  63. func = FuncIR.deserialize(method, ctx)
  64. assert func.decl.id not in ctx.functions, (
  65. "Method %s already in map" % func.decl.fullname
  66. )
  67. ctx.functions[func.decl.id] = func
  68. return {k: ModuleIR.deserialize(v, ctx) for k, v in data.items()}
  69. # ModulesIRs should also always be an *OrderedDict*, but if we
  70. # declared it that way we would need to put it in quotes everywhere...
  71. ModuleIRs = Dict[str, ModuleIR]