mirror of
https://github.com/esphome/esphome.git
synced 2026-05-24 01:37:15 +08:00
[core] Put ComponentMarker outside the IIFE as a visual bracket
The marker comment was being emitted as the first line *inside* each
IIFE:
[]() {
// === logger ===
// logger:
// ...
...
}();
That works but buries the component label inside the lambda body, so
scanning generated main.cpp to find "where does component X's setup
live" is harder than it needs to be. Emit the marker before and after
the IIFE instead:
// === logger ===
[]() {
// logger:
// ...
...
}();
// === logger ===
Comment-only components (e.g. sha256, async_tcp, empty platforms like
binary_sensor:) don't grow a useless trailing duplicate marker —
when there's no IIFE to bracket, the marker is emitted once.
This commit is contained in:
@@ -1052,13 +1052,16 @@ class EsphomeCore:
|
||||
|
||||
# Split main_statements at ComponentMarker sentinels into a prefix
|
||||
# (statements emitted before any component) plus per-component groups.
|
||||
# Each group's first entry is its marker comment, kept separate so
|
||||
# it can bracket the IIFE rather than be buried inside it.
|
||||
prefix: list[str] = []
|
||||
components: list[list[str]] = []
|
||||
components: list[tuple[str, list[str]]] = []
|
||||
current = prefix
|
||||
for exp in self.main_statements:
|
||||
if isinstance(exp, ComponentMarker):
|
||||
current = [str(exp).rstrip()]
|
||||
components.append(current)
|
||||
body: list[str] = []
|
||||
components.append((str(exp).rstrip(), body))
|
||||
current = body
|
||||
continue
|
||||
current.append(str(statement(exp)).rstrip())
|
||||
|
||||
@@ -1066,13 +1069,19 @@ class EsphomeCore:
|
||||
if not components:
|
||||
return "\n".join(prefix) + "\n\n"
|
||||
|
||||
# Each component's block is wrapped in a noinline IIFE lambda so its
|
||||
# stack frame is released on return, bounding peak stack during
|
||||
# setup(). Large blocks are sub-split to cap single heavy components
|
||||
# (e.g. sensor platforms with many filter registrations).
|
||||
# Each component's block is wrapped in IIFE lambdas so its stack
|
||||
# frame is released on return, bounding peak stack during setup().
|
||||
# Large blocks are sub-split to cap single heavy components (e.g.
|
||||
# sensor platforms with many filter registrations). The marker
|
||||
# comment brackets the IIFE on both sides so the generated
|
||||
# main.cpp is easy to scan by component.
|
||||
pieces = list(prefix)
|
||||
for block in components:
|
||||
pieces.extend(_wrap_in_iifes(block, max_statements=50))
|
||||
for marker, body in components:
|
||||
wrapped = _wrap_in_iifes(body, max_statements=50)
|
||||
pieces.append(marker)
|
||||
pieces.extend(wrapped)
|
||||
if any("[]()" in line for line in wrapped):
|
||||
pieces.append(marker)
|
||||
return "\n".join(pieces) + "\n\n"
|
||||
|
||||
@property
|
||||
|
||||
@@ -961,8 +961,23 @@ def test_cpp_main_section_component_marker_wraps_in_iife() -> None:
|
||||
out = target.cpp_main_section
|
||||
assert out.count("[]() {") == 2
|
||||
assert out.count("}();") == 2
|
||||
assert "// === logger ===" in out
|
||||
assert "// === wifi ===" in out
|
||||
# Each component's marker brackets its IIFE (once before, once after).
|
||||
assert out.count("// === logger ===") == 2
|
||||
assert out.count("// === wifi ===") == 2
|
||||
|
||||
|
||||
def test_cpp_main_section_comment_only_component_emits_single_marker() -> None:
|
||||
# A component that emits no C++ statements (only a ComponentMarker)
|
||||
# should not grow a useless trailing duplicate marker.
|
||||
target = core.EsphomeCore()
|
||||
target.main_statements = [
|
||||
ComponentMarker("sha256"),
|
||||
ComponentMarker("wifi"),
|
||||
RawStatement("new_wifi();"),
|
||||
]
|
||||
out = target.cpp_main_section
|
||||
assert out.count("// === sha256 ===") == 1
|
||||
assert out.count("// === wifi ===") == 2 # wifi has an IIFE
|
||||
|
||||
|
||||
def test_cpp_main_section_prefix_statements_stay_outside_iife() -> None:
|
||||
|
||||
Reference in New Issue
Block a user