Spicy
Public Member Functions | Static Public Attributes | Protected Member Functions | Friends | List of all members
hilti::Node Class Referenceabstract

#include <node.h>

Inheritance diagram for hilti::Node:
hilti::ASTRoot hilti::Attribute hilti::AttributeSet hilti::Ctor hilti::Declaration hilti::Expression hilti::Function hilti::QualifiedType hilti::Statement hilti::UnqualifiedType hilti::ctor::bitfield::BitRange hilti::ctor::map::Element hilti::ctor::struct_::Field hilti::detail::cfg::MetaNode hilti::statement::switch_::Case hilti::statement::try_::Catch hilti::type::enum_::Label hilti::type::operand_list::Operand hilti::type::tuple::Element spicy::type::unit::item::switch_::Case

Public Member Functions

node::Tag nodeTag () const
 
bool hasParent () const
 
Nodeparent (int i=1) const
 
template<typename T >
T * parent () const
 
auto pathLength () const
 
const auto & meta () const
 
const auto & location () const
 
void setMeta (Meta m)
 
auto scope () const
 
auto getOrCreateScope ()
 
void clearScope ()
 
Result< std::pair< Declaration *, ID > > lookupID (const ID &id, const std::string_view &what) const
 
virtual bool inheritScope () const
 
std::string typename_ () const
 
uint64_t identity () const
 
const auto & children () const
 
template<typename T >
T * child (unsigned int i) const
 
template<typename T >
T * childTryAs (unsigned int i) const
 
Nodechild (unsigned int i) const
 
template<typename T >
auto children (int begin, std::optional< int > end) const
 
template<typename T >
auto children (int begin, std::optional< int > end)
 
template<typename T >
node::Set< T > childrenOfType () const
 
bool hasChild (const Node *n, bool recurse=false) const
 
Nodesibling (Node *n) const
 
void addChild (ASTContext *ctx, Node *n)
 
void addChildren (ASTContext *ctx, const Nodes &children)
 
void removeChild (Node *n)
 
void removeChildren (int begin, std::optional< int > end)
 
void setChild (ASTContext *ctx, size_t idx, Node *n)
 
void replaceChildren (ASTContext *ctx, const Nodes &children)
 
void replaceChild (ASTContext *ctx, Node *old, Node *new_)
 
template<typename T >
bool isA () const
 
template<typename T >
bool isA_ () const
 
template<typename T >
T * as () const
 
template<typename T >
T * as ()
 
template<typename T >
const T * tryAs () const
 
template<typename T >
T * tryAs ()
 
template<typename T >
T * tryAs_ ()
 
void print (std::ostream &out, bool compact, bool user_visible) const
 
std::string print () const
 
std::string printRaw () const
 
 operator std::string () const
 
std::string dump () const
 
std::string renderSelf (bool include_location=true) const
 
void addError (std::string msg, std::vector< std::string > context={})
 
void addError (std::string msg, node::ErrorPriority priority, std::vector< std::string > context={})
 
void addError (std::string msg, const Location &l, std::vector< std::string > context={})
 
void addError (std::string msg, Location l, node::ErrorPriority priority, std::vector< std::string > context={})
 
bool hasErrors () const
 
const auto & errors () const
 
void clearErrors ()
 
void clearChildren ()
 
void retain ()
 
void release ()
 
bool isRetained () const
 
virtual node::Properties properties () const
 
virtual void dispatch (visitor::Dispatcher &v)=0
 
virtual std::string_view branchTag () const
 
Nodeoperator= (const Node &other)=delete
 
Nodeoperator= (Node &&other) noexcept=delete
 

Static Public Attributes

static constexpr uint16_t NodeLevel = 0
 
static constexpr ::hilti::node::Tag NodeTag = ::hilti::node::tag::Node
 
static constexpr ::hilti::node::Tags NodeTags = {::hilti::node::tag::Node}
 

Protected Member Functions

 Node (ASTContext *ctx, node::Tags node_tags, Nodes children, Meta meta)
 
 Node (ASTContext *ctx, node::Tags node_tags, Meta meta)
 
 Node (Node &&other)=default
 
 Node (const Node &other)
 
virtual std::string _typename () const
 
virtual Node_clone (ASTContext *ctx) const =0
 
virtual std::string _dump () const
 

Friends

Nodenode::detail::deepcopy (ASTContext *ctx, Node *n, bool force)
 

Detailed Description

Base class for all AST nodes.

Constructor & Destructor Documentation

◆ Node() [1/3]

hilti::Node::Node ( ASTContext ctx,
node::Tags  node_tags,
Nodes  children,
Meta  meta 
)
inlineprotected

Constructor initializing the node with children and meta data. The semantics for the children's parent pointering and potential deep-copying are the same as if they were added individually through addChild().

Parameters
ctxcurrent context in use
childrenchild nodes to add initially

◆ Node() [2/3]

hilti::Node::Node ( ASTContext ctx,
node::Tags  node_tags,
Meta  meta 
)
inlineprotected

Constructor initializing the node with meta data but no children.

◆ Node() [3/3]

hilti::Node::Node ( const Node other)
inlineprotected

Copy constructor. This copies only meta data and internal flags, but not any children. The parent of the copied node will be unset.

Use node::deepcopy() to fully copy a node.

Member Function Documentation

◆ _clone()

virtual Node* hilti::Node::_clone ( ASTContext ctx) const
protectedpure virtual

Performs a shallow copy. A new instance of the current node class is created and initialized with copies of all attributes and children with latter being copied just by reference. This is for internal use only, use node::deepcopy() to fully clone nodes.

◆ _dump()

virtual std::string hilti::Node::_dump ( ) const
inlineprotectedvirtual

◆ _typename()

virtual std::string hilti::Node::_typename ( ) const
inlineprotectedvirtual

Returns the C++-level class name for the node's type. This is for internal use only. It's the virtual backend to typename_(), which is the one to call instead of this method.

◆ addChild()

void hilti::Node::addChild ( ASTContext ctx,
Node n 
)
inline

Adds a child node. The node will be appended to the end of the current list of children, and its parent will be set to the current node. If the node already has a parent, it will be deep-copied first, and the new instance will be added instead of the once passed in. ×

Parameters
ctxcurrent context in use
nchild node to add; it's ok for this to be null to leave a child slot unset

◆ addChildren()

void hilti::Node::addChildren ( ASTContext ctx,
const Nodes children 
)
inline

Adds a series of child nodes. This operates like calling addChild() on each of them individually.

Parameters
ctxcurrent context in use
childrennodes to add

◆ addError() [1/4]

void hilti::Node::addError ( std::string  msg,
const Location l,
std::vector< std::string >  context = {} 
)
inline

Associates an error message with the node. The error will have normal priority.

Parameters
msgerror message to report
lcustom location to associate with the error
contextfurther lines of context to show along with error

◆ addError() [2/4]

void hilti::Node::addError ( std::string  msg,
Location  l,
node::ErrorPriority  priority,
std::vector< std::string >  context = {} 
)
inline

Associates an error message with the node.

Parameters
msgerror message to report
lcustom location to associate with the error
priorityimportance of showing the error
contextfurther lines of context to show along with error

◆ addError() [3/4]

void hilti::Node::addError ( std::string  msg,
node::ErrorPriority  priority,
std::vector< std::string >  context = {} 
)
inline

Associates an error message with the node. The error's location will be that of the current node.

Parameters
msgerror message to report
priorityimportance of showing the error
contextfurther lines of context to show along with error

◆ addError() [4/4]

void hilti::Node::addError ( std::string  msg,
std::vector< std::string >  context = {} 
)
inline

Associates an error message with the node. The error's location will be that of the current node, and it will have normal priority.

Parameters
msgerror message to report
contextfurther lines of context to show along with error

◆ as() [1/2]

template<typename T >
T* hilti::Node::as ( )
inline

Casts a node into a particular class. The cast from the node to the target type must be valid. If it isn't, in release builds, the call will result in undefined behavior (and probably crash). In debug builds, we'll catch invalid cases and abort with an internal error.

◆ as() [2/2]

template<typename T >
T* hilti::Node::as ( ) const
inline

Casts a node into a particular class. The cast must be a valid C++ dynamic pointer cast, otherwise execution will abort with an internal error.

◆ branchTag()

virtual std::string_view hilti::Node::branchTag ( ) const
inlinevirtual

Optional tag associated with the AST subbranch that this node is the top of. If a tag is returned, this may be used to by visitors to skip the subbranch entirely based on that tag.

Returns
tag associated with the subbranch, or an empty string if none

Reimplemented in hilti::declaration::Module.

◆ child() [1/2]

template<typename T >
T* hilti::Node::child ( unsigned int  i) const
inline

Returns a child.

Template Parameters
Ttype that the child nodes are assumed to (and must) have
Parameters
izero-based index of the child, in the order they were passed into the constructor and/or added
Returns
child casted to type T, or null if there's no child node at that index

◆ child() [2/2]

Node* hilti::Node::child ( unsigned int  i) const
inline

Returns a child at given index inside the vector of all children. The order in that vector is determined by the order in which the children were passed into the constructor and/or added.

Parameters
iindex of the child, with zero being the first
Returns
child at given index, or null if there's no child at that index

◆ children() [1/3]

const auto& hilti::Node::children ( ) const
inline

Returns the set of all children.

◆ children() [2/3]

template<typename T >
auto hilti::Node::children ( int  begin,
std::optional< int >  end 
)
inline

Returns a subrange of children. The indices correspond to the order children were passed into the constructor and/or added.

Template Parameters
Ttype that the child nodes are assumed to (and must) have
Parameters
beginindex of first child to include
endindex of one beyond last child to include; a negative index for end counts Python-style from end of list; if not given, all children from start to the end of the list are returned
Returns
range containing children from start to end

◆ children() [3/3]

template<typename T >
auto hilti::Node::children ( int  begin,
std::optional< int >  end 
) const
inline

Returns a subrange of children. The indices correspond to the order children were passed into the constructor and/or added.

Template Parameters
Ttype that the child nodes are assumed to (and must) have
Parameters
beginindex of first child to include
endindex of one beyond last child to include; a negative index for end counts Python-style from end of list; if not given, all children from start to the end of the list are returned
Returns
range containing children from start to end

◆ childrenOfType()

template<typename T >
node::Set<T> hilti::Node::childrenOfType ( ) const
inline

Returns a subset of children selected by their type.

Template Parameters
Ttype of children to return
Returns
set of all children that have type T

◆ childTryAs()

template<typename T >
T* hilti::Node::childTryAs ( unsigned int  i) const
inline

Returns a child.

Template Parameters
Ttype that the child nodes are assumed to (and must) have
Parameters
izero-based index of the child, in the order they were passed into the constructor and/or added
Returns
child casted to type T, or null if there's no child node at that index

◆ clearChildren()

void Node::clearChildren ( )

Removes all children from the node. It doesn't destroy the children, pointers remain valid, it just unlinks them from their current parent.

◆ clearErrors()

void hilti::Node::clearErrors ( )
inline

Clears any error message associated with the node.

◆ clearScope()

void hilti::Node::clearScope ( )
inline

Removes any associated scope from the node. Afterwards, scope() will return null again.

◆ dispatch()

virtual void hilti::Node::dispatch ( visitor::Dispatcher v)
pure virtual

Dispatch for the visitor API.

◆ dump()

std::string Node::dump ( ) const

Returns an internal string representation of the node and all its children. Note that this can be called from inside a debugger.

◆ errors()

const auto& hilti::Node::errors ( ) const
inline

Returns any error messages associated with the node.

◆ getOrCreateScope()

auto hilti::Node::getOrCreateScope ( )
inline

Returns the node's direct scope if already created, or creates one if it hasn't yet. In the latter case, the new scope is permanently associated with the node before being returned.

◆ hasChild()

bool hilti::Node::hasChild ( const Node n,
bool  recurse = false 
) const
inline

Returns true if the node's children contain a particular child node.

Parameters
nchild node to look for
recurseif true, will also check children of children recursively

◆ hasErrors()

bool hilti::Node::hasErrors ( ) const
inline

Returns true if there are any errors associated with the node.

◆ hasParent()

bool hilti::Node::hasParent ( ) const
inline

Returns true if the node has a parent (i.e., it's part of an AST).

◆ identity()

uint64_t hilti::Node::identity ( ) const
inline

Returns a globally unique numeric identifier for the node.

◆ inheritScope()

virtual bool hilti::Node::inheritScope ( ) const
inlinevirtual

Returns a flag indicating whether a scope lookup passing this node shall find IDs in parent nodes as well. This returns true by default.

Reimplemented in spicy::type::Unit.

◆ isA()

template<typename T >
bool hilti::Node::isA ( ) const
inline

Returns true if a node is of a particular type (class).

◆ isA_()

template<typename T >
bool hilti::Node::isA_ ( ) const
inline

Alternate version to check if a node is of a particular type (class). This version skips any potential internal consistency checks, which can be helpful in case of false positives. You should normally avoid using this unless absolutely necessary.

◆ isRetained()

bool hilti::Node::isRetained ( ) const
inline

Returns true if at least one party has currently retained the node.

◆ location()

const auto& hilti::Node::location ( ) const
inline

Short-cut to return the location from the node's meta information.

◆ lookupID()

Result< std::pair< Declaration *, ID > > Node::lookupID ( const ID id,
const std::string_view &  what 
) const

Looks up an ID in the node's chain of scope, following HILTI's scoping and visibility rules.

Parameters
idid to look up
whatdescription of what we're looking for, for error reporting
Returns
if found, a pair of the declaration the ID refers to plus the declarations canonical ID; if not found an error message appropriate for reporting to the user

◆ meta()

const auto& hilti::Node::meta ( ) const
inline

Returns the meta data associated with the node.

◆ nodeTag()

node::Tag hilti::Node::nodeTag ( ) const
inline

Returns the node tag associated with the instance's class.

◆ operator std::string()

hilti::Node::operator std::string ( ) const
inline

Renders the node as HILTI source code, using the same semantics as print().

◆ parent() [1/2]

template<typename T >
T* hilti::Node::parent ( ) const
inline

Returns the first parent node of a give type.

Template Parameters
Ttype of parent to search
Returns
parent node, or null if the requested parent does not exist

◆ parent() [2/2]

Node* hilti::Node::parent ( int  i = 1) const
inline

Returns a parent node, assuming the node is part of an AST.

Parameters
ilevel of the parent to return, counting from 1 for the immediate parent
Returns
parent node, or null if the requested parent does not exist

◆ pathLength()

auto hilti::Node::pathLength ( ) const
inline

Returns the length of the AST path to the current node from the AST's root. If the node is part of an AST, returns a number >= 1. If it is not (i.e., there's no parent node), returns 0.

◆ print() [1/2]

std::string Node::print ( ) const

Returns a HILTI source code representation of the node and all its children. This always renders the code as "user-visible", per the flag in the extended version of print().

Note that this can be called from inside a debugger.

◆ print() [2/2]

void Node::print ( std::ostream &  out,
bool  compact,
bool  user_visible 
) const

Print out a HILTI source code representation of the node and all its children. If the node is not the root of an AST, it's not guaranteed that the result will form valid HILTI source code (but it can still be used, e.g., in error messages).

Parameters
outoutput stream
compactcreate a one-line representation
user_visibleif true, signal to the printer that the output is intended for user consumption, permitting it to do some visual polishing

◆ printRaw()

std::string Node::printRaw ( ) const

Returns a HILTI source code representation of the node and all its children. This always renders the code as not "user-visible", per the flag in the extended version of Zeek.

Note that this can be called from inside a debugger.

◆ properties()

virtual node::Properties hilti::Node::properties ( ) const
inlinevirtual

Returns any instance properties associated with the node. These are used (only) for debug logging. Derived classes should override this to add any properties they retain inside internal node member variables.

Reimplemented in hilti::QualifiedType, hilti::UnqualifiedType, hilti::Function, hilti::expression::ResolvedOperator, hilti::declaration::Module, hilti::Declaration, hilti::ctor::Struct, hilti::ctor::struct_::Field, spicy::type::Unit, spicy::type::unit::item::UnresolvedField, spicy::type::unit::item::switch_::Case, spicy::type::unit::item::Field, spicy::declaration::Hook, hilti::type::tuple::Element, hilti::type::operand_list::Operand, hilti::type::Name, hilti::type::Member, hilti::type::Library, hilti::type::detail::IntegerBase, hilti::type::Function, hilti::type::enum_::Label, hilti::type::Bitfield, hilti::type::bitfield::BitRange, hilti::statement::Comment, hilti::statement::Assert, hilti::operator_::reference::DerefBase, hilti::expression::UnresolvedOperator, hilti::expression::Name, hilti::expression::Member, hilti::expression::Keyword, hilti::expression::BuiltInFunction, hilti::declaration::Type, hilti::declaration::Parameter, hilti::declaration::ImportedModule, hilti::declaration::Function, hilti::declaration::Field, hilti::ctor::Time, hilti::ctor::String, hilti::ctor::Stream, hilti::ctor::RegExp, hilti::ctor::Real, hilti::ctor::Port, hilti::ctor::Network, hilti::ctor::Interval, hilti::ctor::detail::IntegerBase< Value >, hilti::ctor::detail::IntegerBase< int64_t >, hilti::ctor::detail::IntegerBase< uint64_t >, hilti::ctor::Error, hilti::ctor::Bytes, hilti::ctor::Bool, hilti::ctor::bitfield::BitRange, hilti::ctor::Address, and hilti::Attribute.

◆ release()

void hilti::Node::release ( )
inline

Unpins the node, allowing garbage collection to delete it (assuming no other pins).

◆ removeChild()

void hilti::Node::removeChild ( Node n)
inline

Removes a child from the node. It's parent will be set back to null. Does nothing if the child isn't found.

Parameters
nchild node to remove

◆ removeChildren()

void hilti::Node::removeChildren ( int  begin,
std::optional< int >  end 
)
inline

Removes a range of children from the node. They nodes won't be destroyed but their parents will be reset back to null.

Parameters
beginindex of first child to remove
endindex of one beyond last child to include; a negative index for end counts Python-style from end of list; if not given, all children from start to the end of the list are returned

◆ renderSelf()

std::string Node::renderSelf ( bool  include_location = true) const

Returns an internal string representation of the node itself, excluding its children.

Parameters
include_locationif true, include source code locations into the output

◆ replaceChild()

void Node::replaceChild ( ASTContext ctx,
Node old,
Node new_ 
)

Replaces a single child with a new one. The old one is removed, and the new one is then stored at the old one's index. Semantics for parent pointering and deep-copying are the same as removing/adding individual children.

Parameters
ctxcurrent context in use
oldchild to replace, which must exist (otherwise the method will abort with an internal error)
new_new child to replace old with

◆ replaceChildren()

void Node::replaceChildren ( ASTContext ctx,
const Nodes children 
)

Replaces all children with a new set children. The function operates like first removing all children, and then adding all the new ones in the same order, with the same semantics for parent pointering and deep-copying as adding/removing individual children exhibits.

Parameters
ctxcurrent context in use
childrennew children to set

◆ retain()

void hilti::Node::retain ( )
inline

Pins the node in memory, ensuring garbage collection won't delete it.

◆ scope()

auto hilti::Node::scope ( ) const
inline

Returns the scope associated with the node, if any. Returns null if no scope has been created for the node yet.

◆ setChild()

void hilti::Node::setChild ( ASTContext ctx,
size_t  idx,
Node n 
)
inline

Sets the child at a particular index. Its parent will be set to the current node. If the node already has a parent, it will be deep-copied first, and the new instance will be added instead of the once passed in. If there's an existing child at that index, it'll be removed first and its parent cleared.

Parameters
ctxcurrent context in use
idxindex of child to set
nchild node to set; this may be null to unset the particular index

◆ setMeta()

void hilti::Node::setMeta ( Meta  m)
inline

Sets the meta data associated with the node.

◆ sibling()

Node* hilti::Node::sibling ( Node n) const
inline

Returns the subsequent sibling of given child node. This skips over null children.

Parameters
nchild whose sibling to return
Returns
sibling of n, or null if n is the last child or not child at all

◆ tryAs() [1/2]

template<typename T >
T* hilti::Node::tryAs ( )
inline

Attempts to casts a node into a particular class. Returns a nullptr if the cast failed.

◆ tryAs() [2/2]

template<typename T >
const T* hilti::Node::tryAs ( ) const
inline

Attempts to casts a node into a particular class. Returns a nullptr if the cast failed.

◆ tryAs_()

template<typename T >
T* hilti::Node::tryAs_ ( )
inline

Alternate version to attempt casting a node into a particular class. Returns a nullptr if the cast failed. This version skips any potential internal consistency checks, which can be helpful in case of false positives. You should normally avoid using this unless absolutely necessary.

◆ typename_()

std::string hilti::Node::typename_ ( ) const
inline

Returns the C++-level type for the nodes' class. This should be only used for for debugging purposes.


The documentation for this class was generated from the following files: