From 34b4ee02de2e3ff50c9c0f9462a22aa7609ee8ad Mon Sep 17 00:00:00 2001 From: Scott Dixon Date: Mon, 23 Feb 2026 12:44:13 -0800 Subject: [PATCH 1/2] Fix for #378 Adding HasFixedPortID = false for types that do not have a fixed port ID --- .gitignore | 3 +++ src/nunavut/lang/cpp/templates/ServiceType.j2 | 8 ++++++++ verification/cpp/suite/test_constant.cpp | 6 ++++++ verification/cpp/suite/test_serialization.cpp | 4 ++++ 4 files changed, 21 insertions(+) diff --git a/.gitignore b/.gitignore index 183190e5..85c06f9f 100644 --- a/.gitignore +++ b/.gitignore @@ -58,3 +58,6 @@ nunavut_out .hypothesis .ropeproject + +#clangd +.cache diff --git a/src/nunavut/lang/cpp/templates/ServiceType.j2 b/src/nunavut/lang/cpp/templates/ServiceType.j2 index e28a1487..59b6f8dc 100644 --- a/src/nunavut/lang/cpp/templates/ServiceType.j2 +++ b/src/nunavut/lang/cpp/templates/ServiceType.j2 @@ -25,11 +25,19 @@ struct {{service_name}} struct _traits_ { _traits_() = delete; +{%- if T.has_fixed_port_id %} + static constexpr bool HasFixedPortID = true; + static constexpr {{ typename_unsigned_port }} FixedPortId = {{ T.fixed_port_id }}U; +{%- else %} + static constexpr bool HasFixedPortID = false; +{%- endif %} static constexpr bool IsServiceType = true; static constexpr bool IsService = true; static constexpr bool IsRequest = false; static constexpr bool IsResponse = false; + + static constexpr const char* FullNameAndVersion() { return "{{ T }}"; } }; }; diff --git a/verification/cpp/suite/test_constant.cpp b/verification/cpp/suite/test_constant.cpp index fa06dfc9..302462e4 100644 --- a/verification/cpp/suite/test_constant.cpp +++ b/verification/cpp/suite/test_constant.cpp @@ -30,6 +30,8 @@ const bool regulated::basics::Service::Response_0_1::_traits_::IsResponse; const bool regulated::basics::Service::Response_0_1::_traits_::IsServiceType; const bool regulated::basics::Service_0_1::_traits_::IsService; const bool regulated::basics::Service_0_1::_traits_::IsServiceType; +const bool regulated::basics::Service_0_1::_traits_::HasFixedPortID; +const std::uint16_t regulated::basics::Service_0_1::_traits_::FixedPortId; const std::size_t regulated::basics::Struct__0_1::_traits_::ArrayCapacity::i10_4; const std::size_t regulated::basics::Struct__0_1::_traits_::ArrayCapacity::f16_le2; @@ -101,6 +103,10 @@ TEST(ConstantTests, Service) // Type parameters. EXPECT_TRUE(regulated::basics::Service_0_1::_traits_::IsService); EXPECT_TRUE(regulated::basics::Service_0_1::_traits_::IsServiceType); + EXPECT_TRUE(regulated::basics::Service_0_1::_traits_::HasFixedPortID); + EXPECT_THAT(regulated::basics::Service_0_1::_traits_::FixedPortId, 300); + EXPECT_THAT(regulated::basics::Service_0_1::_traits_::FullNameAndVersion(), + StrEq("regulated.basics.Service.0.1")); EXPECT_FALSE(regulated::basics::Service::Request_0_1::_traits_::IsService); EXPECT_TRUE(regulated::basics::Service::Request_0_1::_traits_::IsServiceType); diff --git a/verification/cpp/suite/test_serialization.cpp b/verification/cpp/suite/test_serialization.cpp index 94672694..7970479c 100644 --- a/verification/cpp/suite/test_serialization.cpp +++ b/verification/cpp/suite/test_serialization.cpp @@ -29,6 +29,10 @@ static_assert( regulated::basics::Service_0_1::_traits_::IsServiceType, "Service is a service type"); +static_assert( + regulated::basics::Service_0_1::_traits_::HasFixedPortID, + "Service has a fixed port ID"); + static_assert( not regulated::basics::Service_0_1::Request::_traits_::IsService, "Request is not a service"); From d4a933aa70d8efe1647a5773d54166b451a93b7f Mon Sep 17 00:00:00 2001 From: Scott Dixon Date: Mon, 23 Feb 2026 13:55:32 -0800 Subject: [PATCH 2/2] Fix for #187 Adding missing test --- test/gentest_lang/test_lang.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/test/gentest_lang/test_lang.py b/test/gentest_lang/test_lang.py index 7ac0e81a..68d1b874 100644 --- a/test/gentest_lang/test_lang.py +++ b/test/gentest_lang/test_lang.py @@ -15,7 +15,7 @@ from nunavut._namespace import build_namespace_tree from nunavut._utilities import YesNoDefault from nunavut.jinja import DSDLCodeGenerator -from nunavut.lang import Language, LanguageClassLoader, LanguageContextBuilder +from nunavut.lang import Language, LanguageClassLoader, LanguageContextBuilder, UnsupportedLanguageError from nunavut.lang.c import filter_id as c_filter_id from nunavut.lang.cpp import filter_id as cpp_filter_id from nunavut.lang.py import filter_id as py_filter_id @@ -433,3 +433,14 @@ def test_either_target_or_extension() -> None: .get_target_language() .name ) + + +def test_experimental_language_without_enable_flag() -> None: + """ + Verify that using an experimental language without the include_experimental_languages + flag raises UnsupportedLanguageError. Covers the error path in + LanguageContextBuilder._new_language_w_experimental_handling(). + """ + # cpp is experimental (stable_support is not set, defaults to False) + with pytest.raises(UnsupportedLanguageError, match=r"experimental"): + LanguageContextBuilder(include_experimental_languages=False).set_target_language("cpp").create()