Skip to content

Commit 10117c2

Browse files
Support modules in IDL Parser (#5890)
* Refs #22973: Add module support implementation Signed-off-by: Carlosespicur <[email protected]> * Refs #22973: Add extra test cases and remove flags Signed-off-by: Carlosespicur <[email protected]> * Refs #22973: Remove comments and fix identations Signed-off-by: Carlosespicur <[email protected]> * Refs #22973: Uncrustify Signed-off-by: Carlosespicur <[email protected]> * Refs #22973: Update versions.md Signed-off-by: Carlosespicur <[email protected]> * Refs #22973: Fix missing header Signed-off-by: Carlosespicur <[email protected]> * Refs #22973: Apply suggested changes Signed-off-by: Carlosespicur <[email protected]> --------- Signed-off-by: Carlosespicur <[email protected]>
1 parent 56c67be commit 10117c2

File tree

8 files changed

+472
-223
lines changed

8 files changed

+472
-223
lines changed

src/cpp/fastdds/xtypes/dynamic_types/idl_parser/IdlGrammar.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ struct case_label : sor<seq<kw_case, const_expr, colon>, seq<kw_default, colon>>
310310
struct switch_case : seq<plus<case_label>, element_spec, semicolon> {};
311311
struct switch_body : plus<switch_case> {};
312312
struct switch_type_spec : sor<integer_type, char_type, boolean_type, wide_char_type, octet_type, scoped_name> {};
313-
struct union_def : seq<kw_union, identifier, kw_switch, open_parentheses, switch_type_spec, close_parentheses, open_brace, switch_body, close_brace> {};
313+
struct union_def : seq<kw_union, identifier, kw_switch, open_parentheses, star<annotation_appl>, switch_type_spec, close_parentheses, open_brace, switch_body, close_brace> {};
314314
struct union_dcl : sor<union_def, union_forward_dcl> {};
315315
struct struct_forward_dcl : seq<kw_struct, identifier, not_at<open_brace>> {};
316316
struct member : seq<star<annotation_appl>, type_spec, declarators, semicolon> {};

src/cpp/fastdds/xtypes/dynamic_types/idl_parser/IdlModule.hpp

Lines changed: 109 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -44,78 +44,83 @@ class Module
4444
Module(
4545
const Module& other) = delete;
4646

47-
// Module& create_submodule(
48-
// const std::string& submodule)
49-
// {
50-
// std::shared_ptr<Module> new_submodule(new Module(this, submodule));
51-
// auto result = inner_.emplace(submodule, new_submodule);
52-
// return *result.first->second.get();
53-
// }
47+
Module& create_submodule(
48+
const std::string& submodule)
49+
{
50+
std::shared_ptr<Module> new_submodule(new Module(this, submodule));
51+
auto result = inner_.emplace(submodule, new_submodule);
52+
return *result.first->second.get();
53+
}
5454

55-
// std::shared_ptr<Module> submodule(
56-
// const std::string& submodule)
57-
// {
58-
// return inner_[submodule];
59-
// }
55+
const Module* outer() const
56+
{
57+
return outer_;
58+
}
6059

61-
// size_t submodule_size()
62-
// {
63-
// return inner_.size();
64-
// }
60+
std::shared_ptr<Module> submodule(
61+
const std::string& submodule)
62+
{
63+
return inner_[submodule];
64+
}
6565

66-
// using ModuleVisitor = std::function<void(const Module& mod)>;
66+
size_t submodule_size()
67+
{
68+
return inner_.size();
69+
}
6770

68-
// void for_each_submodule(
69-
// ModuleVisitor visitor,
70-
// const Module* module,
71-
// bool recursive = true) const
72-
// {
73-
// for (const auto& inner : module->inner_)
74-
// {
75-
// visitor(*inner.second.get());
76-
// if (recursive)
77-
// {
78-
// for_each_submodule(visitor, inner.second.get());
79-
// }
80-
// }
81-
// }
71+
using ModuleVisitor = std::function<void (const Module& mod)>;
8272

83-
// void for_each_submodule(
84-
// ModuleVisitor visitor,
85-
// bool recursive = true) const
86-
// {
87-
// for_each_submodule(visitor, this, recursive);
88-
// }
73+
void for_each_submodule(
74+
ModuleVisitor visitor,
75+
const Module* module,
76+
bool recursive = true) const
77+
{
78+
for (const auto& inner : module->inner_)
79+
{
80+
visitor(*inner.second.get());
81+
if (recursive)
82+
{
83+
for_each_submodule(visitor, inner.second.get());
84+
}
85+
}
86+
}
8987

90-
// void for_each(
91-
// ModuleVisitor visitor) const
92-
// {
93-
// visitor(*this);
94-
// for_each_submodule(visitor, this);
95-
// }
88+
void for_each_submodule(
89+
ModuleVisitor visitor,
90+
bool recursive = true) const
91+
{
92+
for_each_submodule(visitor, this, recursive);
93+
}
9694

97-
// bool has_submodule(
98-
// const std::string& submodule) const
99-
// {
100-
// return inner_.count(submodule) > 0;
101-
// }
95+
void for_each(
96+
ModuleVisitor visitor) const
97+
{
98+
visitor(*this);
99+
for_each_submodule(visitor, this);
100+
}
102101

103-
// Module& operator [] (
104-
// const std::string& submodule)
105-
// {
106-
// return *inner_[submodule];
107-
// }
102+
bool has_submodule(
103+
const std::string& submodule) const
104+
{
105+
return inner_.count(submodule) > 0;
106+
}
108107

109-
// const Module& operator [] (
110-
// const std::string& submodule) const
111-
// {
112-
// return *inner_.at(submodule);
113-
// }
108+
Module& operator [] (
109+
const std::string& submodule)
110+
{
111+
return *inner_[submodule];
112+
}
114113

115-
// const std::string& name() const
116-
// {
117-
// return name_;
118-
// }
114+
const Module& operator [] (
115+
const std::string& submodule) const
116+
{
117+
return *inner_.at(submodule);
118+
}
119+
120+
const std::string& name() const
121+
{
122+
return name_;
123+
}
119124

120125
std::string scope() const
121126
{
@@ -234,11 +239,6 @@ class Module
234239
bool replace = false)
235240
{
236241
std::string name(builder->get_name());
237-
if (name.find("::") != std::string::npos)
238-
{
239-
return false; // Cannot add a symbol with scoped name.
240-
}
241-
242242
if (replace)
243243
{
244244
auto it = structs_.find(name);
@@ -248,10 +248,6 @@ class Module
248248
}
249249
}
250250

251-
std::string name_space = scope();
252-
TypeDescriptor::_ref_type type_descriptor {traits<TypeDescriptor>::make_shared()};
253-
builder->get_descriptor(type_descriptor);
254-
type_descriptor->name(name_space + (name_space.empty() ? "" : "::") + name);
255251
auto result = structs_.emplace(name, builder);
256252

257253
return result.second;
@@ -315,15 +311,6 @@ class Module
315311
DynamicTypeBuilder::_ref_type builder)
316312
{
317313
std::string name(builder->get_name());
318-
if (name.find("::") != std::string::npos)
319-
{
320-
return false; // Cannot add a symbol with scoped name.
321-
}
322-
323-
std::string name_space = scope();
324-
TypeDescriptor::_ref_type type_descriptor {traits<TypeDescriptor>::make_shared()};
325-
builder->get_descriptor(type_descriptor);
326-
type_descriptor->name(name_space + (name_space.empty() ? "" : "::") + name);
327314
auto result = unions_.emplace(name, builder);
328315

329316
return result.second;
@@ -398,11 +385,6 @@ class Module
398385
bool replace = false,
399386
bool from_enumeration = false)
400387
{
401-
if (name.find("::") != std::string::npos)
402-
{
403-
return false; // Cannot add a symbol with scoped name.
404-
}
405-
406388
if (replace)
407389
{
408390
auto it = constants_.find(name);
@@ -431,11 +413,6 @@ class Module
431413
DynamicTypeBuilder::_ref_type builder,
432414
bool replace = false)
433415
{
434-
if (name.find("::") != std::string::npos)
435-
{
436-
return false; // Cannot add a symbol with scoped name.
437-
}
438-
439416
if (replace)
440417
{
441418
auto it = enumerations_32_.find(name);
@@ -445,10 +422,6 @@ class Module
445422
}
446423
}
447424

448-
std::string name_space = scope();
449-
TypeDescriptor::_ref_type type_descriptor {traits<TypeDescriptor>::make_shared()};
450-
builder->get_descriptor(type_descriptor);
451-
type_descriptor->name(name_space + (name_space.empty() ? "" : "::") + name);
452425
auto result = enumerations_32_.emplace(name, builder);
453426

454427
return result.second;
@@ -472,11 +445,6 @@ class Module
472445
const std::string& name,
473446
DynamicTypeBuilder::_ref_type builder)
474447
{
475-
if (name.find("::") != std::string::npos || has_alias(name))
476-
{
477-
return false; // Cannot define alias with scoped name (or already defined).
478-
}
479-
480448
std::string name_space = scope();
481449
TypeDescriptor::_ref_type type_descriptor {traits<TypeDescriptor>::make_shared()};
482450
builder->get_descriptor(type_descriptor);
@@ -533,14 +501,6 @@ class Module
533501
builder = module.first->aliases_.at(module.second);
534502
}
535503

536-
if (name.find("::") == 0)
537-
{
538-
// Scope ambiguity solver was originally used, add it to the retrieved DynamicTypeBuilder
539-
TypeDescriptor::_ref_type type_descriptor {traits<TypeDescriptor>::make_shared()};
540-
builder->get_descriptor(type_descriptor);
541-
type_descriptor->name(name);
542-
}
543-
544504
// Check bitsets
545505
// TODO
546506

@@ -550,8 +510,17 @@ class Module
550510
return builder;
551511
}
552512

513+
std::string create_scoped_name(
514+
const std::string& plain_name) const
515+
{
516+
assert(plain_name.find("::") == std::string::npos);
517+
const std::string& name_space = scope();
518+
return name_space.empty() ? plain_name : name_space + "::" + plain_name;
519+
}
520+
553521
protected:
554522

523+
// NOTE: Builders are stored using the scoped name as key
555524
std::map<std::string, DynamicTypeBuilder::_ref_type> aliases_;
556525
// std::map<std::string, Type> constants_types_;
557526
std::map<std::string, DynamicData::_ref_type> constants_;
@@ -596,6 +565,7 @@ class Module
596565
}
597566

598567
std::string name = symbol_name;
568+
std::string name_space = scope();
599569
// Solve scope
600570
if (symbol_name.find("::") != std::string::npos) // It is an scoped name
601571
{
@@ -616,16 +586,38 @@ class Module
616586
// Maybe the current scope its me?
617587
if (inner_scope == name_)
618588
{
619-
std::string innest_scope = inner_scope.substr(0, inner_scope.find("::"));
620-
if (inner_.count(innest_scope) > 0)
589+
std::string inner_name = symbol_name.substr(symbol_name.find("::") + 2);
590+
// inner_name is a scoped name (i.e: is this in the scope of one my submodules)?
591+
if (inner_name.find("::") != std::string::npos)
621592
{
622-
std::string inner_name = symbol_name.substr(symbol_name.find("::") + 2);
623-
const auto& it = inner_.find(innest_scope);
624-
PairModuleSymbol result = it->second->resolve_scope(inner_name, original_name);
625-
if (result.first != nullptr)
593+
// We should be in the scope of one of my submodules, go down.
594+
const auto& it = inner_.find(inner_name.substr(0, inner_name.find("::")));
595+
if (it == inner_.end())
626596
{
627-
return result;
597+
EPROSIMA_LOG_ERROR(IDLPARSER, "Cannot find inner scope '" << inner_name << "'.");
598+
// Unknown scope
599+
PairModuleSymbol pair;
600+
pair.first = nullptr;
601+
pair.second = original_name;
602+
return pair;
628603
}
604+
// Resolve from the inner submodule
605+
return it->second->resolve_scope(inner_name, original_name);
606+
}
607+
else
608+
{
609+
// Symbol should be stored in the current module
610+
std::string scoped_name = name_space.empty() ? inner_name : name_space + "::" + inner_name;
611+
if (has_symbol(scoped_name, false))
612+
{
613+
return std::make_pair<const Module*, std::string>(this, std::move(scoped_name));
614+
}
615+
616+
// Failed, not found
617+
PairModuleSymbol pair;
618+
pair.first = nullptr;
619+
pair.second = original_name;
620+
return pair;
629621
}
630622
}
631623
// Do we have a inner scope that matches?
@@ -648,9 +640,10 @@ class Module
648640
}
649641
}
650642

651-
if (has_symbol(name, false))
643+
std::string scoped_name = name_space.empty() ? name : name_space + "::" + name;
644+
if (has_symbol(scoped_name, false))
652645
{
653-
return std::make_pair<const Module*, std::string>(this, std::move(name));
646+
return std::make_pair<const Module*, std::string>(this, std::move(scoped_name));
654647
}
655648

656649
if (outer_ != nullptr)

0 commit comments

Comments
 (0)