[core] Fix placement new storage name for templated types (#15096)

This commit is contained in:
J. Nick Koston
2026-03-23 16:09:23 +13:00
committed by GitHub
parent 98d9fd76b3
commit 8a3b5a8def
2 changed files with 51 additions and 8 deletions
+24 -8
View File
@@ -565,6 +565,29 @@ def new_variable(
return obj
def _extract_component_ns(type_str: str) -> str:
"""Extract the component namespace from a fully-qualified C++ type string.
Strips leading ``esphome::`` and template arguments, then returns
the first namespace segment. Falls back to ``"esphome"`` when the
type has no namespace qualifier (after stripping templates).
Examples::
esphome::dsmr::Dsmr -> dsmr
esphome::logger::Logger -> logger
esphome::Automation<std::optional<bool>, std::optional<bool>> -> esphome
Logger -> esphome
"""
bare = type_str.removeprefix("esphome::")
# Strip template arguments before namespace extraction to avoid
# matching :: inside template params (e.g. Automation<std::optional<bool>>)
bare_no_template = bare.split("<", maxsplit=1)[0]
if "::" in bare_no_template:
return bare_no_template.split("::", maxsplit=1)[0].rstrip("_")
return "esphome"
def Pvariable(id_: ID, rhs: SafeExpType, type_: "MockObj" = None) -> "MockObj":
"""Declare a new pointer variable in the code generation.
@@ -585,14 +608,7 @@ def Pvariable(id_: ID, rhs: SafeExpType, type_: "MockObj" = None) -> "MockObj":
# to avoid heap fragmentation on embedded devices.
the_type = id_.type
# Extract component namespace from type for memory analysis attribution
type_str = str(the_type)
# Strip leading esphome:: to get the component namespace
# e.g. esphome::dsmr::Dsmr -> dsmr, logger::Logger -> logger
bare = type_str.removeprefix("esphome::")
if "::" in bare:
component_ns = bare.split("::", maxsplit=1)[0].rstrip("_")
else:
component_ns = "esphome"
component_ns = _extract_component_ns(str(the_type))
storage_name = f"{component_ns}__{id_.id}__pstorage"
# Declare aligned byte array for the object storage