Bash++
Bash++ compiler internal documentation
EntityMap.h
Go to the documentation of this file.
1
6#pragma once
7#include <optional>
8#include "interval_tree.hpp"
9#include "EntityNode.h"
10
11using IntervalTree = lib_interval_tree::interval_tree<IntervalType, EntityHooks>;
12
14 uint32_t line;
15 uint32_t column;
16
17 operator uint64_t() const {
18 // Encode line and column into a single uint64_t
19 // The first 32 bits represent the line number,
20 // and the last 32 bits represent the column number.
21 // This permits perfect sorting of file positions
22 return (static_cast<uint64_t>(line) << 32) | column;
23 }
24
25 FilePosition(uint32_t line, uint32_t column)
26 : line(line), column(column) {}
27};
28
29class EntityMap {
30 private:
32 public:
33
37 void insert(FilePosition start, FilePosition end, const std::shared_ptr<bpp::bpp_entity>& entity) {
38 auto it = tree.insert({start, end});
39 it.node()->payload = entity;
40 }
41
42 std::shared_ptr<bpp::bpp_entity> find(FilePosition point) {
43 // Because of our strictly-nested tree structure,
44 // The innermost active entity at a given point
45 // Is guaranteed to be the entity which overlaps that point and has the highest start position
46 // We can only make this assumption safely because code entities cannot overlap in arbitrary ways
47 // They can only overlap in a way such that one entity is fully contained within another
48 //
49 // Eg, we can only have structures such as [0 [100 [300 350] 500] 1000]
50 // Imagine we're looking for the innermost active entity at point 301
51 // All of the above entities overlap that point, but the innermost active entity is the one starting at 300
52 // Ie, the one with the highest start position
53 //
54 // It is impossible in our case to have any other kind of overlap, such as [0 100] and [50 150]
55 // (Where an inner entity is not *entirely* contained within the outer entity)
56 // If that were possible, this method would not work correctly
57 std::optional<uint64_t> highestStart = std::nullopt;
58 std::shared_ptr<bpp::bpp_entity> innermostEntity;
59 tree.overlap_find_all({point, point}, [&](auto const& it) {
60 // This is also based on the assumption (valid in our case)
61 // That no two entities can start at the same point
62 if (!highestStart.has_value() || it->low() > highestStart) {
63 highestStart = it->low();
64 innermostEntity = it.node()->payload;
65 }
66 return true; // Continue searching
67 });
68 return innermostEntity;
69 }
70
74 std::shared_ptr<bpp::bpp_entity> find(uint32_t line, uint32_t column) {
75 return find(FilePosition(line, column));
76 }
77};
lib_interval_tree::interval_tree< IntervalType, EntityHooks > IntervalTree
Definition EntityMap.h:11
Definition EntityMap.h:29
IntervalTree tree
Definition EntityMap.h:31
void insert(FilePosition start, FilePosition end, const std::shared_ptr< bpp::bpp_entity > &entity)
Add an entity to the entity map.
Definition EntityMap.h:37
std::shared_ptr< bpp::bpp_entity > find(uint32_t line, uint32_t column)
Find the active code entity at a specific line and column.
Definition EntityMap.h:74
std::shared_ptr< bpp::bpp_entity > find(FilePosition point)
Definition EntityMap.h:42
Definition EntityMap.h:13
uint32_t line
Definition EntityMap.h:14
FilePosition(uint32_t line, uint32_t column)
Definition EntityMap.h:25
uint32_t column
Definition EntityMap.h:15