Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
Compiler_Module_Linker.H
Go to the documentation of this file.
1/*
2 Aleph_w
3
4 Data structures & Algorithms
5 version 2.0.0b
6 https://github.com/lrleon/Aleph-w
7
8 This file is part of Aleph-w library
9
10 Copyright (c) 2002-2026 Leandro Rabindranath Leon
11
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files (the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29*/
30
42#ifndef COMPILER_MODULE_LINKER_H
43#define COMPILER_MODULE_LINKER_H
44
45#include <sstream>
46#include <string>
47
48#include <tpl_dynMapTree.H>
51
52namespace Aleph {
63
73
81
93
101
104{
105 switch (kind)
106 {
108 return "Missing_Metadata";
110 return "Duplicate_Value_Export";
112 return "Duplicate_Type_Export";
113 }
114
115 return "Unknown";
116}
117
118namespace Compiler_Module_Linker_Detail {
120 const std::string &name) noexcept
121{
122 for (size_t i = 0; i < metadata.size(); ++i)
123 if (metadata.access(i).name == name)
124 return i;
125 return static_cast<size_t>(-1);
126}
127
129{
130 return kind == Compiler_Module_Export_Kind::Type ? 1 : 0;
131}
132} // namespace Compiler_Module_Linker_Detail
133
138 const DynArray<size_t> &order)
139{
141
142 for (size_t order_pos = 0; order_pos < order.size(); ++order_pos)
143 {
144 const auto module_index = order.access(order_pos);
145 if (module_index >= descriptors.size())
146 continue;
147
148 const auto &descriptor = descriptors.access(module_index);
151 linkage.module_index = module_index;
152 linkage.order_index = order_pos;
153
154 const auto self_metadata_index
156 if (self_metadata_index == static_cast<size_t>(-1))
157 {
158 result.valid = false;
160 module_index,
161 descriptor.name,
162 "",
163 "",
164 descriptor.name,
165 {}});
166 result.modules.append(std::move(linkage));
167 continue;
168 }
169
170 const auto &self_metadata = metadata.access(self_metadata_index);
171 for (size_t i = 0; i < self_metadata.exports.size(); ++i)
172 {
173 const auto &item = self_metadata.exports.access(i);
174 linkage.visible_exports.append(
175 {item.kind, item.name, module_index, self_metadata.name, item.declaration_span, false});
176 }
177
178 for (size_t i = 0; i < descriptor.imports.size(); ++i)
179 {
180 const auto &dep = descriptor.imports.access(i);
181 const auto dep_index = [&descriptors, &dep]() {
183 if (descriptors.access(descriptor_index).name == dep.module_name)
184 return descriptor_index;
185 return static_cast<size_t>(-1);
186 }();
187 if (dep_index == static_cast<size_t>(-1))
188 continue;
189 linkage.direct_import_indexes.append(dep_index);
190
191 const auto dep_metadata_index
193 if (dep_metadata_index == static_cast<size_t>(-1))
194 {
195 result.valid = false;
197 module_index,
198 descriptor.name,
199 dep.module_name,
200 "",
201 dep.module_name,
202 dep.span});
203 continue;
204 }
205
206 const auto &dep_metadata = metadata.access(dep_metadata_index);
207 for (size_t j = 0; j < dep_metadata.exports.size(); ++j)
208 {
209 const auto &item = dep_metadata.exports.access(j);
210 linkage.visible_exports.append(
211 {item.kind, item.name, dep_index, dep_metadata.name, item.declaration_span, true});
212 }
213 }
214
215 {
216 // Single-pass O(N) duplicate detection keyed by (bucket, name).
217 // bucket 1 = Type namespace, bucket 0 = Value namespace.
218 DynMapTree<std::string, size_t> first_seen; // key -> index into visible_exports
219 for (size_t i = 0; i < linkage.visible_exports.size(); ++i)
220 {
221 const auto &exp = linkage.visible_exports.access(i);
222 const std::string key = std::to_string(
224 const auto *prev_idx = first_seen.search(key);
225 if (prev_idx == nullptr)
226 {
227 first_seen[key] = i;
228 continue;
229 }
230 const auto &prev = linkage.visible_exports.access(prev_idx->second);
231 if (prev.source_module_name == exp.source_module_name and prev.imported == exp.imported)
232 continue;
233 result.valid = false;
234 result.issues.append({exp.kind == Compiler_Module_Export_Kind::Type
237 module_index,
238 descriptor.name,
239 exp.name,
240 prev.source_module_name,
241 exp.source_module_name,
242 exp.declaration_span});
243 }
244 }
245
246 result.modules.append(std::move(linkage));
247 }
248
249 return result;
250}
251
254{
255 std::ostringstream out;
256 out << "ModuleLinkage\n";
257 for (size_t i = 0; i < result.modules.size(); ++i)
258 {
259 const auto &module = result.modules.access(i);
260 out << " Module(" << module.module_name << ") order=" << module.order_index << '\n';
261 for (size_t j = 0; j < module.visible_exports.size(); ++j)
262 {
263 const auto &item = module.visible_exports.access(j);
264 out << " Visible(" << compiler_module_export_kind_name(item.kind) << "(" << item.name
265 << ")) from " << item.source_module_name << (item.imported ? " imported" : " local")
266 << '\n';
267 }
268 }
269
270 if (not result.issues.is_empty())
271 {
272 out << " Issues\n";
273 for (size_t i = 0; i < result.issues.size(); ++i)
274 {
275 const auto &issue = result.issues.access(i);
277 << " module=" << issue.module_name;
278 if (not issue.export_name.empty())
279 out << " export=" << issue.export_name;
280 if (not issue.first_provider_module.empty())
281 out << " first=" << issue.first_provider_module;
282 if (not issue.second_provider_module.empty())
283 out << " second=" << issue.second_provider_module;
284 out << '\n';
285 }
286 }
287
288 return out.str();
289}
290} // namespace Aleph
291
292#endif
Reusable metadata for parsed or analyzed module surfaces.
Reusable source-name module dependency resolution helpers.
size_t size_t int32_t * out
Definition ca-c-api.h:120
size_t size() const noexcept
Return the current dimension of array.
T & access(const size_t i) const noexcept
Fast access without checking allocation and bound_min_clock checking.
Generic key-value map implemented on top of a binary search tree.
Key & access(size_t i)
__gmp_expr< T, __gmp_unary_expr< __gmp_expr< T, U >, __gmp_exp_function > > exp(const __gmp_expr< T, U > &expr)
Definition gmpfrxx.h:4077
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Definition Blossom.H:466
int export_namespace_bucket(const Compiler_Module_Export_Kind kind) noexcept
size_t find_metadata_index(const DynArray< Compiler_Module_Metadata > &metadata, const std::string &name) noexcept
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
Compiler_Module_Export_Kind
Export kinds currently modeled by reusable module metadata.
const char * compiler_module_linkage_issue_name(const Compiler_Module_Linkage_Issue_Kind kind) noexcept
Returns the stable debug name for one linkage issue kind.
and
Check uniqueness with explicit hash + equality functors.
Compiler_Module_Linkage_Issue_Kind
Structural issues emitted while linking module surfaces.
const char * compiler_module_export_kind_name(const Compiler_Module_Export_Kind kind) noexcept
Returns the stable debug name for one module-export kind.
Compiler_Module_Link_Result compiler_link_module_surfaces(const DynArray< Compiler_Module_Descriptor > &descriptors, const DynArray< Compiler_Module_Metadata > &metadata, const DynArray< size_t > &order)
Links direct-import module surfaces into visible top-level views.
std::string compiler_render_module_linkage(const Compiler_Module_Link_Result &result)
Renders one deterministic text artifact for linked module surfaces.
One structural issue reported by the reusable module linker.
Compiler_Module_Linkage_Issue_Kind kind
One linked module view under direct-import surface rules.
DynArray< Compiler_Module_Visible_Export > visible_exports
One visible top-level declaration in a linked module surface.
size_t source_module_index
Index in the descriptor/module array.
bool imported
false for local exports, true for direct-imported exports.
Half-open byte range inside a source file.
Definition ah-source.H:100
Dynamic key-value map based on balanced binary search trees.