|
Packit Service |
7770af |
#ifndef SASS_AST_H
|
|
Packit Service |
7770af |
#define SASS_AST_H
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
#include "sass.hpp"
|
|
Packit Service |
7770af |
#include <set>
|
|
Packit Service |
7770af |
#include <deque>
|
|
Packit Service |
7770af |
#include <vector>
|
|
Packit Service |
7770af |
#include <string>
|
|
Packit Service |
7770af |
#include <sstream>
|
|
Packit Service |
7770af |
#include <iostream>
|
|
Packit Service |
7770af |
#include <typeinfo>
|
|
Packit Service |
7770af |
#include <algorithm>
|
|
Packit Service |
7770af |
#include "sass/base.h"
|
|
Packit Service |
7770af |
#include "ast_fwd_decl.hpp"
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
#ifdef DEBUG_SHARED_PTR
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
#define ATTACH_VIRTUAL_AST_OPERATIONS(klass) \
|
|
Packit Service |
7770af |
virtual klass##_Ptr copy(std::string, size_t) const = 0; \
|
|
Packit Service |
7770af |
virtual klass##_Ptr clone(std::string, size_t) const = 0; \
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
#define ATTACH_AST_OPERATIONS(klass) \
|
|
Packit Service |
7770af |
virtual klass##_Ptr copy(std::string, size_t) const; \
|
|
Packit Service |
7770af |
virtual klass##_Ptr clone(std::string, size_t) const; \
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
#else
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
#define ATTACH_VIRTUAL_AST_OPERATIONS(klass) \
|
|
Packit Service |
7770af |
virtual klass##_Ptr copy() const = 0; \
|
|
Packit Service |
7770af |
virtual klass##_Ptr clone() const = 0; \
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
#define ATTACH_AST_OPERATIONS(klass) \
|
|
Packit Service |
7770af |
virtual klass##_Ptr copy() const; \
|
|
Packit Service |
7770af |
virtual klass##_Ptr clone() const; \
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
#endif
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
#ifdef __clang__
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
/*
|
|
Packit Service |
7770af |
* There are some overloads used here that trigger the clang overload
|
|
Packit Service |
7770af |
* hiding warning. Specifically:
|
|
Packit Service |
7770af |
*
|
|
Packit Service |
7770af |
* Type type() which hides string type() from Expression
|
|
Packit Service |
7770af |
*
|
|
Packit Service |
7770af |
*/
|
|
Packit Service |
7770af |
#pragma clang diagnostic push
|
|
Packit Service |
7770af |
#pragma clang diagnostic ignored "-Woverloaded-virtual"
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
#endif
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
#include "util.hpp"
|
|
Packit Service |
7770af |
#include "units.hpp"
|
|
Packit Service |
7770af |
#include "context.hpp"
|
|
Packit Service |
7770af |
#include "position.hpp"
|
|
Packit Service |
7770af |
#include "constants.hpp"
|
|
Packit Service |
7770af |
#include "operation.hpp"
|
|
Packit Service |
7770af |
#include "position.hpp"
|
|
Packit Service |
7770af |
#include "inspect.hpp"
|
|
Packit Service |
7770af |
#include "source_map.hpp"
|
|
Packit Service |
7770af |
#include "environment.hpp"
|
|
Packit Service |
7770af |
#include "error_handling.hpp"
|
|
Packit Service |
7770af |
#include "ast_def_macros.hpp"
|
|
Packit Service |
7770af |
#include "ast_fwd_decl.hpp"
|
|
Packit Service |
7770af |
#include "source_map.hpp"
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
#include "sass.h"
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
namespace Sass {
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// easier to search with name
|
|
Packit Service |
7770af |
const bool DELAYED = true;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// ToDo: should this really be hardcoded
|
|
Packit Service |
7770af |
// Note: most methods follow precision option
|
|
Packit Service |
7770af |
const double NUMBER_EPSILON = 0.00000000000001;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// ToDo: where does this fit best?
|
|
Packit Service |
7770af |
// We don't share this with C-API?
|
|
Packit Service |
7770af |
class Operand {
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Operand(Sass_OP operand, bool ws_before = false, bool ws_after = false)
|
|
Packit Service |
7770af |
: operand(operand), ws_before(ws_before), ws_after(ws_after)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
enum Sass_OP operand;
|
|
Packit Service |
7770af |
bool ws_before;
|
|
Packit Service |
7770af |
bool ws_after;
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
//////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// `hash_combine` comes from boost (functional/hash):
|
|
Packit Service |
7770af |
// http://www.boost.org/doc/libs/1_35_0/doc/html/hash/combine.html
|
|
Packit Service |
7770af |
// Boost Software License - Version 1.0
|
|
Packit Service |
7770af |
// http://www.boost.org/users/license.html
|
|
Packit Service |
7770af |
template <typename T>
|
|
Packit Service |
7770af |
void hash_combine (std::size_t& seed, const T& val)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
seed ^= std::hash<T>()(val) + 0x9e3779b9
|
|
Packit Service |
7770af |
+ (seed<<6) + (seed>>2);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
//////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
//////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Abstract base class for all abstract syntax tree nodes.
|
|
Packit Service |
7770af |
//////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class AST_Node : public SharedObj {
|
|
Packit Service |
7770af |
ADD_PROPERTY(ParserState, pstate)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
AST_Node(ParserState pstate)
|
|
Packit Service |
7770af |
: pstate_(pstate)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
AST_Node(const AST_Node* ptr)
|
|
Packit Service |
7770af |
: pstate_(ptr->pstate_)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// AST_Node(AST_Node& ptr) = delete;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual ~AST_Node() = 0;
|
|
Packit Service |
7770af |
virtual size_t hash() { return 0; }
|
|
Packit Service |
7770af |
ATTACH_VIRTUAL_AST_OPERATIONS(AST_Node);
|
|
Packit Service |
7770af |
virtual std::string inspect() const { return to_string({ INSPECT, 5 }); }
|
|
Packit Service |
7770af |
virtual std::string to_sass() const { return to_string({ TO_SASS, 5 }); }
|
|
Packit Service |
7770af |
virtual const std::string to_string(Sass_Inspect_Options opt) const;
|
|
Packit Service |
7770af |
virtual const std::string to_string() const;
|
|
Packit Service |
7770af |
virtual void cloneChildren() {};
|
|
Packit Service |
7770af |
// generic find function (not fully implemented yet)
|
|
Packit Service |
7770af |
// ToDo: add specific implementions to all children
|
|
Packit Service |
7770af |
virtual bool find ( bool (*f)(AST_Node_Obj) ) { return f(this); };
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
void update_pstate(const ParserState& pstate);
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Offset off() { return pstate(); }
|
|
Packit Service |
7770af |
Position pos() { return pstate(); }
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
inline AST_Node::~AST_Node() { }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
//////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// define cast template now (need complete type)
|
|
Packit Service |
7770af |
//////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
template<class T>
|
|
Packit Service |
7770af |
T* Cast(AST_Node* ptr) {
|
|
Packit Service |
7770af |
return ptr && typeid(T) == typeid(*ptr) ?
|
|
Packit Service |
7770af |
static_cast<T*>(ptr) : NULL;
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
template<class T>
|
|
Packit Service |
7770af |
const T* Cast(const AST_Node* ptr) {
|
|
Packit Service |
7770af |
return ptr && typeid(T) == typeid(*ptr) ?
|
|
Packit Service |
7770af |
static_cast<const T*>(ptr) : NULL;
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
//////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Abstract base class for expressions. This side of the AST hierarchy
|
|
Packit Service |
7770af |
// represents elements in value contexts, which exist primarily to be
|
|
Packit Service |
7770af |
// evaluated and returned.
|
|
Packit Service |
7770af |
//////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Expression : public AST_Node {
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
enum Concrete_Type {
|
|
Packit Service |
7770af |
NONE,
|
|
Packit Service |
7770af |
BOOLEAN,
|
|
Packit Service |
7770af |
NUMBER,
|
|
Packit Service |
7770af |
COLOR,
|
|
Packit Service |
7770af |
STRING,
|
|
Packit Service |
7770af |
LIST,
|
|
Packit Service |
7770af |
MAP,
|
|
Packit Service |
7770af |
SELECTOR,
|
|
Packit Service |
7770af |
NULL_VAL,
|
|
Packit Service |
7770af |
C_WARNING,
|
|
Packit Service |
7770af |
C_ERROR,
|
|
Packit Service |
7770af |
FUNCTION,
|
|
Packit Service |
7770af |
VARIABLE,
|
|
Packit Service |
7770af |
NUM_TYPES
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
enum Simple_Type {
|
|
Packit Service |
7770af |
SIMPLE,
|
|
Packit Service |
7770af |
ATTR_SEL,
|
|
Packit Service |
7770af |
PSEUDO_SEL,
|
|
Packit Service |
7770af |
WRAPPED_SEL,
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
private:
|
|
Packit Service |
7770af |
// expressions in some contexts shouldn't be evaluated
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, is_delayed)
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, is_expanded)
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, is_interpolant)
|
|
Packit Service |
7770af |
ADD_PROPERTY(Concrete_Type, concrete_type)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Expression(ParserState pstate,
|
|
Packit Service |
7770af |
bool d = false, bool e = false, bool i = false, Concrete_Type ct = NONE)
|
|
Packit Service |
7770af |
: AST_Node(pstate),
|
|
Packit Service |
7770af |
is_delayed_(d),
|
|
Packit Service |
7770af |
is_expanded_(e),
|
|
Packit Service |
7770af |
is_interpolant_(i),
|
|
Packit Service |
7770af |
concrete_type_(ct)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
Expression(const Expression* ptr)
|
|
Packit Service |
7770af |
: AST_Node(ptr),
|
|
Packit Service |
7770af |
is_delayed_(ptr->is_delayed_),
|
|
Packit Service |
7770af |
is_expanded_(ptr->is_expanded_),
|
|
Packit Service |
7770af |
is_interpolant_(ptr->is_interpolant_),
|
|
Packit Service |
7770af |
concrete_type_(ptr->concrete_type_)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
virtual operator bool() { return true; }
|
|
Packit Service |
7770af |
virtual ~Expression() { }
|
|
Packit Service |
7770af |
virtual std::string type() const { return ""; /* TODO: raise an error? */ }
|
|
Packit Service |
7770af |
virtual bool is_invisible() const { return false; }
|
|
Packit Service |
7770af |
static std::string type_name() { return ""; }
|
|
Packit Service |
7770af |
virtual bool is_false() { return false; }
|
|
Packit Service |
7770af |
// virtual bool is_true() { return !is_false(); }
|
|
Packit Service |
7770af |
virtual bool operator== (const Expression& rhs) const { return false; }
|
|
Packit Service |
7770af |
virtual bool eq(const Expression& rhs) const { return *this == rhs; };
|
|
Packit Service |
7770af |
virtual void set_delayed(bool delayed) { is_delayed(delayed); }
|
|
Packit Service |
7770af |
virtual bool has_interpolant() const { return is_interpolant(); }
|
|
Packit Service |
7770af |
virtual bool is_left_interpolant() const { return is_interpolant(); }
|
|
Packit Service |
7770af |
virtual bool is_right_interpolant() const { return is_interpolant(); }
|
|
Packit Service |
7770af |
virtual std::string inspect() const { return to_string({ INSPECT, 5 }); }
|
|
Packit Service |
7770af |
virtual std::string to_sass() const { return to_string({ TO_SASS, 5 }); }
|
|
Packit Service |
7770af |
ATTACH_VIRTUAL_AST_OPERATIONS(Expression);
|
|
Packit Service |
7770af |
virtual size_t hash() { return 0; }
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
//////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Still just an expression, but with a to_string method
|
|
Packit Service |
7770af |
//////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class PreValue : public Expression {
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
PreValue(ParserState pstate,
|
|
Packit Service |
7770af |
bool d = false, bool e = false, bool i = false, Concrete_Type ct = NONE)
|
|
Packit Service |
7770af |
: Expression(pstate, d, e, i, ct)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
PreValue(const PreValue* ptr)
|
|
Packit Service |
7770af |
: Expression(ptr)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
ATTACH_VIRTUAL_AST_OPERATIONS(PreValue);
|
|
Packit Service |
7770af |
virtual ~PreValue() { }
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
//////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// base class for values that support operations
|
|
Packit Service |
7770af |
//////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Value : public Expression {
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Value(ParserState pstate,
|
|
Packit Service |
7770af |
bool d = false, bool e = false, bool i = false, Concrete_Type ct = NONE)
|
|
Packit Service |
7770af |
: Expression(pstate, d, e, i, ct)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
Value(const Value* ptr)
|
|
Packit Service |
7770af |
: Expression(ptr)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
ATTACH_VIRTUAL_AST_OPERATIONS(Value);
|
|
Packit Service |
7770af |
virtual bool operator== (const Expression& rhs) const = 0;
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
/////////////////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Hash method specializations for std::unordered_map to work with Sass::Expression
|
|
Packit Service |
7770af |
/////////////////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
namespace std {
|
|
Packit Service |
7770af |
template<>
|
|
Packit Service |
7770af |
struct hash<Sass::Expression_Obj>
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
size_t operator()(Sass::Expression_Obj s) const
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return s->hash();
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
template<>
|
|
Packit Service |
7770af |
struct equal_to<Sass::Expression_Obj>
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
bool operator()( Sass::Expression_Obj lhs, Sass::Expression_Obj rhs) const
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return lhs->hash() == rhs->hash();
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
namespace Sass {
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
/////////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Mixin class for AST nodes that should behave like vectors. Uses the
|
|
Packit Service |
7770af |
// "Template Method" design pattern to allow subclasses to adjust their flags
|
|
Packit Service |
7770af |
// when certain objects are pushed.
|
|
Packit Service |
7770af |
/////////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
template <typename T>
|
|
Packit Service |
7770af |
class Vectorized {
|
|
Packit Service |
7770af |
std::vector<T> elements_;
|
|
Packit Service |
7770af |
protected:
|
|
Packit Service |
7770af |
size_t hash_;
|
|
Packit Service |
7770af |
void reset_hash() { hash_ = 0; }
|
|
Packit Service |
7770af |
virtual void adjust_after_pushing(T element) { }
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Vectorized(size_t s = 0) : elements_(std::vector<T>()), hash_(0)
|
|
Packit Service |
7770af |
{ elements_.reserve(s); }
|
|
Packit Service |
7770af |
virtual ~Vectorized() = 0;
|
|
Packit Service |
7770af |
size_t length() const { return elements_.size(); }
|
|
Packit Service |
7770af |
bool empty() const { return elements_.empty(); }
|
|
Packit Service |
7770af |
void clear() { return elements_.clear(); }
|
|
Packit Service |
7770af |
T last() const { return elements_.back(); }
|
|
Packit Service |
7770af |
T first() const { return elements_.front(); }
|
|
Packit Service |
7770af |
T& operator[](size_t i) { return elements_[i]; }
|
|
Packit Service |
7770af |
virtual const T& at(size_t i) const { return elements_.at(i); }
|
|
Packit Service |
7770af |
virtual T& at(size_t i) { return elements_.at(i); }
|
|
Packit Service |
7770af |
const T& operator[](size_t i) const { return elements_[i]; }
|
|
Packit Service |
7770af |
virtual void append(T element)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (element) {
|
|
Packit Service |
7770af |
reset_hash();
|
|
Packit Service |
7770af |
elements_.push_back(element);
|
|
Packit Service |
7770af |
adjust_after_pushing(element);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
virtual void concat(Vectorized* v)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
for (size_t i = 0, L = v->length(); i < L; ++i) this->append((*v)[i]);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
Vectorized& unshift(T element)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
elements_.insert(elements_.begin(), element);
|
|
Packit Service |
7770af |
return *this;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
std::vector<T>& elements() { return elements_; }
|
|
Packit Service |
7770af |
const std::vector<T>& elements() const { return elements_; }
|
|
Packit Service |
7770af |
std::vector<T>& elements(std::vector<T>& e) { elements_ = e; return elements_; }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual size_t hash()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (hash_ == 0) {
|
|
Packit Service |
7770af |
for (T& el : elements_) {
|
|
Packit Service |
7770af |
hash_combine(hash_, el->hash());
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
return hash_;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
typename std::vector<T>::iterator end() { return elements_.end(); }
|
|
Packit Service |
7770af |
typename std::vector<T>::iterator begin() { return elements_.begin(); }
|
|
Packit Service |
7770af |
typename std::vector<T>::const_iterator end() const { return elements_.end(); }
|
|
Packit Service |
7770af |
typename std::vector<T>::const_iterator begin() const { return elements_.begin(); }
|
|
Packit Service |
7770af |
typename std::vector<T>::iterator erase(typename std::vector<T>::iterator el) { return elements_.erase(el); }
|
|
Packit Service |
7770af |
typename std::vector<T>::const_iterator erase(typename std::vector<T>::const_iterator el) { return elements_.erase(el); }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
template <typename T>
|
|
Packit Service |
7770af |
inline Vectorized<T>::~Vectorized() { }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
/////////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Mixin class for AST nodes that should behave like a hash table. Uses an
|
|
Packit Service |
7770af |
// extra <std::vector> internally to maintain insertion order for interation.
|
|
Packit Service |
7770af |
/////////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Hashed {
|
|
Packit Service |
7770af |
private:
|
|
Packit Service |
7770af |
ExpressionMap elements_;
|
|
Packit Service |
7770af |
std::vector<Expression_Obj> list_;
|
|
Packit Service |
7770af |
protected:
|
|
Packit Service |
7770af |
size_t hash_;
|
|
Packit Service |
7770af |
Expression_Obj duplicate_key_;
|
|
Packit Service |
7770af |
void reset_hash() { hash_ = 0; }
|
|
Packit Service |
7770af |
void reset_duplicate_key() { duplicate_key_ = 0; }
|
|
Packit Service |
7770af |
virtual void adjust_after_pushing(std::pair<Expression_Obj, Expression_Obj> p) { }
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Hashed(size_t s = 0)
|
|
Packit Service |
7770af |
: elements_(ExpressionMap(s)),
|
|
Packit Service |
7770af |
list_(std::vector<Expression_Obj>()),
|
|
Packit Service |
7770af |
hash_(0), duplicate_key_(NULL)
|
|
Packit Service |
7770af |
{ elements_.reserve(s); list_.reserve(s); }
|
|
Packit Service |
7770af |
virtual ~Hashed();
|
|
Packit Service |
7770af |
size_t length() const { return list_.size(); }
|
|
Packit Service |
7770af |
bool empty() const { return list_.empty(); }
|
|
Packit Service |
7770af |
bool has(Expression_Obj k) const { return elements_.count(k) == 1; }
|
|
Packit Service |
7770af |
Expression_Obj at(Expression_Obj k) const;
|
|
Packit Service |
7770af |
bool has_duplicate_key() const { return duplicate_key_ != 0; }
|
|
Packit Service |
7770af |
Expression_Obj get_duplicate_key() const { return duplicate_key_; }
|
|
Packit Service |
7770af |
const ExpressionMap elements() { return elements_; }
|
|
Packit Service |
7770af |
Hashed& operator<<(std::pair<Expression_Obj, Expression_Obj> p)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
reset_hash();
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
if (!has(p.first)) list_.push_back(p.first);
|
|
Packit Service |
7770af |
else if (!duplicate_key_) duplicate_key_ = p.first;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
elements_[p.first] = p.second;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
adjust_after_pushing(p);
|
|
Packit Service |
7770af |
return *this;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
Hashed& operator+=(Hashed* h)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (length() == 0) {
|
|
Packit Service |
7770af |
this->elements_ = h->elements_;
|
|
Packit Service |
7770af |
this->list_ = h->list_;
|
|
Packit Service |
7770af |
return *this;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
for (auto key : h->keys()) {
|
|
Packit Service |
7770af |
*this << std::make_pair(key, h->at(key));
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
reset_duplicate_key();
|
|
Packit Service |
7770af |
return *this;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
const ExpressionMap& pairs() const { return elements_; }
|
|
Packit Service |
7770af |
const std::vector<Expression_Obj>& keys() const { return list_; }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// std::unordered_map<Expression_Obj, Expression_Obj>::iterator end() { return elements_.end(); }
|
|
Packit Service |
7770af |
// std::unordered_map<Expression_Obj, Expression_Obj>::iterator begin() { return elements_.begin(); }
|
|
Packit Service |
7770af |
// std::unordered_map<Expression_Obj, Expression_Obj>::const_iterator end() const { return elements_.end(); }
|
|
Packit Service |
7770af |
// std::unordered_map<Expression_Obj, Expression_Obj>::const_iterator begin() const { return elements_.begin(); }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
inline Hashed::~Hashed() { }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
/////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Abstract base class for statements. This side of the AST hierarchy
|
|
Packit Service |
7770af |
// represents elements in expansion contexts, which exist primarily to be
|
|
Packit Service |
7770af |
// rewritten and macro-expanded.
|
|
Packit Service |
7770af |
/////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Statement : public AST_Node {
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
enum Statement_Type {
|
|
Packit Service |
7770af |
NONE,
|
|
Packit Service |
7770af |
RULESET,
|
|
Packit Service |
7770af |
MEDIA,
|
|
Packit Service |
7770af |
DIRECTIVE,
|
|
Packit Service |
7770af |
SUPPORTS,
|
|
Packit Service |
7770af |
ATROOT,
|
|
Packit Service |
7770af |
BUBBLE,
|
|
Packit Service |
7770af |
CONTENT,
|
|
Packit Service |
7770af |
KEYFRAMERULE,
|
|
Packit Service |
7770af |
DECLARATION,
|
|
Packit Service |
7770af |
ASSIGNMENT,
|
|
Packit Service |
7770af |
IMPORT_STUB,
|
|
Packit Service |
7770af |
IMPORT,
|
|
Packit Service |
7770af |
COMMENT,
|
|
Packit Service |
7770af |
WARNING,
|
|
Packit Service |
7770af |
RETURN,
|
|
Packit Service |
7770af |
EXTEND,
|
|
Packit Service |
7770af |
ERROR,
|
|
Packit Service |
7770af |
DEBUGSTMT,
|
|
Packit Service |
7770af |
WHILE,
|
|
Packit Service |
7770af |
EACH,
|
|
Packit Service |
7770af |
FOR,
|
|
Packit Service |
7770af |
IF
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
private:
|
|
Packit Service |
7770af |
ADD_PROPERTY(Statement_Type, statement_type)
|
|
Packit Service |
7770af |
ADD_PROPERTY(size_t, tabs)
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, group_end)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Statement(ParserState pstate, Statement_Type st = NONE, size_t t = 0)
|
|
Packit Service |
7770af |
: AST_Node(pstate), statement_type_(st), tabs_(t), group_end_(false)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
Statement(const Statement* ptr)
|
|
Packit Service |
7770af |
: AST_Node(ptr),
|
|
Packit Service |
7770af |
statement_type_(ptr->statement_type_),
|
|
Packit Service |
7770af |
tabs_(ptr->tabs_),
|
|
Packit Service |
7770af |
group_end_(ptr->group_end_)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
virtual ~Statement() = 0;
|
|
Packit Service |
7770af |
// needed for rearranging nested rulesets during CSS emission
|
|
Packit Service |
7770af |
virtual bool is_invisible() const { return false; }
|
|
Packit Service |
7770af |
virtual bool bubbles() { return false; }
|
|
Packit Service |
7770af |
virtual bool has_content()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return statement_type_ == CONTENT;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
inline Statement::~Statement() { }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
////////////////////////
|
|
Packit Service |
7770af |
// Blocks of statements.
|
|
Packit Service |
7770af |
////////////////////////
|
|
Packit Service |
7770af |
class Block : public Statement, public Vectorized<Statement_Obj> {
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, is_root)
|
|
Packit Service |
7770af |
// needed for properly formatted CSS emission
|
|
Packit Service |
7770af |
protected:
|
|
Packit Service |
7770af |
void adjust_after_pushing(Statement_Obj s)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Block(ParserState pstate, size_t s = 0, bool r = false)
|
|
Packit Service |
7770af |
: Statement(pstate),
|
|
Packit Service |
7770af |
Vectorized<Statement_Obj>(s),
|
|
Packit Service |
7770af |
is_root_(r)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
Block(const Block* ptr)
|
|
Packit Service |
7770af |
: Statement(ptr),
|
|
Packit Service |
7770af |
Vectorized<Statement_Obj>(*ptr),
|
|
Packit Service |
7770af |
is_root_(ptr->is_root_)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
virtual bool has_content()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
for (size_t i = 0, L = elements().size(); i < L; ++i) {
|
|
Packit Service |
7770af |
if (elements()[i]->has_content()) return true;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
return Statement::has_content();
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Block)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Abstract base class for statements that contain blocks of statements.
|
|
Packit Service |
7770af |
////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Has_Block : public Statement {
|
|
Packit Service |
7770af |
ADD_PROPERTY(Block_Obj, block)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Has_Block(ParserState pstate, Block_Obj b)
|
|
Packit Service |
7770af |
: Statement(pstate), block_(b)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
Has_Block(const Has_Block* ptr)
|
|
Packit Service |
7770af |
: Statement(ptr), block_(ptr->block_)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
virtual bool has_content()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return (block_ && block_->has_content()) || Statement::has_content();
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
virtual ~Has_Block() = 0;
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
inline Has_Block::~Has_Block() { }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
/////////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Rulesets (i.e., sets of styles headed by a selector and containing a block
|
|
Packit Service |
7770af |
// of style declarations.
|
|
Packit Service |
7770af |
/////////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Ruleset : public Has_Block {
|
|
Packit Service |
7770af |
ADD_PROPERTY(Selector_List_Obj, selector)
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, is_root);
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Ruleset(ParserState pstate, Selector_List_Obj s = 0, Block_Obj b = 0)
|
|
Packit Service |
7770af |
: Has_Block(pstate, b), selector_(s), is_root_(false)
|
|
Packit Service |
7770af |
{ statement_type(RULESET); }
|
|
Packit Service |
7770af |
Ruleset(const Ruleset* ptr)
|
|
Packit Service |
7770af |
: Has_Block(ptr),
|
|
Packit Service |
7770af |
selector_(ptr->selector_),
|
|
Packit Service |
7770af |
is_root_(ptr->is_root_)
|
|
Packit Service |
7770af |
{ statement_type(RULESET); }
|
|
Packit Service |
7770af |
bool is_invisible() const;
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Ruleset)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
/////////////////
|
|
Packit Service |
7770af |
// Bubble.
|
|
Packit Service |
7770af |
/////////////////
|
|
Packit Service |
7770af |
class Bubble : public Statement {
|
|
Packit Service |
7770af |
ADD_PROPERTY(Statement_Obj, node)
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, group_end)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Bubble(ParserState pstate, Statement_Obj n, Statement_Obj g = 0, size_t t = 0)
|
|
Packit Service |
7770af |
: Statement(pstate, Statement::BUBBLE, t), node_(n), group_end_(g == 0)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
Bubble(const Bubble* ptr)
|
|
Packit Service |
7770af |
: Statement(ptr),
|
|
Packit Service |
7770af |
node_(ptr->node_),
|
|
Packit Service |
7770af |
group_end_(ptr->group_end_)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
bool bubbles() { return true; }
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Bubble)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
/////////////////
|
|
Packit Service |
7770af |
// Trace.
|
|
Packit Service |
7770af |
/////////////////
|
|
Packit Service |
7770af |
class Trace : public Has_Block {
|
|
Packit Service |
7770af |
ADD_CONSTREF(std::string, name)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Trace(ParserState pstate, std::string n, Block_Obj b = 0)
|
|
Packit Service |
7770af |
: Has_Block(pstate, b), name_(n)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
Trace(const Trace* ptr)
|
|
Packit Service |
7770af |
: Has_Block(ptr),
|
|
Packit Service |
7770af |
name_(ptr->name_)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Trace)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
/////////////////
|
|
Packit Service |
7770af |
// Media queries.
|
|
Packit Service |
7770af |
/////////////////
|
|
Packit Service |
7770af |
class Media_Block : public Has_Block {
|
|
Packit Service |
7770af |
ADD_PROPERTY(List_Obj, media_queries)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Media_Block(ParserState pstate, List_Obj mqs, Block_Obj b)
|
|
Packit Service |
7770af |
: Has_Block(pstate, b), media_queries_(mqs)
|
|
Packit Service |
7770af |
{ statement_type(MEDIA); }
|
|
Packit Service |
7770af |
Media_Block(const Media_Block* ptr)
|
|
Packit Service |
7770af |
: Has_Block(ptr), media_queries_(ptr->media_queries_)
|
|
Packit Service |
7770af |
{ statement_type(MEDIA); }
|
|
Packit Service |
7770af |
bool bubbles() { return true; }
|
|
Packit Service |
7770af |
bool is_invisible() const;
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Media_Block)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
///////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// At-rules -- arbitrary directives beginning with "@" that may have an
|
|
Packit Service |
7770af |
// optional statement block.
|
|
Packit Service |
7770af |
///////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Directive : public Has_Block {
|
|
Packit Service |
7770af |
ADD_CONSTREF(std::string, keyword)
|
|
Packit Service |
7770af |
ADD_PROPERTY(Selector_List_Obj, selector)
|
|
Packit Service |
7770af |
ADD_PROPERTY(Expression_Obj, value)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Directive(ParserState pstate, std::string kwd, Selector_List_Obj sel = 0, Block_Obj b = 0, Expression_Obj val = 0)
|
|
Packit Service |
7770af |
: Has_Block(pstate, b), keyword_(kwd), selector_(sel), value_(val) // set value manually if needed
|
|
Packit Service |
7770af |
{ statement_type(DIRECTIVE); }
|
|
Packit Service |
7770af |
Directive(const Directive* ptr)
|
|
Packit Service |
7770af |
: Has_Block(ptr),
|
|
Packit Service |
7770af |
keyword_(ptr->keyword_),
|
|
Packit Service |
7770af |
selector_(ptr->selector_),
|
|
Packit Service |
7770af |
value_(ptr->value_) // set value manually if needed
|
|
Packit Service |
7770af |
{ statement_type(DIRECTIVE); }
|
|
Packit Service |
7770af |
bool bubbles() { return is_keyframes() || is_media(); }
|
|
Packit Service |
7770af |
bool is_media() {
|
|
Packit Service |
7770af |
return keyword_.compare("@-webkit-media") == 0 ||
|
|
Packit Service |
7770af |
keyword_.compare("@-moz-media") == 0 ||
|
|
Packit Service |
7770af |
keyword_.compare("@-o-media") == 0 ||
|
|
Packit Service |
7770af |
keyword_.compare("@media") == 0;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
bool is_keyframes() {
|
|
Packit Service |
7770af |
return keyword_.compare("@-webkit-keyframes") == 0 ||
|
|
Packit Service |
7770af |
keyword_.compare("@-moz-keyframes") == 0 ||
|
|
Packit Service |
7770af |
keyword_.compare("@-o-keyframes") == 0 ||
|
|
Packit Service |
7770af |
keyword_.compare("@keyframes") == 0;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Directive)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
///////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Keyframe-rules -- the child blocks of "@keyframes" nodes.
|
|
Packit Service |
7770af |
///////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Keyframe_Rule : public Has_Block {
|
|
Packit Service |
7770af |
// according to css spec, this should be <keyframes-name>
|
|
Packit Service |
7770af |
// <keyframes-name> = <custom-ident> | <string>
|
|
Packit Service |
7770af |
ADD_PROPERTY(Selector_List_Obj, name)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Keyframe_Rule(ParserState pstate, Block_Obj b)
|
|
Packit Service |
7770af |
: Has_Block(pstate, b), name_()
|
|
Packit Service |
7770af |
{ statement_type(KEYFRAMERULE); }
|
|
Packit Service |
7770af |
Keyframe_Rule(const Keyframe_Rule* ptr)
|
|
Packit Service |
7770af |
: Has_Block(ptr), name_(ptr->name_)
|
|
Packit Service |
7770af |
{ statement_type(KEYFRAMERULE); }
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Keyframe_Rule)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Declarations -- style rules consisting of a property name and values.
|
|
Packit Service |
7770af |
////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Declaration : public Has_Block {
|
|
Packit Service |
7770af |
ADD_PROPERTY(String_Obj, property)
|
|
Packit Service |
7770af |
ADD_PROPERTY(Expression_Obj, value)
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, is_important)
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, is_indented)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Declaration(ParserState pstate,
|
|
Packit Service |
7770af |
String_Obj prop, Expression_Obj val, bool i = false, Block_Obj b = 0)
|
|
Packit Service |
7770af |
: Has_Block(pstate, b), property_(prop), value_(val), is_important_(i), is_indented_(false)
|
|
Packit Service |
7770af |
{ statement_type(DECLARATION); }
|
|
Packit Service |
7770af |
Declaration(const Declaration* ptr)
|
|
Packit Service |
7770af |
: Has_Block(ptr),
|
|
Packit Service |
7770af |
property_(ptr->property_),
|
|
Packit Service |
7770af |
value_(ptr->value_),
|
|
Packit Service |
7770af |
is_important_(ptr->is_important_),
|
|
Packit Service |
7770af |
is_indented_(ptr->is_indented_)
|
|
Packit Service |
7770af |
{ statement_type(DECLARATION); }
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Declaration)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
/////////////////////////////////////
|
|
Packit Service |
7770af |
// Assignments -- variable and value.
|
|
Packit Service |
7770af |
/////////////////////////////////////
|
|
Packit Service |
7770af |
class Assignment : public Statement {
|
|
Packit Service |
7770af |
ADD_CONSTREF(std::string, variable)
|
|
Packit Service |
7770af |
ADD_PROPERTY(Expression_Obj, value)
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, is_default)
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, is_global)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Assignment(ParserState pstate,
|
|
Packit Service |
7770af |
std::string var, Expression_Obj val,
|
|
Packit Service |
7770af |
bool is_default = false,
|
|
Packit Service |
7770af |
bool is_global = false)
|
|
Packit Service |
7770af |
: Statement(pstate), variable_(var), value_(val), is_default_(is_default), is_global_(is_global)
|
|
Packit Service |
7770af |
{ statement_type(ASSIGNMENT); }
|
|
Packit Service |
7770af |
Assignment(const Assignment* ptr)
|
|
Packit Service |
7770af |
: Statement(ptr),
|
|
Packit Service |
7770af |
variable_(ptr->variable_),
|
|
Packit Service |
7770af |
value_(ptr->value_),
|
|
Packit Service |
7770af |
is_default_(ptr->is_default_),
|
|
Packit Service |
7770af |
is_global_(ptr->is_global_)
|
|
Packit Service |
7770af |
{ statement_type(ASSIGNMENT); }
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Assignment)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
////////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Import directives. CSS and Sass import lists can be intermingled, so it's
|
|
Packit Service |
7770af |
// necessary to store a list of each in an Import node.
|
|
Packit Service |
7770af |
////////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Import : public Statement {
|
|
Packit Service |
7770af |
std::vector<Expression_Obj> urls_;
|
|
Packit Service |
7770af |
std::vector<Include> incs_;
|
|
Packit Service |
7770af |
ADD_PROPERTY(List_Obj, import_queries);
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Import(ParserState pstate)
|
|
Packit Service |
7770af |
: Statement(pstate),
|
|
Packit Service |
7770af |
urls_(std::vector<Expression_Obj>()),
|
|
Packit Service |
7770af |
incs_(std::vector<Include>()),
|
|
Packit Service |
7770af |
import_queries_()
|
|
Packit Service |
7770af |
{ statement_type(IMPORT); }
|
|
Packit Service |
7770af |
Import(const Import* ptr)
|
|
Packit Service |
7770af |
: Statement(ptr),
|
|
Packit Service |
7770af |
urls_(ptr->urls_),
|
|
Packit Service |
7770af |
incs_(ptr->incs_),
|
|
Packit Service |
7770af |
import_queries_(ptr->import_queries_)
|
|
Packit Service |
7770af |
{ statement_type(IMPORT); }
|
|
Packit Service |
7770af |
std::vector<Expression_Obj>& urls() { return urls_; }
|
|
Packit Service |
7770af |
std::vector<Include>& incs() { return incs_; }
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Import)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// not yet resolved single import
|
|
Packit Service |
7770af |
// so far we only know requested name
|
|
Packit Service |
7770af |
class Import_Stub : public Statement {
|
|
Packit Service |
7770af |
Include resource_;
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
std::string abs_path() { return resource_.abs_path; };
|
|
Packit Service |
7770af |
std::string imp_path() { return resource_.imp_path; };
|
|
Packit Service |
7770af |
Include resource() { return resource_; };
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
Import_Stub(ParserState pstate, Include res)
|
|
Packit Service |
7770af |
: Statement(pstate), resource_(res)
|
|
Packit Service |
7770af |
{ statement_type(IMPORT_STUB); }
|
|
Packit Service |
7770af |
Import_Stub(const Import_Stub* ptr)
|
|
Packit Service |
7770af |
: Statement(ptr), resource_(ptr->resource_)
|
|
Packit Service |
7770af |
{ statement_type(IMPORT_STUB); }
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Import_Stub)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
//////////////////////////////
|
|
Packit Service |
7770af |
// The Sass `@warn` directive.
|
|
Packit Service |
7770af |
//////////////////////////////
|
|
Packit Service |
7770af |
class Warning : public Statement {
|
|
Packit Service |
7770af |
ADD_PROPERTY(Expression_Obj, message)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Warning(ParserState pstate, Expression_Obj msg)
|
|
Packit Service |
7770af |
: Statement(pstate), message_(msg)
|
|
Packit Service |
7770af |
{ statement_type(WARNING); }
|
|
Packit Service |
7770af |
Warning(const Warning* ptr)
|
|
Packit Service |
7770af |
: Statement(ptr), message_(ptr->message_)
|
|
Packit Service |
7770af |
{ statement_type(WARNING); }
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Warning)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
///////////////////////////////
|
|
Packit Service |
7770af |
// The Sass `@error` directive.
|
|
Packit Service |
7770af |
///////////////////////////////
|
|
Packit Service |
7770af |
class Error : public Statement {
|
|
Packit Service |
7770af |
ADD_PROPERTY(Expression_Obj, message)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Error(ParserState pstate, Expression_Obj msg)
|
|
Packit Service |
7770af |
: Statement(pstate), message_(msg)
|
|
Packit Service |
7770af |
{ statement_type(ERROR); }
|
|
Packit Service |
7770af |
Error(const Error* ptr)
|
|
Packit Service |
7770af |
: Statement(ptr), message_(ptr->message_)
|
|
Packit Service |
7770af |
{ statement_type(ERROR); }
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Error)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
///////////////////////////////
|
|
Packit Service |
7770af |
// The Sass `@debug` directive.
|
|
Packit Service |
7770af |
///////////////////////////////
|
|
Packit Service |
7770af |
class Debug : public Statement {
|
|
Packit Service |
7770af |
ADD_PROPERTY(Expression_Obj, value)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Debug(ParserState pstate, Expression_Obj val)
|
|
Packit Service |
7770af |
: Statement(pstate), value_(val)
|
|
Packit Service |
7770af |
{ statement_type(DEBUGSTMT); }
|
|
Packit Service |
7770af |
Debug(const Debug* ptr)
|
|
Packit Service |
7770af |
: Statement(ptr), value_(ptr->value_)
|
|
Packit Service |
7770af |
{ statement_type(DEBUGSTMT); }
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Debug)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
///////////////////////////////////////////
|
|
Packit Service |
7770af |
// CSS comments. These may be interpolated.
|
|
Packit Service |
7770af |
///////////////////////////////////////////
|
|
Packit Service |
7770af |
class Comment : public Statement {
|
|
Packit Service |
7770af |
ADD_PROPERTY(String_Obj, text)
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, is_important)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Comment(ParserState pstate, String_Obj txt, bool is_important)
|
|
Packit Service |
7770af |
: Statement(pstate), text_(txt), is_important_(is_important)
|
|
Packit Service |
7770af |
{ statement_type(COMMENT); }
|
|
Packit Service |
7770af |
Comment(const Comment* ptr)
|
|
Packit Service |
7770af |
: Statement(ptr),
|
|
Packit Service |
7770af |
text_(ptr->text_),
|
|
Packit Service |
7770af |
is_important_(ptr->is_important_)
|
|
Packit Service |
7770af |
{ statement_type(COMMENT); }
|
|
Packit Service |
7770af |
virtual bool is_invisible() const
|
|
Packit Service |
7770af |
{ return /* is_important() == */ false; }
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Comment)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
////////////////////////////////////
|
|
Packit Service |
7770af |
// The Sass `@if` control directive.
|
|
Packit Service |
7770af |
////////////////////////////////////
|
|
Packit Service |
7770af |
class If : public Has_Block {
|
|
Packit Service |
7770af |
ADD_PROPERTY(Expression_Obj, predicate)
|
|
Packit Service |
7770af |
ADD_PROPERTY(Block_Obj, alternative)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
If(ParserState pstate, Expression_Obj pred, Block_Obj con, Block_Obj alt = 0)
|
|
Packit Service |
7770af |
: Has_Block(pstate, con), predicate_(pred), alternative_(alt)
|
|
Packit Service |
7770af |
{ statement_type(IF); }
|
|
Packit Service |
7770af |
If(const If* ptr)
|
|
Packit Service |
7770af |
: Has_Block(ptr),
|
|
Packit Service |
7770af |
predicate_(ptr->predicate_),
|
|
Packit Service |
7770af |
alternative_(ptr->alternative_)
|
|
Packit Service |
7770af |
{ statement_type(IF); }
|
|
Packit Service |
7770af |
virtual bool has_content()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return Has_Block::has_content() || (alternative_ && alternative_->has_content());
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(If)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
/////////////////////////////////////
|
|
Packit Service |
7770af |
// The Sass `@for` control directive.
|
|
Packit Service |
7770af |
/////////////////////////////////////
|
|
Packit Service |
7770af |
class For : public Has_Block {
|
|
Packit Service |
7770af |
ADD_CONSTREF(std::string, variable)
|
|
Packit Service |
7770af |
ADD_PROPERTY(Expression_Obj, lower_bound)
|
|
Packit Service |
7770af |
ADD_PROPERTY(Expression_Obj, upper_bound)
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, is_inclusive)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
For(ParserState pstate,
|
|
Packit Service |
7770af |
std::string var, Expression_Obj lo, Expression_Obj hi, Block_Obj b, bool inc)
|
|
Packit Service |
7770af |
: Has_Block(pstate, b),
|
|
Packit Service |
7770af |
variable_(var), lower_bound_(lo), upper_bound_(hi), is_inclusive_(inc)
|
|
Packit Service |
7770af |
{ statement_type(FOR); }
|
|
Packit Service |
7770af |
For(const For* ptr)
|
|
Packit Service |
7770af |
: Has_Block(ptr),
|
|
Packit Service |
7770af |
variable_(ptr->variable_),
|
|
Packit Service |
7770af |
lower_bound_(ptr->lower_bound_),
|
|
Packit Service |
7770af |
upper_bound_(ptr->upper_bound_),
|
|
Packit Service |
7770af |
is_inclusive_(ptr->is_inclusive_)
|
|
Packit Service |
7770af |
{ statement_type(FOR); }
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(For)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
//////////////////////////////////////
|
|
Packit Service |
7770af |
// The Sass `@each` control directive.
|
|
Packit Service |
7770af |
//////////////////////////////////////
|
|
Packit Service |
7770af |
class Each : public Has_Block {
|
|
Packit Service |
7770af |
ADD_PROPERTY(std::vector<std::string>, variables)
|
|
Packit Service |
7770af |
ADD_PROPERTY(Expression_Obj, list)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Each(ParserState pstate, std::vector<std::string> vars, Expression_Obj lst, Block_Obj b)
|
|
Packit Service |
7770af |
: Has_Block(pstate, b), variables_(vars), list_(lst)
|
|
Packit Service |
7770af |
{ statement_type(EACH); }
|
|
Packit Service |
7770af |
Each(const Each* ptr)
|
|
Packit Service |
7770af |
: Has_Block(ptr), variables_(ptr->variables_), list_(ptr->list_)
|
|
Packit Service |
7770af |
{ statement_type(EACH); }
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Each)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
///////////////////////////////////////
|
|
Packit Service |
7770af |
// The Sass `@while` control directive.
|
|
Packit Service |
7770af |
///////////////////////////////////////
|
|
Packit Service |
7770af |
class While : public Has_Block {
|
|
Packit Service |
7770af |
ADD_PROPERTY(Expression_Obj, predicate)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
While(ParserState pstate, Expression_Obj pred, Block_Obj b)
|
|
Packit Service |
7770af |
: Has_Block(pstate, b), predicate_(pred)
|
|
Packit Service |
7770af |
{ statement_type(WHILE); }
|
|
Packit Service |
7770af |
While(const While* ptr)
|
|
Packit Service |
7770af |
: Has_Block(ptr), predicate_(ptr->predicate_)
|
|
Packit Service |
7770af |
{ statement_type(WHILE); }
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(While)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
/////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// The @return directive for use inside SassScript functions.
|
|
Packit Service |
7770af |
/////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Return : public Statement {
|
|
Packit Service |
7770af |
ADD_PROPERTY(Expression_Obj, value)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Return(ParserState pstate, Expression_Obj val)
|
|
Packit Service |
7770af |
: Statement(pstate), value_(val)
|
|
Packit Service |
7770af |
{ statement_type(RETURN); }
|
|
Packit Service |
7770af |
Return(const Return* ptr)
|
|
Packit Service |
7770af |
: Statement(ptr), value_(ptr->value_)
|
|
Packit Service |
7770af |
{ statement_type(RETURN); }
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Return)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
////////////////////////////////
|
|
Packit Service |
7770af |
// The Sass `@extend` directive.
|
|
Packit Service |
7770af |
////////////////////////////////
|
|
Packit Service |
7770af |
class Extension : public Statement {
|
|
Packit Service |
7770af |
ADD_PROPERTY(Selector_List_Obj, selector)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Extension(ParserState pstate, Selector_List_Obj s)
|
|
Packit Service |
7770af |
: Statement(pstate), selector_(s)
|
|
Packit Service |
7770af |
{ statement_type(EXTEND); }
|
|
Packit Service |
7770af |
Extension(const Extension* ptr)
|
|
Packit Service |
7770af |
: Statement(ptr), selector_(ptr->selector_)
|
|
Packit Service |
7770af |
{ statement_type(EXTEND); }
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Extension)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
/////////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Definitions for both mixins and functions. The two cases are distinguished
|
|
Packit Service |
7770af |
// by a type tag.
|
|
Packit Service |
7770af |
/////////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
struct Backtrace;
|
|
Packit Service |
7770af |
typedef const char* Signature;
|
|
Packit Service |
7770af |
typedef Expression_Ptr (*Native_Function)(Env&, Env&, Context&, Signature, ParserState, Backtrace*, std::vector<Selector_List_Obj>);
|
|
Packit Service |
7770af |
class Definition : public Has_Block {
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
enum Type { MIXIN, FUNCTION };
|
|
Packit Service |
7770af |
ADD_CONSTREF(std::string, name)
|
|
Packit Service |
7770af |
ADD_PROPERTY(Parameters_Obj, parameters)
|
|
Packit Service |
7770af |
ADD_PROPERTY(Env*, environment)
|
|
Packit Service |
7770af |
ADD_PROPERTY(Type, type)
|
|
Packit Service |
7770af |
ADD_PROPERTY(Native_Function, native_function)
|
|
Packit Service |
7770af |
ADD_PROPERTY(Sass_Function_Entry, c_function)
|
|
Packit Service |
7770af |
ADD_PROPERTY(void*, cookie)
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, is_overload_stub)
|
|
Packit Service |
7770af |
ADD_PROPERTY(Signature, signature)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Definition(const Definition* ptr)
|
|
Packit Service |
7770af |
: Has_Block(ptr),
|
|
Packit Service |
7770af |
name_(ptr->name_),
|
|
Packit Service |
7770af |
parameters_(ptr->parameters_),
|
|
Packit Service |
7770af |
environment_(ptr->environment_),
|
|
Packit Service |
7770af |
type_(ptr->type_),
|
|
Packit Service |
7770af |
native_function_(ptr->native_function_),
|
|
Packit Service |
7770af |
c_function_(ptr->c_function_),
|
|
Packit Service |
7770af |
cookie_(ptr->cookie_),
|
|
Packit Service |
7770af |
is_overload_stub_(ptr->is_overload_stub_),
|
|
Packit Service |
7770af |
signature_(ptr->signature_)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
Definition(ParserState pstate,
|
|
Packit Service |
7770af |
std::string n,
|
|
Packit Service |
7770af |
Parameters_Obj params,
|
|
Packit Service |
7770af |
Block_Obj b,
|
|
Packit Service |
7770af |
Type t)
|
|
Packit Service |
7770af |
: Has_Block(pstate, b),
|
|
Packit Service |
7770af |
name_(n),
|
|
Packit Service |
7770af |
parameters_(params),
|
|
Packit Service |
7770af |
environment_(0),
|
|
Packit Service |
7770af |
type_(t),
|
|
Packit Service |
7770af |
native_function_(0),
|
|
Packit Service |
7770af |
c_function_(0),
|
|
Packit Service |
7770af |
cookie_(0),
|
|
Packit Service |
7770af |
is_overload_stub_(false),
|
|
Packit Service |
7770af |
signature_(0)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
Definition(ParserState pstate,
|
|
Packit Service |
7770af |
Signature sig,
|
|
Packit Service |
7770af |
std::string n,
|
|
Packit Service |
7770af |
Parameters_Obj params,
|
|
Packit Service |
7770af |
Native_Function func_ptr,
|
|
Packit Service |
7770af |
bool overload_stub = false)
|
|
Packit Service |
7770af |
: Has_Block(pstate, 0),
|
|
Packit Service |
7770af |
name_(n),
|
|
Packit Service |
7770af |
parameters_(params),
|
|
Packit Service |
7770af |
environment_(0),
|
|
Packit Service |
7770af |
type_(FUNCTION),
|
|
Packit Service |
7770af |
native_function_(func_ptr),
|
|
Packit Service |
7770af |
c_function_(0),
|
|
Packit Service |
7770af |
cookie_(0),
|
|
Packit Service |
7770af |
is_overload_stub_(overload_stub),
|
|
Packit Service |
7770af |
signature_(sig)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
Definition(ParserState pstate,
|
|
Packit Service |
7770af |
Signature sig,
|
|
Packit Service |
7770af |
std::string n,
|
|
Packit Service |
7770af |
Parameters_Obj params,
|
|
Packit Service |
7770af |
Sass_Function_Entry c_func,
|
|
Packit Service |
7770af |
bool whatever,
|
|
Packit Service |
7770af |
bool whatever2)
|
|
Packit Service |
7770af |
: Has_Block(pstate, 0),
|
|
Packit Service |
7770af |
name_(n),
|
|
Packit Service |
7770af |
parameters_(params),
|
|
Packit Service |
7770af |
environment_(0),
|
|
Packit Service |
7770af |
type_(FUNCTION),
|
|
Packit Service |
7770af |
native_function_(0),
|
|
Packit Service |
7770af |
c_function_(c_func),
|
|
Packit Service |
7770af |
cookie_(sass_function_get_cookie(c_func)),
|
|
Packit Service |
7770af |
is_overload_stub_(false),
|
|
Packit Service |
7770af |
signature_(sig)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Definition)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
//////////////////////////////////////
|
|
Packit Service |
7770af |
// Mixin calls (i.e., `@include ...`).
|
|
Packit Service |
7770af |
//////////////////////////////////////
|
|
Packit Service |
7770af |
class Mixin_Call : public Has_Block {
|
|
Packit Service |
7770af |
ADD_CONSTREF(std::string, name)
|
|
Packit Service |
7770af |
ADD_PROPERTY(Arguments_Obj, arguments)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Mixin_Call(ParserState pstate, std::string n, Arguments_Obj args, Block_Obj b = 0)
|
|
Packit Service |
7770af |
: Has_Block(pstate, b), name_(n), arguments_(args)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
Mixin_Call(const Mixin_Call* ptr)
|
|
Packit Service |
7770af |
: Has_Block(ptr),
|
|
Packit Service |
7770af |
name_(ptr->name_),
|
|
Packit Service |
7770af |
arguments_(ptr->arguments_)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Mixin_Call)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
///////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// The @content directive for mixin content blocks.
|
|
Packit Service |
7770af |
///////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Content : public Statement {
|
|
Packit Service |
7770af |
ADD_PROPERTY(Media_Block_Ptr, media_block)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Content(ParserState pstate)
|
|
Packit Service |
7770af |
: Statement(pstate),
|
|
Packit Service |
7770af |
media_block_(NULL)
|
|
Packit Service |
7770af |
{ statement_type(CONTENT); }
|
|
Packit Service |
7770af |
Content(const Content* ptr)
|
|
Packit Service |
7770af |
: Statement(ptr),
|
|
Packit Service |
7770af |
media_block_(ptr->media_block_)
|
|
Packit Service |
7770af |
{ statement_type(CONTENT); }
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Content)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
///////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Lists of values, both comma- and space-separated (distinguished by a
|
|
Packit Service |
7770af |
// type-tag.) Also used to represent variable-length argument lists.
|
|
Packit Service |
7770af |
///////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class List : public Value, public Vectorized<Expression_Obj> {
|
|
Packit Service |
7770af |
void adjust_after_pushing(Expression_Obj e) { is_expanded(false); }
|
|
Packit Service |
7770af |
private:
|
|
Packit Service |
7770af |
ADD_PROPERTY(enum Sass_Separator, separator)
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, is_arglist)
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, from_selector)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
List(ParserState pstate,
|
|
Packit Service |
7770af |
size_t size = 0, enum Sass_Separator sep = SASS_SPACE, bool argl = false)
|
|
Packit Service |
7770af |
: Value(pstate),
|
|
Packit Service |
7770af |
Vectorized<Expression_Obj>(size),
|
|
Packit Service |
7770af |
separator_(sep),
|
|
Packit Service |
7770af |
is_arglist_(argl),
|
|
Packit Service |
7770af |
from_selector_(false)
|
|
Packit Service |
7770af |
{ concrete_type(LIST); }
|
|
Packit Service |
7770af |
List(const List* ptr)
|
|
Packit Service |
7770af |
: Value(ptr),
|
|
Packit Service |
7770af |
Vectorized<Expression_Obj>(*ptr),
|
|
Packit Service |
7770af |
separator_(ptr->separator_),
|
|
Packit Service |
7770af |
is_arglist_(ptr->is_arglist_),
|
|
Packit Service |
7770af |
from_selector_(ptr->from_selector_)
|
|
Packit Service |
7770af |
{ concrete_type(LIST); }
|
|
Packit Service |
7770af |
std::string type() const { return is_arglist_ ? "arglist" : "list"; }
|
|
Packit Service |
7770af |
static std::string type_name() { return "list"; }
|
|
Packit Service |
7770af |
const char* sep_string(bool compressed = false) const {
|
|
Packit Service |
7770af |
return separator() == SASS_SPACE ?
|
|
Packit Service |
7770af |
" " : (compressed ? "," : ", ");
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
bool is_invisible() const { return empty(); }
|
|
Packit Service |
7770af |
Expression_Obj value_at_index(size_t i);
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual size_t size() const;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual size_t hash()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (hash_ == 0) {
|
|
Packit Service |
7770af |
hash_ = std::hash<std::string>()(sep_string());
|
|
Packit Service |
7770af |
for (size_t i = 0, L = length(); i < L; ++i)
|
|
Packit Service |
7770af |
hash_combine(hash_, (elements()[i])->hash());
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
return hash_;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual void set_delayed(bool delayed)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
is_delayed(delayed);
|
|
Packit Service |
7770af |
// don't set children
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual bool operator== (const Expression& rhs) const;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(List)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
///////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Key value paris.
|
|
Packit Service |
7770af |
///////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Map : public Value, public Hashed {
|
|
Packit Service |
7770af |
void adjust_after_pushing(std::pair<Expression_Obj, Expression_Obj> p) { is_expanded(false); }
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Map(ParserState pstate,
|
|
Packit Service |
7770af |
size_t size = 0)
|
|
Packit Service |
7770af |
: Value(pstate),
|
|
Packit Service |
7770af |
Hashed(size)
|
|
Packit Service |
7770af |
{ concrete_type(MAP); }
|
|
Packit Service |
7770af |
Map(const Map* ptr)
|
|
Packit Service |
7770af |
: Value(ptr),
|
|
Packit Service |
7770af |
Hashed(*ptr)
|
|
Packit Service |
7770af |
{ concrete_type(MAP); }
|
|
Packit Service |
7770af |
std::string type() const { return "map"; }
|
|
Packit Service |
7770af |
static std::string type_name() { return "map"; }
|
|
Packit Service |
7770af |
bool is_invisible() const { return empty(); }
|
|
Packit Service |
7770af |
List_Obj to_list(ParserState& pstate);
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual size_t hash()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (hash_ == 0) {
|
|
Packit Service |
7770af |
for (auto key : keys()) {
|
|
Packit Service |
7770af |
hash_combine(hash_, key->hash());
|
|
Packit Service |
7770af |
hash_combine(hash_, at(key)->hash());
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
return hash_;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual bool operator== (const Expression& rhs) const;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Map)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
inline static const std::string sass_op_to_name(enum Sass_OP op) {
|
|
Packit Service |
7770af |
switch (op) {
|
|
Packit Service |
7770af |
case AND: return "and";
|
|
Packit Service |
7770af |
case OR: return "or";
|
|
Packit Service |
7770af |
case EQ: return "eq";
|
|
Packit Service |
7770af |
case NEQ: return "neq";
|
|
Packit Service |
7770af |
case GT: return "gt";
|
|
Packit Service |
7770af |
case GTE: return "gte";
|
|
Packit Service |
7770af |
case LT: return "lt";
|
|
Packit Service |
7770af |
case LTE: return "lte";
|
|
Packit Service |
7770af |
case ADD: return "plus";
|
|
Packit Service |
7770af |
case SUB: return "sub";
|
|
Packit Service |
7770af |
case MUL: return "times";
|
|
Packit Service |
7770af |
case DIV: return "div";
|
|
Packit Service |
7770af |
case MOD: return "mod";
|
|
Packit Service |
7770af |
// this is only used internally!
|
|
Packit Service |
7770af |
case NUM_OPS: return "[OPS]";
|
|
Packit Service |
7770af |
default: return "invalid";
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
//////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Binary expressions. Represents logical, relational, and arithmetic
|
|
Packit Service |
7770af |
// operations. Templatized to avoid large switch statements and repetitive
|
|
Packit Service |
7770af |
// subclassing.
|
|
Packit Service |
7770af |
//////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Binary_Expression : public PreValue {
|
|
Packit Service |
7770af |
private:
|
|
Packit Service |
7770af |
HASH_PROPERTY(Operand, op)
|
|
Packit Service |
7770af |
HASH_PROPERTY(Expression_Obj, left)
|
|
Packit Service |
7770af |
HASH_PROPERTY(Expression_Obj, right)
|
|
Packit Service |
7770af |
size_t hash_;
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Binary_Expression(ParserState pstate,
|
|
Packit Service |
7770af |
Operand op, Expression_Obj lhs, Expression_Obj rhs)
|
|
Packit Service |
7770af |
: PreValue(pstate), op_(op), left_(lhs), right_(rhs), hash_(0)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
Binary_Expression(const Binary_Expression* ptr)
|
|
Packit Service |
7770af |
: PreValue(ptr),
|
|
Packit Service |
7770af |
op_(ptr->op_),
|
|
Packit Service |
7770af |
left_(ptr->left_),
|
|
Packit Service |
7770af |
right_(ptr->right_),
|
|
Packit Service |
7770af |
hash_(ptr->hash_)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
const std::string type_name() {
|
|
Packit Service |
7770af |
switch (optype()) {
|
|
Packit Service |
7770af |
case AND: return "and";
|
|
Packit Service |
7770af |
case OR: return "or";
|
|
Packit Service |
7770af |
case EQ: return "eq";
|
|
Packit Service |
7770af |
case NEQ: return "neq";
|
|
Packit Service |
7770af |
case GT: return "gt";
|
|
Packit Service |
7770af |
case GTE: return "gte";
|
|
Packit Service |
7770af |
case LT: return "lt";
|
|
Packit Service |
7770af |
case LTE: return "lte";
|
|
Packit Service |
7770af |
case ADD: return "add";
|
|
Packit Service |
7770af |
case SUB: return "sub";
|
|
Packit Service |
7770af |
case MUL: return "mul";
|
|
Packit Service |
7770af |
case DIV: return "div";
|
|
Packit Service |
7770af |
case MOD: return "mod";
|
|
Packit Service |
7770af |
// this is only used internally!
|
|
Packit Service |
7770af |
case NUM_OPS: return "[OPS]";
|
|
Packit Service |
7770af |
default: return "invalid";
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
const std::string separator() {
|
|
Packit Service |
7770af |
switch (optype()) {
|
|
Packit Service |
7770af |
case AND: return "&&";
|
|
Packit Service |
7770af |
case OR: return "||";
|
|
Packit Service |
7770af |
case EQ: return "==";
|
|
Packit Service |
7770af |
case NEQ: return "!=";
|
|
Packit Service |
7770af |
case GT: return ">";
|
|
Packit Service |
7770af |
case GTE: return ">=";
|
|
Packit Service |
7770af |
case LT: return "<";
|
|
Packit Service |
7770af |
case LTE: return "<=";
|
|
Packit Service |
7770af |
case ADD: return "+";
|
|
Packit Service |
7770af |
case SUB: return "-";
|
|
Packit Service |
7770af |
case MUL: return "*";
|
|
Packit Service |
7770af |
case DIV: return "/";
|
|
Packit Service |
7770af |
case MOD: return "%";
|
|
Packit Service |
7770af |
// this is only used internally!
|
|
Packit Service |
7770af |
case NUM_OPS: return "[OPS]";
|
|
Packit Service |
7770af |
default: return "invalid";
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
bool is_left_interpolant(void) const;
|
|
Packit Service |
7770af |
bool is_right_interpolant(void) const;
|
|
Packit Service |
7770af |
bool has_interpolant() const
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return is_left_interpolant() ||
|
|
Packit Service |
7770af |
is_right_interpolant();
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
virtual void set_delayed(bool delayed)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
right()->set_delayed(delayed);
|
|
Packit Service |
7770af |
left()->set_delayed(delayed);
|
|
Packit Service |
7770af |
is_delayed(delayed);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
virtual bool operator==(const Expression& rhs) const
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
try
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
Binary_Expression_Ptr_Const m = Cast<Binary_Expression>(&rhs;;
|
|
Packit Service |
7770af |
if (m == 0) return false;
|
|
Packit Service |
7770af |
return type() == m->type() &&
|
|
Packit Service |
7770af |
*left() == *m->left() &&
|
|
Packit Service |
7770af |
*right() == *m->right();
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
catch (std::bad_cast&)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return false;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
catch (...) { throw; }
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
virtual size_t hash()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (hash_ == 0) {
|
|
Packit Service |
7770af |
hash_ = std::hash<size_t>()(optype());
|
|
Packit Service |
7770af |
hash_combine(hash_, left()->hash());
|
|
Packit Service |
7770af |
hash_combine(hash_, right()->hash());
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
return hash_;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
enum Sass_OP optype() const { return op_.operand; }
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Binary_Expression)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
////////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Arithmetic negation (logical negation is just an ordinary function call).
|
|
Packit Service |
7770af |
////////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Unary_Expression : public Expression {
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
enum Type { PLUS, MINUS, NOT, SLASH };
|
|
Packit Service |
7770af |
private:
|
|
Packit Service |
7770af |
HASH_PROPERTY(Type, optype)
|
|
Packit Service |
7770af |
HASH_PROPERTY(Expression_Obj, operand)
|
|
Packit Service |
7770af |
size_t hash_;
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Unary_Expression(ParserState pstate, Type t, Expression_Obj o)
|
|
Packit Service |
7770af |
: Expression(pstate), optype_(t), operand_(o), hash_(0)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
Unary_Expression(const Unary_Expression* ptr)
|
|
Packit Service |
7770af |
: Expression(ptr),
|
|
Packit Service |
7770af |
optype_(ptr->optype_),
|
|
Packit Service |
7770af |
operand_(ptr->operand_),
|
|
Packit Service |
7770af |
hash_(ptr->hash_)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
const std::string type_name() {
|
|
Packit Service |
7770af |
switch (optype_) {
|
|
Packit Service |
7770af |
case PLUS: return "plus";
|
|
Packit Service |
7770af |
case MINUS: return "minus";
|
|
Packit Service |
7770af |
case SLASH: return "slash";
|
|
Packit Service |
7770af |
case NOT: return "not";
|
|
Packit Service |
7770af |
default: return "invalid";
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
virtual bool operator==(const Expression& rhs) const
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
try
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
Unary_Expression_Ptr_Const m = Cast<Unary_Expression>(&rhs;;
|
|
Packit Service |
7770af |
if (m == 0) return false;
|
|
Packit Service |
7770af |
return type() == m->type() &&
|
|
Packit Service |
7770af |
*operand() == *m->operand();
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
catch (std::bad_cast&)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return false;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
catch (...) { throw; }
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
virtual size_t hash()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (hash_ == 0) {
|
|
Packit Service |
7770af |
hash_ = std::hash<size_t>()(optype_);
|
|
Packit Service |
7770af |
hash_combine(hash_, operand()->hash());
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
return hash_;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Unary_Expression)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Individual argument objects for mixin and function calls.
|
|
Packit Service |
7770af |
////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Argument : public Expression {
|
|
Packit Service |
7770af |
HASH_PROPERTY(Expression_Obj, value)
|
|
Packit Service |
7770af |
HASH_CONSTREF(std::string, name)
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, is_rest_argument)
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, is_keyword_argument)
|
|
Packit Service |
7770af |
size_t hash_;
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Argument(ParserState pstate, Expression_Obj val, std::string n = "", bool rest = false, bool keyword = false)
|
|
Packit Service |
7770af |
: Expression(pstate), value_(val), name_(n), is_rest_argument_(rest), is_keyword_argument_(keyword), hash_(0)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (!name_.empty() && is_rest_argument_) {
|
|
Packit Service |
7770af |
error("variable-length argument may not be passed by name", pstate_);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
Argument(const Argument* ptr)
|
|
Packit Service |
7770af |
: Expression(ptr),
|
|
Packit Service |
7770af |
value_(ptr->value_),
|
|
Packit Service |
7770af |
name_(ptr->name_),
|
|
Packit Service |
7770af |
is_rest_argument_(ptr->is_rest_argument_),
|
|
Packit Service |
7770af |
is_keyword_argument_(ptr->is_keyword_argument_),
|
|
Packit Service |
7770af |
hash_(ptr->hash_)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (!name_.empty() && is_rest_argument_) {
|
|
Packit Service |
7770af |
error("variable-length argument may not be passed by name", pstate_);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual void set_delayed(bool delayed);
|
|
Packit Service |
7770af |
virtual bool operator==(const Expression& rhs) const
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
try
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
Argument_Ptr_Const m = Cast<Argument>(&rhs;;
|
|
Packit Service |
7770af |
if (!(m && name() == m->name())) return false;
|
|
Packit Service |
7770af |
return *value() == *m->value();
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
catch (std::bad_cast&)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return false;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
catch (...) { throw; }
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual size_t hash()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (hash_ == 0) {
|
|
Packit Service |
7770af |
hash_ = std::hash<std::string>()(name());
|
|
Packit Service |
7770af |
hash_combine(hash_, value()->hash());
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
return hash_;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Argument)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Argument lists -- in their own class to facilitate context-sensitive
|
|
Packit Service |
7770af |
// error checking (e.g., ensuring that all ordinal arguments precede all
|
|
Packit Service |
7770af |
// named arguments).
|
|
Packit Service |
7770af |
////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Arguments : public Expression, public Vectorized<Argument_Obj> {
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, has_named_arguments)
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, has_rest_argument)
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, has_keyword_argument)
|
|
Packit Service |
7770af |
protected:
|
|
Packit Service |
7770af |
void adjust_after_pushing(Argument_Obj a);
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Arguments(ParserState pstate)
|
|
Packit Service |
7770af |
: Expression(pstate),
|
|
Packit Service |
7770af |
Vectorized<Argument_Obj>(),
|
|
Packit Service |
7770af |
has_named_arguments_(false),
|
|
Packit Service |
7770af |
has_rest_argument_(false),
|
|
Packit Service |
7770af |
has_keyword_argument_(false)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
Arguments(const Arguments* ptr)
|
|
Packit Service |
7770af |
: Expression(ptr),
|
|
Packit Service |
7770af |
Vectorized<Argument_Obj>(*ptr),
|
|
Packit Service |
7770af |
has_named_arguments_(ptr->has_named_arguments_),
|
|
Packit Service |
7770af |
has_rest_argument_(ptr->has_rest_argument_),
|
|
Packit Service |
7770af |
has_keyword_argument_(ptr->has_keyword_argument_)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual void set_delayed(bool delayed);
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
Argument_Obj get_rest_argument();
|
|
Packit Service |
7770af |
Argument_Obj get_keyword_argument();
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Arguments)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
//////////////////
|
|
Packit Service |
7770af |
// Function calls.
|
|
Packit Service |
7770af |
//////////////////
|
|
Packit Service |
7770af |
class Function_Call : public PreValue {
|
|
Packit Service |
7770af |
HASH_CONSTREF(std::string, name)
|
|
Packit Service |
7770af |
HASH_PROPERTY(Arguments_Obj, arguments)
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, via_call)
|
|
Packit Service |
7770af |
ADD_PROPERTY(void*, cookie)
|
|
Packit Service |
7770af |
size_t hash_;
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Function_Call(ParserState pstate, std::string n, Arguments_Obj args, void* cookie)
|
|
Packit Service |
7770af |
: PreValue(pstate), name_(n), arguments_(args), via_call_(false), cookie_(cookie), hash_(0)
|
|
Packit Service |
7770af |
{ concrete_type(FUNCTION); }
|
|
Packit Service |
7770af |
Function_Call(ParserState pstate, std::string n, Arguments_Obj args)
|
|
Packit Service |
7770af |
: PreValue(pstate), name_(n), arguments_(args), via_call_(false), cookie_(0), hash_(0)
|
|
Packit Service |
7770af |
{ concrete_type(FUNCTION); }
|
|
Packit Service |
7770af |
Function_Call(const Function_Call* ptr)
|
|
Packit Service |
7770af |
: PreValue(ptr),
|
|
Packit Service |
7770af |
name_(ptr->name_),
|
|
Packit Service |
7770af |
arguments_(ptr->arguments_),
|
|
Packit Service |
7770af |
via_call_(ptr->via_call_),
|
|
Packit Service |
7770af |
cookie_(ptr->cookie_),
|
|
Packit Service |
7770af |
hash_(ptr->hash_)
|
|
Packit Service |
7770af |
{ concrete_type(FUNCTION); }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual bool operator==(const Expression& rhs) const
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
try
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
Function_Call_Ptr_Const m = Cast<Function_Call>(&rhs;;
|
|
Packit Service |
7770af |
if (!(m && name() == m->name())) return false;
|
|
Packit Service |
7770af |
if (!(m && arguments()->length() == m->arguments()->length())) return false;
|
|
Packit Service |
7770af |
for (size_t i =0, L = arguments()->length(); i < L; ++i)
|
|
Packit Service |
7770af |
if (!(*(*arguments())[i] == *(*m->arguments())[i])) return false;
|
|
Packit Service |
7770af |
return true;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
catch (std::bad_cast&)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return false;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
catch (...) { throw; }
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual size_t hash()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (hash_ == 0) {
|
|
Packit Service |
7770af |
hash_ = std::hash<std::string>()(name());
|
|
Packit Service |
7770af |
for (auto argument : arguments()->elements())
|
|
Packit Service |
7770af |
hash_combine(hash_, argument->hash());
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
return hash_;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Function_Call)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
/////////////////////////
|
|
Packit Service |
7770af |
// Function call schemas.
|
|
Packit Service |
7770af |
/////////////////////////
|
|
Packit Service |
7770af |
class Function_Call_Schema : public Expression {
|
|
Packit Service |
7770af |
ADD_PROPERTY(String_Obj, name)
|
|
Packit Service |
7770af |
ADD_PROPERTY(Arguments_Obj, arguments)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Function_Call_Schema(ParserState pstate, String_Obj n, Arguments_Obj args)
|
|
Packit Service |
7770af |
: Expression(pstate), name_(n), arguments_(args)
|
|
Packit Service |
7770af |
{ concrete_type(STRING); }
|
|
Packit Service |
7770af |
Function_Call_Schema(const Function_Call_Schema* ptr)
|
|
Packit Service |
7770af |
: Expression(ptr),
|
|
Packit Service |
7770af |
name_(ptr->name_),
|
|
Packit Service |
7770af |
arguments_(ptr->arguments_)
|
|
Packit Service |
7770af |
{ concrete_type(STRING); }
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Function_Call_Schema)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
///////////////////////
|
|
Packit Service |
7770af |
// Variable references.
|
|
Packit Service |
7770af |
///////////////////////
|
|
Packit Service |
7770af |
class Variable : public PreValue {
|
|
Packit Service |
7770af |
ADD_CONSTREF(std::string, name)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Variable(ParserState pstate, std::string n)
|
|
Packit Service |
7770af |
: PreValue(pstate), name_(n)
|
|
Packit Service |
7770af |
{ concrete_type(VARIABLE); }
|
|
Packit Service |
7770af |
Variable(const Variable* ptr)
|
|
Packit Service |
7770af |
: PreValue(ptr), name_(ptr->name_)
|
|
Packit Service |
7770af |
{ concrete_type(VARIABLE); }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual bool operator==(const Expression& rhs) const
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
try
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
Variable_Ptr_Const e = Cast<Variable>(&rhs;;
|
|
Packit Service |
7770af |
return e && name() == e->name();
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
catch (std::bad_cast&)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return false;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
catch (...) { throw; }
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual size_t hash()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return std::hash<std::string>()(name());
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Variable)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Numbers, percentages, dimensions, and colors.
|
|
Packit Service |
7770af |
////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Number : public Value {
|
|
Packit Service |
7770af |
HASH_PROPERTY(double, value)
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, zero)
|
|
Packit Service |
7770af |
std::vector<std::string> numerator_units_;
|
|
Packit Service |
7770af |
std::vector<std::string> denominator_units_;
|
|
Packit Service |
7770af |
size_t hash_;
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Number(ParserState pstate, double val, std::string u = "", bool zero = true);
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
Number(const Number* ptr)
|
|
Packit Service |
7770af |
: Value(ptr),
|
|
Packit Service |
7770af |
value_(ptr->value_), zero_(ptr->zero_),
|
|
Packit Service |
7770af |
numerator_units_(ptr->numerator_units_),
|
|
Packit Service |
7770af |
denominator_units_(ptr->denominator_units_),
|
|
Packit Service |
7770af |
hash_(ptr->hash_)
|
|
Packit Service |
7770af |
{ concrete_type(NUMBER); }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
bool zero() { return zero_; }
|
|
Packit Service |
7770af |
bool is_valid_css_unit() const;
|
|
Packit Service |
7770af |
std::vector<std::string>& numerator_units() { return numerator_units_; }
|
|
Packit Service |
7770af |
std::vector<std::string>& denominator_units() { return denominator_units_; }
|
|
Packit Service |
7770af |
const std::vector<std::string>& numerator_units() const { return numerator_units_; }
|
|
Packit Service |
7770af |
const std::vector<std::string>& denominator_units() const { return denominator_units_; }
|
|
Packit Service |
7770af |
std::string type() const { return "number"; }
|
|
Packit Service |
7770af |
static std::string type_name() { return "number"; }
|
|
Packit Service |
7770af |
std::string unit() const;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
bool is_unitless() const;
|
|
Packit Service |
7770af |
double convert_factor(const Number&) const;
|
|
Packit Service |
7770af |
bool convert(const std::string& unit = "", bool strict = false);
|
|
Packit Service |
7770af |
void normalize(const std::string& unit = "", bool strict = false);
|
|
Packit Service |
7770af |
// useful for making one number compatible with another
|
|
Packit Service |
7770af |
std::string find_convertible_unit() const;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual size_t hash()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (hash_ == 0) {
|
|
Packit Service |
7770af |
hash_ = std::hash<double>()(value_);
|
|
Packit Service |
7770af |
for (const auto numerator : numerator_units())
|
|
Packit Service |
7770af |
hash_combine(hash_, std::hash<std::string>()(numerator));
|
|
Packit Service |
7770af |
for (const auto denominator : denominator_units())
|
|
Packit Service |
7770af |
hash_combine(hash_, std::hash<std::string>()(denominator));
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
return hash_;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual bool operator< (const Number& rhs) const;
|
|
Packit Service |
7770af |
virtual bool operator== (const Expression& rhs) const;
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Number)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
//////////
|
|
Packit Service |
7770af |
// Colors.
|
|
Packit Service |
7770af |
//////////
|
|
Packit Service |
7770af |
class Color : public Value {
|
|
Packit Service |
7770af |
HASH_PROPERTY(double, r)
|
|
Packit Service |
7770af |
HASH_PROPERTY(double, g)
|
|
Packit Service |
7770af |
HASH_PROPERTY(double, b)
|
|
Packit Service |
7770af |
HASH_PROPERTY(double, a)
|
|
Packit Service |
7770af |
ADD_CONSTREF(std::string, disp)
|
|
Packit Service |
7770af |
size_t hash_;
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Color(ParserState pstate, double r, double g, double b, double a = 1, const std::string disp = "")
|
|
Packit Service |
7770af |
: Value(pstate), r_(r), g_(g), b_(b), a_(a), disp_(disp),
|
|
Packit Service |
7770af |
hash_(0)
|
|
Packit Service |
7770af |
{ concrete_type(COLOR); }
|
|
Packit Service |
7770af |
Color(const Color* ptr)
|
|
Packit Service |
7770af |
: Value(ptr),
|
|
Packit Service |
7770af |
r_(ptr->r_),
|
|
Packit Service |
7770af |
g_(ptr->g_),
|
|
Packit Service |
7770af |
b_(ptr->b_),
|
|
Packit Service |
7770af |
a_(ptr->a_),
|
|
Packit Service |
7770af |
disp_(ptr->disp_),
|
|
Packit Service |
7770af |
hash_(ptr->hash_)
|
|
Packit Service |
7770af |
{ concrete_type(COLOR); }
|
|
Packit Service |
7770af |
std::string type() const { return "color"; }
|
|
Packit Service |
7770af |
static std::string type_name() { return "color"; }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual size_t hash()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (hash_ == 0) {
|
|
Packit Service |
7770af |
hash_ = std::hash<double>()(a_);
|
|
Packit Service |
7770af |
hash_combine(hash_, std::hash<double>()(r_));
|
|
Packit Service |
7770af |
hash_combine(hash_, std::hash<double>()(g_));
|
|
Packit Service |
7770af |
hash_combine(hash_, std::hash<double>()(b_));
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
return hash_;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual bool operator== (const Expression& rhs) const;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Color)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
//////////////////////////////
|
|
Packit Service |
7770af |
// Errors from Sass_Values.
|
|
Packit Service |
7770af |
//////////////////////////////
|
|
Packit Service |
7770af |
class Custom_Error : public Value {
|
|
Packit Service |
7770af |
ADD_CONSTREF(std::string, message)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Custom_Error(ParserState pstate, std::string msg)
|
|
Packit Service |
7770af |
: Value(pstate), message_(msg)
|
|
Packit Service |
7770af |
{ concrete_type(C_ERROR); }
|
|
Packit Service |
7770af |
Custom_Error(const Custom_Error* ptr)
|
|
Packit Service |
7770af |
: Value(ptr), message_(ptr->message_)
|
|
Packit Service |
7770af |
{ concrete_type(C_ERROR); }
|
|
Packit Service |
7770af |
virtual bool operator== (const Expression& rhs) const;
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Custom_Error)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
//////////////////////////////
|
|
Packit Service |
7770af |
// Warnings from Sass_Values.
|
|
Packit Service |
7770af |
//////////////////////////////
|
|
Packit Service |
7770af |
class Custom_Warning : public Value {
|
|
Packit Service |
7770af |
ADD_CONSTREF(std::string, message)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Custom_Warning(ParserState pstate, std::string msg)
|
|
Packit Service |
7770af |
: Value(pstate), message_(msg)
|
|
Packit Service |
7770af |
{ concrete_type(C_WARNING); }
|
|
Packit Service |
7770af |
Custom_Warning(const Custom_Warning* ptr)
|
|
Packit Service |
7770af |
: Value(ptr), message_(ptr->message_)
|
|
Packit Service |
7770af |
{ concrete_type(C_WARNING); }
|
|
Packit Service |
7770af |
virtual bool operator== (const Expression& rhs) const;
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Custom_Warning)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
////////////
|
|
Packit Service |
7770af |
// Booleans.
|
|
Packit Service |
7770af |
////////////
|
|
Packit Service |
7770af |
class Boolean : public Value {
|
|
Packit Service |
7770af |
HASH_PROPERTY(bool, value)
|
|
Packit Service |
7770af |
size_t hash_;
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Boolean(ParserState pstate, bool val)
|
|
Packit Service |
7770af |
: Value(pstate), value_(val),
|
|
Packit Service |
7770af |
hash_(0)
|
|
Packit Service |
7770af |
{ concrete_type(BOOLEAN); }
|
|
Packit Service |
7770af |
Boolean(const Boolean* ptr)
|
|
Packit Service |
7770af |
: Value(ptr),
|
|
Packit Service |
7770af |
value_(ptr->value_),
|
|
Packit Service |
7770af |
hash_(ptr->hash_)
|
|
Packit Service |
7770af |
{ concrete_type(BOOLEAN); }
|
|
Packit Service |
7770af |
virtual operator bool() { return value_; }
|
|
Packit Service |
7770af |
std::string type() const { return "bool"; }
|
|
Packit Service |
7770af |
static std::string type_name() { return "bool"; }
|
|
Packit Service |
7770af |
virtual bool is_false() { return !value_; }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual size_t hash()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (hash_ == 0) {
|
|
Packit Service |
7770af |
hash_ = std::hash<bool>()(value_);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
return hash_;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual bool operator== (const Expression& rhs) const;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Boolean)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Abstract base class for Sass string values. Includes interpolated and
|
|
Packit Service |
7770af |
// "flat" strings.
|
|
Packit Service |
7770af |
////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class String : public Value {
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
String(ParserState pstate, bool delayed = false)
|
|
Packit Service |
7770af |
: Value(pstate, delayed)
|
|
Packit Service |
7770af |
{ concrete_type(STRING); }
|
|
Packit Service |
7770af |
String(const String* ptr)
|
|
Packit Service |
7770af |
: Value(ptr)
|
|
Packit Service |
7770af |
{ concrete_type(STRING); }
|
|
Packit Service |
7770af |
static std::string type_name() { return "string"; }
|
|
Packit Service |
7770af |
virtual ~String() = 0;
|
|
Packit Service |
7770af |
virtual void rtrim() = 0;
|
|
Packit Service |
7770af |
virtual bool operator==(const Expression& rhs) const = 0;
|
|
Packit Service |
7770af |
virtual bool operator<(const Expression& rhs) const {
|
|
Packit Service |
7770af |
return this->to_string() < rhs.to_string();
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
ATTACH_VIRTUAL_AST_OPERATIONS(String);
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
inline String::~String() { };
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
///////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Interpolated strings. Meant to be reduced to flat strings during the
|
|
Packit Service |
7770af |
// evaluation phase.
|
|
Packit Service |
7770af |
///////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class String_Schema : public String, public Vectorized<Expression_Obj> {
|
|
Packit Service |
7770af |
// ADD_PROPERTY(bool, has_interpolants)
|
|
Packit Service |
7770af |
size_t hash_;
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
String_Schema(ParserState pstate, size_t size = 0, bool has_interpolants = false)
|
|
Packit Service |
7770af |
: String(pstate), Vectorized<Expression_Obj>(size), hash_(0)
|
|
Packit Service |
7770af |
{ concrete_type(STRING); }
|
|
Packit Service |
7770af |
String_Schema(const String_Schema* ptr)
|
|
Packit Service |
7770af |
: String(ptr),
|
|
Packit Service |
7770af |
Vectorized<Expression_Obj>(*ptr),
|
|
Packit Service |
7770af |
hash_(ptr->hash_)
|
|
Packit Service |
7770af |
{ concrete_type(STRING); }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
std::string type() const { return "string"; }
|
|
Packit Service |
7770af |
static std::string type_name() { return "string"; }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
bool is_left_interpolant(void) const;
|
|
Packit Service |
7770af |
bool is_right_interpolant(void) const;
|
|
Packit Service |
7770af |
// void has_interpolants(bool tc) { }
|
|
Packit Service |
7770af |
bool has_interpolants() {
|
|
Packit Service |
7770af |
for (auto el : elements()) {
|
|
Packit Service |
7770af |
if (el->is_interpolant()) return true;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
return false;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
virtual void rtrim();
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual size_t hash()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (hash_ == 0) {
|
|
Packit Service |
7770af |
for (auto string : elements())
|
|
Packit Service |
7770af |
hash_combine(hash_, string->hash());
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
return hash_;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual void set_delayed(bool delayed) {
|
|
Packit Service |
7770af |
is_delayed(delayed);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual bool operator==(const Expression& rhs) const;
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(String_Schema)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Flat strings -- the lowest level of raw textual data.
|
|
Packit Service |
7770af |
////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class String_Constant : public String {
|
|
Packit Service |
7770af |
ADD_PROPERTY(char, quote_mark)
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, can_compress_whitespace)
|
|
Packit Service |
7770af |
HASH_CONSTREF(std::string, value)
|
|
Packit Service |
7770af |
protected:
|
|
Packit Service |
7770af |
size_t hash_;
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
String_Constant(const String_Constant* ptr)
|
|
Packit Service |
7770af |
: String(ptr),
|
|
Packit Service |
7770af |
quote_mark_(ptr->quote_mark_),
|
|
Packit Service |
7770af |
can_compress_whitespace_(ptr->can_compress_whitespace_),
|
|
Packit Service |
7770af |
value_(ptr->value_),
|
|
Packit Service |
7770af |
hash_(ptr->hash_)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
String_Constant(ParserState pstate, std::string val)
|
|
Packit Service |
7770af |
: String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(val)), hash_(0)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
String_Constant(ParserState pstate, const char* beg)
|
|
Packit Service |
7770af |
: String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(std::string(beg))), hash_(0)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
String_Constant(ParserState pstate, const char* beg, const char* end)
|
|
Packit Service |
7770af |
: String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(std::string(beg, end-beg))), hash_(0)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
String_Constant(ParserState pstate, const Token& tok)
|
|
Packit Service |
7770af |
: String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(std::string(tok.begin, tok.end))), hash_(0)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
std::string type() const { return "string"; }
|
|
Packit Service |
7770af |
static std::string type_name() { return "string"; }
|
|
Packit Service |
7770af |
virtual bool is_invisible() const;
|
|
Packit Service |
7770af |
virtual void rtrim();
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual size_t hash()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (hash_ == 0) {
|
|
Packit Service |
7770af |
hash_ = std::hash<std::string>()(value_);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
return hash_;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual bool operator==(const Expression& rhs) const;
|
|
Packit Service |
7770af |
virtual std::string inspect() const; // quotes are forced on inspection
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// static char auto_quote() { return '*'; }
|
|
Packit Service |
7770af |
static char double_quote() { return '"'; }
|
|
Packit Service |
7770af |
static char single_quote() { return '\''; }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(String_Constant)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Possibly quoted string (unquote on instantiation)
|
|
Packit Service |
7770af |
////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class String_Quoted : public String_Constant {
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
String_Quoted(ParserState pstate, std::string val, char q = 0,
|
|
Packit Service |
7770af |
bool keep_utf8_escapes = false, bool skip_unquoting = false,
|
|
Packit Service |
7770af |
bool strict_unquoting = true)
|
|
Packit Service |
7770af |
: String_Constant(pstate, val)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (skip_unquoting == false) {
|
|
Packit Service |
7770af |
value_ = unquote(value_, "e_mark_, keep_utf8_escapes, strict_unquoting);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
if (q && quote_mark_) quote_mark_ = q;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
String_Quoted(const String_Quoted* ptr)
|
|
Packit Service |
7770af |
: String_Constant(ptr)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
virtual bool operator==(const Expression& rhs) const;
|
|
Packit Service |
7770af |
virtual std::string inspect() const; // quotes are forced on inspection
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(String_Quoted)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
/////////////////
|
|
Packit Service |
7770af |
// Media queries.
|
|
Packit Service |
7770af |
/////////////////
|
|
Packit Service |
7770af |
class Media_Query : public Expression,
|
|
Packit Service |
7770af |
public Vectorized<Media_Query_Expression_Obj> {
|
|
Packit Service |
7770af |
ADD_PROPERTY(String_Obj, media_type)
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, is_negated)
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, is_restricted)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Media_Query(ParserState pstate,
|
|
Packit Service |
7770af |
String_Obj t = 0, size_t s = 0, bool n = false, bool r = false)
|
|
Packit Service |
7770af |
: Expression(pstate), Vectorized<Media_Query_Expression_Obj>(s),
|
|
Packit Service |
7770af |
media_type_(t), is_negated_(n), is_restricted_(r)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
Media_Query(const Media_Query* ptr)
|
|
Packit Service |
7770af |
: Expression(ptr),
|
|
Packit Service |
7770af |
Vectorized<Media_Query_Expression_Obj>(*ptr),
|
|
Packit Service |
7770af |
media_type_(ptr->media_type_),
|
|
Packit Service |
7770af |
is_negated_(ptr->is_negated_),
|
|
Packit Service |
7770af |
is_restricted_(ptr->is_restricted_)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Media_Query)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Media expressions (for use inside media queries).
|
|
Packit Service |
7770af |
////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Media_Query_Expression : public Expression {
|
|
Packit Service |
7770af |
ADD_PROPERTY(Expression_Obj, feature)
|
|
Packit Service |
7770af |
ADD_PROPERTY(Expression_Obj, value)
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, is_interpolated)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Media_Query_Expression(ParserState pstate,
|
|
Packit Service |
7770af |
Expression_Obj f, Expression_Obj v, bool i = false)
|
|
Packit Service |
7770af |
: Expression(pstate), feature_(f), value_(v), is_interpolated_(i)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
Media_Query_Expression(const Media_Query_Expression* ptr)
|
|
Packit Service |
7770af |
: Expression(ptr),
|
|
Packit Service |
7770af |
feature_(ptr->feature_),
|
|
Packit Service |
7770af |
value_(ptr->value_),
|
|
Packit Service |
7770af |
is_interpolated_(ptr->is_interpolated_)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Media_Query_Expression)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
////////////////////
|
|
Packit Service |
7770af |
// `@supports` rule.
|
|
Packit Service |
7770af |
////////////////////
|
|
Packit Service |
7770af |
class Supports_Block : public Has_Block {
|
|
Packit Service |
7770af |
ADD_PROPERTY(Supports_Condition_Obj, condition)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Supports_Block(ParserState pstate, Supports_Condition_Obj condition, Block_Obj block = 0)
|
|
Packit Service |
7770af |
: Has_Block(pstate, block), condition_(condition)
|
|
Packit Service |
7770af |
{ statement_type(SUPPORTS); }
|
|
Packit Service |
7770af |
Supports_Block(const Supports_Block* ptr)
|
|
Packit Service |
7770af |
: Has_Block(ptr), condition_(ptr->condition_)
|
|
Packit Service |
7770af |
{ statement_type(SUPPORTS); }
|
|
Packit Service |
7770af |
bool bubbles() { return true; }
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Supports_Block)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
//////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// The abstract superclass of all Supports conditions.
|
|
Packit Service |
7770af |
//////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Supports_Condition : public Expression {
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Supports_Condition(ParserState pstate)
|
|
Packit Service |
7770af |
: Expression(pstate)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
Supports_Condition(const Supports_Condition* ptr)
|
|
Packit Service |
7770af |
: Expression(ptr)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
virtual bool needs_parens(Supports_Condition_Obj cond) const { return false; }
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Supports_Condition)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// An operator condition (e.g. `CONDITION1 and CONDITION2`).
|
|
Packit Service |
7770af |
////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Supports_Operator : public Supports_Condition {
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
enum Operand { AND, OR };
|
|
Packit Service |
7770af |
private:
|
|
Packit Service |
7770af |
ADD_PROPERTY(Supports_Condition_Obj, left);
|
|
Packit Service |
7770af |
ADD_PROPERTY(Supports_Condition_Obj, right);
|
|
Packit Service |
7770af |
ADD_PROPERTY(Operand, operand);
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Supports_Operator(ParserState pstate, Supports_Condition_Obj l, Supports_Condition_Obj r, Operand o)
|
|
Packit Service |
7770af |
: Supports_Condition(pstate), left_(l), right_(r), operand_(o)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
Supports_Operator(const Supports_Operator* ptr)
|
|
Packit Service |
7770af |
: Supports_Condition(ptr),
|
|
Packit Service |
7770af |
left_(ptr->left_),
|
|
Packit Service |
7770af |
right_(ptr->right_),
|
|
Packit Service |
7770af |
operand_(ptr->operand_)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
virtual bool needs_parens(Supports_Condition_Obj cond) const;
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Supports_Operator)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
//////////////////////////////////////////
|
|
Packit Service |
7770af |
// A negation condition (`not CONDITION`).
|
|
Packit Service |
7770af |
//////////////////////////////////////////
|
|
Packit Service |
7770af |
class Supports_Negation : public Supports_Condition {
|
|
Packit Service |
7770af |
private:
|
|
Packit Service |
7770af |
ADD_PROPERTY(Supports_Condition_Obj, condition);
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Supports_Negation(ParserState pstate, Supports_Condition_Obj c)
|
|
Packit Service |
7770af |
: Supports_Condition(pstate), condition_(c)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
Supports_Negation(const Supports_Negation* ptr)
|
|
Packit Service |
7770af |
: Supports_Condition(ptr), condition_(ptr->condition_)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
virtual bool needs_parens(Supports_Condition_Obj cond) const;
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Supports_Negation)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
/////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// A declaration condition (e.g. `(feature: value)`).
|
|
Packit Service |
7770af |
/////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Supports_Declaration : public Supports_Condition {
|
|
Packit Service |
7770af |
private:
|
|
Packit Service |
7770af |
ADD_PROPERTY(Expression_Obj, feature);
|
|
Packit Service |
7770af |
ADD_PROPERTY(Expression_Obj, value);
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Supports_Declaration(ParserState pstate, Expression_Obj f, Expression_Obj v)
|
|
Packit Service |
7770af |
: Supports_Condition(pstate), feature_(f), value_(v)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
Supports_Declaration(const Supports_Declaration* ptr)
|
|
Packit Service |
7770af |
: Supports_Condition(ptr),
|
|
Packit Service |
7770af |
feature_(ptr->feature_),
|
|
Packit Service |
7770af |
value_(ptr->value_)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
virtual bool needs_parens(Supports_Condition_Obj cond) const { return false; }
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Supports_Declaration)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
///////////////////////////////////////////////
|
|
Packit Service |
7770af |
// An interpolation condition (e.g. `#{$var}`).
|
|
Packit Service |
7770af |
///////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Supports_Interpolation : public Supports_Condition {
|
|
Packit Service |
7770af |
private:
|
|
Packit Service |
7770af |
ADD_PROPERTY(Expression_Obj, value);
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Supports_Interpolation(ParserState pstate, Expression_Obj v)
|
|
Packit Service |
7770af |
: Supports_Condition(pstate), value_(v)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
Supports_Interpolation(const Supports_Interpolation* ptr)
|
|
Packit Service |
7770af |
: Supports_Condition(ptr),
|
|
Packit Service |
7770af |
value_(ptr->value_)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
virtual bool needs_parens(Supports_Condition_Obj cond) const { return false; }
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Supports_Interpolation)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
/////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// At root expressions (for use inside @at-root).
|
|
Packit Service |
7770af |
/////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class At_Root_Query : public Expression {
|
|
Packit Service |
7770af |
private:
|
|
Packit Service |
7770af |
ADD_PROPERTY(Expression_Obj, feature)
|
|
Packit Service |
7770af |
ADD_PROPERTY(Expression_Obj, value)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
At_Root_Query(ParserState pstate, Expression_Obj f = 0, Expression_Obj v = 0, bool i = false)
|
|
Packit Service |
7770af |
: Expression(pstate), feature_(f), value_(v)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
At_Root_Query(const At_Root_Query* ptr)
|
|
Packit Service |
7770af |
: Expression(ptr),
|
|
Packit Service |
7770af |
feature_(ptr->feature_),
|
|
Packit Service |
7770af |
value_(ptr->value_)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
bool exclude(std::string str);
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(At_Root_Query)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
///////////
|
|
Packit Service |
7770af |
// At-root.
|
|
Packit Service |
7770af |
///////////
|
|
Packit Service |
7770af |
class At_Root_Block : public Has_Block {
|
|
Packit Service |
7770af |
ADD_PROPERTY(At_Root_Query_Obj, expression)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
At_Root_Block(ParserState pstate, Block_Obj b = 0, At_Root_Query_Obj e = 0)
|
|
Packit Service |
7770af |
: Has_Block(pstate, b), expression_(e)
|
|
Packit Service |
7770af |
{ statement_type(ATROOT); }
|
|
Packit Service |
7770af |
At_Root_Block(const At_Root_Block* ptr)
|
|
Packit Service |
7770af |
: Has_Block(ptr), expression_(ptr->expression_)
|
|
Packit Service |
7770af |
{ statement_type(ATROOT); }
|
|
Packit Service |
7770af |
bool bubbles() { return true; }
|
|
Packit Service |
7770af |
bool exclude_node(Statement_Obj s) {
|
|
Packit Service |
7770af |
if (expression() == 0)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return s->statement_type() == Statement::RULESET;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
if (s->statement_type() == Statement::DIRECTIVE)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (Directive_Obj dir = Cast<Directive>(s))
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
std::string keyword(dir->keyword());
|
|
Packit Service |
7770af |
if (keyword.length() > 0) keyword.erase(0, 1);
|
|
Packit Service |
7770af |
return expression()->exclude(keyword);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
if (s->statement_type() == Statement::MEDIA)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return expression()->exclude("media");
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
if (s->statement_type() == Statement::RULESET)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return expression()->exclude("rule");
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
if (s->statement_type() == Statement::SUPPORTS)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return expression()->exclude("supports");
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
if (Directive_Obj dir = Cast<Directive>(s))
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (dir->is_keyframes()) return expression()->exclude("keyframes");
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
return false;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(At_Root_Block)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
//////////////////
|
|
Packit Service |
7770af |
// The null value.
|
|
Packit Service |
7770af |
//////////////////
|
|
Packit Service |
7770af |
class Null : public Value {
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Null(ParserState pstate) : Value(pstate) { concrete_type(NULL_VAL); }
|
|
Packit Service |
7770af |
Null(const Null* ptr) : Value(ptr) { concrete_type(NULL_VAL); }
|
|
Packit Service |
7770af |
std::string type() const { return "null"; }
|
|
Packit Service |
7770af |
static std::string type_name() { return "null"; }
|
|
Packit Service |
7770af |
bool is_invisible() const { return true; }
|
|
Packit Service |
7770af |
operator bool() { return false; }
|
|
Packit Service |
7770af |
bool is_false() { return true; }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual size_t hash()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return -1;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual bool operator== (const Expression& rhs) const;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Null)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
/////////////////////////////////
|
|
Packit Service |
7770af |
// Thunks for delayed evaluation.
|
|
Packit Service |
7770af |
/////////////////////////////////
|
|
Packit Service |
7770af |
class Thunk : public Expression {
|
|
Packit Service |
7770af |
ADD_PROPERTY(Expression_Obj, expression)
|
|
Packit Service |
7770af |
ADD_PROPERTY(Env*, environment)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Thunk(ParserState pstate, Expression_Obj exp, Env* env = 0)
|
|
Packit Service |
7770af |
: Expression(pstate), expression_(exp), environment_(env)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
/////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Individual parameter objects for mixins and functions.
|
|
Packit Service |
7770af |
/////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Parameter : public AST_Node {
|
|
Packit Service |
7770af |
ADD_CONSTREF(std::string, name)
|
|
Packit Service |
7770af |
ADD_PROPERTY(Expression_Obj, default_value)
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, is_rest_parameter)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Parameter(ParserState pstate,
|
|
Packit Service |
7770af |
std::string n, Expression_Obj def = 0, bool rest = false)
|
|
Packit Service |
7770af |
: AST_Node(pstate), name_(n), default_value_(def), is_rest_parameter_(rest)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
// tried to come up with a spec test for this, but it does no longer
|
|
Packit Service |
7770af |
// get past the parser (it error out earlier). A spec test was added!
|
|
Packit Service |
7770af |
// if (default_value_ && is_rest_parameter_) {
|
|
Packit Service |
7770af |
// error("variable-length parameter may not have a default value", pstate_);
|
|
Packit Service |
7770af |
// }
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
Parameter(const Parameter* ptr)
|
|
Packit Service |
7770af |
: AST_Node(ptr),
|
|
Packit Service |
7770af |
name_(ptr->name_),
|
|
Packit Service |
7770af |
default_value_(ptr->default_value_),
|
|
Packit Service |
7770af |
is_rest_parameter_(ptr->is_rest_parameter_)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
// tried to come up with a spec test for this, but it does no longer
|
|
Packit Service |
7770af |
// get past the parser (it error out earlier). A spec test was added!
|
|
Packit Service |
7770af |
// if (default_value_ && is_rest_parameter_) {
|
|
Packit Service |
7770af |
// error("variable-length parameter may not have a default value", pstate_);
|
|
Packit Service |
7770af |
// }
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Parameter)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
/////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Parameter lists -- in their own class to facilitate context-sensitive
|
|
Packit Service |
7770af |
// error checking (e.g., ensuring that all optional parameters follow all
|
|
Packit Service |
7770af |
// required parameters).
|
|
Packit Service |
7770af |
/////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Parameters : public AST_Node, public Vectorized<Parameter_Obj> {
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, has_optional_parameters)
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, has_rest_parameter)
|
|
Packit Service |
7770af |
protected:
|
|
Packit Service |
7770af |
void adjust_after_pushing(Parameter_Obj p)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (p->default_value()) {
|
|
Packit Service |
7770af |
if (has_rest_parameter()) {
|
|
Packit Service |
7770af |
error("optional parameters may not be combined with variable-length parameters", p->pstate());
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
has_optional_parameters(true);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
else if (p->is_rest_parameter()) {
|
|
Packit Service |
7770af |
if (has_rest_parameter()) {
|
|
Packit Service |
7770af |
error("functions and mixins cannot have more than one variable-length parameter", p->pstate());
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
has_rest_parameter(true);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
else {
|
|
Packit Service |
7770af |
if (has_rest_parameter()) {
|
|
Packit Service |
7770af |
error("required parameters must precede variable-length parameters", p->pstate());
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
if (has_optional_parameters()) {
|
|
Packit Service |
7770af |
error("required parameters must precede optional parameters", p->pstate());
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Parameters(ParserState pstate)
|
|
Packit Service |
7770af |
: AST_Node(pstate),
|
|
Packit Service |
7770af |
Vectorized<Parameter_Obj>(),
|
|
Packit Service |
7770af |
has_optional_parameters_(false),
|
|
Packit Service |
7770af |
has_rest_parameter_(false)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
Parameters(const Parameters* ptr)
|
|
Packit Service |
7770af |
: AST_Node(ptr),
|
|
Packit Service |
7770af |
Vectorized<Parameter_Obj>(*ptr),
|
|
Packit Service |
7770af |
has_optional_parameters_(ptr->has_optional_parameters_),
|
|
Packit Service |
7770af |
has_rest_parameter_(ptr->has_rest_parameter_)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Parameters)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
/////////////////////////////////////////
|
|
Packit Service |
7770af |
// Abstract base class for CSS selectors.
|
|
Packit Service |
7770af |
/////////////////////////////////////////
|
|
Packit Service |
7770af |
class Selector : public Expression {
|
|
Packit Service |
7770af |
// ADD_PROPERTY(bool, has_reference)
|
|
Packit Service |
7770af |
// line break before list separator
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, has_line_feed)
|
|
Packit Service |
7770af |
// line break after list separator
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, has_line_break)
|
|
Packit Service |
7770af |
// maybe we have optional flag
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, is_optional)
|
|
Packit Service |
7770af |
// parent block pointers
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// must not be a reference counted object
|
|
Packit Service |
7770af |
// otherwise we create circular references
|
|
Packit Service |
7770af |
ADD_PROPERTY(Media_Block_Ptr, media_block)
|
|
Packit Service |
7770af |
protected:
|
|
Packit Service |
7770af |
size_t hash_;
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Selector(ParserState pstate)
|
|
Packit Service |
7770af |
: Expression(pstate),
|
|
Packit Service |
7770af |
has_line_feed_(false),
|
|
Packit Service |
7770af |
has_line_break_(false),
|
|
Packit Service |
7770af |
is_optional_(false),
|
|
Packit Service |
7770af |
media_block_(0),
|
|
Packit Service |
7770af |
hash_(0)
|
|
Packit Service |
7770af |
{ concrete_type(SELECTOR); }
|
|
Packit Service |
7770af |
Selector(const Selector* ptr)
|
|
Packit Service |
7770af |
: Expression(ptr),
|
|
Packit Service |
7770af |
// has_reference_(ptr->has_reference_),
|
|
Packit Service |
7770af |
has_line_feed_(ptr->has_line_feed_),
|
|
Packit Service |
7770af |
has_line_break_(ptr->has_line_break_),
|
|
Packit Service |
7770af |
is_optional_(ptr->is_optional_),
|
|
Packit Service |
7770af |
media_block_(ptr->media_block_),
|
|
Packit Service |
7770af |
hash_(ptr->hash_)
|
|
Packit Service |
7770af |
{ concrete_type(SELECTOR); }
|
|
Packit Service |
7770af |
virtual ~Selector() = 0;
|
|
Packit Service |
7770af |
virtual size_t hash() = 0;
|
|
Packit Service |
7770af |
virtual unsigned long specificity() const = 0;
|
|
Packit Service |
7770af |
virtual void set_media_block(Media_Block_Ptr mb) {
|
|
Packit Service |
7770af |
media_block(mb);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
virtual bool has_parent_ref() const {
|
|
Packit Service |
7770af |
return false;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
virtual bool has_real_parent_ref() const {
|
|
Packit Service |
7770af |
return false;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
// dispatch to correct handlers
|
|
Packit Service |
7770af |
virtual bool operator<(const Selector& rhs) const = 0;
|
|
Packit Service |
7770af |
virtual bool operator==(const Selector& rhs) const = 0;
|
|
Packit Service |
7770af |
ATTACH_VIRTUAL_AST_OPERATIONS(Selector);
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
inline Selector::~Selector() { }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
/////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Interpolated selectors -- the interpolated String will be expanded and
|
|
Packit Service |
7770af |
// re-parsed into a normal selector class.
|
|
Packit Service |
7770af |
/////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Selector_Schema : public AST_Node {
|
|
Packit Service |
7770af |
ADD_PROPERTY(String_Obj, contents)
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, connect_parent);
|
|
Packit Service |
7770af |
// must not be a reference counted object
|
|
Packit Service |
7770af |
// otherwise we create circular references
|
|
Packit Service |
7770af |
ADD_PROPERTY(Media_Block_Ptr, media_block)
|
|
Packit Service |
7770af |
// store computed hash
|
|
Packit Service |
7770af |
size_t hash_;
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Selector_Schema(ParserState pstate, String_Obj c)
|
|
Packit Service |
7770af |
: AST_Node(pstate),
|
|
Packit Service |
7770af |
contents_(c),
|
|
Packit Service |
7770af |
connect_parent_(true),
|
|
Packit Service |
7770af |
media_block_(NULL),
|
|
Packit Service |
7770af |
hash_(0)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
Selector_Schema(const Selector_Schema* ptr)
|
|
Packit Service |
7770af |
: AST_Node(ptr),
|
|
Packit Service |
7770af |
contents_(ptr->contents_),
|
|
Packit Service |
7770af |
connect_parent_(ptr->connect_parent_),
|
|
Packit Service |
7770af |
media_block_(ptr->media_block_),
|
|
Packit Service |
7770af |
hash_(ptr->hash_)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
virtual bool has_parent_ref() const;
|
|
Packit Service |
7770af |
virtual bool has_real_parent_ref() const;
|
|
Packit Service |
7770af |
virtual bool operator<(const Selector& rhs) const;
|
|
Packit Service |
7770af |
virtual bool operator==(const Selector& rhs) const;
|
|
Packit Service |
7770af |
// selector schema is not yet a final selector, so we do not
|
|
Packit Service |
7770af |
// have a specificity for it yet. We need to
|
|
Packit Service |
7770af |
virtual unsigned long specificity() const { return 0; }
|
|
Packit Service |
7770af |
virtual size_t hash() {
|
|
Packit Service |
7770af |
if (hash_ == 0) {
|
|
Packit Service |
7770af |
hash_combine(hash_, contents_->hash());
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
return hash_;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Selector_Schema)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Abstract base class for simple selectors.
|
|
Packit Service |
7770af |
////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Simple_Selector : public Selector {
|
|
Packit Service |
7770af |
ADD_CONSTREF(std::string, ns)
|
|
Packit Service |
7770af |
ADD_CONSTREF(std::string, name)
|
|
Packit Service |
7770af |
ADD_PROPERTY(Simple_Type, simple_type)
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, has_ns)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Simple_Selector(ParserState pstate, std::string n = "")
|
|
Packit Service |
7770af |
: Selector(pstate), ns_(""), name_(n), has_ns_(false)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
simple_type(SIMPLE);
|
|
Packit Service |
7770af |
size_t pos = n.find('|');
|
|
Packit Service |
7770af |
// found some namespace
|
|
Packit Service |
7770af |
if (pos != std::string::npos) {
|
|
Packit Service |
7770af |
has_ns_ = true;
|
|
Packit Service |
7770af |
ns_ = n.substr(0, pos);
|
|
Packit Service |
7770af |
name_ = n.substr(pos + 1);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
Simple_Selector(const Simple_Selector* ptr)
|
|
Packit Service |
7770af |
: Selector(ptr),
|
|
Packit Service |
7770af |
ns_(ptr->ns_),
|
|
Packit Service |
7770af |
name_(ptr->name_),
|
|
Packit Service |
7770af |
has_ns_(ptr->has_ns_)
|
|
Packit Service |
7770af |
{ simple_type(SIMPLE); }
|
|
Packit Service |
7770af |
virtual std::string ns_name() const
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
std::string name("");
|
|
Packit Service |
7770af |
if (has_ns_)
|
|
Packit Service |
7770af |
name += ns_ + "|";
|
|
Packit Service |
7770af |
return name + name_;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
virtual size_t hash()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (hash_ == 0) {
|
|
Packit Service |
7770af |
hash_combine(hash_, std::hash<int>()(SELECTOR));
|
|
Packit Service |
7770af |
hash_combine(hash_, std::hash<std::string>()(ns()));
|
|
Packit Service |
7770af |
hash_combine(hash_, std::hash<std::string>()(name()));
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
return hash_;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
// namespace compare functions
|
|
Packit Service |
7770af |
bool is_ns_eq(const Simple_Selector& r) const;
|
|
Packit Service |
7770af |
// namespace query functions
|
|
Packit Service |
7770af |
bool is_universal_ns() const
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return has_ns_ && ns_ == "*";
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
bool has_universal_ns() const
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return !has_ns_ || ns_ == "*";
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
bool is_empty_ns() const
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return !has_ns_ || ns_ == "";
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
bool has_empty_ns() const
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return has_ns_ && ns_ == "";
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
bool has_qualified_ns() const
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return has_ns_ && ns_ != "" && ns_ != "*";
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
// name query functions
|
|
Packit Service |
7770af |
bool is_universal() const
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return name_ == "*";
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual bool has_placeholder() {
|
|
Packit Service |
7770af |
return false;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual ~Simple_Selector() = 0;
|
|
Packit Service |
7770af |
virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr);
|
|
Packit Service |
7770af |
virtual bool has_parent_ref() const { return false; };
|
|
Packit Service |
7770af |
virtual bool has_real_parent_ref() const { return false; };
|
|
Packit Service |
7770af |
virtual bool is_pseudo_element() const { return false; }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual bool is_superselector_of(Compound_Selector_Obj sub) { return false; }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual bool operator==(const Selector& rhs) const;
|
|
Packit Service |
7770af |
virtual bool operator==(const Simple_Selector& rhs) const;
|
|
Packit Service |
7770af |
inline bool operator!=(const Simple_Selector& rhs) const { return !(*this == rhs); }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
bool operator<(const Selector& rhs) const;
|
|
Packit Service |
7770af |
bool operator<(const Simple_Selector& rhs) const;
|
|
Packit Service |
7770af |
// default implementation should work for most of the simple selectors (otherwise overload)
|
|
Packit Service |
7770af |
ATTACH_VIRTUAL_AST_OPERATIONS(Simple_Selector);
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS();
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
inline Simple_Selector::~Simple_Selector() { }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
//////////////////////////////////
|
|
Packit Service |
7770af |
// The Parent Selector Expression.
|
|
Packit Service |
7770af |
//////////////////////////////////
|
|
Packit Service |
7770af |
// parent selectors can occur in selectors but also
|
|
Packit Service |
7770af |
// inside strings in declarations (Compound_Selector).
|
|
Packit Service |
7770af |
// only one simple parent selector means the first case.
|
|
Packit Service |
7770af |
class Parent_Selector : public Simple_Selector {
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, real)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Parent_Selector(ParserState pstate, bool r = true)
|
|
Packit Service |
7770af |
: Simple_Selector(pstate, "&"), real_(r)
|
|
Packit Service |
7770af |
{ /* has_reference(true); */ }
|
|
Packit Service |
7770af |
Parent_Selector(const Parent_Selector* ptr)
|
|
Packit Service |
7770af |
: Simple_Selector(ptr), real_(ptr->real_)
|
|
Packit Service |
7770af |
{ /* has_reference(true); */ }
|
|
Packit Service |
7770af |
bool is_real_parent_ref() const { return real(); };
|
|
Packit Service |
7770af |
virtual bool has_parent_ref() const { return true; };
|
|
Packit Service |
7770af |
virtual bool has_real_parent_ref() const { return is_real_parent_ref(); };
|
|
Packit Service |
7770af |
virtual unsigned long specificity() const
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return 0;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
std::string type() const { return "selector"; }
|
|
Packit Service |
7770af |
static std::string type_name() { return "selector"; }
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Parent_Selector)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
/////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Placeholder selectors (e.g., "%foo") for use in extend-only selectors.
|
|
Packit Service |
7770af |
/////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Placeholder_Selector : public Simple_Selector {
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Placeholder_Selector(ParserState pstate, std::string n)
|
|
Packit Service |
7770af |
: Simple_Selector(pstate, n)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
Placeholder_Selector(const Placeholder_Selector* ptr)
|
|
Packit Service |
7770af |
: Simple_Selector(ptr)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
virtual unsigned long specificity() const
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return Constants::Specificity_Base;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
virtual bool has_placeholder() {
|
|
Packit Service |
7770af |
return true;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
virtual ~Placeholder_Selector() {};
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Placeholder_Selector)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
/////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Element selectors (and the universal selector) -- e.g., div, span, *.
|
|
Packit Service |
7770af |
/////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Element_Selector : public Simple_Selector {
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Element_Selector(ParserState pstate, std::string n)
|
|
Packit Service |
7770af |
: Simple_Selector(pstate, n)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
Element_Selector(const Element_Selector* ptr)
|
|
Packit Service |
7770af |
: Simple_Selector(ptr)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
virtual unsigned long specificity() const
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (name() == "*") return 0;
|
|
Packit Service |
7770af |
else return Constants::Specificity_Element;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
virtual Simple_Selector_Ptr unify_with(Simple_Selector_Ptr);
|
|
Packit Service |
7770af |
virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr);
|
|
Packit Service |
7770af |
virtual bool operator==(const Simple_Selector& rhs) const;
|
|
Packit Service |
7770af |
virtual bool operator==(const Element_Selector& rhs) const;
|
|
Packit Service |
7770af |
virtual bool operator<(const Simple_Selector& rhs) const;
|
|
Packit Service |
7770af |
virtual bool operator<(const Element_Selector& rhs) const;
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Element_Selector)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Class selectors -- i.e., .foo.
|
|
Packit Service |
7770af |
////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Class_Selector : public Simple_Selector {
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Class_Selector(ParserState pstate, std::string n)
|
|
Packit Service |
7770af |
: Simple_Selector(pstate, n)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
Class_Selector(const Class_Selector* ptr)
|
|
Packit Service |
7770af |
: Simple_Selector(ptr)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
virtual unsigned long specificity() const
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return Constants::Specificity_Class;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr);
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Class_Selector)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// ID selectors -- i.e., #foo.
|
|
Packit Service |
7770af |
////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Id_Selector : public Simple_Selector {
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Id_Selector(ParserState pstate, std::string n)
|
|
Packit Service |
7770af |
: Simple_Selector(pstate, n)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
Id_Selector(const Id_Selector* ptr)
|
|
Packit Service |
7770af |
: Simple_Selector(ptr)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
virtual unsigned long specificity() const
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return Constants::Specificity_ID;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr);
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Id_Selector)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
///////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Attribute selectors -- e.g., [src*=".jpg"], etc.
|
|
Packit Service |
7770af |
///////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Attribute_Selector : public Simple_Selector {
|
|
Packit Service |
7770af |
ADD_CONSTREF(std::string, matcher)
|
|
Packit Service |
7770af |
// this cannot be changed to obj atm!!!!!!????!!!!!!!
|
|
Packit Service |
7770af |
ADD_PROPERTY(String_Obj, value) // might be interpolated
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Attribute_Selector(ParserState pstate, std::string n, std::string m, String_Obj v)
|
|
Packit Service |
7770af |
: Simple_Selector(pstate, n), matcher_(m), value_(v)
|
|
Packit Service |
7770af |
{ simple_type(ATTR_SEL); }
|
|
Packit Service |
7770af |
Attribute_Selector(const Attribute_Selector* ptr)
|
|
Packit Service |
7770af |
: Simple_Selector(ptr),
|
|
Packit Service |
7770af |
matcher_(ptr->matcher_),
|
|
Packit Service |
7770af |
value_(ptr->value_)
|
|
Packit Service |
7770af |
{ simple_type(ATTR_SEL); }
|
|
Packit Service |
7770af |
virtual size_t hash()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (hash_ == 0) {
|
|
Packit Service |
7770af |
hash_combine(hash_, Simple_Selector::hash());
|
|
Packit Service |
7770af |
hash_combine(hash_, std::hash<std::string>()(matcher()));
|
|
Packit Service |
7770af |
if (value_) hash_combine(hash_, value_->hash());
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
return hash_;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
virtual unsigned long specificity() const
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return Constants::Specificity_Attr;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
virtual bool operator==(const Simple_Selector& rhs) const;
|
|
Packit Service |
7770af |
virtual bool operator==(const Attribute_Selector& rhs) const;
|
|
Packit Service |
7770af |
virtual bool operator<(const Simple_Selector& rhs) const;
|
|
Packit Service |
7770af |
virtual bool operator<(const Attribute_Selector& rhs) const;
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Attribute_Selector)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
//////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Pseudo selectors -- e.g., :first-child, :nth-of-type(...), etc.
|
|
Packit Service |
7770af |
//////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
/* '::' starts a pseudo-element, ':' a pseudo-class */
|
|
Packit Service |
7770af |
/* Except :first-line, :first-letter, :before and :after */
|
|
Packit Service |
7770af |
/* Note that pseudo-elements are restricted to one per selector */
|
|
Packit Service |
7770af |
/* and occur only in the last simple_selector_sequence. */
|
|
Packit Service |
7770af |
inline bool is_pseudo_class_element(const std::string& name)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return name == ":before" ||
|
|
Packit Service |
7770af |
name == ":after" ||
|
|
Packit Service |
7770af |
name == ":first-line" ||
|
|
Packit Service |
7770af |
name == ":first-letter";
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// Pseudo Selector cannot have any namespace?
|
|
Packit Service |
7770af |
class Pseudo_Selector : public Simple_Selector {
|
|
Packit Service |
7770af |
ADD_PROPERTY(String_Obj, expression)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Pseudo_Selector(ParserState pstate, std::string n, String_Obj expr = 0)
|
|
Packit Service |
7770af |
: Simple_Selector(pstate, n), expression_(expr)
|
|
Packit Service |
7770af |
{ simple_type(PSEUDO_SEL); }
|
|
Packit Service |
7770af |
Pseudo_Selector(const Pseudo_Selector* ptr)
|
|
Packit Service |
7770af |
: Simple_Selector(ptr), expression_(ptr->expression_)
|
|
Packit Service |
7770af |
{ simple_type(PSEUDO_SEL); }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// A pseudo-element is made of two colons (::) followed by the name.
|
|
Packit Service |
7770af |
// The `::` notation is introduced by the current document in order to
|
|
Packit Service |
7770af |
// establish a discrimination between pseudo-classes and pseudo-elements.
|
|
Packit Service |
7770af |
// For compatibility with existing style sheets, user agents must also
|
|
Packit Service |
7770af |
// accept the previous one-colon notation for pseudo-elements introduced
|
|
Packit Service |
7770af |
// in CSS levels 1 and 2 (namely, :first-line, :first-letter, :before and
|
|
Packit Service |
7770af |
// :after). This compatibility is not allowed for the new pseudo-elements
|
|
Packit Service |
7770af |
// introduced in this specification.
|
|
Packit Service |
7770af |
virtual bool is_pseudo_element() const
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return (name_[0] == ':' && name_[1] == ':')
|
|
Packit Service |
7770af |
|| is_pseudo_class_element(name_);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
virtual size_t hash()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (hash_ == 0) {
|
|
Packit Service |
7770af |
hash_combine(hash_, Simple_Selector::hash());
|
|
Packit Service |
7770af |
if (expression_) hash_combine(hash_, expression_->hash());
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
return hash_;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
virtual unsigned long specificity() const
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (is_pseudo_element())
|
|
Packit Service |
7770af |
return Constants::Specificity_Element;
|
|
Packit Service |
7770af |
return Constants::Specificity_Pseudo;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
virtual bool operator==(const Simple_Selector& rhs) const;
|
|
Packit Service |
7770af |
virtual bool operator==(const Pseudo_Selector& rhs) const;
|
|
Packit Service |
7770af |
virtual bool operator<(const Simple_Selector& rhs) const;
|
|
Packit Service |
7770af |
virtual bool operator<(const Pseudo_Selector& rhs) const;
|
|
Packit Service |
7770af |
virtual Compound_Selector_Ptr unify_with(Compound_Selector_Ptr);
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Pseudo_Selector)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
/////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Wrapped selector -- pseudo selector that takes a list of selectors as argument(s) e.g., :not(:first-of-type), :-moz-any(ol p.blah, ul, menu, dir)
|
|
Packit Service |
7770af |
/////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Wrapped_Selector : public Simple_Selector {
|
|
Packit Service |
7770af |
ADD_PROPERTY(Selector_List_Obj, selector)
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Wrapped_Selector(ParserState pstate, std::string n, Selector_List_Obj sel)
|
|
Packit Service |
7770af |
: Simple_Selector(pstate, n), selector_(sel)
|
|
Packit Service |
7770af |
{ simple_type(WRAPPED_SEL); }
|
|
Packit Service |
7770af |
Wrapped_Selector(const Wrapped_Selector* ptr)
|
|
Packit Service |
7770af |
: Simple_Selector(ptr), selector_(ptr->selector_)
|
|
Packit Service |
7770af |
{ simple_type(WRAPPED_SEL); }
|
|
Packit Service |
7770af |
virtual bool is_superselector_of(Wrapped_Selector_Obj sub);
|
|
Packit Service |
7770af |
// Selectors inside the negation pseudo-class are counted like any
|
|
Packit Service |
7770af |
// other, but the negation itself does not count as a pseudo-class.
|
|
Packit Service |
7770af |
virtual size_t hash();
|
|
Packit Service |
7770af |
virtual bool has_parent_ref() const;
|
|
Packit Service |
7770af |
virtual bool has_real_parent_ref() const;
|
|
Packit Service |
7770af |
virtual unsigned long specificity() const;
|
|
Packit Service |
7770af |
virtual bool find ( bool (*f)(AST_Node_Obj) );
|
|
Packit Service |
7770af |
virtual bool operator==(const Simple_Selector& rhs) const;
|
|
Packit Service |
7770af |
virtual bool operator==(const Wrapped_Selector& rhs) const;
|
|
Packit Service |
7770af |
virtual bool operator<(const Simple_Selector& rhs) const;
|
|
Packit Service |
7770af |
virtual bool operator<(const Wrapped_Selector& rhs) const;
|
|
Packit Service |
7770af |
virtual void cloneChildren();
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Wrapped_Selector)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
////////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// Simple selector sequences. Maintains flags indicating whether it contains
|
|
Packit Service |
7770af |
// any parent references or placeholders, to simplify expansion.
|
|
Packit Service |
7770af |
////////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Compound_Selector : public Selector, public Vectorized<Simple_Selector_Obj> {
|
|
Packit Service |
7770af |
private:
|
|
Packit Service |
7770af |
ComplexSelectorSet sources_;
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, extended);
|
|
Packit Service |
7770af |
ADD_PROPERTY(bool, has_parent_reference);
|
|
Packit Service |
7770af |
protected:
|
|
Packit Service |
7770af |
void adjust_after_pushing(Simple_Selector_Obj s)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
// if (s->has_reference()) has_reference(true);
|
|
Packit Service |
7770af |
// if (s->has_placeholder()) has_placeholder(true);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Compound_Selector(ParserState pstate, size_t s = 0)
|
|
Packit Service |
7770af |
: Selector(pstate),
|
|
Packit Service |
7770af |
Vectorized<Simple_Selector_Obj>(s),
|
|
Packit Service |
7770af |
extended_(false),
|
|
Packit Service |
7770af |
has_parent_reference_(false)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
Compound_Selector(const Compound_Selector* ptr)
|
|
Packit Service |
7770af |
: Selector(ptr),
|
|
Packit Service |
7770af |
Vectorized<Simple_Selector_Obj>(*ptr),
|
|
Packit Service |
7770af |
extended_(ptr->extended_),
|
|
Packit Service |
7770af |
has_parent_reference_(ptr->has_parent_reference_)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
bool contains_placeholder() {
|
|
Packit Service |
7770af |
for (size_t i = 0, L = length(); i < L; ++i) {
|
|
Packit Service |
7770af |
if ((*this)[i]->has_placeholder()) return true;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
return false;
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
void append(Simple_Selector_Ptr element);
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
bool is_universal() const
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return length() == 1 && (*this)[0]->is_universal();
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
Complex_Selector_Obj to_complex();
|
|
Packit Service |
7770af |
Compound_Selector_Ptr unify_with(Compound_Selector_Ptr rhs);
|
|
Packit Service |
7770af |
// virtual Placeholder_Selector_Ptr find_placeholder();
|
|
Packit Service |
7770af |
virtual bool has_parent_ref() const;
|
|
Packit Service |
7770af |
virtual bool has_real_parent_ref() const;
|
|
Packit Service |
7770af |
Simple_Selector_Ptr base() const {
|
|
Packit Service |
7770af |
if (length() == 0) return 0;
|
|
Packit Service |
7770af |
// ToDo: why is this needed?
|
|
Packit Service |
7770af |
if (Cast<Element_Selector>((*this)[0]))
|
|
Packit Service |
7770af |
return (*this)[0];
|
|
Packit Service |
7770af |
return 0;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
virtual bool is_superselector_of(Compound_Selector_Obj sub, std::string wrapped = "");
|
|
Packit Service |
7770af |
virtual bool is_superselector_of(Complex_Selector_Obj sub, std::string wrapped = "");
|
|
Packit Service |
7770af |
virtual bool is_superselector_of(Selector_List_Obj sub, std::string wrapped = "");
|
|
Packit Service |
7770af |
virtual size_t hash()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (Selector::hash_ == 0) {
|
|
Packit Service |
7770af |
hash_combine(Selector::hash_, std::hash<int>()(SELECTOR));
|
|
Packit Service |
7770af |
if (length()) hash_combine(Selector::hash_, Vectorized::hash());
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
return Selector::hash_;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
virtual unsigned long specificity() const
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
int sum = 0;
|
|
Packit Service |
7770af |
for (size_t i = 0, L = length(); i < L; ++i)
|
|
Packit Service |
7770af |
{ sum += (*this)[i]->specificity(); }
|
|
Packit Service |
7770af |
return sum;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual bool has_placeholder()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (length() == 0) return false;
|
|
Packit Service |
7770af |
if (Simple_Selector_Obj ss = elements().front()) {
|
|
Packit Service |
7770af |
if (ss->has_placeholder()) return true;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
return false;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
bool is_empty_reference()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return length() == 1 &&
|
|
Packit Service |
7770af |
Cast<Parent_Selector>((*this)[0]);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual bool find ( bool (*f)(AST_Node_Obj) );
|
|
Packit Service |
7770af |
virtual bool operator<(const Selector& rhs) const;
|
|
Packit Service |
7770af |
virtual bool operator==(const Selector& rhs) const;
|
|
Packit Service |
7770af |
virtual bool operator<(const Compound_Selector& rhs) const;
|
|
Packit Service |
7770af |
virtual bool operator==(const Compound_Selector& rhs) const;
|
|
Packit Service |
7770af |
inline bool operator!=(const Compound_Selector& rhs) const { return !(*this == rhs); }
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
ComplexSelectorSet& sources() { return sources_; }
|
|
Packit Service |
7770af |
void clearSources() { sources_.clear(); }
|
|
Packit Service |
7770af |
void mergeSources(ComplexSelectorSet& sources);
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
Compound_Selector_Ptr minus(Compound_Selector_Ptr rhs);
|
|
Packit Service |
7770af |
virtual void cloneChildren();
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Compound_Selector)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
////////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
// General selectors -- i.e., simple sequences combined with one of the four
|
|
Packit Service |
7770af |
// CSS selector combinators (">", "+", "~", and whitespace). Essentially a
|
|
Packit Service |
7770af |
// linked list.
|
|
Packit Service |
7770af |
////////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
7770af |
class Complex_Selector : public Selector {
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
enum Combinator { ANCESTOR_OF, PARENT_OF, PRECEDES, ADJACENT_TO, REFERENCE };
|
|
Packit Service |
7770af |
private:
|
|
Packit Service |
7770af |
HASH_CONSTREF(Combinator, combinator)
|
|
Packit Service |
7770af |
HASH_PROPERTY(Compound_Selector_Obj, head)
|
|
Packit Service |
7770af |
HASH_PROPERTY(Complex_Selector_Obj, tail)
|
|
Packit Service |
7770af |
HASH_PROPERTY(String_Obj, reference);
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
bool contains_placeholder() {
|
|
Packit Service |
7770af |
if (head() && head()->contains_placeholder()) return true;
|
|
Packit Service |
7770af |
if (tail() && tail()->contains_placeholder()) return true;
|
|
Packit Service |
7770af |
return false;
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
Complex_Selector(ParserState pstate,
|
|
Packit Service |
7770af |
Combinator c = ANCESTOR_OF,
|
|
Packit Service |
7770af |
Compound_Selector_Obj h = 0,
|
|
Packit Service |
7770af |
Complex_Selector_Obj t = 0,
|
|
Packit Service |
7770af |
String_Obj r = 0)
|
|
Packit Service |
7770af |
: Selector(pstate),
|
|
Packit Service |
7770af |
combinator_(c),
|
|
Packit Service |
7770af |
head_(h), tail_(t),
|
|
Packit Service |
7770af |
reference_(r)
|
|
Packit Service |
7770af |
{}
|
|
Packit Service |
7770af |
Complex_Selector(const Complex_Selector* ptr)
|
|
Packit Service |
7770af |
: Selector(ptr),
|
|
Packit Service |
7770af |
combinator_(ptr->combinator_),
|
|
Packit Service |
7770af |
head_(ptr->head_), tail_(ptr->tail_),
|
|
Packit Service |
7770af |
reference_(ptr->reference_)
|
|
Packit Service |
7770af |
{};
|
|
Packit Service |
7770af |
virtual bool has_parent_ref() const;
|
|
Packit Service |
7770af |
virtual bool has_real_parent_ref() const;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
Complex_Selector_Obj skip_empty_reference()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if ((!head_ || !head_->length() || head_->is_empty_reference()) &&
|
|
Packit Service |
7770af |
combinator() == Combinator::ANCESTOR_OF)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (!tail_) return 0;
|
|
Packit Service |
7770af |
tail_->has_line_feed_ = this->has_line_feed_;
|
|
Packit Service |
7770af |
// tail_->has_line_break_ = this->has_line_break_;
|
|
Packit Service |
7770af |
return tail_->skip_empty_reference();
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
return this;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// can still have a tail
|
|
Packit Service |
7770af |
bool is_empty_ancestor() const
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
return (!head() || head()->length() == 0) &&
|
|
Packit Service |
7770af |
combinator() == Combinator::ANCESTOR_OF;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
Selector_List_Ptr tails(Selector_List_Ptr tails);
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// front returns the first real tail
|
|
Packit Service |
7770af |
// skips over parent and empty ones
|
|
Packit Service |
7770af |
Complex_Selector_Obj first();
|
|
Packit Service |
7770af |
// last returns the last real tail
|
|
Packit Service |
7770af |
Complex_Selector_Obj last();
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// some shortcuts that should be removed
|
|
Packit Service |
7770af |
Complex_Selector_Obj innermost() { return last(); };
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
size_t length() const;
|
|
Packit Service |
7770af |
Selector_List_Ptr resolve_parent_refs(std::vector<Selector_List_Obj>& pstack, bool implicit_parent = true);
|
|
Packit Service |
7770af |
virtual bool is_superselector_of(Compound_Selector_Obj sub, std::string wrapping = "");
|
|
Packit Service |
7770af |
virtual bool is_superselector_of(Complex_Selector_Obj sub, std::string wrapping = "");
|
|
Packit Service |
7770af |
virtual bool is_superselector_of(Selector_List_Obj sub, std::string wrapping = "");
|
|
Packit Service |
7770af |
Selector_List_Ptr unify_with(Complex_Selector_Ptr rhs);
|
|
Packit Service |
7770af |
Combinator clear_innermost();
|
|
Packit Service |
7770af |
void append(Complex_Selector_Obj);
|
|
Packit Service |
7770af |
void set_innermost(Complex_Selector_Obj, Combinator);
|
|
Packit Service |
7770af |
virtual size_t hash()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (hash_ == 0) {
|
|
Packit Service |
7770af |
hash_combine(hash_, std::hash<int>()(SELECTOR));
|
|
Packit Service |
7770af |
hash_combine(hash_, std::hash<int>()(combinator_));
|
|
Packit Service |
7770af |
if (head_) hash_combine(hash_, head_->hash());
|
|
Packit Service |
7770af |
if (tail_) hash_combine(hash_, tail_->hash());
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
return hash_;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
virtual unsigned long specificity() const
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
int sum = 0;
|
|
Packit Service |
7770af |
if (head()) sum += head()->specificity();
|
|
Packit Service |
7770af |
if (tail()) sum += tail()->specificity();
|
|
Packit Service |
7770af |
return sum;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
virtual void set_media_block(Media_Block_Ptr mb) {
|
|
Packit Service |
7770af |
media_block(mb);
|
|
Packit Service |
7770af |
if (tail_) tail_->set_media_block(mb);
|
|
Packit Service |
7770af |
if (head_) head_->set_media_block(mb);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
virtual bool has_placeholder() {
|
|
Packit Service |
7770af |
if (head_ && head_->has_placeholder()) return true;
|
|
Packit Service |
7770af |
if (tail_ && tail_->has_placeholder()) return true;
|
|
Packit Service |
7770af |
return false;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
virtual bool find ( bool (*f)(AST_Node_Obj) );
|
|
Packit Service |
7770af |
virtual bool operator<(const Selector& rhs) const;
|
|
Packit Service |
7770af |
virtual bool operator==(const Selector& rhs) const;
|
|
Packit Service |
7770af |
virtual bool operator<(const Complex_Selector& rhs) const;
|
|
Packit Service |
7770af |
virtual bool operator==(const Complex_Selector& rhs) const;
|
|
Packit Service |
7770af |
inline bool operator!=(const Complex_Selector& rhs) const { return !(*this == rhs); }
|
|
Packit Service |
7770af |
const ComplexSelectorSet sources()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
//s = Set.new
|
|
Packit Service |
7770af |
//seq.map {|sseq_or_op| s.merge sseq_or_op.sources if sseq_or_op.is_a?(SimpleSequence)}
|
|
Packit Service |
7770af |
//s
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
ComplexSelectorSet srcs;
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
Compound_Selector_Obj pHead = head();
|
|
Packit Service |
7770af |
Complex_Selector_Obj pTail = tail();
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
if (pHead) {
|
|
Packit Service |
7770af |
const ComplexSelectorSet& headSources = pHead->sources();
|
|
Packit Service |
7770af |
srcs.insert(headSources.begin(), headSources.end());
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
if (pTail) {
|
|
Packit Service |
7770af |
const ComplexSelectorSet& tailSources = pTail->sources();
|
|
Packit Service |
7770af |
srcs.insert(tailSources.begin(), tailSources.end());
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
return srcs;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
void addSources(ComplexSelectorSet& sources) {
|
|
Packit Service |
7770af |
// members.map! {|m| m.is_a?(SimpleSequence) ? m.with_more_sources(sources) : m}
|
|
Packit Service |
7770af |
Complex_Selector_Ptr pIter = this;
|
|
Packit Service |
7770af |
while (pIter) {
|
|
Packit Service |
7770af |
Compound_Selector_Ptr pHead = pIter->head();
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
if (pHead) {
|
|
Packit Service |
7770af |
pHead->mergeSources(sources);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
pIter = pIter->tail();
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
void clearSources() {
|
|
Packit Service |
7770af |
Complex_Selector_Ptr pIter = this;
|
|
Packit Service |
7770af |
while (pIter) {
|
|
Packit Service |
7770af |
Compound_Selector_Ptr pHead = pIter->head();
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
if (pHead) {
|
|
Packit Service |
7770af |
pHead->clearSources();
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
pIter = pIter->tail();
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
virtual void cloneChildren();
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Complex_Selector)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
///////////////////////////////////
|
|
Packit Service |
7770af |
// Comma-separated selector groups.
|
|
Packit Service |
7770af |
///////////////////////////////////
|
|
Packit Service |
7770af |
class Selector_List : public Selector, public Vectorized<Complex_Selector_Obj> {
|
|
Packit Service |
7770af |
ADD_PROPERTY(Selector_Schema_Obj, schema)
|
|
Packit Service |
7770af |
ADD_CONSTREF(std::vector<std::string>, wspace)
|
|
Packit Service |
7770af |
protected:
|
|
Packit Service |
7770af |
void adjust_after_pushing(Complex_Selector_Obj c);
|
|
Packit Service |
7770af |
public:
|
|
Packit Service |
7770af |
Selector_List(ParserState pstate, size_t s = 0)
|
|
Packit Service |
7770af |
: Selector(pstate),
|
|
Packit Service |
7770af |
Vectorized<Complex_Selector_Obj>(s),
|
|
Packit Service |
7770af |
schema_(NULL),
|
|
Packit Service |
7770af |
wspace_(0)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
Selector_List(const Selector_List* ptr)
|
|
Packit Service |
7770af |
: Selector(ptr),
|
|
Packit Service |
7770af |
Vectorized<Complex_Selector_Obj>(*ptr),
|
|
Packit Service |
7770af |
schema_(ptr->schema_),
|
|
Packit Service |
7770af |
wspace_(ptr->wspace_)
|
|
Packit Service |
7770af |
{ }
|
|
Packit Service |
7770af |
std::string type() const { return "list"; }
|
|
Packit Service |
7770af |
// remove parent selector references
|
|
Packit Service |
7770af |
// basically unwraps parsed selectors
|
|
Packit Service |
7770af |
virtual bool has_parent_ref() const;
|
|
Packit Service |
7770af |
virtual bool has_real_parent_ref() const;
|
|
Packit Service |
7770af |
void remove_parent_selectors();
|
|
Packit Service |
7770af |
Selector_List_Ptr resolve_parent_refs(std::vector<Selector_List_Obj>& pstack, bool implicit_parent = true);
|
|
Packit Service |
7770af |
virtual bool is_superselector_of(Compound_Selector_Obj sub, std::string wrapping = "");
|
|
Packit Service |
7770af |
virtual bool is_superselector_of(Complex_Selector_Obj sub, std::string wrapping = "");
|
|
Packit Service |
7770af |
virtual bool is_superselector_of(Selector_List_Obj sub, std::string wrapping = "");
|
|
Packit Service |
7770af |
Selector_List_Ptr unify_with(Selector_List_Ptr);
|
|
Packit Service |
7770af |
void populate_extends(Selector_List_Obj, Subset_Map&);
|
|
Packit Service |
7770af |
Selector_List_Obj eval(Eval& eval);
|
|
Packit Service |
7770af |
virtual size_t hash()
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
if (Selector::hash_ == 0) {
|
|
Packit Service |
7770af |
hash_combine(Selector::hash_, std::hash<int>()(SELECTOR));
|
|
Packit Service |
7770af |
hash_combine(Selector::hash_, Vectorized::hash());
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
return Selector::hash_;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
virtual unsigned long specificity() const
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
unsigned long sum = 0;
|
|
Packit Service |
7770af |
unsigned long specificity;
|
|
Packit Service |
7770af |
for (size_t i = 0, L = length(); i < L; ++i)
|
|
Packit Service |
7770af |
{
|
|
Packit Service |
7770af |
specificity = (*this)[i]->specificity();
|
|
Packit Service |
7770af |
if (sum < specificity) sum = specificity;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
return sum;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
virtual void set_media_block(Media_Block_Ptr mb) {
|
|
Packit Service |
7770af |
media_block(mb);
|
|
Packit Service |
7770af |
for (Complex_Selector_Obj cs : elements()) {
|
|
Packit Service |
7770af |
cs->set_media_block(mb);
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
virtual bool has_placeholder() {
|
|
Packit Service |
7770af |
for (Complex_Selector_Obj cs : elements()) {
|
|
Packit Service |
7770af |
if (cs->has_placeholder()) return true;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
return false;
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
virtual bool find ( bool (*f)(AST_Node_Obj) );
|
|
Packit Service |
7770af |
virtual bool operator<(const Selector& rhs) const;
|
|
Packit Service |
7770af |
virtual bool operator==(const Selector& rhs) const;
|
|
Packit Service |
7770af |
virtual bool operator<(const Selector_List& rhs) const;
|
|
Packit Service |
7770af |
virtual bool operator==(const Selector_List& rhs) const;
|
|
Packit Service |
7770af |
// Selector Lists can be compared to comma lists
|
|
Packit Service |
7770af |
virtual bool operator==(const Expression& rhs) const;
|
|
Packit Service |
7770af |
virtual void cloneChildren();
|
|
Packit Service |
7770af |
ATTACH_AST_OPERATIONS(Selector_List)
|
|
Packit Service |
7770af |
ATTACH_OPERATIONS()
|
|
Packit Service |
7770af |
};
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
// compare function for sorting and probably other other uses
|
|
Packit Service |
7770af |
struct cmp_complex_selector { inline bool operator() (const Complex_Selector_Obj l, const Complex_Selector_Obj r) { return (*l < *r); } };
|
|
Packit Service |
7770af |
struct cmp_compound_selector { inline bool operator() (const Compound_Selector_Obj l, const Compound_Selector_Obj r) { return (*l < *r); } };
|
|
Packit Service |
7770af |
struct cmp_simple_selector { inline bool operator() (const Simple_Selector_Obj l, const Simple_Selector_Obj r) { return (*l < *r); } };
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
}
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
#ifdef __clang__
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
#pragma clang diagnostic pop
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
#endif
|
|
Packit Service |
7770af |
|
|
Packit Service |
7770af |
#endif
|