sassc 2.0.1 → 2.1.0.pre1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.gitmodules +1 -1
- data/.travis.yml +7 -3
- data/CHANGELOG.md +3 -0
- data/CODE_OF_CONDUCT.md +1 -1
- data/README.md +1 -1
- data/Rakefile +23 -8
- data/ext/extconf.rb +39 -0
- data/ext/libsass/.gitignore +1 -0
- data/ext/libsass/GNUmakefile.am +23 -39
- data/ext/libsass/Makefile +56 -91
- data/ext/libsass/Makefile.conf +16 -2
- data/ext/libsass/configure.ac +8 -12
- data/ext/libsass/include/sass/base.h +1 -0
- data/ext/libsass/include/sass/context.h +1 -1
- data/ext/libsass/src/GNUmakefile.am +1 -5
- data/ext/libsass/src/ast.cpp +747 -2010
- data/ext/libsass/src/ast.hpp +239 -2383
- data/ext/libsass/src/{to_c.cpp → ast2c.cpp} +22 -16
- data/ext/libsass/src/ast2c.hpp +39 -0
- data/ext/libsass/src/ast_def_macros.hpp +62 -10
- data/ext/libsass/src/ast_fwd_decl.cpp +1 -0
- data/ext/libsass/src/ast_fwd_decl.hpp +43 -165
- data/ext/libsass/src/ast_sel_cmp.cpp +909 -0
- data/ext/libsass/src/ast_sel_unify.cpp +280 -0
- data/ext/libsass/src/ast_selectors.cpp +1475 -0
- data/ext/libsass/src/ast_selectors.hpp +568 -0
- data/ext/libsass/src/ast_supports.cpp +130 -0
- data/ext/libsass/src/ast_supports.hpp +121 -0
- data/ext/libsass/src/ast_values.cpp +967 -0
- data/ext/libsass/src/ast_values.hpp +489 -0
- data/ext/libsass/src/backtrace.cpp +4 -0
- data/ext/libsass/src/base64vlq.cpp +3 -0
- data/ext/libsass/src/bind.cpp +18 -17
- data/ext/libsass/src/bind.hpp +3 -1
- data/ext/libsass/src/c2ast.cpp +64 -0
- data/ext/libsass/src/c2ast.hpp +14 -0
- data/ext/libsass/src/cencode.c +2 -2
- data/ext/libsass/src/check_nesting.cpp +52 -56
- data/ext/libsass/src/check_nesting.hpp +35 -34
- data/ext/libsass/src/color_maps.cpp +156 -153
- data/ext/libsass/src/color_maps.hpp +152 -152
- data/ext/libsass/src/constants.cpp +15 -0
- data/ext/libsass/src/constants.hpp +13 -0
- data/ext/libsass/src/context.cpp +24 -14
- data/ext/libsass/src/context.hpp +6 -6
- data/ext/libsass/src/cssize.cpp +69 -71
- data/ext/libsass/src/cssize.hpp +50 -50
- data/ext/libsass/src/debugger.hpp +117 -110
- data/ext/libsass/src/emitter.cpp +13 -12
- data/ext/libsass/src/emitter.hpp +13 -9
- data/ext/libsass/src/environment.cpp +15 -1
- data/ext/libsass/src/environment.hpp +6 -0
- data/ext/libsass/src/error_handling.cpp +36 -59
- data/ext/libsass/src/error_handling.hpp +29 -16
- data/ext/libsass/src/eval.cpp +302 -323
- data/ext/libsass/src/eval.hpp +64 -55
- data/ext/libsass/src/expand.cpp +94 -88
- data/ext/libsass/src/expand.hpp +33 -37
- data/ext/libsass/src/extend.cpp +38 -36
- data/ext/libsass/src/extend.hpp +15 -15
- data/ext/libsass/src/file.cpp +34 -2
- data/ext/libsass/src/fn_colors.cpp +594 -0
- data/ext/libsass/src/fn_colors.hpp +85 -0
- data/ext/libsass/src/fn_lists.cpp +284 -0
- data/ext/libsass/src/fn_lists.hpp +34 -0
- data/ext/libsass/src/fn_maps.cpp +94 -0
- data/ext/libsass/src/fn_maps.hpp +30 -0
- data/ext/libsass/src/fn_miscs.cpp +256 -0
- data/ext/libsass/src/fn_miscs.hpp +40 -0
- data/ext/libsass/src/fn_numbers.cpp +220 -0
- data/ext/libsass/src/fn_numbers.hpp +45 -0
- data/ext/libsass/src/fn_selectors.cpp +235 -0
- data/ext/libsass/src/fn_selectors.hpp +35 -0
- data/ext/libsass/src/fn_strings.cpp +254 -0
- data/ext/libsass/src/fn_strings.hpp +34 -0
- data/ext/libsass/src/fn_utils.cpp +156 -0
- data/ext/libsass/src/fn_utils.hpp +56 -0
- data/ext/libsass/src/inspect.cpp +101 -152
- data/ext/libsass/src/inspect.hpp +69 -73
- data/ext/libsass/src/json.cpp +2 -2
- data/ext/libsass/src/lexer.cpp +6 -3
- data/ext/libsass/src/listize.cpp +9 -11
- data/ext/libsass/src/listize.hpp +11 -7
- data/ext/libsass/src/memory/SharedPtr.cpp +2 -83
- data/ext/libsass/src/memory/SharedPtr.hpp +127 -143
- data/ext/libsass/src/node.cpp +13 -10
- data/ext/libsass/src/node.hpp +3 -3
- data/ext/libsass/src/operation.hpp +184 -144
- data/ext/libsass/src/operators.cpp +43 -17
- data/ext/libsass/src/operators.hpp +5 -5
- data/ext/libsass/src/output.cpp +21 -18
- data/ext/libsass/src/output.hpp +14 -21
- data/ext/libsass/src/parser.cpp +215 -183
- data/ext/libsass/src/parser.hpp +28 -24
- data/ext/libsass/src/plugins.cpp +5 -1
- data/ext/libsass/src/position.cpp +3 -0
- data/ext/libsass/src/prelexer.cpp +9 -3
- data/ext/libsass/src/prelexer.hpp +9 -9
- data/ext/libsass/src/remove_placeholders.cpp +14 -11
- data/ext/libsass/src/remove_placeholders.hpp +8 -9
- data/ext/libsass/src/sass.cpp +9 -3
- data/ext/libsass/src/sass.hpp +12 -9
- data/ext/libsass/src/sass2scss.cpp +45 -14
- data/ext/libsass/src/sass_context.cpp +18 -15
- data/ext/libsass/src/sass_functions.cpp +6 -3
- data/ext/libsass/src/sass_functions.hpp +1 -1
- data/ext/libsass/src/sass_util.cpp +3 -0
- data/ext/libsass/src/sass_values.cpp +21 -13
- data/ext/libsass/src/source_map.cpp +5 -2
- data/ext/libsass/src/source_map.hpp +2 -2
- data/ext/libsass/src/subset_map.cpp +4 -1
- data/ext/libsass/src/to_value.cpp +23 -21
- data/ext/libsass/src/to_value.hpp +18 -22
- data/ext/libsass/src/units.cpp +4 -0
- data/ext/libsass/src/units.hpp +1 -0
- data/ext/libsass/src/utf8/checked.h +12 -10
- data/ext/libsass/src/utf8/core.h +3 -0
- data/ext/libsass/src/utf8_string.cpp +3 -0
- data/ext/libsass/src/util.cpp +67 -75
- data/ext/libsass/src/util.hpp +64 -19
- data/ext/libsass/src/util_string.cpp +75 -0
- data/ext/libsass/src/util_string.hpp +19 -0
- data/ext/libsass/src/values.cpp +22 -13
- data/ext/libsass/src/values.hpp +2 -2
- data/ext/libsass/win/libsass.targets +30 -4
- data/ext/libsass/win/libsass.vcxproj.filters +82 -4
- data/lib/sassc.rb +24 -0
- data/lib/sassc/engine.rb +2 -2
- data/lib/sassc/native.rb +8 -1
- data/lib/sassc/version.rb +1 -1
- data/sassc.gemspec +19 -11
- data/test/engine_test.rb +26 -1
- data/test/native_test.rb +1 -1
- metadata +66 -72
- data/ext/Rakefile +0 -3
- data/ext/libsass/.github/CONTRIBUTING.md +0 -65
- data/ext/libsass/.github/ISSUE_TEMPLATE.md +0 -54
- data/ext/libsass/.travis.yml +0 -64
- data/ext/libsass/Readme.md +0 -104
- data/ext/libsass/SECURITY.md +0 -10
- data/ext/libsass/appveyor.yml +0 -91
- data/ext/libsass/docs/README.md +0 -20
- data/ext/libsass/docs/api-context-example.md +0 -45
- data/ext/libsass/docs/api-context-internal.md +0 -163
- data/ext/libsass/docs/api-context.md +0 -295
- data/ext/libsass/docs/api-doc.md +0 -215
- data/ext/libsass/docs/api-function-example.md +0 -67
- data/ext/libsass/docs/api-function-internal.md +0 -8
- data/ext/libsass/docs/api-function.md +0 -74
- data/ext/libsass/docs/api-importer-example.md +0 -112
- data/ext/libsass/docs/api-importer-internal.md +0 -20
- data/ext/libsass/docs/api-importer.md +0 -86
- data/ext/libsass/docs/api-value-example.md +0 -55
- data/ext/libsass/docs/api-value-internal.md +0 -76
- data/ext/libsass/docs/api-value.md +0 -154
- data/ext/libsass/docs/build-on-darwin.md +0 -27
- data/ext/libsass/docs/build-on-gentoo.md +0 -55
- data/ext/libsass/docs/build-on-windows.md +0 -139
- data/ext/libsass/docs/build-shared-library.md +0 -35
- data/ext/libsass/docs/build-with-autotools.md +0 -78
- data/ext/libsass/docs/build-with-makefiles.md +0 -68
- data/ext/libsass/docs/build-with-mingw.md +0 -107
- data/ext/libsass/docs/build-with-visual-studio.md +0 -90
- data/ext/libsass/docs/build.md +0 -97
- data/ext/libsass/docs/compatibility-plan.md +0 -48
- data/ext/libsass/docs/contributing.md +0 -17
- data/ext/libsass/docs/custom-functions-internal.md +0 -122
- data/ext/libsass/docs/dev-ast-memory.md +0 -223
- data/ext/libsass/docs/implementations.md +0 -56
- data/ext/libsass/docs/plugins.md +0 -47
- data/ext/libsass/docs/setup-environment.md +0 -68
- data/ext/libsass/docs/source-map-internals.md +0 -51
- data/ext/libsass/docs/trace.md +0 -26
- data/ext/libsass/docs/triage.md +0 -17
- data/ext/libsass/docs/unicode.md +0 -39
- data/ext/libsass/extconf.rb +0 -6
- data/ext/libsass/script/bootstrap +0 -13
- data/ext/libsass/script/branding +0 -10
- data/ext/libsass/script/ci-build-libsass +0 -134
- data/ext/libsass/script/ci-build-plugin +0 -62
- data/ext/libsass/script/ci-install-compiler +0 -6
- data/ext/libsass/script/ci-install-deps +0 -20
- data/ext/libsass/script/ci-report-coverage +0 -42
- data/ext/libsass/script/spec +0 -5
- data/ext/libsass/script/tap-driver +0 -652
- data/ext/libsass/script/tap-runner +0 -1
- data/ext/libsass/script/test-leaks.pl +0 -103
- data/ext/libsass/src/functions.cpp +0 -2234
- data/ext/libsass/src/functions.hpp +0 -198
- data/ext/libsass/src/to_c.hpp +0 -39
- data/ext/libsass/test/test_node.cpp +0 -94
- data/ext/libsass/test/test_paths.cpp +0 -28
- data/ext/libsass/test/test_selector_difference.cpp +0 -25
- data/ext/libsass/test/test_specificity.cpp +0 -25
- data/ext/libsass/test/test_subset_map.cpp +0 -472
- data/ext/libsass/test/test_superselector.cpp +0 -69
- data/ext/libsass/test/test_unification.cpp +0 -31
- data/lib/tasks/libsass.rb +0 -33
@@ -0,0 +1,130 @@
|
|
1
|
+
// sass.hpp must go before all system headers to get the
|
2
|
+
// __EXTENSIONS__ fix on Solaris.
|
3
|
+
#include "sass.hpp"
|
4
|
+
|
5
|
+
#include "ast.hpp"
|
6
|
+
#include "context.hpp"
|
7
|
+
#include "node.hpp"
|
8
|
+
#include "eval.hpp"
|
9
|
+
#include "extend.hpp"
|
10
|
+
#include "emitter.hpp"
|
11
|
+
#include "color_maps.hpp"
|
12
|
+
#include "ast_fwd_decl.hpp"
|
13
|
+
#include <set>
|
14
|
+
#include <iomanip>
|
15
|
+
#include <iostream>
|
16
|
+
#include <algorithm>
|
17
|
+
#include <functional>
|
18
|
+
#include <cctype>
|
19
|
+
#include <locale>
|
20
|
+
|
21
|
+
#include "ast_values.hpp"
|
22
|
+
|
23
|
+
namespace Sass {
|
24
|
+
|
25
|
+
/////////////////////////////////////////////////////////////////////////
|
26
|
+
/////////////////////////////////////////////////////////////////////////
|
27
|
+
|
28
|
+
Supports_Block::Supports_Block(ParserState pstate, Supports_Condition_Obj condition, Block_Obj block)
|
29
|
+
: Has_Block(pstate, block), condition_(condition)
|
30
|
+
{ statement_type(SUPPORTS); }
|
31
|
+
Supports_Block::Supports_Block(const Supports_Block* ptr)
|
32
|
+
: Has_Block(ptr), condition_(ptr->condition_)
|
33
|
+
{ statement_type(SUPPORTS); }
|
34
|
+
bool Supports_Block::bubbles() { return true; }
|
35
|
+
|
36
|
+
/////////////////////////////////////////////////////////////////////////
|
37
|
+
/////////////////////////////////////////////////////////////////////////
|
38
|
+
|
39
|
+
Supports_Condition::Supports_Condition(ParserState pstate)
|
40
|
+
: Expression(pstate)
|
41
|
+
{ }
|
42
|
+
|
43
|
+
Supports_Condition::Supports_Condition(const Supports_Condition* ptr)
|
44
|
+
: Expression(ptr)
|
45
|
+
{ }
|
46
|
+
|
47
|
+
/////////////////////////////////////////////////////////////////////////
|
48
|
+
/////////////////////////////////////////////////////////////////////////
|
49
|
+
|
50
|
+
Supports_Operator::Supports_Operator(ParserState pstate, Supports_Condition_Obj l, Supports_Condition_Obj r, Operand o)
|
51
|
+
: Supports_Condition(pstate), left_(l), right_(r), operand_(o)
|
52
|
+
{ }
|
53
|
+
Supports_Operator::Supports_Operator(const Supports_Operator* ptr)
|
54
|
+
: Supports_Condition(ptr),
|
55
|
+
left_(ptr->left_),
|
56
|
+
right_(ptr->right_),
|
57
|
+
operand_(ptr->operand_)
|
58
|
+
{ }
|
59
|
+
|
60
|
+
bool Supports_Operator::needs_parens(Supports_Condition_Obj cond) const
|
61
|
+
{
|
62
|
+
if (Supports_Operator_Obj op = Cast<Supports_Operator>(cond)) {
|
63
|
+
return op->operand() != operand();
|
64
|
+
}
|
65
|
+
return Cast<Supports_Negation>(cond) != NULL;
|
66
|
+
}
|
67
|
+
|
68
|
+
/////////////////////////////////////////////////////////////////////////
|
69
|
+
/////////////////////////////////////////////////////////////////////////
|
70
|
+
|
71
|
+
Supports_Negation::Supports_Negation(ParserState pstate, Supports_Condition_Obj c)
|
72
|
+
: Supports_Condition(pstate), condition_(c)
|
73
|
+
{ }
|
74
|
+
Supports_Negation::Supports_Negation(const Supports_Negation* ptr)
|
75
|
+
: Supports_Condition(ptr), condition_(ptr->condition_)
|
76
|
+
{ }
|
77
|
+
|
78
|
+
bool Supports_Negation::needs_parens(Supports_Condition_Obj cond) const
|
79
|
+
{
|
80
|
+
return Cast<Supports_Negation>(cond) ||
|
81
|
+
Cast<Supports_Operator>(cond);
|
82
|
+
}
|
83
|
+
|
84
|
+
/////////////////////////////////////////////////////////////////////////
|
85
|
+
/////////////////////////////////////////////////////////////////////////
|
86
|
+
|
87
|
+
Supports_Declaration::Supports_Declaration(ParserState pstate, Expression_Obj f, Expression_Obj v)
|
88
|
+
: Supports_Condition(pstate), feature_(f), value_(v)
|
89
|
+
{ }
|
90
|
+
Supports_Declaration::Supports_Declaration(const Supports_Declaration* ptr)
|
91
|
+
: Supports_Condition(ptr),
|
92
|
+
feature_(ptr->feature_),
|
93
|
+
value_(ptr->value_)
|
94
|
+
{ }
|
95
|
+
|
96
|
+
bool Supports_Declaration::needs_parens(Supports_Condition_Obj cond) const
|
97
|
+
{
|
98
|
+
return false;
|
99
|
+
}
|
100
|
+
|
101
|
+
/////////////////////////////////////////////////////////////////////////
|
102
|
+
/////////////////////////////////////////////////////////////////////////
|
103
|
+
|
104
|
+
Supports_Interpolation::Supports_Interpolation(ParserState pstate, Expression_Obj v)
|
105
|
+
: Supports_Condition(pstate), value_(v)
|
106
|
+
{ }
|
107
|
+
Supports_Interpolation::Supports_Interpolation(const Supports_Interpolation* ptr)
|
108
|
+
: Supports_Condition(ptr),
|
109
|
+
value_(ptr->value_)
|
110
|
+
{ }
|
111
|
+
|
112
|
+
bool Supports_Interpolation::needs_parens(Supports_Condition_Obj cond) const
|
113
|
+
{
|
114
|
+
return false;
|
115
|
+
}
|
116
|
+
|
117
|
+
/////////////////////////////////////////////////////////////////////////
|
118
|
+
/////////////////////////////////////////////////////////////////////////
|
119
|
+
|
120
|
+
IMPLEMENT_AST_OPERATORS(Supports_Block);
|
121
|
+
IMPLEMENT_AST_OPERATORS(Supports_Condition);
|
122
|
+
IMPLEMENT_AST_OPERATORS(Supports_Operator);
|
123
|
+
IMPLEMENT_AST_OPERATORS(Supports_Negation);
|
124
|
+
IMPLEMENT_AST_OPERATORS(Supports_Declaration);
|
125
|
+
IMPLEMENT_AST_OPERATORS(Supports_Interpolation);
|
126
|
+
|
127
|
+
/////////////////////////////////////////////////////////////////////////
|
128
|
+
/////////////////////////////////////////////////////////////////////////
|
129
|
+
|
130
|
+
}
|
@@ -0,0 +1,121 @@
|
|
1
|
+
#ifndef SASS_AST_SUPPORTS_H
|
2
|
+
#define SASS_AST_SUPPORTS_H
|
3
|
+
|
4
|
+
// sass.hpp must go before all system headers to get the
|
5
|
+
// __EXTENSIONS__ fix on Solaris.
|
6
|
+
#include "sass.hpp"
|
7
|
+
|
8
|
+
#include <set>
|
9
|
+
#include <deque>
|
10
|
+
#include <vector>
|
11
|
+
#include <string>
|
12
|
+
#include <sstream>
|
13
|
+
#include <iostream>
|
14
|
+
#include <typeinfo>
|
15
|
+
#include <algorithm>
|
16
|
+
#include "sass/base.h"
|
17
|
+
#include "ast_fwd_decl.hpp"
|
18
|
+
|
19
|
+
#include "util.hpp"
|
20
|
+
#include "units.hpp"
|
21
|
+
#include "context.hpp"
|
22
|
+
#include "position.hpp"
|
23
|
+
#include "constants.hpp"
|
24
|
+
#include "operation.hpp"
|
25
|
+
#include "position.hpp"
|
26
|
+
#include "inspect.hpp"
|
27
|
+
#include "source_map.hpp"
|
28
|
+
#include "environment.hpp"
|
29
|
+
#include "error_handling.hpp"
|
30
|
+
#include "ast_def_macros.hpp"
|
31
|
+
#include "ast_fwd_decl.hpp"
|
32
|
+
#include "source_map.hpp"
|
33
|
+
#include "fn_utils.hpp"
|
34
|
+
|
35
|
+
#include "sass.h"
|
36
|
+
|
37
|
+
namespace Sass {
|
38
|
+
|
39
|
+
////////////////////
|
40
|
+
// `@supports` rule.
|
41
|
+
////////////////////
|
42
|
+
class Supports_Block : public Has_Block {
|
43
|
+
ADD_PROPERTY(Supports_Condition_Obj, condition)
|
44
|
+
public:
|
45
|
+
Supports_Block(ParserState pstate, Supports_Condition_Obj condition, Block_Obj block = {});
|
46
|
+
bool bubbles() override;
|
47
|
+
ATTACH_AST_OPERATIONS(Supports_Block)
|
48
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
49
|
+
};
|
50
|
+
|
51
|
+
//////////////////////////////////////////////////////
|
52
|
+
// The abstract superclass of all Supports conditions.
|
53
|
+
//////////////////////////////////////////////////////
|
54
|
+
class Supports_Condition : public Expression {
|
55
|
+
public:
|
56
|
+
Supports_Condition(ParserState pstate);
|
57
|
+
virtual bool needs_parens(Supports_Condition_Obj cond) const { return false; }
|
58
|
+
ATTACH_AST_OPERATIONS(Supports_Condition)
|
59
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
60
|
+
};
|
61
|
+
|
62
|
+
////////////////////////////////////////////////////////////
|
63
|
+
// An operator condition (e.g. `CONDITION1 and CONDITION2`).
|
64
|
+
////////////////////////////////////////////////////////////
|
65
|
+
class Supports_Operator : public Supports_Condition {
|
66
|
+
public:
|
67
|
+
enum Operand { AND, OR };
|
68
|
+
private:
|
69
|
+
ADD_PROPERTY(Supports_Condition_Obj, left);
|
70
|
+
ADD_PROPERTY(Supports_Condition_Obj, right);
|
71
|
+
ADD_PROPERTY(Operand, operand);
|
72
|
+
public:
|
73
|
+
Supports_Operator(ParserState pstate, Supports_Condition_Obj l, Supports_Condition_Obj r, Operand o);
|
74
|
+
virtual bool needs_parens(Supports_Condition_Obj cond) const override;
|
75
|
+
ATTACH_AST_OPERATIONS(Supports_Operator)
|
76
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
77
|
+
};
|
78
|
+
|
79
|
+
//////////////////////////////////////////
|
80
|
+
// A negation condition (`not CONDITION`).
|
81
|
+
//////////////////////////////////////////
|
82
|
+
class Supports_Negation : public Supports_Condition {
|
83
|
+
private:
|
84
|
+
ADD_PROPERTY(Supports_Condition_Obj, condition);
|
85
|
+
public:
|
86
|
+
Supports_Negation(ParserState pstate, Supports_Condition_Obj c);
|
87
|
+
virtual bool needs_parens(Supports_Condition_Obj cond) const override;
|
88
|
+
ATTACH_AST_OPERATIONS(Supports_Negation)
|
89
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
90
|
+
};
|
91
|
+
|
92
|
+
/////////////////////////////////////////////////////
|
93
|
+
// A declaration condition (e.g. `(feature: value)`).
|
94
|
+
/////////////////////////////////////////////////////
|
95
|
+
class Supports_Declaration : public Supports_Condition {
|
96
|
+
private:
|
97
|
+
ADD_PROPERTY(Expression_Obj, feature);
|
98
|
+
ADD_PROPERTY(Expression_Obj, value);
|
99
|
+
public:
|
100
|
+
Supports_Declaration(ParserState pstate, Expression_Obj f, Expression_Obj v);
|
101
|
+
virtual bool needs_parens(Supports_Condition_Obj cond) const override;
|
102
|
+
ATTACH_AST_OPERATIONS(Supports_Declaration)
|
103
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
104
|
+
};
|
105
|
+
|
106
|
+
///////////////////////////////////////////////
|
107
|
+
// An interpolation condition (e.g. `#{$var}`).
|
108
|
+
///////////////////////////////////////////////
|
109
|
+
class Supports_Interpolation : public Supports_Condition {
|
110
|
+
private:
|
111
|
+
ADD_PROPERTY(Expression_Obj, value);
|
112
|
+
public:
|
113
|
+
Supports_Interpolation(ParserState pstate, Expression_Obj v);
|
114
|
+
virtual bool needs_parens(Supports_Condition_Obj cond) const override;
|
115
|
+
ATTACH_AST_OPERATIONS(Supports_Interpolation)
|
116
|
+
ATTACH_CRTP_PERFORM_METHODS()
|
117
|
+
};
|
118
|
+
|
119
|
+
}
|
120
|
+
|
121
|
+
#endif
|
@@ -0,0 +1,967 @@
|
|
1
|
+
// sass.hpp must go before all system headers to get the
|
2
|
+
// __EXTENSIONS__ fix on Solaris.
|
3
|
+
#include "sass.hpp"
|
4
|
+
|
5
|
+
#include "ast.hpp"
|
6
|
+
#include "context.hpp"
|
7
|
+
#include "node.hpp"
|
8
|
+
#include "eval.hpp"
|
9
|
+
#include "extend.hpp"
|
10
|
+
#include "emitter.hpp"
|
11
|
+
#include "color_maps.hpp"
|
12
|
+
#include "ast_fwd_decl.hpp"
|
13
|
+
#include <set>
|
14
|
+
#include <iomanip>
|
15
|
+
#include <iostream>
|
16
|
+
#include <algorithm>
|
17
|
+
#include <functional>
|
18
|
+
#include <cctype>
|
19
|
+
#include <locale>
|
20
|
+
|
21
|
+
#include "ast_values.hpp"
|
22
|
+
|
23
|
+
namespace Sass {
|
24
|
+
|
25
|
+
void str_rtrim(std::string& str, const std::string& delimiters = " \f\n\r\t\v")
|
26
|
+
{
|
27
|
+
str.erase( str.find_last_not_of( delimiters ) + 1 );
|
28
|
+
}
|
29
|
+
|
30
|
+
/////////////////////////////////////////////////////////////////////////
|
31
|
+
/////////////////////////////////////////////////////////////////////////
|
32
|
+
|
33
|
+
PreValue::PreValue(ParserState pstate, bool d, bool e, bool i, Type ct)
|
34
|
+
: Expression(pstate, d, e, i, ct)
|
35
|
+
{ }
|
36
|
+
PreValue::PreValue(const PreValue* ptr)
|
37
|
+
: Expression(ptr)
|
38
|
+
{ }
|
39
|
+
|
40
|
+
/////////////////////////////////////////////////////////////////////////
|
41
|
+
/////////////////////////////////////////////////////////////////////////
|
42
|
+
|
43
|
+
Value::Value(ParserState pstate, bool d, bool e, bool i, Type ct)
|
44
|
+
: PreValue(pstate, d, e, i, ct)
|
45
|
+
{ }
|
46
|
+
Value::Value(const Value* ptr)
|
47
|
+
: PreValue(ptr)
|
48
|
+
{ }
|
49
|
+
|
50
|
+
/////////////////////////////////////////////////////////////////////////
|
51
|
+
/////////////////////////////////////////////////////////////////////////
|
52
|
+
|
53
|
+
List::List(ParserState pstate, size_t size, enum Sass_Separator sep, bool argl, bool bracket)
|
54
|
+
: Value(pstate),
|
55
|
+
Vectorized<Expression_Obj>(size),
|
56
|
+
separator_(sep),
|
57
|
+
is_arglist_(argl),
|
58
|
+
is_bracketed_(bracket),
|
59
|
+
from_selector_(false)
|
60
|
+
{ concrete_type(LIST); }
|
61
|
+
|
62
|
+
List::List(const List* ptr)
|
63
|
+
: Value(ptr),
|
64
|
+
Vectorized<Expression_Obj>(*ptr),
|
65
|
+
separator_(ptr->separator_),
|
66
|
+
is_arglist_(ptr->is_arglist_),
|
67
|
+
is_bracketed_(ptr->is_bracketed_),
|
68
|
+
from_selector_(ptr->from_selector_)
|
69
|
+
{ concrete_type(LIST); }
|
70
|
+
|
71
|
+
size_t List::hash() const
|
72
|
+
{
|
73
|
+
if (hash_ == 0) {
|
74
|
+
hash_ = std::hash<std::string>()(sep_string());
|
75
|
+
hash_combine(hash_, std::hash<bool>()(is_bracketed()));
|
76
|
+
for (size_t i = 0, L = length(); i < L; ++i)
|
77
|
+
hash_combine(hash_, (elements()[i])->hash());
|
78
|
+
}
|
79
|
+
return hash_;
|
80
|
+
}
|
81
|
+
|
82
|
+
void List::set_delayed(bool delayed)
|
83
|
+
{
|
84
|
+
is_delayed(delayed);
|
85
|
+
// don't set children
|
86
|
+
}
|
87
|
+
|
88
|
+
bool List::operator== (const Expression& rhs) const
|
89
|
+
{
|
90
|
+
if (auto r = Cast<List>(&rhs)) {
|
91
|
+
if (length() != r->length()) return false;
|
92
|
+
if (separator() != r->separator()) return false;
|
93
|
+
if (is_bracketed() != r->is_bracketed()) return false;
|
94
|
+
for (size_t i = 0, L = length(); i < L; ++i) {
|
95
|
+
auto rv = r->at(i);
|
96
|
+
auto lv = this->at(i);
|
97
|
+
if (!lv && rv) return false;
|
98
|
+
else if (!rv && lv) return false;
|
99
|
+
else if (*lv != *rv) return false;
|
100
|
+
}
|
101
|
+
return true;
|
102
|
+
}
|
103
|
+
return false;
|
104
|
+
}
|
105
|
+
|
106
|
+
size_t List::size() const {
|
107
|
+
if (!is_arglist_) return length();
|
108
|
+
// arglist expects a list of arguments
|
109
|
+
// so we need to break before keywords
|
110
|
+
for (size_t i = 0, L = length(); i < L; ++i) {
|
111
|
+
Expression_Obj obj = this->at(i);
|
112
|
+
if (Argument* arg = Cast<Argument>(obj)) {
|
113
|
+
if (!arg->name().empty()) return i;
|
114
|
+
}
|
115
|
+
}
|
116
|
+
return length();
|
117
|
+
}
|
118
|
+
|
119
|
+
|
120
|
+
Expression_Obj List::value_at_index(size_t i) {
|
121
|
+
Expression_Obj obj = this->at(i);
|
122
|
+
if (is_arglist_) {
|
123
|
+
if (Argument* arg = Cast<Argument>(obj)) {
|
124
|
+
return arg->value();
|
125
|
+
} else {
|
126
|
+
return obj;
|
127
|
+
}
|
128
|
+
} else {
|
129
|
+
return obj;
|
130
|
+
}
|
131
|
+
}
|
132
|
+
|
133
|
+
/////////////////////////////////////////////////////////////////////////
|
134
|
+
/////////////////////////////////////////////////////////////////////////
|
135
|
+
|
136
|
+
Map::Map(ParserState pstate, size_t size)
|
137
|
+
: Value(pstate),
|
138
|
+
Hashed(size)
|
139
|
+
{ concrete_type(MAP); }
|
140
|
+
|
141
|
+
Map::Map(const Map* ptr)
|
142
|
+
: Value(ptr),
|
143
|
+
Hashed(*ptr)
|
144
|
+
{ concrete_type(MAP); }
|
145
|
+
|
146
|
+
bool Map::operator== (const Expression& rhs) const
|
147
|
+
{
|
148
|
+
if (auto r = Cast<Map>(&rhs)) {
|
149
|
+
if (length() != r->length()) return false;
|
150
|
+
for (auto key : keys()) {
|
151
|
+
auto rv = r->at(key);
|
152
|
+
auto lv = this->at(key);
|
153
|
+
if (!lv && rv) return false;
|
154
|
+
else if (!rv && lv) return false;
|
155
|
+
else if (*lv != *rv) return false;
|
156
|
+
}
|
157
|
+
return true;
|
158
|
+
}
|
159
|
+
return false;
|
160
|
+
}
|
161
|
+
|
162
|
+
List_Obj Map::to_list(ParserState& pstate) {
|
163
|
+
List_Obj ret = SASS_MEMORY_NEW(List, pstate, length(), SASS_COMMA);
|
164
|
+
|
165
|
+
for (auto key : keys()) {
|
166
|
+
List_Obj l = SASS_MEMORY_NEW(List, pstate, 2);
|
167
|
+
l->append(key);
|
168
|
+
l->append(at(key));
|
169
|
+
ret->append(l);
|
170
|
+
}
|
171
|
+
|
172
|
+
return ret;
|
173
|
+
}
|
174
|
+
|
175
|
+
size_t Map::hash() const
|
176
|
+
{
|
177
|
+
if (hash_ == 0) {
|
178
|
+
for (auto key : keys()) {
|
179
|
+
hash_combine(hash_, key->hash());
|
180
|
+
hash_combine(hash_, at(key)->hash());
|
181
|
+
}
|
182
|
+
}
|
183
|
+
|
184
|
+
return hash_;
|
185
|
+
}
|
186
|
+
|
187
|
+
/////////////////////////////////////////////////////////////////////////
|
188
|
+
/////////////////////////////////////////////////////////////////////////
|
189
|
+
|
190
|
+
Binary_Expression::Binary_Expression(ParserState pstate,
|
191
|
+
Operand op, Expression_Obj lhs, Expression_Obj rhs)
|
192
|
+
: PreValue(pstate), op_(op), left_(lhs), right_(rhs), hash_(0)
|
193
|
+
{ }
|
194
|
+
|
195
|
+
Binary_Expression::Binary_Expression(const Binary_Expression* ptr)
|
196
|
+
: PreValue(ptr),
|
197
|
+
op_(ptr->op_),
|
198
|
+
left_(ptr->left_),
|
199
|
+
right_(ptr->right_),
|
200
|
+
hash_(ptr->hash_)
|
201
|
+
{ }
|
202
|
+
|
203
|
+
bool Binary_Expression::is_left_interpolant(void) const
|
204
|
+
{
|
205
|
+
return is_interpolant() || (left() && left()->is_left_interpolant());
|
206
|
+
}
|
207
|
+
bool Binary_Expression::is_right_interpolant(void) const
|
208
|
+
{
|
209
|
+
return is_interpolant() || (right() && right()->is_right_interpolant());
|
210
|
+
}
|
211
|
+
|
212
|
+
const std::string Binary_Expression::type_name()
|
213
|
+
{
|
214
|
+
return sass_op_to_name(optype());
|
215
|
+
}
|
216
|
+
|
217
|
+
const std::string Binary_Expression::separator()
|
218
|
+
{
|
219
|
+
return sass_op_separator(optype());
|
220
|
+
}
|
221
|
+
|
222
|
+
bool Binary_Expression::has_interpolant() const
|
223
|
+
{
|
224
|
+
return is_left_interpolant() ||
|
225
|
+
is_right_interpolant();
|
226
|
+
}
|
227
|
+
|
228
|
+
void Binary_Expression::set_delayed(bool delayed)
|
229
|
+
{
|
230
|
+
right()->set_delayed(delayed);
|
231
|
+
left()->set_delayed(delayed);
|
232
|
+
is_delayed(delayed);
|
233
|
+
}
|
234
|
+
|
235
|
+
bool Binary_Expression::operator==(const Expression& rhs) const
|
236
|
+
{
|
237
|
+
if (auto m = Cast<Binary_Expression>(&rhs)) {
|
238
|
+
return type() == m->type() &&
|
239
|
+
*left() == *m->left() &&
|
240
|
+
*right() == *m->right();
|
241
|
+
}
|
242
|
+
return false;
|
243
|
+
}
|
244
|
+
|
245
|
+
size_t Binary_Expression::hash() const
|
246
|
+
{
|
247
|
+
if (hash_ == 0) {
|
248
|
+
hash_ = std::hash<size_t>()(optype());
|
249
|
+
hash_combine(hash_, left()->hash());
|
250
|
+
hash_combine(hash_, right()->hash());
|
251
|
+
}
|
252
|
+
return hash_;
|
253
|
+
}
|
254
|
+
|
255
|
+
/////////////////////////////////////////////////////////////////////////
|
256
|
+
/////////////////////////////////////////////////////////////////////////
|
257
|
+
|
258
|
+
Function::Function(ParserState pstate, Definition_Obj def, bool css)
|
259
|
+
: Value(pstate), definition_(def), is_css_(css)
|
260
|
+
{ concrete_type(FUNCTION_VAL); }
|
261
|
+
|
262
|
+
Function::Function(const Function* ptr)
|
263
|
+
: Value(ptr), definition_(ptr->definition_), is_css_(ptr->is_css_)
|
264
|
+
{ concrete_type(FUNCTION_VAL); }
|
265
|
+
|
266
|
+
bool Function::operator== (const Expression& rhs) const
|
267
|
+
{
|
268
|
+
if (auto r = Cast<Function>(&rhs)) {
|
269
|
+
auto d1 = Cast<Definition>(definition());
|
270
|
+
auto d2 = Cast<Definition>(r->definition());
|
271
|
+
return d1 && d2 && d1 == d2 && is_css() == r->is_css();
|
272
|
+
}
|
273
|
+
return false;
|
274
|
+
}
|
275
|
+
|
276
|
+
std::string Function::name() {
|
277
|
+
if (definition_) {
|
278
|
+
return definition_->name();
|
279
|
+
}
|
280
|
+
return "";
|
281
|
+
}
|
282
|
+
|
283
|
+
/////////////////////////////////////////////////////////////////////////
|
284
|
+
/////////////////////////////////////////////////////////////////////////
|
285
|
+
|
286
|
+
Function_Call::Function_Call(ParserState pstate, String_Obj n, Arguments_Obj args, void* cookie)
|
287
|
+
: PreValue(pstate), sname_(n), arguments_(args), func_(), via_call_(false), cookie_(cookie), hash_(0)
|
288
|
+
{ concrete_type(FUNCTION); }
|
289
|
+
Function_Call::Function_Call(ParserState pstate, String_Obj n, Arguments_Obj args, Function_Obj func)
|
290
|
+
: PreValue(pstate), sname_(n), arguments_(args), func_(func), via_call_(false), cookie_(0), hash_(0)
|
291
|
+
{ concrete_type(FUNCTION); }
|
292
|
+
Function_Call::Function_Call(ParserState pstate, String_Obj n, Arguments_Obj args)
|
293
|
+
: PreValue(pstate), sname_(n), arguments_(args), via_call_(false), cookie_(0), hash_(0)
|
294
|
+
{ concrete_type(FUNCTION); }
|
295
|
+
|
296
|
+
Function_Call::Function_Call(ParserState pstate, std::string n, Arguments_Obj args, void* cookie)
|
297
|
+
: PreValue(pstate), sname_(SASS_MEMORY_NEW(String_Constant, pstate, n)), arguments_(args), func_(), via_call_(false), cookie_(cookie), hash_(0)
|
298
|
+
{ concrete_type(FUNCTION); }
|
299
|
+
Function_Call::Function_Call(ParserState pstate, std::string n, Arguments_Obj args, Function_Obj func)
|
300
|
+
: PreValue(pstate), sname_(SASS_MEMORY_NEW(String_Constant, pstate, n)), arguments_(args), func_(func), via_call_(false), cookie_(0), hash_(0)
|
301
|
+
{ concrete_type(FUNCTION); }
|
302
|
+
Function_Call::Function_Call(ParserState pstate, std::string n, Arguments_Obj args)
|
303
|
+
: PreValue(pstate), sname_(SASS_MEMORY_NEW(String_Constant, pstate, n)), arguments_(args), via_call_(false), cookie_(0), hash_(0)
|
304
|
+
{ concrete_type(FUNCTION); }
|
305
|
+
|
306
|
+
Function_Call::Function_Call(const Function_Call* ptr)
|
307
|
+
: PreValue(ptr),
|
308
|
+
sname_(ptr->sname_),
|
309
|
+
arguments_(ptr->arguments_),
|
310
|
+
func_(ptr->func_),
|
311
|
+
via_call_(ptr->via_call_),
|
312
|
+
cookie_(ptr->cookie_),
|
313
|
+
hash_(ptr->hash_)
|
314
|
+
{ concrete_type(FUNCTION); }
|
315
|
+
|
316
|
+
bool Function_Call::operator==(const Expression& rhs) const
|
317
|
+
{
|
318
|
+
if (auto m = Cast<Function_Call>(&rhs)) {
|
319
|
+
if (*sname() != *m->sname()) return false;
|
320
|
+
if (arguments()->length() != m->arguments()->length()) return false;
|
321
|
+
for (size_t i = 0, L = arguments()->length(); i < L; ++i)
|
322
|
+
if (*arguments()->get(i) != *m->arguments()->get(i)) return false;
|
323
|
+
return true;
|
324
|
+
}
|
325
|
+
return false;
|
326
|
+
}
|
327
|
+
|
328
|
+
size_t Function_Call::hash() const
|
329
|
+
{
|
330
|
+
if (hash_ == 0) {
|
331
|
+
hash_ = std::hash<std::string>()(name());
|
332
|
+
for (auto argument : arguments()->elements())
|
333
|
+
hash_combine(hash_, argument->hash());
|
334
|
+
}
|
335
|
+
return hash_;
|
336
|
+
}
|
337
|
+
|
338
|
+
std::string Function_Call::name() const
|
339
|
+
{
|
340
|
+
return sname();
|
341
|
+
}
|
342
|
+
|
343
|
+
bool Function_Call::is_css() {
|
344
|
+
if (func_) return func_->is_css();
|
345
|
+
return false;
|
346
|
+
}
|
347
|
+
|
348
|
+
/////////////////////////////////////////////////////////////////////////
|
349
|
+
/////////////////////////////////////////////////////////////////////////
|
350
|
+
|
351
|
+
Variable::Variable(ParserState pstate, std::string n)
|
352
|
+
: PreValue(pstate), name_(n)
|
353
|
+
{ concrete_type(VARIABLE); }
|
354
|
+
|
355
|
+
Variable::Variable(const Variable* ptr)
|
356
|
+
: PreValue(ptr), name_(ptr->name_)
|
357
|
+
{ concrete_type(VARIABLE); }
|
358
|
+
|
359
|
+
bool Variable::operator==(const Expression& rhs) const
|
360
|
+
{
|
361
|
+
if (auto e = Cast<Variable>(&rhs)) {
|
362
|
+
return name() == e->name();
|
363
|
+
}
|
364
|
+
return false;
|
365
|
+
}
|
366
|
+
|
367
|
+
size_t Variable::hash() const
|
368
|
+
{
|
369
|
+
return std::hash<std::string>()(name());
|
370
|
+
}
|
371
|
+
|
372
|
+
/////////////////////////////////////////////////////////////////////////
|
373
|
+
/////////////////////////////////////////////////////////////////////////
|
374
|
+
|
375
|
+
Number::Number(ParserState pstate, double val, std::string u, bool zero)
|
376
|
+
: Value(pstate),
|
377
|
+
Units(),
|
378
|
+
value_(val),
|
379
|
+
zero_(zero),
|
380
|
+
hash_(0)
|
381
|
+
{
|
382
|
+
size_t l = 0;
|
383
|
+
size_t r;
|
384
|
+
if (!u.empty()) {
|
385
|
+
bool nominator = true;
|
386
|
+
while (true) {
|
387
|
+
r = u.find_first_of("*/", l);
|
388
|
+
std::string unit(u.substr(l, r == std::string::npos ? r : r - l));
|
389
|
+
if (!unit.empty()) {
|
390
|
+
if (nominator) numerators.push_back(unit);
|
391
|
+
else denominators.push_back(unit);
|
392
|
+
}
|
393
|
+
if (r == std::string::npos) break;
|
394
|
+
// ToDo: should error for multiple slashes
|
395
|
+
// if (!nominator && u[r] == '/') error(...)
|
396
|
+
if (u[r] == '/')
|
397
|
+
nominator = false;
|
398
|
+
// strange math parsing?
|
399
|
+
// else if (u[r] == '*')
|
400
|
+
// nominator = true;
|
401
|
+
l = r + 1;
|
402
|
+
}
|
403
|
+
}
|
404
|
+
concrete_type(NUMBER);
|
405
|
+
}
|
406
|
+
|
407
|
+
Number::Number(const Number* ptr)
|
408
|
+
: Value(ptr),
|
409
|
+
Units(ptr),
|
410
|
+
value_(ptr->value_), zero_(ptr->zero_),
|
411
|
+
hash_(ptr->hash_)
|
412
|
+
{ concrete_type(NUMBER); }
|
413
|
+
|
414
|
+
// cancel out unnecessary units
|
415
|
+
void Number::reduce()
|
416
|
+
{
|
417
|
+
// apply conversion factor
|
418
|
+
value_ *= this->Units::reduce();
|
419
|
+
}
|
420
|
+
|
421
|
+
void Number::normalize()
|
422
|
+
{
|
423
|
+
// apply conversion factor
|
424
|
+
value_ *= this->Units::normalize();
|
425
|
+
}
|
426
|
+
|
427
|
+
size_t Number::hash() const
|
428
|
+
{
|
429
|
+
if (hash_ == 0) {
|
430
|
+
hash_ = std::hash<double>()(value_);
|
431
|
+
for (const auto numerator : numerators)
|
432
|
+
hash_combine(hash_, std::hash<std::string>()(numerator));
|
433
|
+
for (const auto denominator : denominators)
|
434
|
+
hash_combine(hash_, std::hash<std::string>()(denominator));
|
435
|
+
}
|
436
|
+
return hash_;
|
437
|
+
}
|
438
|
+
|
439
|
+
bool Number::operator== (const Expression& rhs) const
|
440
|
+
{
|
441
|
+
if (auto n = Cast<Number>(&rhs)) {
|
442
|
+
return *this == *n;
|
443
|
+
}
|
444
|
+
return false;
|
445
|
+
}
|
446
|
+
|
447
|
+
bool Number::operator== (const Number& rhs) const
|
448
|
+
{
|
449
|
+
// unitless or only having one unit are equivalent (3.4)
|
450
|
+
// therefore we need to reduce the units beforehand
|
451
|
+
Number l(*this), r(rhs); l.reduce(); r.reduce();
|
452
|
+
size_t lhs_units = l.numerators.size() + l.denominators.size();
|
453
|
+
size_t rhs_units = r.numerators.size() + r.denominators.size();
|
454
|
+
if (!lhs_units || !rhs_units) {
|
455
|
+
return NEAR_EQUAL(l.value(), r.value());
|
456
|
+
}
|
457
|
+
// ensure both have same units
|
458
|
+
l.normalize(); r.normalize();
|
459
|
+
Units &lhs_unit = l, &rhs_unit = r;
|
460
|
+
return lhs_unit == rhs_unit &&
|
461
|
+
NEAR_EQUAL(l.value(), r.value());
|
462
|
+
}
|
463
|
+
|
464
|
+
bool Number::operator< (const Number& rhs) const
|
465
|
+
{
|
466
|
+
// unitless or only having one unit are equivalent (3.4)
|
467
|
+
// therefore we need to reduce the units beforehand
|
468
|
+
Number l(*this), r(rhs); l.reduce(); r.reduce();
|
469
|
+
size_t lhs_units = l.numerators.size() + l.denominators.size();
|
470
|
+
size_t rhs_units = r.numerators.size() + r.denominators.size();
|
471
|
+
if (!lhs_units || !rhs_units) {
|
472
|
+
return l.value() < r.value();
|
473
|
+
}
|
474
|
+
// ensure both have same units
|
475
|
+
l.normalize(); r.normalize();
|
476
|
+
Units &lhs_unit = l, &rhs_unit = r;
|
477
|
+
if (!(lhs_unit == rhs_unit)) {
|
478
|
+
/* ToDo: do we always get usefull backtraces? */
|
479
|
+
throw Exception::IncompatibleUnits(rhs, *this);
|
480
|
+
}
|
481
|
+
if (lhs_unit == rhs_unit) {
|
482
|
+
return l.value() < r.value();
|
483
|
+
} else {
|
484
|
+
return lhs_unit < rhs_unit;
|
485
|
+
}
|
486
|
+
}
|
487
|
+
|
488
|
+
/////////////////////////////////////////////////////////////////////////
|
489
|
+
/////////////////////////////////////////////////////////////////////////
|
490
|
+
|
491
|
+
Color::Color(ParserState pstate, double a, const std::string disp)
|
492
|
+
: Value(pstate),
|
493
|
+
disp_(disp), a_(a),
|
494
|
+
hash_(0)
|
495
|
+
{ concrete_type(COLOR); }
|
496
|
+
|
497
|
+
Color::Color(const Color* ptr)
|
498
|
+
: Value(ptr->pstate()),
|
499
|
+
// reset on copy
|
500
|
+
disp_(""),
|
501
|
+
a_(ptr->a_),
|
502
|
+
hash_(ptr->hash_)
|
503
|
+
{ concrete_type(COLOR); }
|
504
|
+
|
505
|
+
bool Color::operator== (const Expression& rhs) const
|
506
|
+
{
|
507
|
+
if (auto r = Cast<Color_RGBA>(&rhs)) {
|
508
|
+
return *this == *r;
|
509
|
+
}
|
510
|
+
else if (auto r = Cast<Color_HSLA>(&rhs)) {
|
511
|
+
return *this == *r;
|
512
|
+
}
|
513
|
+
else if (auto r = Cast<Color>(&rhs)) {
|
514
|
+
return a_ == r->a();
|
515
|
+
}
|
516
|
+
return false;
|
517
|
+
}
|
518
|
+
|
519
|
+
/////////////////////////////////////////////////////////////////////////
|
520
|
+
/////////////////////////////////////////////////////////////////////////
|
521
|
+
|
522
|
+
Color_RGBA::Color_RGBA(ParserState pstate, double r, double g, double b, double a, const std::string disp)
|
523
|
+
: Color(pstate, a, disp),
|
524
|
+
r_(r), g_(g), b_(b)
|
525
|
+
{ concrete_type(COLOR); }
|
526
|
+
|
527
|
+
Color_RGBA::Color_RGBA(const Color_RGBA* ptr)
|
528
|
+
: Color(ptr),
|
529
|
+
r_(ptr->r_),
|
530
|
+
g_(ptr->g_),
|
531
|
+
b_(ptr->b_)
|
532
|
+
{ concrete_type(COLOR); }
|
533
|
+
|
534
|
+
bool Color_RGBA::operator== (const Expression& rhs) const
|
535
|
+
{
|
536
|
+
if (auto r = Cast<Color_RGBA>(&rhs)) {
|
537
|
+
return r_ == r->r() &&
|
538
|
+
g_ == r->g() &&
|
539
|
+
b_ == r->b() &&
|
540
|
+
a_ == r->a();
|
541
|
+
}
|
542
|
+
return false;
|
543
|
+
}
|
544
|
+
|
545
|
+
size_t Color_RGBA::hash() const
|
546
|
+
{
|
547
|
+
if (hash_ == 0) {
|
548
|
+
hash_ = std::hash<std::string>()("RGBA");
|
549
|
+
hash_combine(hash_, std::hash<double>()(a_));
|
550
|
+
hash_combine(hash_, std::hash<double>()(r_));
|
551
|
+
hash_combine(hash_, std::hash<double>()(g_));
|
552
|
+
hash_combine(hash_, std::hash<double>()(b_));
|
553
|
+
}
|
554
|
+
return hash_;
|
555
|
+
}
|
556
|
+
|
557
|
+
Color_HSLA* Color_RGBA::copyAsHSLA() const
|
558
|
+
{
|
559
|
+
|
560
|
+
// Algorithm from http://en.wikipedia.org/wiki/wHSL_and_HSV#Conversion_from_RGB_to_HSL_or_HSV
|
561
|
+
double r = r_ / 255.0;
|
562
|
+
double g = g_ / 255.0;
|
563
|
+
double b = b_ / 255.0;
|
564
|
+
|
565
|
+
double max = std::max(r, std::max(g, b));
|
566
|
+
double min = std::min(r, std::min(g, b));
|
567
|
+
double delta = max - min;
|
568
|
+
|
569
|
+
double h = 0;
|
570
|
+
double s;
|
571
|
+
double l = (max + min) / 2.0;
|
572
|
+
|
573
|
+
if (NEAR_EQUAL(max, min)) {
|
574
|
+
h = s = 0; // achromatic
|
575
|
+
}
|
576
|
+
else {
|
577
|
+
if (l < 0.5) s = delta / (max + min);
|
578
|
+
else s = delta / (2.0 - max - min);
|
579
|
+
|
580
|
+
if (r == max) h = (g - b) / delta + (g < b ? 6 : 0);
|
581
|
+
else if (g == max) h = (b - r) / delta + 2;
|
582
|
+
else if (b == max) h = (r - g) / delta + 4;
|
583
|
+
}
|
584
|
+
|
585
|
+
// HSL hsl_struct;
|
586
|
+
h = h * 60;
|
587
|
+
s = s * 100;
|
588
|
+
l = l * 100;
|
589
|
+
|
590
|
+
return SASS_MEMORY_NEW(Color_HSLA,
|
591
|
+
pstate(), h, s, l, a(), ""
|
592
|
+
);
|
593
|
+
}
|
594
|
+
|
595
|
+
Color_RGBA* Color_RGBA::copyAsRGBA() const
|
596
|
+
{
|
597
|
+
return SASS_MEMORY_COPY(this);
|
598
|
+
}
|
599
|
+
|
600
|
+
/////////////////////////////////////////////////////////////////////////
|
601
|
+
/////////////////////////////////////////////////////////////////////////
|
602
|
+
|
603
|
+
Color_HSLA::Color_HSLA(ParserState pstate, double h, double s, double l, double a, const std::string disp)
|
604
|
+
: Color(pstate, a, disp),
|
605
|
+
h_(absmod(h, 360.0)),
|
606
|
+
s_(clip(s, 0.0, 100.0)),
|
607
|
+
l_(clip(l, 0.0, 100.0))
|
608
|
+
// hash_(0)
|
609
|
+
{ concrete_type(COLOR); }
|
610
|
+
|
611
|
+
Color_HSLA::Color_HSLA(const Color_HSLA* ptr)
|
612
|
+
: Color(ptr),
|
613
|
+
h_(ptr->h_),
|
614
|
+
s_(ptr->s_),
|
615
|
+
l_(ptr->l_)
|
616
|
+
// hash_(ptr->hash_)
|
617
|
+
{ concrete_type(COLOR); }
|
618
|
+
|
619
|
+
bool Color_HSLA::operator== (const Expression& rhs) const
|
620
|
+
{
|
621
|
+
if (auto r = Cast<Color_HSLA>(&rhs)) {
|
622
|
+
return h_ == r->h() &&
|
623
|
+
s_ == r->s() &&
|
624
|
+
l_ == r->l() &&
|
625
|
+
a_ == r->a();
|
626
|
+
}
|
627
|
+
return false;
|
628
|
+
}
|
629
|
+
|
630
|
+
size_t Color_HSLA::hash() const
|
631
|
+
{
|
632
|
+
if (hash_ == 0) {
|
633
|
+
hash_ = std::hash<std::string>()("HSLA");
|
634
|
+
hash_combine(hash_, std::hash<double>()(a_));
|
635
|
+
hash_combine(hash_, std::hash<double>()(h_));
|
636
|
+
hash_combine(hash_, std::hash<double>()(s_));
|
637
|
+
hash_combine(hash_, std::hash<double>()(l_));
|
638
|
+
}
|
639
|
+
return hash_;
|
640
|
+
}
|
641
|
+
|
642
|
+
// hue to RGB helper function
|
643
|
+
double h_to_rgb(double m1, double m2, double h)
|
644
|
+
{
|
645
|
+
h = absmod(h, 1.0);
|
646
|
+
if (h*6.0 < 1) return m1 + (m2 - m1)*h*6;
|
647
|
+
if (h*2.0 < 1) return m2;
|
648
|
+
if (h*3.0 < 2) return m1 + (m2 - m1) * (2.0/3.0 - h)*6;
|
649
|
+
return m1;
|
650
|
+
}
|
651
|
+
|
652
|
+
Color_RGBA* Color_HSLA::copyAsRGBA() const
|
653
|
+
{
|
654
|
+
|
655
|
+
double h = absmod(h_ / 360.0, 1.0);
|
656
|
+
double s = clip(s_ / 100.0, 0.0, 1.0);
|
657
|
+
double l = clip(l_ / 100.0, 0.0, 1.0);
|
658
|
+
|
659
|
+
// Algorithm from the CSS3 spec: http://www.w3.org/TR/css3-color/#hsl-color.
|
660
|
+
double m2;
|
661
|
+
if (l <= 0.5) m2 = l*(s+1.0);
|
662
|
+
else m2 = (l+s)-(l*s);
|
663
|
+
double m1 = (l*2.0)-m2;
|
664
|
+
// round the results -- consider moving this into the Color constructor
|
665
|
+
double r = (h_to_rgb(m1, m2, h + 1.0/3.0) * 255.0);
|
666
|
+
double g = (h_to_rgb(m1, m2, h) * 255.0);
|
667
|
+
double b = (h_to_rgb(m1, m2, h - 1.0/3.0) * 255.0);
|
668
|
+
|
669
|
+
return SASS_MEMORY_NEW(Color_RGBA,
|
670
|
+
pstate(), r, g, b, a(), ""
|
671
|
+
);
|
672
|
+
}
|
673
|
+
|
674
|
+
Color_HSLA* Color_HSLA::copyAsHSLA() const
|
675
|
+
{
|
676
|
+
return SASS_MEMORY_COPY(this);
|
677
|
+
}
|
678
|
+
|
679
|
+
/////////////////////////////////////////////////////////////////////////
|
680
|
+
/////////////////////////////////////////////////////////////////////////
|
681
|
+
|
682
|
+
Custom_Error::Custom_Error(ParserState pstate, std::string msg)
|
683
|
+
: Value(pstate), message_(msg)
|
684
|
+
{ concrete_type(C_ERROR); }
|
685
|
+
|
686
|
+
Custom_Error::Custom_Error(const Custom_Error* ptr)
|
687
|
+
: Value(ptr), message_(ptr->message_)
|
688
|
+
{ concrete_type(C_ERROR); }
|
689
|
+
|
690
|
+
bool Custom_Error::operator== (const Expression& rhs) const
|
691
|
+
{
|
692
|
+
if (auto r = Cast<Custom_Error>(&rhs)) {
|
693
|
+
return message() == r->message();
|
694
|
+
}
|
695
|
+
return false;
|
696
|
+
}
|
697
|
+
|
698
|
+
/////////////////////////////////////////////////////////////////////////
|
699
|
+
/////////////////////////////////////////////////////////////////////////
|
700
|
+
|
701
|
+
Custom_Warning::Custom_Warning(ParserState pstate, std::string msg)
|
702
|
+
: Value(pstate), message_(msg)
|
703
|
+
{ concrete_type(C_WARNING); }
|
704
|
+
|
705
|
+
Custom_Warning::Custom_Warning(const Custom_Warning* ptr)
|
706
|
+
: Value(ptr), message_(ptr->message_)
|
707
|
+
{ concrete_type(C_WARNING); }
|
708
|
+
|
709
|
+
bool Custom_Warning::operator== (const Expression& rhs) const
|
710
|
+
{
|
711
|
+
if (auto r = Cast<Custom_Warning>(&rhs)) {
|
712
|
+
return message() == r->message();
|
713
|
+
}
|
714
|
+
return false;
|
715
|
+
}
|
716
|
+
|
717
|
+
/////////////////////////////////////////////////////////////////////////
|
718
|
+
/////////////////////////////////////////////////////////////////////////
|
719
|
+
|
720
|
+
Boolean::Boolean(ParserState pstate, bool val)
|
721
|
+
: Value(pstate), value_(val),
|
722
|
+
hash_(0)
|
723
|
+
{ concrete_type(BOOLEAN); }
|
724
|
+
|
725
|
+
Boolean::Boolean(const Boolean* ptr)
|
726
|
+
: Value(ptr),
|
727
|
+
value_(ptr->value_),
|
728
|
+
hash_(ptr->hash_)
|
729
|
+
{ concrete_type(BOOLEAN); }
|
730
|
+
|
731
|
+
bool Boolean::operator== (const Expression& rhs) const
|
732
|
+
{
|
733
|
+
if (auto r = Cast<Boolean>(&rhs)) {
|
734
|
+
return (value() == r->value());
|
735
|
+
}
|
736
|
+
return false;
|
737
|
+
}
|
738
|
+
|
739
|
+
size_t Boolean::hash() const
|
740
|
+
{
|
741
|
+
if (hash_ == 0) {
|
742
|
+
hash_ = std::hash<bool>()(value_);
|
743
|
+
}
|
744
|
+
return hash_;
|
745
|
+
}
|
746
|
+
|
747
|
+
/////////////////////////////////////////////////////////////////////////
|
748
|
+
/////////////////////////////////////////////////////////////////////////
|
749
|
+
|
750
|
+
String::String(ParserState pstate, bool delayed)
|
751
|
+
: Value(pstate, delayed)
|
752
|
+
{ concrete_type(STRING); }
|
753
|
+
String::String(const String* ptr)
|
754
|
+
: Value(ptr)
|
755
|
+
{ concrete_type(STRING); }
|
756
|
+
|
757
|
+
/////////////////////////////////////////////////////////////////////////
|
758
|
+
/////////////////////////////////////////////////////////////////////////
|
759
|
+
|
760
|
+
String_Schema::String_Schema(ParserState pstate, size_t size, bool css)
|
761
|
+
: String(pstate), Vectorized<PreValue_Obj>(size), css_(css), hash_(0)
|
762
|
+
{ concrete_type(STRING); }
|
763
|
+
|
764
|
+
String_Schema::String_Schema(const String_Schema* ptr)
|
765
|
+
: String(ptr),
|
766
|
+
Vectorized<PreValue_Obj>(*ptr),
|
767
|
+
css_(ptr->css_),
|
768
|
+
hash_(ptr->hash_)
|
769
|
+
{ concrete_type(STRING); }
|
770
|
+
|
771
|
+
void String_Schema::rtrim()
|
772
|
+
{
|
773
|
+
if (!empty()) {
|
774
|
+
if (String* str = Cast<String>(last())) str->rtrim();
|
775
|
+
}
|
776
|
+
}
|
777
|
+
|
778
|
+
bool String_Schema::is_left_interpolant(void) const
|
779
|
+
{
|
780
|
+
return length() && first()->is_left_interpolant();
|
781
|
+
}
|
782
|
+
bool String_Schema::is_right_interpolant(void) const
|
783
|
+
{
|
784
|
+
return length() && last()->is_right_interpolant();
|
785
|
+
}
|
786
|
+
|
787
|
+
bool String_Schema::operator== (const Expression& rhs) const
|
788
|
+
{
|
789
|
+
if (auto r = Cast<String_Schema>(&rhs)) {
|
790
|
+
if (length() != r->length()) return false;
|
791
|
+
for (size_t i = 0, L = length(); i < L; ++i) {
|
792
|
+
auto rv = (*r)[i];
|
793
|
+
auto lv = (*this)[i];
|
794
|
+
if (*lv != *rv) return false;
|
795
|
+
}
|
796
|
+
return true;
|
797
|
+
}
|
798
|
+
return false;
|
799
|
+
}
|
800
|
+
|
801
|
+
bool String_Schema::has_interpolants()
|
802
|
+
{
|
803
|
+
for (auto el : elements()) {
|
804
|
+
if (el->is_interpolant()) return true;
|
805
|
+
}
|
806
|
+
return false;
|
807
|
+
}
|
808
|
+
|
809
|
+
size_t String_Schema::hash() const
|
810
|
+
{
|
811
|
+
if (hash_ == 0) {
|
812
|
+
for (auto string : elements())
|
813
|
+
hash_combine(hash_, string->hash());
|
814
|
+
}
|
815
|
+
return hash_;
|
816
|
+
}
|
817
|
+
|
818
|
+
void String_Schema::set_delayed(bool delayed)
|
819
|
+
{
|
820
|
+
is_delayed(delayed);
|
821
|
+
}
|
822
|
+
|
823
|
+
/////////////////////////////////////////////////////////////////////////
|
824
|
+
/////////////////////////////////////////////////////////////////////////
|
825
|
+
|
826
|
+
String_Constant::String_Constant(ParserState pstate, std::string val, bool css)
|
827
|
+
: String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(val, css)), hash_(0)
|
828
|
+
{ }
|
829
|
+
String_Constant::String_Constant(ParserState pstate, const char* beg, bool css)
|
830
|
+
: String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(std::string(beg), css)), hash_(0)
|
831
|
+
{ }
|
832
|
+
String_Constant::String_Constant(ParserState pstate, const char* beg, const char* end, bool css)
|
833
|
+
: String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(std::string(beg, end-beg), css)), hash_(0)
|
834
|
+
{ }
|
835
|
+
String_Constant::String_Constant(ParserState pstate, const Token& tok, bool css)
|
836
|
+
: String(pstate), quote_mark_(0), can_compress_whitespace_(false), value_(read_css_string(std::string(tok.begin, tok.end), css)), hash_(0)
|
837
|
+
{ }
|
838
|
+
|
839
|
+
String_Constant::String_Constant(const String_Constant* ptr)
|
840
|
+
: String(ptr),
|
841
|
+
quote_mark_(ptr->quote_mark_),
|
842
|
+
can_compress_whitespace_(ptr->can_compress_whitespace_),
|
843
|
+
value_(ptr->value_),
|
844
|
+
hash_(ptr->hash_)
|
845
|
+
{ }
|
846
|
+
|
847
|
+
bool String_Constant::is_invisible() const {
|
848
|
+
return value_.empty() && quote_mark_ == 0;
|
849
|
+
}
|
850
|
+
|
851
|
+
bool String_Constant::operator== (const Expression& rhs) const
|
852
|
+
{
|
853
|
+
if (auto qstr = Cast<String_Quoted>(&rhs)) {
|
854
|
+
return value() == qstr->value();
|
855
|
+
} else if (auto cstr = Cast<String_Constant>(&rhs)) {
|
856
|
+
return value() == cstr->value();
|
857
|
+
}
|
858
|
+
return false;
|
859
|
+
}
|
860
|
+
|
861
|
+
std::string String_Constant::inspect() const
|
862
|
+
{
|
863
|
+
return quote(value_, '*');
|
864
|
+
}
|
865
|
+
|
866
|
+
void String_Constant::rtrim()
|
867
|
+
{
|
868
|
+
str_rtrim(value_);
|
869
|
+
}
|
870
|
+
|
871
|
+
size_t String_Constant::hash() const
|
872
|
+
{
|
873
|
+
if (hash_ == 0) {
|
874
|
+
hash_ = std::hash<std::string>()(value_);
|
875
|
+
}
|
876
|
+
return hash_;
|
877
|
+
}
|
878
|
+
|
879
|
+
/////////////////////////////////////////////////////////////////////////
|
880
|
+
/////////////////////////////////////////////////////////////////////////
|
881
|
+
|
882
|
+
String_Quoted::String_Quoted(ParserState pstate, std::string val, char q,
|
883
|
+
bool keep_utf8_escapes, bool skip_unquoting,
|
884
|
+
bool strict_unquoting, bool css)
|
885
|
+
: String_Constant(pstate, val, css)
|
886
|
+
{
|
887
|
+
if (skip_unquoting == false) {
|
888
|
+
value_ = unquote(value_, "e_mark_, keep_utf8_escapes, strict_unquoting);
|
889
|
+
}
|
890
|
+
if (q && quote_mark_) quote_mark_ = q;
|
891
|
+
}
|
892
|
+
|
893
|
+
String_Quoted::String_Quoted(const String_Quoted* ptr)
|
894
|
+
: String_Constant(ptr)
|
895
|
+
{ }
|
896
|
+
|
897
|
+
bool String_Quoted::operator== (const Expression& rhs) const
|
898
|
+
{
|
899
|
+
if (auto qstr = Cast<String_Quoted>(&rhs)) {
|
900
|
+
return value() == qstr->value();
|
901
|
+
} else if (auto cstr = Cast<String_Constant>(&rhs)) {
|
902
|
+
return value() == cstr->value();
|
903
|
+
}
|
904
|
+
return false;
|
905
|
+
}
|
906
|
+
|
907
|
+
std::string String_Quoted::inspect() const
|
908
|
+
{
|
909
|
+
return quote(value_, '*');
|
910
|
+
}
|
911
|
+
|
912
|
+
/////////////////////////////////////////////////////////////////////////
|
913
|
+
/////////////////////////////////////////////////////////////////////////
|
914
|
+
|
915
|
+
Null::Null(ParserState pstate)
|
916
|
+
: Value(pstate)
|
917
|
+
{ concrete_type(NULL_VAL); }
|
918
|
+
|
919
|
+
Null::Null(const Null* ptr) : Value(ptr)
|
920
|
+
{ concrete_type(NULL_VAL); }
|
921
|
+
|
922
|
+
bool Null::operator== (const Expression& rhs) const
|
923
|
+
{
|
924
|
+
return Cast<Null>(&rhs) != NULL;
|
925
|
+
}
|
926
|
+
|
927
|
+
size_t Null::hash() const
|
928
|
+
{
|
929
|
+
return -1;
|
930
|
+
}
|
931
|
+
|
932
|
+
/////////////////////////////////////////////////////////////////////////
|
933
|
+
/////////////////////////////////////////////////////////////////////////
|
934
|
+
|
935
|
+
Parent_Reference::Parent_Reference(ParserState pstate)
|
936
|
+
: Value(pstate)
|
937
|
+
{ concrete_type(PARENT); }
|
938
|
+
|
939
|
+
Parent_Reference::Parent_Reference(const Parent_Reference* ptr)
|
940
|
+
: Value(ptr)
|
941
|
+
{ concrete_type(PARENT); }
|
942
|
+
|
943
|
+
/////////////////////////////////////////////////////////////////////////
|
944
|
+
/////////////////////////////////////////////////////////////////////////
|
945
|
+
|
946
|
+
IMPLEMENT_AST_OPERATORS(List);
|
947
|
+
IMPLEMENT_AST_OPERATORS(Map);
|
948
|
+
IMPLEMENT_AST_OPERATORS(Binary_Expression);
|
949
|
+
IMPLEMENT_AST_OPERATORS(Function);
|
950
|
+
IMPLEMENT_AST_OPERATORS(Function_Call);
|
951
|
+
IMPLEMENT_AST_OPERATORS(Variable);
|
952
|
+
IMPLEMENT_AST_OPERATORS(Number);
|
953
|
+
IMPLEMENT_AST_OPERATORS(Color_RGBA);
|
954
|
+
IMPLEMENT_AST_OPERATORS(Color_HSLA);
|
955
|
+
IMPLEMENT_AST_OPERATORS(Custom_Error);
|
956
|
+
IMPLEMENT_AST_OPERATORS(Custom_Warning);
|
957
|
+
IMPLEMENT_AST_OPERATORS(Boolean);
|
958
|
+
IMPLEMENT_AST_OPERATORS(String_Schema);
|
959
|
+
IMPLEMENT_AST_OPERATORS(String_Constant);
|
960
|
+
IMPLEMENT_AST_OPERATORS(String_Quoted);
|
961
|
+
IMPLEMENT_AST_OPERATORS(Null);
|
962
|
+
IMPLEMENT_AST_OPERATORS(Parent_Reference);
|
963
|
+
|
964
|
+
/////////////////////////////////////////////////////////////////////////
|
965
|
+
/////////////////////////////////////////////////////////////////////////
|
966
|
+
|
967
|
+
}
|