Patrick Kelley 8fd444092b initial
2025-05-07 15:35:15 -04:00

102 lines
2.8 KiB
C++

// Copyright (c) 2020-now by the Zeek Project. See LICENSE for details.
#pragma once
#include <map>
#include <optional>
#include <string>
#include <unordered_set>
#include <vector>
#include <hilti/ast/forward.h>
namespace hilti {
class Declaration;
class ID;
/**
* Scope mapping a set of identifiers to target declarations. An identifier can
* be mapped to more than one target.
*/
class Scope {
public:
Scope() = default;
~Scope() = default;
/**
* Inserts a declaration into the scope.
*
* @param d declaration to insert
*/
void insert(Declaration* d);
/**
* Inserts a declaration into it's scope under a given ID.
*
* @param id ID to insert the declaration under, which does not need to match the declaration's own ID
* @param d declaration to insert
*/
void insert(const ID& id, Declaration* d);
/**
* Inserts a place-holder into the scope that let's lookup fail here if it
* would normally return that ID.
*
* @param id ID to insert the place-holder under
*/
void insertNotFound(const ID& id);
/** Returns if there's at least one mapping for an ID. */
bool has(const ID& id) const { return ! _findID(id).empty(); }
/** Result type for the lookup methods. */
struct Referee {
Declaration* node = nullptr; /**< node that ID maps to */
std::string qualified; /**< qualified ID with full path used to find it */
bool external{}; /**< true if found in a different (imported) module */
};
/** Returns all mappings for an ID. */
std::vector<Referee> lookupAll(const ID& id) const { return _findID(id); }
/** Returns first mapping for an ID. */
std::optional<Referee> lookup(const ID& id) const {
if ( auto ids = _findID(id); ! ids.empty() )
return ids.front();
return {};
}
/** Empties the scope. */
void clear() { _items.clear(); }
/** Returns all mappings of the scope. */
const auto& items() const { return _items; }
/**
* Prints out a debugging representation of the scope's content.
*
* @param out stream to print to
* @param prefix string to prefix each printed scope item with
*/
void dump(std::ostream& out, const std::string& prefix = "") const;
std::string print() const;
Scope(const Scope& other) = delete;
Scope(Scope&& other) = delete;
Scope& operator=(const Scope& other) = delete;
Scope& operator=(Scope&& other) = delete;
private:
using ItemMap = std::map<std::string, std::unordered_set<Declaration*>>;
std::vector<Referee> _findID(const ID& id, bool external = false) const;
std::vector<Referee> _findID(const Scope* scope, const ID& id, bool external = false) const;
ItemMap _items;
};
} // namespace hilti