121 lines
3.7 KiB
Python
121 lines
3.7 KiB
Python
|
|
"""
|
||
|
|
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
|