[core] Declare apply locals right before their first use

A local declared at the top ran option_at before a publish placed before
the statement, which changed the call order and grew ld2412 by 16 bytes.
This commit is contained in:
J. Nick Koston
2026-10-16 14:06:17 -10:00
parent f7a60f5859
commit 754a960ed1
2 changed files with 21 additions and 10 deletions
+6 -7
View File
@@ -477,7 +477,7 @@ ApplyPublish = Literal["before", "after"] | None
class ApplyEntity:
"""A domain's ``Apply*`` class, its generated function's parameters and its publish statement.
``locals`` are (name, declaration) pairs, emitted only when the body uses the name.
``locals`` are (name, declaration) pairs, declared only when the body uses the name.
"""
cls: MockObjClass
@@ -567,12 +567,11 @@ class SubEntities:
body.insert(0, apply_entity.publish)
elif publish == "after":
body.append(apply_entity.publish)
text = "\n".join(body)
body[:0] = [
decl
for name, decl in apply_entity.locals
if re.search(rf"\b{name}\b", text)
]
for name, decl in apply_entity.locals:
# Declared right before its first use, so calls keep their order.
uses = (i for i, line in enumerate(body) if re.search(rf"\b{name}\b", line))
if (first := next(uses, None)) is not None:
body.insert(first, decl)
functions: dict[str, SafeExpType] = CORE.data.setdefault(_APPLY_DOMAIN, {})
key = "\n".join([*(f"{t} {n}" for t, n in apply_entity.params), *body])
if (fn := functions.get(key)) is None:
+15 -3
View File
@@ -1396,17 +1396,28 @@ _SELECT_APPLY = entity_helpers.ApplyEntity(
@pytest.mark.asyncio
@pytest.mark.parametrize(
("apply", "body"),
("apply", "publish", "body"),
[
(
"set_mode(option)",
"after",
(
"const char *option = entity->option_at(index);\n"
"::hub->set_mode(option);\nentity->publish_state(index);"
),
),
(
"set_mode(option)",
"before",
(
"entity->publish_state(index);\n"
"const char *option = entity->option_at(index);\n"
"::hub->set_mode(option);"
),
),
(
"set_mode(index, options_)",
"after",
"::hub->set_mode(index, options_);\nentity->publish_state(index);",
),
],
@@ -1415,12 +1426,13 @@ async def test_sub_entities_apply_locals(
setup_test_environment: list[str],
apply_functions: list[tuple[str, str, str]],
apply: str,
publish: str,
body: str,
) -> None:
"""A local is declared only when the body names it as a whole identifier."""
"""A local is declared before its first use, and only when named as a whole identifier."""
conf = _apply_conf("m_sel", _SELECT_APPLY.cls)
sub = _apply_sub([], {"m": conf}, _SELECT_APPLY)
await sub("m", None, apply=apply, publish="after")
await sub("m", None, apply=apply, publish=publish)
assert apply_functions == [
("esphome__m_sel__fn", "select::Select * entity, size_t index", body)
]