src/global/TypeNameDisambiguator.cpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // Copyright (c) 2021-2026 ChilliBits. All rights reserved. | ||
| 2 | |||
| 3 | #include "TypeNameDisambiguator.h" | ||
| 4 | |||
| 5 | #include <util/Concurrency.h> | ||
| 6 | |||
| 7 | namespace spice::compiler { | ||
| 8 | |||
| 9 | // Static member initialization | ||
| 10 | std::unordered_map<std::string, std::vector<uint64_t>> TypeNameDisambiguator::claimedTypeIds = {}; | ||
| 11 | std::mutex TypeNameDisambiguator::claimedTypeIdsMutex; | ||
| 12 | |||
| 13 | /** | ||
| 14 | * Get the disambiguation suffix for a struct/interface type with the given name and type id. | ||
| 15 | * The first type id to claim a name keeps it unchanged (empty suffix); every further distinct type id sharing the name | ||
| 16 | * receives a deterministic, dot-separated suffix (e.g. ".1", ".2"). A dot is used on purpose: it is not a valid Spice | ||
| 17 | * identifier character, so the disambiguated name can never collide with a genuine, user-declared type name. | ||
| 18 | * | ||
| 19 | * @param name Simple type name | ||
| 20 | * @param typeId Custom type id of the type | ||
| 21 | * @return Disambiguation suffix (empty for the first claimer of the name) | ||
| 22 | */ | ||
| 23 | 2116655 | std::string TypeNameDisambiguator::getDisambiguationSuffix(const std::string &name, uint64_t typeId) { | |
| 24 |
1/2✓ Branch 2 → 3 taken 2116655 times.
✗ Branch 2 → 38 not taken.
|
2116655 | ConditionalLock lock(claimedTypeIdsMutex); |
| 25 | |||
| 26 |
1/2✓ Branch 3 → 4 taken 2116655 times.
✗ Branch 3 → 36 not taken.
|
2116655 | std::vector<uint64_t> &ids = claimedTypeIds[name]; |
| 27 | |||
| 28 | // Find the index of the type id among the ones already claiming this name | ||
| 29 | 2116655 | size_t index = ids.size(); | |
| 30 |
2/2✓ Branch 11 → 6 taken 2164092 times.
✓ Branch 11 → 12 taken 8247 times.
|
2172339 | for (size_t i = 0; i < ids.size(); i++) { |
| 31 |
3/4✓ Branch 6 → 7 taken 2164092 times.
✗ Branch 6 → 36 not taken.
✓ Branch 7 → 8 taken 2108408 times.
✓ Branch 7 → 9 taken 55684 times.
|
2164092 | if (ids.at(i) == typeId) { |
| 32 | 2108408 | index = i; | |
| 33 | 2108408 | break; | |
| 34 | } | ||
| 35 | } | ||
| 36 | // If not seen yet, claim the name | ||
| 37 |
2/2✓ Branch 13 → 14 taken 8247 times.
✓ Branch 13 → 15 taken 2108408 times.
|
2116655 | if (index == ids.size()) |
| 38 |
1/2✓ Branch 14 → 15 taken 8247 times.
✗ Branch 14 → 36 not taken.
|
8247 | ids.push_back(typeId); |
| 39 | |||
| 40 | // The first claimer keeps the plain name to avoid churn for the common, non-colliding case | ||
| 41 |
2/2✓ Branch 15 → 16 taken 2065883 times.
✓ Branch 15 → 22 taken 50772 times.
|
2116655 | if (index == 0) |
| 42 |
1/2✓ Branch 18 → 19 taken 2065883 times.
✗ Branch 18 → 30 not taken.
|
4131766 | return ""; |
| 43 |
2/4✓ Branch 22 → 23 taken 50772 times.
✗ Branch 22 → 35 not taken.
✓ Branch 23 → 24 taken 50772 times.
✗ Branch 23 → 33 not taken.
|
101544 | return "." + std::to_string(index); |
| 44 | 2116655 | } | |
| 45 | |||
| 46 | /** | ||
| 47 | * Clear the disambiguation registry. Must be called between compilations. | ||
| 48 | */ | ||
| 49 | 1298 | void TypeNameDisambiguator::clear() { claimedTypeIds.clear(); } | |
| 50 | |||
| 51 | } // namespace spice::compiler | ||
| 52 |