1
0
Fork 0
arangodb/arangod/Aql/AstNode.h

790 lines
33 KiB
C++

////////////////////////////////////////////////////////////////////////////////
/// @brief Aql, AST node
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Jan Steemann
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
#ifndef ARANGODB_AQL_ASTNODE_H
#define ARANGODB_AQL_ASTNODE_H 1
#include "Basics/Common.h"
#include "Basics/Exceptions.h"
#include "Basics/json.h"
#include "Basics/vector.h"
#include "Basics/JsonHelper.h"
#include "Aql/Query.h"
namespace triagens {
namespace basics {
class StringBuffer;
}
namespace aql {
class Ast;
////////////////////////////////////////////////////////////////////////////////
/// @brief type for node flags
////////////////////////////////////////////////////////////////////////////////
typedef uint32_t AstNodeFlagsType;
////////////////////////////////////////////////////////////////////////////////
/// @brief different flags for nodes
/// the flags are used to prevent repeated calculations of node properties
/// (e.g. is the node value constant, sorted etc.)
////////////////////////////////////////////////////////////////////////////////
enum AstNodeFlagType : AstNodeFlagsType {
DETERMINED_SORTED = 1, // node is a list and its members are sorted asc.
DETERMINED_CONSTANT = 2, // node value is constant (i.e. not dynamic)
DETERMINED_SIMPLE = 4, // node value is simple (i.e. for use in a simple expression)
DETERMINED_THROWS = 8, // node can throw an exception
DETERMINED_NONDETERMINISTIC = 16, // node produces non-deterministic result (e.g. function call nodes)
DETERMINED_RUNONDBSERVER = 32, // node can run on the DB server in a cluster setup
VALUE_SORTED = 64, // node is a list and its members are sorted asc.
VALUE_CONSTANT = 128, // node value is constant (i.e. not dynamic)
VALUE_SIMPLE = 256, // node value is simple (i.e. for use in a simple expression)
VALUE_THROWS = 512, // node can throw an exception
VALUE_NONDETERMINISTIC = 1024, // node produces non-deterministic result (e.g. function call nodes)
VALUE_RUNONDBSERVER = 2048, // node can run on the DB server in a cluster setup
FLAG_KEEP_VARIABLENAME = 4096, // node is a reference to a variable name, not the variable value (used in KEEP nodes)
FLAG_BIND_PARAMETER = 8192 // node was created from a JSON bind parameter
};
////////////////////////////////////////////////////////////////////////////////
/// @brief enumeration of AST node value types
/// note: these types must be declared in asc. sort order
////////////////////////////////////////////////////////////////////////////////
enum AstNodeValueType : uint8_t {
VALUE_TYPE_NULL = 0,
VALUE_TYPE_BOOL = 1,
VALUE_TYPE_INT = 2,
VALUE_TYPE_DOUBLE = 3,
VALUE_TYPE_STRING = 4
};
static_assert(VALUE_TYPE_NULL < VALUE_TYPE_BOOL, "incorrect ast node value types");
static_assert(VALUE_TYPE_BOOL < VALUE_TYPE_INT, "incorrect ast node value types");
static_assert(VALUE_TYPE_INT < VALUE_TYPE_DOUBLE, "incorrect ast node value types");
static_assert(VALUE_TYPE_DOUBLE < VALUE_TYPE_STRING, "incorrect ast node value types");
////////////////////////////////////////////////////////////////////////////////
/// @brief AST node value
////////////////////////////////////////////////////////////////////////////////
struct AstNodeValue {
union {
int64_t _int;
double _double;
bool _bool;
char const* _string;
void* _data;
}
value;
uint32_t length; // only used for string values
AstNodeValueType type;
};
////////////////////////////////////////////////////////////////////////////////
/// @brief enumeration of AST node types
////////////////////////////////////////////////////////////////////////////////
enum AstNodeType : uint32_t {
NODE_TYPE_ROOT = 0,
NODE_TYPE_FOR = 1,
NODE_TYPE_LET = 2,
NODE_TYPE_FILTER = 3,
NODE_TYPE_RETURN = 4,
NODE_TYPE_REMOVE = 5,
NODE_TYPE_INSERT = 6,
NODE_TYPE_UPDATE = 7,
NODE_TYPE_REPLACE = 8,
NODE_TYPE_COLLECT = 9,
NODE_TYPE_SORT = 10,
NODE_TYPE_SORT_ELEMENT = 11,
NODE_TYPE_LIMIT = 12,
NODE_TYPE_VARIABLE = 13,
NODE_TYPE_ASSIGN = 14,
NODE_TYPE_OPERATOR_UNARY_PLUS = 15,
NODE_TYPE_OPERATOR_UNARY_MINUS = 16,
NODE_TYPE_OPERATOR_UNARY_NOT = 17,
NODE_TYPE_OPERATOR_BINARY_AND = 18,
NODE_TYPE_OPERATOR_BINARY_OR = 19,
NODE_TYPE_OPERATOR_BINARY_PLUS = 20,
NODE_TYPE_OPERATOR_BINARY_MINUS = 21,
NODE_TYPE_OPERATOR_BINARY_TIMES = 22,
NODE_TYPE_OPERATOR_BINARY_DIV = 23,
NODE_TYPE_OPERATOR_BINARY_MOD = 24,
NODE_TYPE_OPERATOR_BINARY_EQ = 25,
NODE_TYPE_OPERATOR_BINARY_NE = 26,
NODE_TYPE_OPERATOR_BINARY_LT = 27,
NODE_TYPE_OPERATOR_BINARY_LE = 28,
NODE_TYPE_OPERATOR_BINARY_GT = 29,
NODE_TYPE_OPERATOR_BINARY_GE = 30,
NODE_TYPE_OPERATOR_BINARY_IN = 31,
NODE_TYPE_OPERATOR_BINARY_NIN = 32,
NODE_TYPE_OPERATOR_TERNARY = 33,
NODE_TYPE_SUBQUERY = 34,
NODE_TYPE_ATTRIBUTE_ACCESS = 35,
NODE_TYPE_BOUND_ATTRIBUTE_ACCESS = 36,
NODE_TYPE_INDEXED_ACCESS = 37,
NODE_TYPE_EXPANSION = 38,
NODE_TYPE_ITERATOR = 39,
NODE_TYPE_VALUE = 40,
NODE_TYPE_ARRAY = 41,
NODE_TYPE_OBJECT = 42,
NODE_TYPE_OBJECT_ELEMENT = 43,
NODE_TYPE_COLLECTION = 44,
NODE_TYPE_REFERENCE = 45,
NODE_TYPE_PARAMETER = 46,
NODE_TYPE_FCALL = 47,
NODE_TYPE_FCALL_USER = 48,
NODE_TYPE_RANGE = 49,
NODE_TYPE_NOP = 50,
NODE_TYPE_COLLECT_COUNT = 51,
NODE_TYPE_COLLECT_EXPRESSION = 52,
NODE_TYPE_CALCULATED_OBJECT_ELEMENT = 53,
NODE_TYPE_UPSERT = 54,
NODE_TYPE_EXAMPLE = 55,
NODE_TYPE_PASSTHRU = 56,
NODE_TYPE_ARRAY_LIMIT = 57,
NODE_TYPE_DISTINCT = 58
};
static_assert(NODE_TYPE_VALUE < NODE_TYPE_ARRAY, "incorrect node types order");
static_assert(NODE_TYPE_ARRAY < NODE_TYPE_OBJECT, "incorrect node types order");
// -----------------------------------------------------------------------------
// --SECTION-- struct AstNode
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief the node
////////////////////////////////////////////////////////////////////////////////
struct AstNode {
static std::unordered_map<int, std::string const> const Operators;
static std::unordered_map<int, std::string const> const TypeNames;
static std::unordered_map<int, std::string const> const ValueTypeNames;
// -----------------------------------------------------------------------------
// --SECTION-- constructors / destructors
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief create the node
////////////////////////////////////////////////////////////////////////////////
explicit AstNode (AstNodeType);
////////////////////////////////////////////////////////////////////////////////
/// @brief create a node, with defining a value type
////////////////////////////////////////////////////////////////////////////////
explicit AstNode (AstNodeType, AstNodeValueType);
////////////////////////////////////////////////////////////////////////////////
/// @brief create a boolean node, with defining a value type
////////////////////////////////////////////////////////////////////////////////
explicit AstNode (bool, AstNodeValueType);
////////////////////////////////////////////////////////////////////////////////
/// @brief create a boolean node, with defining a value type
////////////////////////////////////////////////////////////////////////////////
explicit AstNode (int64_t, AstNodeValueType);
////////////////////////////////////////////////////////////////////////////////
/// @brief create a string node, with defining a value type
////////////////////////////////////////////////////////////////////////////////
explicit AstNode (char const*, size_t, AstNodeValueType);
////////////////////////////////////////////////////////////////////////////////
/// @brief create the node from JSON
////////////////////////////////////////////////////////////////////////////////
AstNode (Ast*,
triagens::basics::Json const& json);
////////////////////////////////////////////////////////////////////////////////
/// @brief destroy the node
////////////////////////////////////////////////////////////////////////////////
~AstNode ();
// -----------------------------------------------------------------------------
// --SECTION-- public methods
// -----------------------------------------------------------------------------
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief compute the JSON for a constant value node
/// the JSON is owned by the node and must not be freed by the caller
/// note that the return value might be NULL in case of OOM
////////////////////////////////////////////////////////////////////////////////
TRI_json_t* computeJson () const;
////////////////////////////////////////////////////////////////////////////////
/// @brief sort the members of a (list) node
/// this will also set the FLAG_SORTED flag for the node
////////////////////////////////////////////////////////////////////////////////
void sort ();
////////////////////////////////////////////////////////////////////////////////
/// @brief return the type name of a node
////////////////////////////////////////////////////////////////////////////////
std::string const& getTypeString () const;
////////////////////////////////////////////////////////////////////////////////
/// @brief return the value type name of a node
////////////////////////////////////////////////////////////////////////////////
std::string const& getValueTypeString () const;
////////////////////////////////////////////////////////////////////////////////
/// @brief checks whether we know a type of this kind; throws exception if not.
////////////////////////////////////////////////////////////////////////////////
static void validateType (int type);
////////////////////////////////////////////////////////////////////////////////
/// @brief checks whether we know a value type of this kind;
/// throws exception if not.
////////////////////////////////////////////////////////////////////////////////
static void validateValueType (int type);
////////////////////////////////////////////////////////////////////////////////
/// @brief fetch a node's type from json
////////////////////////////////////////////////////////////////////////////////
static AstNodeType getNodeTypeFromJson (triagens::basics::Json const& json);
////////////////////////////////////////////////////////////////////////////////
/// @brief return a JSON representation of the node value
/// the caller is responsible for freeing the JSON later
////////////////////////////////////////////////////////////////////////////////
TRI_json_t* toJsonValue (TRI_memory_zone_t*) const;
////////////////////////////////////////////////////////////////////////////////
/// @brief return a JSON representation of the node
/// the caller is responsible for freeing the JSON later
////////////////////////////////////////////////////////////////////////////////
TRI_json_t* toJson (TRI_memory_zone_t*,
bool) const;
////////////////////////////////////////////////////////////////////////////////
/// @brief adds a JSON representation of the node to the JSON list specified
/// in the first argument
////////////////////////////////////////////////////////////////////////////////
void toJson (TRI_json_t*,
TRI_memory_zone_t*,
bool) const;
////////////////////////////////////////////////////////////////////////////////
/// @brief convert the node's value to a boolean value
/// this may create a new node or return the node itself if it is already a
/// boolean value node
////////////////////////////////////////////////////////////////////////////////
AstNode* castToBool (Ast*);
////////////////////////////////////////////////////////////////////////////////
/// @brief convert the node's value to a number value
/// this may create a new node or return the node itself if it is already a
/// numeric value node
////////////////////////////////////////////////////////////////////////////////
AstNode* castToNumber (Ast*);
////////////////////////////////////////////////////////////////////////////////
/// @brief convert the node's value to a string value
/// this may create a new node or return the node itself if it is already a
/// string value node
////////////////////////////////////////////////////////////////////////////////
AstNode* castToString (Ast*);
////////////////////////////////////////////////////////////////////////////////
/// @brief check a flag for the node
////////////////////////////////////////////////////////////////////////////////
inline bool hasFlag (AstNodeFlagType flag) const {
return ((flags & static_cast<decltype(flags)>(flag)) != 0);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief reset flags in case a node is changed drastically
////////////////////////////////////////////////////////////////////////////////
inline void clearFlags () {
flags = 0;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief set a flag for the node
////////////////////////////////////////////////////////////////////////////////
inline void setFlag (AstNodeFlagType flag) const {
flags |= static_cast<decltype(flags)>(flag);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief set two flags for the node
////////////////////////////////////////////////////////////////////////////////
inline void setFlag (AstNodeFlagType typeFlag,
AstNodeFlagType valueFlag) const {
flags |= static_cast<decltype(flags)>(typeFlag | valueFlag);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not the node value is trueish
////////////////////////////////////////////////////////////////////////////////
bool isTrue () const;
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not the node value is falsey
////////////////////////////////////////////////////////////////////////////////
bool isFalse () const;
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not the members of a list node are sorted
////////////////////////////////////////////////////////////////////////////////
inline bool isSorted () const {
return ((flags & static_cast<decltype(flags)>(DETERMINED_SORTED | VALUE_SORTED)) ==
static_cast<decltype(flags)>(DETERMINED_SORTED | VALUE_SORTED));
}
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not a value node is NULL
////////////////////////////////////////////////////////////////////////////////
inline bool isNullValue () const {
return (type == NODE_TYPE_VALUE && value.type == VALUE_TYPE_NULL);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not a value node is an integer
////////////////////////////////////////////////////////////////////////////////
inline bool isIntValue () const {
return (type == NODE_TYPE_VALUE && value.type == VALUE_TYPE_INT);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not a value node is a dobule
////////////////////////////////////////////////////////////////////////////////
inline bool isDoubleValue () const {
return (type == NODE_TYPE_VALUE && value.type == VALUE_TYPE_DOUBLE);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not a value node is of numeric type
////////////////////////////////////////////////////////////////////////////////
inline bool isNumericValue () const {
return (type == NODE_TYPE_VALUE &&
(value.type == VALUE_TYPE_INT || value.type == VALUE_TYPE_DOUBLE));
}
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not a value node is of bool type
////////////////////////////////////////////////////////////////////////////////
inline bool isBoolValue () const {
return (type == NODE_TYPE_VALUE && value.type == VALUE_TYPE_BOOL);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not a value node is of string type
////////////////////////////////////////////////////////////////////////////////
inline bool isStringValue () const {
return (type == NODE_TYPE_VALUE && value.type == VALUE_TYPE_STRING);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not a value node is of list type
////////////////////////////////////////////////////////////////////////////////
inline bool isArray () const {
return (type == NODE_TYPE_ARRAY);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not a value node is of array type
////////////////////////////////////////////////////////////////////////////////
inline bool isObject () const {
return (type == NODE_TYPE_OBJECT);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not a node is simple enough to be used in a simple
/// expression
/// this may also set the FLAG_SIMPLE flag for the node
////////////////////////////////////////////////////////////////////////////////
bool isSimple () const;
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not a node has a constant value
/// this may also set the FLAG_CONSTANT or the FLAG_DYNAMIC flags for the node
////////////////////////////////////////////////////////////////////////////////
bool isConstant () const;
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not a node is a comparison operator
////////////////////////////////////////////////////////////////////////////////
bool isComparisonOperator () const;
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not a node (and its subnodes) may throw a runtime
/// exception
////////////////////////////////////////////////////////////////////////////////
bool canThrow () const;
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not a node (and its subnodes) can safely be executed on
/// a DB server
////////////////////////////////////////////////////////////////////////////////
bool canRunOnDBServer () const;
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not a node (and its subnodes) is deterministic
////////////////////////////////////////////////////////////////////////////////
bool isDeterministic () const;
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not a node (and its subnodes) is cacheable
////////////////////////////////////////////////////////////////////////////////
bool isCacheable () const;
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not the object node contains dynamically named attributes
/// on its first level
////////////////////////////////////////////////////////////////////////////////
bool containsDynamicAttributeName () const;
////////////////////////////////////////////////////////////////////////////////
/// @brief return the number of members
////////////////////////////////////////////////////////////////////////////////
inline size_t numMembers () const throw() {
return members._length;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief add a member to the node
////////////////////////////////////////////////////////////////////////////////
void addMember (AstNode* node) {
if (node == nullptr) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
}
int res = TRI_PushBackVectorPointer(&members, static_cast<void*>(node));
if (res != TRI_ERROR_NO_ERROR) {
THROW_ARANGO_EXCEPTION(res);
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief add a member to the node
////////////////////////////////////////////////////////////////////////////////
inline void addMember (AstNode const* node) {
addMember(const_cast<AstNode*>(node));
}
////////////////////////////////////////////////////////////////////////////////
/// @brief change a member of the node
////////////////////////////////////////////////////////////////////////////////
void changeMember (size_t i,
AstNode* node) {
if (i >= members._length) {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "member out of range");
}
members._buffer[i] = node;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return a member of the node
////////////////////////////////////////////////////////////////////////////////
inline AstNode* getMember (size_t i) const {
if (i >= members._length) {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "member out of range");
}
return getMemberUnchecked(i);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return a member of the node
////////////////////////////////////////////////////////////////////////////////
inline AstNode* getMemberUnchecked (size_t i) const throw() {
return static_cast<AstNode*>(members._buffer[i]);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief set the node's value type
////////////////////////////////////////////////////////////////////////////////
inline void setValueType (AstNodeValueType type) {
value.type = type;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief check whether this node value is of expectedType
////////////////////////////////////////////////////////////////////////////////
inline bool isValueType (AstNodeValueType expectedType) {
return value.type == expectedType;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return the bool value of a node
////////////////////////////////////////////////////////////////////////////////
inline bool getBoolValue () const {
return value.value._bool;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief set the bool value of a node
////////////////////////////////////////////////////////////////////////////////
inline void setBoolValue (bool v) {
value.value._bool = v;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return the int value of a node
/// this will return 0 for all non-value nodes and for all non-int value nodes!!
////////////////////////////////////////////////////////////////////////////////
int64_t getIntValue () const;
////////////////////////////////////////////////////////////////////////////////
/// @brief return the int value stored for a node, regardless of the node type
////////////////////////////////////////////////////////////////////////////////
inline int64_t getIntValue (bool) const {
return value.value._int;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief set the int value of a node
////////////////////////////////////////////////////////////////////////////////
inline void setIntValue (int64_t v) {
value.value._int = v;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return the double value of a node
////////////////////////////////////////////////////////////////////////////////
double getDoubleValue () const;
////////////////////////////////////////////////////////////////////////////////
/// @brief set the string value of a node
////////////////////////////////////////////////////////////////////////////////
inline void setDoubleValue (double v) {
value.value._double = v;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return the string value of a node
////////////////////////////////////////////////////////////////////////////////
inline char const* getStringValue () const {
return value.value._string;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return the string value of a node
////////////////////////////////////////////////////////////////////////////////
inline size_t getStringLength () const {
return static_cast<size_t>(value.length);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief set the string value of a node
////////////////////////////////////////////////////////////////////////////////
inline void setStringValue (char const* v,
size_t length) {
// note: v may contain the NUL byte
TRI_ASSERT(v == nullptr || strlen(v) <= length);
value.value._string = v;
value.length = static_cast<uint32_t>(length);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return the data value of a node
////////////////////////////////////////////////////////////////////////////////
inline void* getData () const {
return value.value._data;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief set the data value of a node
////////////////////////////////////////////////////////////////////////////////
inline void setData (void* v) {
value.value._data = v;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief set the data value of a node
////////////////////////////////////////////////////////////////////////////////
inline void setData (void const* v) {
value.value._data = const_cast<void*>(v);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief clone a node, recursively
////////////////////////////////////////////////////////////////////////////////
AstNode* clone (Ast*) const;
////////////////////////////////////////////////////////////////////////////////
/// @brief append a JavaScript representation of the node into a string buffer
////////////////////////////////////////////////////////////////////////////////
void stringify (triagens::basics::StringBuffer*,
bool,
bool) const;
std::string toString () const;
// -----------------------------------------------------------------------------
// --SECTION-- private methods
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief stringify the value of a node into a string buffer
/// this method is used when generated JavaScript code for the node!
/// this creates an equivalent to what JSON.stringify() would do
////////////////////////////////////////////////////////////////////////////////
void appendValue (triagens::basics::StringBuffer*) const;
// -----------------------------------------------------------------------------
// --SECTION-- public variables
// -----------------------------------------------------------------------------
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief the node type
////////////////////////////////////////////////////////////////////////////////
AstNodeType const type;
////////////////////////////////////////////////////////////////////////////////
/// @brief flags for the node
////////////////////////////////////////////////////////////////////////////////
AstNodeFlagsType mutable flags;
////////////////////////////////////////////////////////////////////////////////
/// @brief the node value
////////////////////////////////////////////////////////////////////////////////
AstNodeValue value;
// -----------------------------------------------------------------------------
// --SECTION-- private variables
// -----------------------------------------------------------------------------
private:
////////////////////////////////////////////////////////////////////////////////
/// @brief precomputed JSON value (used when executing expressions)
////////////////////////////////////////////////////////////////////////////////
TRI_json_t mutable* computedJson;
////////////////////////////////////////////////////////////////////////////////
/// @brief the node's sub nodes
////////////////////////////////////////////////////////////////////////////////
TRI_vector_pointer_t members;
};
int CompareAstNodes (AstNode const*, AstNode const*, bool);
}
}
#endif
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------
// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
// End: