""" JSON v0/v1 compatibility layer for MIR Call instructions. This module provides utilities to normalize JSON v0 and v1 formats for MIR Call instructions, making it easier to remove v0 in Phase 124+. JSON v0 format: {"method": "log", "box_type": "ConsoleBox", "receiver": 42} JSON v1 format: {"name": "log", "box_name": "ConsoleBox", "receiver": 42} """ from typing import Dict, Any, Optional class MirCallCompat: """JSON v0/v1 compatibility processor for MIR Call instructions.""" @staticmethod def normalize_callee(callee_json: Dict[str, Any]) -> Dict[str, Any]: """ Normalize JSON v0/v1 callee format to unified internal format. Args: callee_json: Callee dict from MIR Call instruction Returns: Normalized dict with consistent keys: { "type": "Global" | "Method" | "Constructor" | "Closure" | "Value" | "Extern", "name": str (function/method name), "box_name": str (for Method/Constructor), "receiver": int (for Method), ... other fields } Examples: v0: {"method": "log", "box_type": "ConsoleBox"} v1: {"name": "log", "box_name": "ConsoleBox"} → {"type": "Method", "name": "log", "box_name": "ConsoleBox"} """ if not callee_json: return {} # Extract type (should already be present in both v0/v1) callee_type = callee_json.get("type") # Normalize method/function name (v0: "method", v1: "name") name = callee_json.get("name") or callee_json.get("method") # Normalize box type name (v0: "box_type", v1: "box_name") box_name = callee_json.get("box_name") or callee_json.get("box_type") # Build normalized result normalized = { "type": callee_type, } if name is not None: normalized["name"] = name if box_name is not None: normalized["box_name"] = box_name # Copy other fields as-is for key in ["receiver", "value", "params", "captures", "me_capture", "certainty"]: if key in callee_json: normalized[key] = callee_json[key] return normalized @staticmethod def detect_format_version(callee_json: Dict[str, Any]) -> int: """ Detect whether callee JSON is v0 or v1 format. Args: callee_json: Callee dict from MIR Call instruction Returns: 0 for v0 format (uses "method"/"box_type") 1 for v1 format (uses "name"/"box_name") Raises: ValueError: If format cannot be determined """ if not callee_json: raise ValueError("Empty callee JSON") # Check for v0 markers if "method" in callee_json or "box_type" in callee_json: return 0 # Check for v1 markers if "name" in callee_json or "box_name" in callee_json: return 1 # No clear markers - check callee type if callee_json.get("type") in ["Global", "Method", "Constructor", "Extern"]: # Modern format (v1) return 1 raise ValueError(f"Unknown callee format: {callee_json}") @staticmethod def is_v0_format(callee_json: Dict[str, Any]) -> bool: """Check if callee JSON uses v0 format.""" try: return MirCallCompat.detect_format_version(callee_json) == 0 except ValueError: return False @staticmethod def is_v1_format(callee_json: Dict[str, Any]) -> bool: """Check if callee JSON uses v1 format.""" try: return MirCallCompat.detect_format_version(callee_json) == 1 except ValueError: return False