diff --git a/robotpy_build/autowrap/context.py b/robotpy_build/autowrap/context.py index 737f770d..c42079fc 100644 --- a/robotpy_build/autowrap/context.py +++ b/robotpy_build/autowrap/context.py @@ -287,6 +287,12 @@ class BaseClassData: Render data for each base that a class inherits """ + #: Just the class name + cls_name: str + + #: This ends with :: + namespace_: str + #: C++ name, including all known components full_cpp_name: str # was x_qualname @@ -296,9 +302,6 @@ class BaseClassData: #: turned into underscores. full_cpp_name_identifier: str # was x_qualname_ - #: This ends with :: - namespace_: str - #: C++ name + components, no template parameters dep_cpp_name: str diff --git a/robotpy_build/autowrap/cxxparser.py b/robotpy_build/autowrap/cxxparser.py index 357b8ee3..3603a797 100644 --- a/robotpy_build/autowrap/cxxparser.py +++ b/robotpy_build/autowrap/cxxparser.py @@ -193,7 +193,7 @@ def _count_and_unwrap( def _fmt_base_name( typename: PQName, -) -> typing.Tuple[str, str, str, str, typing.List[str]]: +) -> typing.Tuple[str, str, str, str, str, typing.List[str]]: all_parts = [] nameonly_parts = [] @@ -222,6 +222,7 @@ def _fmt_base_name( tparam_list = [] return ( + last_segment.name, "::".join(most_parts), "::".join(all_parts), "::".join(nameonly_parts), @@ -292,7 +293,6 @@ class ClassStateData(typing.NamedTuple): defer_protected_fields: typing.List[Field] # Needed for trampoline - cls_cpp_identifier: str template_argument_list: str base_template_params: str base_template_args: str @@ -756,7 +756,6 @@ def on_class_start(self, state: AWClassBlockState) -> typing.Optional[bool]: defer_private_virtual_methods=[], defer_protected_fields=[], # Trampoline data - cls_cpp_identifier=cls_cpp_identifier, template_argument_list=template_argument_list, base_template_args=base_template_args_s, base_template_params=base_template_params_s, @@ -829,15 +828,20 @@ def _process_class_bases( if base.access == "private": continue - cpp_name, cpp_name_w_templates, dep_cpp_name, base_ns, tparam_list = ( - _fmt_base_name(base.typename) - ) + ( + cpp_name, + full_cpp_name, + cpp_name_w_templates, + dep_cpp_name, + base_ns, + tparam_list, + ) = _fmt_base_name(base.typename) if ignored_bases.pop(cpp_name_w_templates, None): continue # Sometimes, we can't guess all the information about the base, so the # user needs to specify it explicitly. - user_bqual = class_data.base_qualnames.get(cpp_name) + user_bqual = class_data.base_qualnames.get(full_cpp_name) if user_bqual: cpp_name_w_templates = user_bqual # TODO: sometimes need to add this to pybase_params, but @@ -845,17 +849,17 @@ def _process_class_bases( # obscure, going to omit it for now. tp = user_bqual.find("<") if tp == -1: - cpp_name = user_bqual + full_cpp_name = user_bqual template_params = "" else: - cpp_name = user_bqual[:tp] + full_cpp_name = user_bqual[:tp] template_params = user_bqual[tp + 1 : -1] - dep_cpp_name = cpp_name - ns_idx = cpp_name.rfind("::") + dep_cpp_name = full_cpp_name + ns_idx = full_cpp_name.rfind("::") if ns_idx == -1: base_ns = "" else: - base_ns = cpp_name[:ns_idx] + base_ns = full_cpp_name[:ns_idx] else: # TODO: we don't handle nested child classes with templates here # ... but that has to be rather obscure? @@ -869,21 +873,22 @@ def _process_class_bases( # live in the same namespace as the class if len(base.typename.segments) == 1: base_ns = cls_namespace - cpp_name = f"{cls_namespace}::{cpp_name}" + full_cpp_name = f"{cls_namespace}::{full_cpp_name}" cpp_name_w_templates = f"{cls_namespace}::{cpp_name_w_templates}" dep_cpp_name = f"{cls_namespace}::{dep_cpp_name}" - base_identifier = cpp_name.translate(_qualname_trans) + base_identifier = full_cpp_name.translate(_qualname_trans) if base_ns: base_ns = f"{base_ns}::" bases.append( BaseClassData( - full_cpp_name=cpp_name, + cls_name=cpp_name, + namespace_=base_ns, + full_cpp_name=full_cpp_name, full_cpp_name_w_templates=cpp_name_w_templates, full_cpp_name_identifier=base_identifier, - namespace_=base_ns, dep_cpp_name=dep_cpp_name, template_params=template_params, ) @@ -1257,8 +1262,8 @@ def on_class_end(self, state: AWClassBlockState) -> None: if cdata.template_argument_list: tmpl = f", {cdata.template_argument_list}" - trampoline_cfg = f"{cdata.ctx.namespace}::PyTrampolineCfg_{cdata.cls_cpp_identifier}<{cdata.template_argument_list}>" - tname = f"{cdata.ctx.namespace}::PyTrampoline_{cdata.cls_cpp_identifier}" + trampoline_cfg = f"{ctx.namespace}::PyTrampolineCfg_{ctx.cpp_name}<{cdata.template_argument_list}>" + tname = f"{ctx.namespace}::PyTrampoline_{ctx.cpp_name}" tvar = f"{ctx.cpp_name}_Trampoline" ctx.trampoline = TrampolineData( diff --git a/robotpy_build/autowrap/render_cls_rpy_include.py b/robotpy_build/autowrap/render_cls_rpy_include.py index 16c25b30..b6694684 100644 --- a/robotpy_build/autowrap/render_cls_rpy_include.py +++ b/robotpy_build/autowrap/render_cls_rpy_include.py @@ -124,12 +124,12 @@ def _render_cls_trampoline( ) if cls.bases: - r.writeln(f"struct PyTrampolineCfg_{cls.full_cpp_name_identifier} :") + r.writeln(f"struct PyTrampolineCfg_{cls.cpp_name} :") with r.indent(): for base in cls.bases: r.writeln( - f"{base.namespace_}PyTrampolineCfg_{base.full_cpp_name_identifier}<{postcomma(base.template_params)}" + f"{base.namespace_}PyTrampolineCfg_{base.cls_name}<{postcomma(base.template_params)}" ) r.writeln("CfgBase") @@ -137,7 +137,7 @@ def _render_cls_trampoline( for base in cls.bases: r.writeln(">") else: - r.writeln(f"struct PyTrampolineCfg_{cls.full_cpp_name_identifier} : CfgBase") + r.writeln(f"struct PyTrampolineCfg_{cls.cpp_name} : CfgBase") r.writeln("{") @@ -162,11 +162,11 @@ def _render_cls_trampoline( r.writeln( f"template " ) - r.writeln(f"using PyTrampolineBase_{cls.full_cpp_name_identifier} =") + r.writeln(f"using PyTrampolineBase_{cls.cpp_name} =") for base in cls.bases: r.rel_indent(2) - r.writeln(f"{base.namespace_}PyTrampoline_{base.full_cpp_name_identifier}<") + r.writeln(f"{base.namespace_}PyTrampoline_{base.cls_name}<") with r.indent(): r.writeln("PyTrampolineBase") @@ -182,8 +182,8 @@ def _render_cls_trampoline( ; template - struct PyTrampoline_{ cls.full_cpp_name_identifier } : PyTrampolineBase_{ cls.full_cpp_name_identifier } {{ - using PyTrampolineBase_{ cls.full_cpp_name_identifier }::PyTrampolineBase_{ cls.full_cpp_name_identifier }; + struct PyTrampoline_{ cls.cpp_name } : PyTrampolineBase_{ cls.cpp_name } {{ + using PyTrampolineBase_{ cls.cpp_name }::PyTrampolineBase_{ cls.cpp_name }; """ ) @@ -192,7 +192,7 @@ def _render_cls_trampoline( r.write_trim( f""" template - struct PyTrampoline_{ cls.full_cpp_name_identifier } : PyTrampolineBase {{ + struct PyTrampoline_{ cls.cpp_name } : PyTrampolineBase {{ using PyTrampolineBase::PyTrampolineBase; """ ) @@ -232,11 +232,11 @@ def _render_cls_trampoline( with r.indent(): all_decls = ", ".join(p.decl for p in fn.all_params) all_names = ", ".join(p.arg_name for p in fn.all_params) - r.writeln(f"PyTrampoline_{cls.full_cpp_name_identifier}({all_decls}) :") + r.writeln(f"PyTrampoline_{cls.cpp_name}({all_decls}) :") if cls.bases: r.writeln( - f" PyTrampolineBase_{cls.full_cpp_name_identifier}({all_names})" + f" PyTrampolineBase_{cls.cpp_name}({all_names})" ) else: r.writeln(f" PyTrampolineBase({all_names})")