11#include < sourcemeta/codegen/ir.h>
22
3+ #include < sourcemeta/core/uri.h>
4+
35#include < algorithm> // std::ranges::reverse
46#include < cassert> // assert
5- #include < string> // std::string
7+ #include < sstream> // std::istringstream
8+ #include < string> // std::string, std::getline
69#include < vector> // std::vector
710
11+ namespace {
12+
13+ // If the input looks like an absolute URI, extract its path segments.
14+ // Otherwise, add the input as a single segment.
15+ // Note: segments are added in reverse order because the caller reverses
16+ // the entire result at the end.
17+ auto push_token_segments (std::vector<std::string> &result,
18+ const std::string &value) -> void {
19+ try {
20+ const sourcemeta::core::URI uri{value};
21+ if (uri.is_absolute ()) {
22+ const auto path{uri.path ()};
23+ if (path.has_value () && !path->empty ()) {
24+ std::vector<std::string> segments;
25+ std::istringstream stream{std::string{path.value ()}};
26+ std::string segment;
27+ while (std::getline (stream, segment, ' /' )) {
28+ if (!segment.empty ()) {
29+ segments.emplace_back (segment);
30+ }
31+ }
32+
33+ // Reverse segments since the caller will reverse the entire result
34+ std::ranges::reverse (segments);
35+ for (const auto &path_segment : segments) {
36+ result.emplace_back (path_segment);
37+ }
38+
39+ return ;
40+ }
41+ }
42+ // NOLINTNEXTLINE(bugprone-empty-catch)
43+ } catch (const sourcemeta::core::URIParseError &) {
44+ // Not a valid URI, fall through to default behavior
45+ }
46+
47+ result.emplace_back (value);
48+ }
49+
50+ } // namespace
51+
852namespace sourcemeta ::codegen {
953
1054auto symbol (const sourcemeta::core::SchemaFrame &frame,
@@ -29,14 +73,14 @@ auto symbol(const sourcemeta::core::SchemaFrame &frame,
2973 if (segments_skipped >= 2 ) {
3074 const auto &last_token{current_pointer.back ()};
3175 if (last_token.is_property ()) {
32- result. emplace_back ( last_token.to_property ());
76+ push_token_segments (result, last_token.to_property ());
3377 } else {
3478 result.emplace_back (std::to_string (last_token.to_index ()));
3579 }
3680 } else {
3781 const auto &token{current_pointer.back ()};
3882 if (token.is_property ()) {
39- result. emplace_back ( token.to_property ());
83+ push_token_segments (result, token.to_property ());
4084 } else {
4185 result.emplace_back (std::to_string (token.to_index ()));
4286 }
0 commit comments