Skip to content

Commit 2e8e278

Browse files
committed
Support classes with explicit namespace, ignore specialized classes
1 parent 0c4ae1c commit 2e8e278

File tree

5 files changed

+51
-15
lines changed

5 files changed

+51
-15
lines changed

robotpy_build/autowrap/cxxparser.py

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -580,7 +580,11 @@ def on_class_start(self, state: AWClassBlockState) -> typing.Optional[bool]:
580580
):
581581
return False
582582

583-
cls_key, cls_name, cls_namespace, parent_ctx = self._process_class_name(state)
583+
cls_name_result = self._process_class_name(state)
584+
if cls_name_result is None:
585+
return False
586+
587+
cls_key, cls_name, cls_namespace, parent_ctx = cls_name_result
584588
class_data = self.gendata.get_class_data(cls_key)
585589

586590
# Ignore explicitly ignored classes
@@ -761,23 +765,24 @@ def on_class_start(self, state: AWClassBlockState) -> typing.Optional[bool]:
761765

762766
def _process_class_name(
763767
self, state: AWClassBlockState
764-
) -> typing.Tuple[str, str, str, typing.Optional[ClassContext]]:
768+
) -> typing.Optional[typing.Tuple[str, str, str, typing.Optional[ClassContext]]]:
765769
class_decl = state.class_decl
766770
segments = class_decl.typename.segments
767771
assert len(segments) > 0
768772

769-
name_segment = segments[-1]
770-
if not isinstance(name_segment, NameSpecifier):
771-
raise ValueError(f"not sure how to handle '{class_decl.typename}'")
772-
773-
cls_name = name_segment.name
773+
segment_names: typing.List[str] = []
774+
for segment in segments:
775+
if not isinstance(segment, NameSpecifier):
776+
raise ValueError(
777+
f"not sure how to handle '{class_decl.typename.format()}'"
778+
)
779+
# ignore specializations for now
780+
if segment.specialization is not None:
781+
return None
782+
segment_names.append(segment.name)
774783

775-
# for now, don't support these?
776-
other_segments = segments[:-1]
777-
if other_segments:
778-
raise ValueError(
779-
f"not sure what to do with compound name '{class_decl.typename}'"
780-
)
784+
cls_name = segment_names[-1]
785+
extra_segments = "::".join(segment_names[:-1])
781786

782787
parent_ctx: typing.Optional[ClassContext] = None
783788

@@ -787,13 +792,18 @@ def _process_class_name(
787792
# easy case -- namespace is the next user_data up
788793
cls_key = cls_name
789794
cls_namespace = typing.cast(str, parent.user_data)
795+
if extra_segments:
796+
cls_namespace = f"{cls_namespace}::{extra_segments}"
790797
else:
791798
# Use things the parent already computed
792799
cdata = typing.cast(ClassStateData, parent.user_data)
793800
# parent: AWClassBlockState = state.parent
794801
parent_ctx = cdata.ctx
795802
# the parent context already computed namespace, so use that
796-
cls_key = f"{cdata.cls_key}::{cls_name}"
803+
if extra_segments:
804+
cls_key = f"{cdata.cls_key}::{extra_segments}::{cls_name}"
805+
else:
806+
cls_key = f"{cdata.cls_key}::{cls_name}"
797807
cls_namespace = parent_ctx.namespace
798808

799809
return cls_key, cls_name, cls_namespace, parent_ctx

tests/cpp/pyproject.toml.tmpl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ generate = [
5959
{ inline_code = "inline_code.h" },
6060
{ lifetime = "lifetime.h" },
6161
{ nested = "nested.h" },
62+
{ ns_class = "ns_class.h" },
6263
{ operators = "operators.h" },
6364
{ overloads = "overloads.h" },
6465
{ parameters = "parameters.h" },
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
namespace ns {
3+
struct NSClass;
4+
}
5+
6+
struct ns::NSClass {
7+
int getN() const { return 4; }
8+
};

tests/cpp/rpytest/ft/include/templates/basic.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

22
#pragma once
33

4+
// basic template
45
template <typename T>
56
struct TBasic
67
{
@@ -10,4 +11,11 @@ struct TBasic
1011
virtual void setT(const T &t) { this->t = t; }
1112

1213
T t;
13-
};
14+
};
15+
16+
// basic specialization
17+
// - TODO: ignored for now since this is annoying
18+
template <>
19+
struct TBasic<int> {
20+
int add5() { return 5; }
21+
};

tests/test_ft_misc.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,15 @@ def test_cpp_code_with_constant():
146146
assert o.cpp_code_with_constant() == 4
147147

148148

149+
#
150+
# ns_class.h
151+
#
152+
153+
154+
def test_ns_class():
155+
assert ft._rpytest_ft.NSClass().getN() == 4
156+
157+
149158
#
150159
# operators.h
151160
#

0 commit comments

Comments
 (0)