masaori335 commented on code in PR #13857:
URL: https://github.com/apache/trafficserver/pull/13857#discussion_r4355790040


##########
tools/hrw4u/src/procedures.py:
##########
@@ -20,10 +20,114 @@
 
 from __future__ import annotations
 
+from dataclasses import dataclass, field
 from pathlib import Path
+from typing import TYPE_CHECKING
+
+from hrw4u.errors import Hrw4uSyntaxError, SourceMap
+
+if TYPE_CHECKING:
+    import hrw4u.ast_nodes as ast
 
 
 def resolve_use_path(spec: str, search_paths: list[Path]) -> Path | None:
     """Resolve 'foo::bar::Baz' to <search_path>/foo/bar/Baz.hrw4u."""
     rel = Path(*spec.split('::')).with_suffix('.hrw4u')
     return next((base / rel for base in search_paths if (base / 
rel).is_file()), None)
+
+
+@dataclass(frozen=True, slots=True)
+class ProcEntry:
+    name: str
+    params: tuple[ast.ProcParam, ...]
+    body: tuple[ast.BodyNode, ...]
+    source_file: str
+
+
+@dataclass
+class ProcRegistry:
+    """Procedure declarations, keyed by qualified name."""
+    source_map: SourceMap
+    _sigs: dict[str, ProcEntry] = field(default_factory=dict, init=False)
+    _loaded: set[str] = field(default_factory=set, init=False)
+
+    def get(self, name: str) -> ProcEntry | None:
+        return self._sigs.get(name)
+
+    def register(self, decl: ast.ProcedureDecl, expected_ns: str | None = 
None, use_spec: str | None = None) -> None:
+        span = decl.span
+        if '::' not in decl.name:
+            raise self.source_map.error_at(span, f"procedure name 
'{decl.name}' must be qualified (e.g. 'ns::name')")
+        if expected_ns and not decl.name.startswith(expected_ns):
+            namespace = expected_ns.removesuffix('::')
+            raise self.source_map.error_at(
+                span, f"procedure '{decl.name}' does not match namespace 
'{namespace}' (expected from 'use {use_spec}')")
+        if existing := self._sigs.get(decl.name):
+            raise self.source_map.error_at(span, f"procedure '{decl.name}' 
already declared in {existing.source_file}")
+
+        seen_default = False
+        for param in decl.params:
+            if param.default is None and seen_default:

Review Comment:
   The CST emitter already rejects this for an inline declaration, so I'm 
treating the missing check on the `use` path as a CST emitter bug, not as 
behaviour to keep. The default can never apply anyway: there are no named 
arguments, and `syn::p("1")` crashes the CST emitter with `'NoneType' object 
has no attribute 'paramRef'`. Python and C++ reject the same declaration.
   
   d40b503094 records it with `CstBug.ACCEPTS`, the same as the other one. The 
trailing `unknown procedure` matches what the CST emitter reports after 
rejecting an inline declaration, so I left that as is.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to