Skip to content

Commit 677be34

Browse files
Correct error
1 parent 881a41d commit 677be34

2 files changed

Lines changed: 40 additions & 4 deletions

File tree

multilingualprogramming/codegen/ui_lowering.py

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"""Lower reactive Core IR into a self-contained HTML/JavaScript preview."""
88

99
# pylint: disable=too-many-return-statements,too-many-branches
10+
# pylint: disable=too-many-instance-attributes,too-many-locals,too-many-statements
1011

1112
from __future__ import annotations
1213

@@ -125,7 +126,11 @@ def __init__(self) -> None:
125126
self._ui_function_names: set[str] = set()
126127
self._render_function = ""
127128

128-
def lower(self, program: IRProgram, modules: dict[str, IRProgram] | None = None) -> UILoweringResult:
129+
def lower(
130+
self,
131+
program: IRProgram,
132+
modules: dict[str, IRProgram] | None = None,
133+
) -> UILoweringResult:
129134
"""Lower an IRProgram to UI output."""
130135
preamble = self._emit_preamble()
131136
self._lower_imported_modules(modules or {})
@@ -208,12 +213,24 @@ def _lower_node(self, node: IRNode) -> None:
208213
self._lower_render_block(node)
209214
return
210215
if isinstance(node, IRFunction):
216+
if self._is_ui_entry_function(node):
217+
self._ui_function_names.add(node.name)
218+
for child in node.body:
219+
self._lower_node(child)
220+
return
211221
self._lower_function(node)
212222
if not node.is_async:
213223
self._ui_function_names.add(node.name)
214224
for child in node.body:
215225
self._lower_node(child)
216226

227+
def _is_ui_entry_function(self, node: IRFunction) -> bool:
228+
"""Return True for functions that serve as reactive UI entry containers."""
229+
effects = getattr(node, "effects", None)
230+
if effects is None or not hasattr(effects, "names"):
231+
return False
232+
return "ui" in effects.names()
233+
217234
def _emit_preamble(self) -> str:
218235
return """// Generated by Multilingual UI lowering
219236
class ReactiveSignal {
@@ -832,8 +849,16 @@ def _expr_to_js(self, node: IRNode | None) -> str:
832849
return node.name
833850
if isinstance(node, IRIndexAccess):
834851
if isinstance(node.index, IRSliceExpr):
835-
start = self._expr_to_js(node.index.start) if node.index.start is not None else "undefined"
836-
stop = self._expr_to_js(node.index.stop) if node.index.stop is not None else "undefined"
852+
start = (
853+
self._expr_to_js(node.index.start)
854+
if node.index.start is not None
855+
else "undefined"
856+
)
857+
stop = (
858+
self._expr_to_js(node.index.stop)
859+
if node.index.stop is not None
860+
else "undefined"
861+
)
837862
return f"{self._expr_to_js(node.obj)}.slice({start}, {stop})"
838863
return f"{self._expr_to_js(node.obj)}[{self._expr_to_js(node.index)}]"
839864
if isinstance(node, IRSliceExpr):
@@ -946,6 +971,9 @@ def _call_name(self, node: IRNode | None) -> str | None:
946971
return None
947972

948973

949-
def lower_to_ui(program: IRProgram, modules: dict[str, IRProgram] | None = None) -> UILoweringResult:
974+
def lower_to_ui(
975+
program: IRProgram,
976+
modules: dict[str, IRProgram] | None = None,
977+
) -> UILoweringResult:
950978
"""Lower an IRProgram to a browser preview bundle."""
951979
return UILoweringPass().lower(program, modules=modules)

tests/core1/test_ui_output_validation.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,14 @@ def test_memory_game_js_no_undefined_calls():
9292
assert "class undefined" not in js
9393

9494

95+
def test_memory_game_js_has_no_unsupported_placeholders():
96+
"""Generated JS should not include unsupported placeholder comments."""
97+
ui_result = _load_memory_game_ui()
98+
js = ui_result.emit_js()
99+
100+
assert "unsupported" not in js
101+
102+
95103
def test_memory_game_js_has_render_initialization():
96104
"""Generated JS initializes render on page load."""
97105
ui_result = _load_memory_game_ui()

0 commit comments

Comments
 (0)