in python/moz/l10n/formats/mf2/validate.py [0:0]
def _validate_declarations(declarations: dict[str, Expression]) -> None:
decl_data: list[tuple[str, bool]] = []
dependencies: dict[str, set[str]] = {}
def deep_dependencies(name: str, res: set[str]) -> set[str]:
if name in dependencies:
for dep in dependencies[name]:
if dep not in res:
res.add(dep)
deep_dependencies(dep, res)
return res
def cmp_decl_data(a: tuple[str, bool], b: tuple[str, bool]) -> int:
a_name, a_input = a
b_name, b_input = b
if a_name in dependencies[b_name]:
return -1
if b_name in dependencies[a_name]:
return 1
if a_input != b_input:
return -1 if a_input else 1
return -1 if a_name < b_name else 1
if not isinstance(declarations, Mapping):
raise MF2ValidationError(f"Invalid declarations: {declarations}")
for name, expr in declarations.items():
if not isinstance(name, str) or not name_re.fullmatch(name):
raise MF2ValidationError(f"Invalid declaration name: {name}")
if not isinstance(expr, Expression):
raise MF2ValidationError(f"Invalid declaration expression: {expr}")
_validate_expression(expr)
var_name = expr.arg.name if isinstance(expr.arg, VariableRef) else None
is_input = var_name == name
decl_data.append((name, is_input))
deps: set[str] = set()
if var_name is not None and not is_input:
deps.add(var_name)
for opt in expr.options.values():
if isinstance(opt, VariableRef):
deps.add(opt.name)
dependencies[name] = deps
for name in dependencies:
deps = deep_dependencies(name, set())
if name in deps:
raise MF2ValidationError(f"Duplicate declaration for ${name}")
dependencies[name] = deps
if len(declarations) > 1:
decl_data.sort(key=cmp_to_key(cmp_decl_data))
inserts = [(name, declarations.pop(name)) for name, _ in decl_data[1:]]
for name, expr in inserts:
declarations[name] = expr