sassc 2.0.1 → 2.1.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (200) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.gitmodules +1 -1
  4. data/.travis.yml +7 -3
  5. data/CHANGELOG.md +3 -0
  6. data/CODE_OF_CONDUCT.md +1 -1
  7. data/README.md +1 -1
  8. data/Rakefile +23 -8
  9. data/ext/extconf.rb +39 -0
  10. data/ext/libsass/.gitignore +1 -0
  11. data/ext/libsass/GNUmakefile.am +23 -39
  12. data/ext/libsass/Makefile +56 -91
  13. data/ext/libsass/Makefile.conf +16 -2
  14. data/ext/libsass/configure.ac +8 -12
  15. data/ext/libsass/include/sass/base.h +1 -0
  16. data/ext/libsass/include/sass/context.h +1 -1
  17. data/ext/libsass/src/GNUmakefile.am +1 -5
  18. data/ext/libsass/src/ast.cpp +747 -2010
  19. data/ext/libsass/src/ast.hpp +239 -2383
  20. data/ext/libsass/src/{to_c.cpp → ast2c.cpp} +22 -16
  21. data/ext/libsass/src/ast2c.hpp +39 -0
  22. data/ext/libsass/src/ast_def_macros.hpp +62 -10
  23. data/ext/libsass/src/ast_fwd_decl.cpp +1 -0
  24. data/ext/libsass/src/ast_fwd_decl.hpp +43 -165
  25. data/ext/libsass/src/ast_sel_cmp.cpp +909 -0
  26. data/ext/libsass/src/ast_sel_unify.cpp +280 -0
  27. data/ext/libsass/src/ast_selectors.cpp +1475 -0
  28. data/ext/libsass/src/ast_selectors.hpp +568 -0
  29. data/ext/libsass/src/ast_supports.cpp +130 -0
  30. data/ext/libsass/src/ast_supports.hpp +121 -0
  31. data/ext/libsass/src/ast_values.cpp +967 -0
  32. data/ext/libsass/src/ast_values.hpp +489 -0
  33. data/ext/libsass/src/backtrace.cpp +4 -0
  34. data/ext/libsass/src/base64vlq.cpp +3 -0
  35. data/ext/libsass/src/bind.cpp +18 -17
  36. data/ext/libsass/src/bind.hpp +3 -1
  37. data/ext/libsass/src/c2ast.cpp +64 -0
  38. data/ext/libsass/src/c2ast.hpp +14 -0
  39. data/ext/libsass/src/cencode.c +2 -2
  40. data/ext/libsass/src/check_nesting.cpp +52 -56
  41. data/ext/libsass/src/check_nesting.hpp +35 -34
  42. data/ext/libsass/src/color_maps.cpp +156 -153
  43. data/ext/libsass/src/color_maps.hpp +152 -152
  44. data/ext/libsass/src/constants.cpp +15 -0
  45. data/ext/libsass/src/constants.hpp +13 -0
  46. data/ext/libsass/src/context.cpp +24 -14
  47. data/ext/libsass/src/context.hpp +6 -6
  48. data/ext/libsass/src/cssize.cpp +69 -71
  49. data/ext/libsass/src/cssize.hpp +50 -50
  50. data/ext/libsass/src/debugger.hpp +117 -110
  51. data/ext/libsass/src/emitter.cpp +13 -12
  52. data/ext/libsass/src/emitter.hpp +13 -9
  53. data/ext/libsass/src/environment.cpp +15 -1
  54. data/ext/libsass/src/environment.hpp +6 -0
  55. data/ext/libsass/src/error_handling.cpp +36 -59
  56. data/ext/libsass/src/error_handling.hpp +29 -16
  57. data/ext/libsass/src/eval.cpp +302 -323
  58. data/ext/libsass/src/eval.hpp +64 -55
  59. data/ext/libsass/src/expand.cpp +94 -88
  60. data/ext/libsass/src/expand.hpp +33 -37
  61. data/ext/libsass/src/extend.cpp +38 -36
  62. data/ext/libsass/src/extend.hpp +15 -15
  63. data/ext/libsass/src/file.cpp +34 -2
  64. data/ext/libsass/src/fn_colors.cpp +594 -0
  65. data/ext/libsass/src/fn_colors.hpp +85 -0
  66. data/ext/libsass/src/fn_lists.cpp +284 -0
  67. data/ext/libsass/src/fn_lists.hpp +34 -0
  68. data/ext/libsass/src/fn_maps.cpp +94 -0
  69. data/ext/libsass/src/fn_maps.hpp +30 -0
  70. data/ext/libsass/src/fn_miscs.cpp +256 -0
  71. data/ext/libsass/src/fn_miscs.hpp +40 -0
  72. data/ext/libsass/src/fn_numbers.cpp +220 -0
  73. data/ext/libsass/src/fn_numbers.hpp +45 -0
  74. data/ext/libsass/src/fn_selectors.cpp +235 -0
  75. data/ext/libsass/src/fn_selectors.hpp +35 -0
  76. data/ext/libsass/src/fn_strings.cpp +254 -0
  77. data/ext/libsass/src/fn_strings.hpp +34 -0
  78. data/ext/libsass/src/fn_utils.cpp +156 -0
  79. data/ext/libsass/src/fn_utils.hpp +56 -0
  80. data/ext/libsass/src/inspect.cpp +101 -152
  81. data/ext/libsass/src/inspect.hpp +69 -73
  82. data/ext/libsass/src/json.cpp +2 -2
  83. data/ext/libsass/src/lexer.cpp +6 -3
  84. data/ext/libsass/src/listize.cpp +9 -11
  85. data/ext/libsass/src/listize.hpp +11 -7
  86. data/ext/libsass/src/memory/SharedPtr.cpp +2 -83
  87. data/ext/libsass/src/memory/SharedPtr.hpp +127 -143
  88. data/ext/libsass/src/node.cpp +13 -10
  89. data/ext/libsass/src/node.hpp +3 -3
  90. data/ext/libsass/src/operation.hpp +184 -144
  91. data/ext/libsass/src/operators.cpp +43 -17
  92. data/ext/libsass/src/operators.hpp +5 -5
  93. data/ext/libsass/src/output.cpp +21 -18
  94. data/ext/libsass/src/output.hpp +14 -21
  95. data/ext/libsass/src/parser.cpp +215 -183
  96. data/ext/libsass/src/parser.hpp +28 -24
  97. data/ext/libsass/src/plugins.cpp +5 -1
  98. data/ext/libsass/src/position.cpp +3 -0
  99. data/ext/libsass/src/prelexer.cpp +9 -3
  100. data/ext/libsass/src/prelexer.hpp +9 -9
  101. data/ext/libsass/src/remove_placeholders.cpp +14 -11
  102. data/ext/libsass/src/remove_placeholders.hpp +8 -9
  103. data/ext/libsass/src/sass.cpp +9 -3
  104. data/ext/libsass/src/sass.hpp +12 -9
  105. data/ext/libsass/src/sass2scss.cpp +45 -14
  106. data/ext/libsass/src/sass_context.cpp +18 -15
  107. data/ext/libsass/src/sass_functions.cpp +6 -3
  108. data/ext/libsass/src/sass_functions.hpp +1 -1
  109. data/ext/libsass/src/sass_util.cpp +3 -0
  110. data/ext/libsass/src/sass_values.cpp +21 -13
  111. data/ext/libsass/src/source_map.cpp +5 -2
  112. data/ext/libsass/src/source_map.hpp +2 -2
  113. data/ext/libsass/src/subset_map.cpp +4 -1
  114. data/ext/libsass/src/to_value.cpp +23 -21
  115. data/ext/libsass/src/to_value.hpp +18 -22
  116. data/ext/libsass/src/units.cpp +4 -0
  117. data/ext/libsass/src/units.hpp +1 -0
  118. data/ext/libsass/src/utf8/checked.h +12 -10
  119. data/ext/libsass/src/utf8/core.h +3 -0
  120. data/ext/libsass/src/utf8_string.cpp +3 -0
  121. data/ext/libsass/src/util.cpp +67 -75
  122. data/ext/libsass/src/util.hpp +64 -19
  123. data/ext/libsass/src/util_string.cpp +75 -0
  124. data/ext/libsass/src/util_string.hpp +19 -0
  125. data/ext/libsass/src/values.cpp +22 -13
  126. data/ext/libsass/src/values.hpp +2 -2
  127. data/ext/libsass/win/libsass.targets +30 -4
  128. data/ext/libsass/win/libsass.vcxproj.filters +82 -4
  129. data/lib/sassc.rb +24 -0
  130. data/lib/sassc/engine.rb +2 -2
  131. data/lib/sassc/native.rb +8 -1
  132. data/lib/sassc/version.rb +1 -1
  133. data/sassc.gemspec +19 -11
  134. data/test/engine_test.rb +26 -1
  135. data/test/native_test.rb +1 -1
  136. metadata +66 -72
  137. data/ext/Rakefile +0 -3
  138. data/ext/libsass/.github/CONTRIBUTING.md +0 -65
  139. data/ext/libsass/.github/ISSUE_TEMPLATE.md +0 -54
  140. data/ext/libsass/.travis.yml +0 -64
  141. data/ext/libsass/Readme.md +0 -104
  142. data/ext/libsass/SECURITY.md +0 -10
  143. data/ext/libsass/appveyor.yml +0 -91
  144. data/ext/libsass/docs/README.md +0 -20
  145. data/ext/libsass/docs/api-context-example.md +0 -45
  146. data/ext/libsass/docs/api-context-internal.md +0 -163
  147. data/ext/libsass/docs/api-context.md +0 -295
  148. data/ext/libsass/docs/api-doc.md +0 -215
  149. data/ext/libsass/docs/api-function-example.md +0 -67
  150. data/ext/libsass/docs/api-function-internal.md +0 -8
  151. data/ext/libsass/docs/api-function.md +0 -74
  152. data/ext/libsass/docs/api-importer-example.md +0 -112
  153. data/ext/libsass/docs/api-importer-internal.md +0 -20
  154. data/ext/libsass/docs/api-importer.md +0 -86
  155. data/ext/libsass/docs/api-value-example.md +0 -55
  156. data/ext/libsass/docs/api-value-internal.md +0 -76
  157. data/ext/libsass/docs/api-value.md +0 -154
  158. data/ext/libsass/docs/build-on-darwin.md +0 -27
  159. data/ext/libsass/docs/build-on-gentoo.md +0 -55
  160. data/ext/libsass/docs/build-on-windows.md +0 -139
  161. data/ext/libsass/docs/build-shared-library.md +0 -35
  162. data/ext/libsass/docs/build-with-autotools.md +0 -78
  163. data/ext/libsass/docs/build-with-makefiles.md +0 -68
  164. data/ext/libsass/docs/build-with-mingw.md +0 -107
  165. data/ext/libsass/docs/build-with-visual-studio.md +0 -90
  166. data/ext/libsass/docs/build.md +0 -97
  167. data/ext/libsass/docs/compatibility-plan.md +0 -48
  168. data/ext/libsass/docs/contributing.md +0 -17
  169. data/ext/libsass/docs/custom-functions-internal.md +0 -122
  170. data/ext/libsass/docs/dev-ast-memory.md +0 -223
  171. data/ext/libsass/docs/implementations.md +0 -56
  172. data/ext/libsass/docs/plugins.md +0 -47
  173. data/ext/libsass/docs/setup-environment.md +0 -68
  174. data/ext/libsass/docs/source-map-internals.md +0 -51
  175. data/ext/libsass/docs/trace.md +0 -26
  176. data/ext/libsass/docs/triage.md +0 -17
  177. data/ext/libsass/docs/unicode.md +0 -39
  178. data/ext/libsass/extconf.rb +0 -6
  179. data/ext/libsass/script/bootstrap +0 -13
  180. data/ext/libsass/script/branding +0 -10
  181. data/ext/libsass/script/ci-build-libsass +0 -134
  182. data/ext/libsass/script/ci-build-plugin +0 -62
  183. data/ext/libsass/script/ci-install-compiler +0 -6
  184. data/ext/libsass/script/ci-install-deps +0 -20
  185. data/ext/libsass/script/ci-report-coverage +0 -42
  186. data/ext/libsass/script/spec +0 -5
  187. data/ext/libsass/script/tap-driver +0 -652
  188. data/ext/libsass/script/tap-runner +0 -1
  189. data/ext/libsass/script/test-leaks.pl +0 -103
  190. data/ext/libsass/src/functions.cpp +0 -2234
  191. data/ext/libsass/src/functions.hpp +0 -198
  192. data/ext/libsass/src/to_c.hpp +0 -39
  193. data/ext/libsass/test/test_node.cpp +0 -94
  194. data/ext/libsass/test/test_paths.cpp +0 -28
  195. data/ext/libsass/test/test_selector_difference.cpp +0 -25
  196. data/ext/libsass/test/test_specificity.cpp +0 -25
  197. data/ext/libsass/test/test_subset_map.cpp +0 -472
  198. data/ext/libsass/test/test_superselector.cpp +0 -69
  199. data/ext/libsass/test/test_unification.cpp +0 -31
  200. data/lib/tasks/libsass.rb +0 -33
@@ -7,16 +7,29 @@
7
7
 
8
8
  SOURCES = \
9
9
  ast.cpp \
10
+ ast_values.cpp \
11
+ ast_supports.cpp \
12
+ ast_sel_cmp.cpp \
13
+ ast_sel_unify.cpp \
14
+ ast_selectors.cpp \
10
15
  node.cpp \
11
16
  context.cpp \
12
17
  constants.cpp \
13
- functions.cpp \
18
+ fn_utils.cpp \
19
+ fn_miscs.cpp \
20
+ fn_maps.cpp \
21
+ fn_lists.cpp \
22
+ fn_colors.cpp \
23
+ fn_numbers.cpp \
24
+ fn_strings.cpp \
25
+ fn_selectors.cpp \
14
26
  color_maps.cpp \
15
27
  environment.cpp \
16
28
  ast_fwd_decl.cpp \
17
29
  bind.cpp \
18
30
  file.cpp \
19
31
  util.cpp \
32
+ util_string.cpp \
20
33
  json.cpp \
21
34
  units.cpp \
22
35
  values.cpp \
@@ -43,7 +56,8 @@ SOURCES = \
43
56
  sass2scss.cpp \
44
57
  backtrace.cpp \
45
58
  operators.cpp \
46
- to_c.cpp \
59
+ ast2c.cpp \
60
+ c2ast.cpp \
47
61
  to_value.cpp \
48
62
  source_map.cpp \
49
63
  subset_map.cpp \
@@ -9,6 +9,7 @@ AC_CONFIG_MACRO_DIR([m4])
9
9
  AC_CONFIG_HEADERS([src/config.h])
10
10
  AC_CONFIG_FILES([include/sass/version.h])
11
11
  AC_CONFIG_AUX_DIR([script])
12
+
12
13
  # These are flags passed to automake
13
14
  # Though they look like gcc flags!
14
15
  AM_INIT_AUTOMAKE([foreign parallel-tests -Wall])
@@ -93,21 +94,16 @@ the --with-sass-spec-dir=<dir> argument.
93
94
  ;;
94
95
  esac
95
96
  AC_SUBST(SASS_SPEC_PATH)
96
-
97
- # TODO: Remove this when automake requirements are 1.12+
98
- AC_MSG_CHECKING([whether we can use TAP mode])
99
- tmp=`$AWK '/TEST_LOG_DRIVER/' $srcdir/GNUmakefile.in`
100
- if test "x$tmp" != "x"; then
101
- use_tap=yes
102
- else
103
- use_tap=no
104
- fi
105
- AC_MSG_RESULT([$use_tap])
106
-
97
+ else
98
+ # we do not really need these paths for non test build
99
+ # but automake may error if we do not define them here
100
+ SASS_SPEC_PATH=sass-spec
101
+ SASS_SASSC_PATH=sassc
102
+ AC_SUBST(SASS_SPEC_PATH)
103
+ AC_SUBST(SASS_SASSC_PATH)
107
104
  fi
108
105
 
109
106
  AM_CONDITIONAL(ENABLE_TESTS, test "x$enable_tests" = "xyes")
110
- AM_CONDITIONAL(USE_TAP, test "x$use_tap" = "xyes")
111
107
 
112
108
  AC_ARG_ENABLE([coverage],
113
109
  [AS_HELP_STRING([--enable-coverage],
@@ -1,6 +1,7 @@
1
1
  #ifndef SASS_BASE_H
2
2
  #define SASS_BASE_H
3
3
 
4
+ // #define DEBUG
4
5
  // #define DEBUG_SHARED_PTR
5
6
 
6
7
  #ifdef _MSC_VER
@@ -43,7 +43,7 @@ ADDAPI struct Sass_Compiler* ADDCALL sass_make_file_compiler (struct Sass_File_C
43
43
  ADDAPI struct Sass_Compiler* ADDCALL sass_make_data_compiler (struct Sass_Data_Context* data_ctx);
44
44
 
45
45
  // Execute the different compilation steps individually
46
- // Usefull if you only want to query the included files
46
+ // Useful if you only want to query the included files
47
47
  ADDAPI int ADDCALL sass_compiler_parse(struct Sass_Compiler* compiler);
48
48
  ADDAPI int ADDCALL sass_compiler_execute(struct Sass_Compiler* compiler);
49
49
 
@@ -13,11 +13,7 @@ AM_CFLAGS = $(AM_COPT)
13
13
  AM_CXXFLAGS = $(AM_COPT)
14
14
  AM_LDFLAGS = $(AM_COPT) $(AM_COVLDFLAGS)
15
15
 
16
- if COMPILER_IS_MINGW32
17
- AM_CXXFLAGS += -std=gnu++0x
18
- else
19
- AM_CXXFLAGS += -std=c++0x
20
- endif
16
+ AM_CXXFLAGS += -std=c++11
21
17
 
22
18
  EXTRA_DIST = \
23
19
  COPYING \
@@ -19,1725 +19,678 @@ namespace Sass {
19
19
 
20
20
  static Null sass_null(ParserState("null"));
21
21
 
22
- bool Wrapped_Selector::find ( bool (*f)(AST_Node_Obj) )
23
- {
24
- // check children first
25
- if (selector_) {
26
- if (selector_->find(f)) return true;
27
- }
28
- // execute last
29
- return f(this);
30
- }
31
-
32
- bool Selector_List::find ( bool (*f)(AST_Node_Obj) )
33
- {
34
- // check children first
35
- for (Complex_Selector_Obj sel : elements()) {
36
- if (sel->find(f)) return true;
37
- }
38
- // execute last
39
- return f(this);
40
- }
41
-
42
- bool Compound_Selector::find ( bool (*f)(AST_Node_Obj) )
43
- {
44
- // check children first
45
- for (Simple_Selector_Obj sel : elements()) {
46
- if (sel->find(f)) return true;
47
- }
48
- // execute last
49
- return f(this);
50
- }
51
-
52
- bool Complex_Selector::find ( bool (*f)(AST_Node_Obj) )
53
- {
54
- // check children first
55
- if (head_ && head_->find(f)) return true;
56
- if (tail_ && tail_->find(f)) return true;
57
- // execute last
58
- return f(this);
59
- }
60
-
61
- bool Supports_Operator::needs_parens(Supports_Condition_Obj cond) const {
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
- bool Supports_Negation::needs_parens(Supports_Condition_Obj cond) const {
69
- return Cast<Supports_Negation>(cond) ||
70
- Cast<Supports_Operator>(cond);
71
- }
72
-
73
- void str_rtrim(std::string& str, const std::string& delimiters = " \f\n\r\t\v")
74
- {
75
- str.erase( str.find_last_not_of( delimiters ) + 1 );
76
- }
77
-
78
- void String_Constant::rtrim()
79
- {
80
- str_rtrim(value_);
81
- }
82
-
83
- void String_Schema::rtrim()
84
- {
85
- if (!empty()) {
86
- if (String_Ptr str = Cast<String>(last())) str->rtrim();
87
- }
88
- }
89
-
90
- void Argument::set_delayed(bool delayed)
91
- {
92
- if (value_) value_->set_delayed(delayed);
93
- is_delayed(delayed);
94
- }
95
-
96
- void Arguments::set_delayed(bool delayed)
97
- {
98
- for (Argument_Obj arg : elements()) {
99
- if (arg) arg->set_delayed(delayed);
100
- }
101
- is_delayed(delayed);
102
- }
103
-
104
-
105
- bool At_Root_Query::exclude(std::string str)
106
- {
107
- bool with = feature() && unquote(feature()->to_string()).compare("with") == 0;
108
- List_Ptr l = static_cast<List_Ptr>(value().ptr());
109
- std::string v;
110
-
111
- if (with)
112
- {
113
- if (!l || l->length() == 0) return str.compare("rule") != 0;
114
- for (size_t i = 0, L = l->length(); i < L; ++i)
115
- {
116
- v = unquote((*l)[i]->to_string());
117
- if (v.compare("all") == 0 || v == str) return false;
118
- }
119
- return true;
120
- }
121
- else
122
- {
123
- if (!l || !l->length()) return str.compare("rule") == 0;
124
- for (size_t i = 0, L = l->length(); i < L; ++i)
125
- {
126
- v = unquote((*l)[i]->to_string());
127
- if (v.compare("all") == 0 || v == str) return true;
128
- }
129
- return false;
130
- }
131
- }
22
+ const char* sass_op_to_name(enum Sass_OP op) {
23
+ switch (op) {
24
+ case AND: return "and";
25
+ case OR: return "or";
26
+ case EQ: return "eq";
27
+ case NEQ: return "neq";
28
+ case GT: return "gt";
29
+ case GTE: return "gte";
30
+ case LT: return "lt";
31
+ case LTE: return "lte";
32
+ case ADD: return "plus";
33
+ case SUB: return "minus";
34
+ case MUL: return "times";
35
+ case DIV: return "div";
36
+ case MOD: return "mod";
37
+ // this is only used internally!
38
+ case NUM_OPS: return "[OPS]";
39
+ default: return "invalid";
40
+ }
41
+ }
42
+
43
+ const char* sass_op_separator(enum Sass_OP op) {
44
+ switch (op) {
45
+ case AND: return "&&";
46
+ case OR: return "||";
47
+ case EQ: return "==";
48
+ case NEQ: return "!=";
49
+ case GT: return ">";
50
+ case GTE: return ">=";
51
+ case LT: return "<";
52
+ case LTE: return "<=";
53
+ case ADD: return "+";
54
+ case SUB: return "-";
55
+ case MUL: return "*";
56
+ case DIV: return "/";
57
+ case MOD: return "%";
58
+ // this is only used internally!
59
+ case NUM_OPS: return "[OPS]";
60
+ default: return "invalid";
61
+ }
62
+ }
63
+
64
+ /////////////////////////////////////////////////////////////////////////
65
+ /////////////////////////////////////////////////////////////////////////
132
66
 
133
67
  void AST_Node::update_pstate(const ParserState& pstate)
134
68
  {
135
69
  pstate_.offset += pstate - pstate_ + pstate.offset;
136
70
  }
137
71
 
138
- bool Simple_Selector::is_ns_eq(const Simple_Selector& r) const
139
- {
140
- // https://github.com/sass/sass/issues/2229
141
- if ((has_ns_ == r.has_ns_) ||
142
- (has_ns_ && ns_.empty()) ||
143
- (r.has_ns_ && r.ns_.empty())
144
- ) {
145
- if (ns_.empty() && r.ns() == "*") return false;
146
- else if (r.ns().empty() && ns() == "*") return false;
147
- else return ns() == r.ns();
148
- }
149
- return false;
150
- }
151
-
152
- bool Compound_Selector::operator< (const Compound_Selector& rhs) const
153
- {
154
- size_t L = std::min(length(), rhs.length());
155
- for (size_t i = 0; i < L; ++i)
156
- {
157
- Simple_Selector_Obj l = (*this)[i];
158
- Simple_Selector_Obj r = rhs[i];
159
- if (!l && !r) return false;
160
- else if (!r) return false;
161
- else if (!l) return true;
162
- else if (*l != *r)
163
- { return *l < *r; }
164
- }
165
- // just compare the length now
166
- return length() < rhs.length();
167
- }
168
-
169
- bool Compound_Selector::has_parent_ref() const
170
- {
171
- for (Simple_Selector_Obj s : *this) {
172
- if (s && s->has_parent_ref()) return true;
173
- }
174
- return false;
175
- }
176
-
177
- bool Compound_Selector::has_real_parent_ref() const
178
- {
179
- for (Simple_Selector_Obj s : *this) {
180
- if (s && s->has_real_parent_ref()) return true;
181
- }
182
- return false;
183
- }
184
-
185
- bool Complex_Selector::has_parent_ref() const
186
- {
187
- return (head() && head()->has_parent_ref()) ||
188
- (tail() && tail()->has_parent_ref());
189
- }
190
-
191
- bool Complex_Selector::has_real_parent_ref() const
192
- {
193
- return (head() && head()->has_real_parent_ref()) ||
194
- (tail() && tail()->has_real_parent_ref());
195
- }
196
-
197
- bool Complex_Selector::operator< (const Complex_Selector& rhs) const
198
- {
199
- // const iterators for tails
200
- Complex_Selector_Ptr_Const l = this;
201
- Complex_Selector_Ptr_Const r = &rhs;
202
- Compound_Selector_Ptr l_h = NULL;
203
- Compound_Selector_Ptr r_h = NULL;
204
- if (l) l_h = l->head();
205
- if (r) r_h = r->head();
206
- // process all tails
207
- while (true)
208
- {
209
- #ifdef DEBUG
210
- // skip empty ancestor first
211
- if (l && l->is_empty_ancestor())
212
- {
213
- l_h = NULL;
214
- l = l->tail();
215
- if(l) l_h = l->head();
216
- continue;
217
- }
218
- // skip empty ancestor first
219
- if (r && r->is_empty_ancestor())
220
- {
221
- r_h = NULL;
222
- r = r->tail();
223
- if (r) r_h = r->head();
224
- continue;
225
- }
226
- #endif
227
- // check for valid selectors
228
- if (!l) return !!r;
229
- if (!r) return false;
230
- // both are null
231
- else if (!l_h && !r_h)
232
- {
233
- // check combinator after heads
234
- if (l->combinator() != r->combinator())
235
- { return l->combinator() < r->combinator(); }
236
- // advance to next tails
237
- l = l->tail();
238
- r = r->tail();
239
- // fetch the next headers
240
- l_h = NULL; r_h = NULL;
241
- if (l) l_h = l->head();
242
- if (r) r_h = r->head();
243
- }
244
- // one side is null
245
- else if (!r_h) return true;
246
- else if (!l_h) return false;
247
- // heads ok and equal
248
- else if (*l_h == *r_h)
249
- {
250
- // check combinator after heads
251
- if (l->combinator() != r->combinator())
252
- { return l->combinator() < r->combinator(); }
253
- // advance to next tails
254
- l = l->tail();
255
- r = r->tail();
256
- // fetch the next headers
257
- l_h = NULL; r_h = NULL;
258
- if (l) l_h = l->head();
259
- if (r) r_h = r->head();
260
- }
261
- // heads are not equal
262
- else return *l_h < *r_h;
263
- }
264
- }
265
-
266
- bool Complex_Selector::operator== (const Complex_Selector& rhs) const
267
- {
268
- // const iterators for tails
269
- Complex_Selector_Ptr_Const l = this;
270
- Complex_Selector_Ptr_Const r = &rhs;
271
- Compound_Selector_Ptr l_h = NULL;
272
- Compound_Selector_Ptr r_h = NULL;
273
- if (l) l_h = l->head();
274
- if (r) r_h = r->head();
275
- // process all tails
276
- while (true)
277
- {
278
- #ifdef DEBUG
279
- // skip empty ancestor first
280
- if (l && l->is_empty_ancestor())
281
- {
282
- l_h = NULL;
283
- l = l->tail();
284
- if (l) l_h = l->head();
285
- continue;
286
- }
287
- // skip empty ancestor first
288
- if (r && r->is_empty_ancestor())
289
- {
290
- r_h = NULL;
291
- r = r->tail();
292
- if (r) r_h = r->head();
293
- continue;
294
- }
295
- #endif
296
- // check the pointers
297
- if (!r) return !l;
298
- if (!l) return !r;
299
- // both are null
300
- if (!l_h && !r_h)
301
- {
302
- // check combinator after heads
303
- if (l->combinator() != r->combinator())
304
- { return l->combinator() < r->combinator(); }
305
- // advance to next tails
306
- l = l->tail();
307
- r = r->tail();
308
- // fetch the next heads
309
- l_h = NULL; r_h = NULL;
310
- if (l) l_h = l->head();
311
- if (r) r_h = r->head();
312
- }
313
- // equals if other head is empty
314
- else if ((!l_h && !r_h) ||
315
- (!l_h && r_h->empty()) ||
316
- (!r_h && l_h->empty()) ||
317
- (l_h && r_h && *l_h == *r_h))
318
- {
319
- // check combinator after heads
320
- if (l->combinator() != r->combinator())
321
- { return l->combinator() == r->combinator(); }
322
- // advance to next tails
323
- l = l->tail();
324
- r = r->tail();
325
- // fetch the next heads
326
- l_h = NULL; r_h = NULL;
327
- if (l) l_h = l->head();
328
- if (r) r_h = r->head();
329
- }
330
- // abort
331
- else break;
332
- }
333
- // unreachable
334
- return false;
335
- }
336
-
337
- Compound_Selector_Ptr Compound_Selector::unify_with(Compound_Selector_Ptr rhs)
338
- {
339
- if (empty()) return rhs;
340
- Compound_Selector_Obj unified = SASS_MEMORY_COPY(rhs);
341
- for (size_t i = 0, L = length(); i < L; ++i)
342
- {
343
- if (unified.isNull()) break;
344
- unified = at(i)->unify_with(unified);
345
- }
346
- return unified.detach();
347
- }
348
-
349
- bool Complex_Selector::operator== (const Selector& rhs) const
350
- {
351
- if (const Selector_List* sl = Cast<Selector_List>(&rhs)) return *this == *sl;
352
- if (const Simple_Selector* sp = Cast<Simple_Selector>(&rhs)) return *this == *sp;
353
- if (const Complex_Selector* cs = Cast<Complex_Selector>(&rhs)) return *this == *cs;
354
- if (const Compound_Selector* ch = Cast<Compound_Selector>(&rhs)) return *this == *ch;
355
- throw std::runtime_error("invalid selector base classes to compare");
356
- }
357
-
358
-
359
- bool Complex_Selector::operator< (const Selector& rhs) const
360
- {
361
- if (const Selector_List* sl = Cast<Selector_List>(&rhs)) return *this < *sl;
362
- if (const Simple_Selector* sp = Cast<Simple_Selector>(&rhs)) return *this < *sp;
363
- if (const Complex_Selector* cs = Cast<Complex_Selector>(&rhs)) return *this < *cs;
364
- if (const Compound_Selector* ch = Cast<Compound_Selector>(&rhs)) return *this < *ch;
365
- throw std::runtime_error("invalid selector base classes to compare");
366
- }
367
-
368
- bool Compound_Selector::operator== (const Selector& rhs) const
369
- {
370
- if (const Selector_List* sl = Cast<Selector_List>(&rhs)) return *this == *sl;
371
- if (const Simple_Selector* sp = Cast<Simple_Selector>(&rhs)) return *this == *sp;
372
- if (const Complex_Selector* cs = Cast<Complex_Selector>(&rhs)) return *this == *cs;
373
- if (const Compound_Selector* ch = Cast<Compound_Selector>(&rhs)) return *this == *ch;
374
- throw std::runtime_error("invalid selector base classes to compare");
375
- }
376
-
377
- bool Compound_Selector::operator< (const Selector& rhs) const
378
- {
379
- if (const Selector_List* sl = Cast<Selector_List>(&rhs)) return *this < *sl;
380
- if (const Simple_Selector* sp = Cast<Simple_Selector>(&rhs)) return *this < *sp;
381
- if (const Complex_Selector* cs = Cast<Complex_Selector>(&rhs)) return *this < *cs;
382
- if (const Compound_Selector* ch = Cast<Compound_Selector>(&rhs)) return *this < *ch;
383
- throw std::runtime_error("invalid selector base classes to compare");
384
- }
385
-
386
- bool Selector_Schema::operator== (const Selector& rhs) const
387
- {
388
- if (const Selector_List* sl = Cast<Selector_List>(&rhs)) return *this == *sl;
389
- if (const Simple_Selector* sp = Cast<Simple_Selector>(&rhs)) return *this == *sp;
390
- if (const Complex_Selector* cs = Cast<Complex_Selector>(&rhs)) return *this == *cs;
391
- if (const Compound_Selector* ch = Cast<Compound_Selector>(&rhs)) return *this == *ch;
392
- throw std::runtime_error("invalid selector base classes to compare");
393
- }
394
-
395
- bool Selector_Schema::operator< (const Selector& rhs) const
396
- {
397
- if (const Selector_List* sl = Cast<Selector_List>(&rhs)) return *this < *sl;
398
- if (const Simple_Selector* sp = Cast<Simple_Selector>(&rhs)) return *this < *sp;
399
- if (const Complex_Selector* cs = Cast<Complex_Selector>(&rhs)) return *this < *cs;
400
- if (const Compound_Selector* ch = Cast<Compound_Selector>(&rhs)) return *this < *ch;
401
- throw std::runtime_error("invalid selector base classes to compare");
402
- }
403
-
404
- bool Simple_Selector::operator== (const Selector& rhs) const
405
- {
406
- if (Simple_Selector_Ptr_Const sp = Cast<Simple_Selector>(&rhs)) return *this == *sp;
407
- return false;
408
- }
409
-
410
- bool Simple_Selector::operator< (const Selector& rhs) const
411
- {
412
- if (Simple_Selector_Ptr_Const sp = Cast<Simple_Selector>(&rhs)) return *this < *sp;
413
- return false;
414
- }
415
-
416
- bool Simple_Selector::operator== (const Simple_Selector& rhs) const
417
- {
418
- // solve the double dispatch problem by using RTTI information via dynamic cast
419
- if (const Pseudo_Selector* lhs = Cast<Pseudo_Selector>(this)) {return *lhs == rhs; }
420
- else if (const Wrapped_Selector* lhs = Cast<Wrapped_Selector>(this)) {return *lhs == rhs; }
421
- else if (const Element_Selector* lhs = Cast<Element_Selector>(this)) {return *lhs == rhs; }
422
- else if (const Attribute_Selector* lhs = Cast<Attribute_Selector>(this)) {return *lhs == rhs; }
423
- else if (name_ == rhs.name_)
424
- { return is_ns_eq(rhs); }
425
- else return false;
426
- }
427
-
428
- bool Simple_Selector::operator< (const Simple_Selector& rhs) const
429
- {
430
- // solve the double dispatch problem by using RTTI information via dynamic cast
431
- if (const Pseudo_Selector* lhs = Cast<Pseudo_Selector>(this)) {return *lhs < rhs; }
432
- else if (const Wrapped_Selector* lhs = Cast<Wrapped_Selector>(this)) {return *lhs < rhs; }
433
- else if (const Element_Selector* lhs = Cast<Element_Selector>(this)) {return *lhs < rhs; }
434
- else if (const Attribute_Selector* lhs = Cast<Attribute_Selector>(this)) {return *lhs < rhs; }
435
- if (is_ns_eq(rhs))
436
- { return name_ < rhs.name_; }
437
- return ns_ < rhs.ns_;
438
- }
439
-
440
- bool Selector_List::operator== (const Selector& rhs) const
441
- {
442
- // solve the double dispatch problem by using RTTI information via dynamic cast
443
- if (Selector_List_Ptr_Const sl = Cast<Selector_List>(&rhs)) { return *this == *sl; }
444
- else if (Complex_Selector_Ptr_Const cpx = Cast<Complex_Selector>(&rhs)) { return *this == *cpx; }
445
- else if (Compound_Selector_Ptr_Const cpd = Cast<Compound_Selector>(&rhs)) { return *this == *cpd; }
446
- // no compare method
447
- return this == &rhs;
448
- }
449
-
450
- // Selector lists can be compared to comma lists
451
- bool Selector_List::operator== (const Expression& rhs) const
452
- {
453
- // solve the double dispatch problem by using RTTI information via dynamic cast
454
- if (List_Ptr_Const ls = Cast<List>(&rhs)) { return *ls == *this; }
455
- if (Selector_Ptr_Const ls = Cast<Selector>(&rhs)) { return *this == *ls; }
456
- // compare invalid (maybe we should error?)
457
- return false;
458
- }
459
-
460
- bool Selector_List::operator== (const Selector_List& rhs) const
461
- {
462
- // for array access
463
- size_t i = 0, n = 0;
464
- size_t iL = length();
465
- size_t nL = rhs.length();
466
- // create temporary vectors and sort them
467
- std::vector<Complex_Selector_Obj> l_lst = this->elements();
468
- std::vector<Complex_Selector_Obj> r_lst = rhs.elements();
469
- std::sort(l_lst.begin(), l_lst.end(), OrderNodes());
470
- std::sort(r_lst.begin(), r_lst.end(), OrderNodes());
471
- // process loop
472
- while (true)
473
- {
474
- // first check for valid index
475
- if (i == iL) return iL == nL;
476
- else if (n == nL) return iL == nL;
477
- // the access the vector items
478
- Complex_Selector_Obj l = l_lst[i];
479
- Complex_Selector_Obj r = r_lst[n];
480
- // skip nulls
481
- if (!l) ++i;
482
- else if (!r) ++n;
483
- // do the check
484
- else if (*l != *r)
485
- { return false; }
486
- // advance
487
- ++i; ++n;
488
- }
489
- // there is no break?!
490
- }
491
-
492
- bool Selector_List::operator< (const Selector& rhs) const
493
- {
494
- if (Selector_List_Ptr_Const sp = Cast<Selector_List>(&rhs)) return *this < *sp;
495
- return false;
496
- }
497
-
498
- bool Selector_List::operator< (const Selector_List& rhs) const
499
- {
500
- size_t l = rhs.length();
501
- if (length() < l) l = length();
502
- for (size_t i = 0; i < l; i ++) {
503
- if (*at(i) < *rhs.at(i)) return true;
504
- }
505
- return false;
506
- }
507
-
508
- Compound_Selector_Ptr Simple_Selector::unify_with(Compound_Selector_Ptr rhs)
509
- {
510
- for (size_t i = 0, L = rhs->length(); i < L; ++i)
511
- { if (to_string() == rhs->at(i)->to_string()) return rhs; }
512
-
513
- // check for pseudo elements because they are always last
514
- size_t i, L;
515
- bool found = false;
516
- if (typeid(*this) == typeid(Pseudo_Selector) || typeid(*this) == typeid(Wrapped_Selector) || typeid(*this) == typeid(Attribute_Selector))
517
- {
518
- for (i = 0, L = rhs->length(); i < L; ++i)
519
- {
520
- if ((Cast<Pseudo_Selector>((*rhs)[i]) || Cast<Wrapped_Selector>((*rhs)[i]) || Cast<Attribute_Selector>((*rhs)[i])) && (*rhs)[L-1]->is_pseudo_element())
521
- { found = true; break; }
522
- }
523
- }
524
- else
525
- {
526
- for (i = 0, L = rhs->length(); i < L; ++i)
527
- {
528
- if (Cast<Pseudo_Selector>((*rhs)[i]) || Cast<Wrapped_Selector>((*rhs)[i]) || Cast<Attribute_Selector>((*rhs)[i]))
529
- { found = true; break; }
530
- }
531
- }
532
- if (!found)
533
- {
534
- rhs->append(this);
535
- } else {
536
- rhs->elements().insert(rhs->elements().begin() + i, this);
537
- }
538
- return rhs;
539
- }
540
-
541
- Simple_Selector_Ptr Element_Selector::unify_with(Simple_Selector_Ptr rhs)
542
- {
543
- // check if ns can be extended
544
- // true for no ns or universal
545
- if (has_universal_ns())
546
- {
547
- // but dont extend with universal
548
- // true for valid ns and universal
549
- if (!rhs->is_universal_ns())
550
- {
551
- // overwrite the name if star is given as name
552
- if (this->name() == "*") { this->name(rhs->name()); }
553
- // now overwrite the namespace name and flag
554
- this->ns(rhs->ns()); this->has_ns(rhs->has_ns());
555
- // return copy
556
- return this;
557
- }
558
- }
559
- // namespace may changed, check the name now
560
- // overwrite star (but not with another star)
561
- if (name() == "*" && rhs->name() != "*")
562
- {
563
- // simply set the new name
564
- this->name(rhs->name());
565
- // return copy
566
- return this;
567
- }
568
- // return original
569
- return this;
570
- }
571
-
572
- Compound_Selector_Ptr Element_Selector::unify_with(Compound_Selector_Ptr rhs)
573
- {
574
- // TODO: handle namespaces
575
-
576
- // if the rhs is empty, just return a copy of this
577
- if (rhs->length() == 0) {
578
- rhs->append(this);
579
- return rhs;
580
- }
581
-
582
- Simple_Selector_Ptr rhs_0 = rhs->at(0);
583
- // otherwise, this is a tag name
584
- if (name() == "*")
585
- {
586
- if (typeid(*rhs_0) == typeid(Element_Selector))
587
- {
588
- // if rhs is universal, just return this tagname + rhs's qualifiers
589
- Element_Selector_Ptr ts = Cast<Element_Selector>(rhs_0);
590
- rhs->at(0) = this->unify_with(ts);
591
- return rhs;
592
- }
593
- else if (Cast<Class_Selector>(rhs_0) || Cast<Id_Selector>(rhs_0)) {
594
- // qualifier is `.class`, so we can prefix with `ns|*.class`
595
- if (has_ns() && !rhs_0->has_ns()) {
596
- if (ns() != "*") rhs->elements().insert(rhs->begin(), this);
597
- }
598
- return rhs;
599
- }
600
-
601
-
602
- return rhs;
603
- }
604
-
605
- if (typeid(*rhs_0) == typeid(Element_Selector))
606
- {
607
- // if rhs is universal, just return this tagname + rhs's qualifiers
608
- if (rhs_0->name() != "*" && rhs_0->ns() != "*" && rhs_0->name() != name()) return 0;
609
- // otherwise create new compound and unify first simple selector
610
- rhs->at(0) = this->unify_with(rhs_0);
611
- return rhs;
612
-
613
- }
614
- // else it's a tag name and a bunch of qualifiers -- just append them
615
- if (name() != "*") rhs->elements().insert(rhs->begin(), this);
616
- return rhs;
617
- }
618
-
619
- Compound_Selector_Ptr Class_Selector::unify_with(Compound_Selector_Ptr rhs)
620
- {
621
- rhs->has_line_break(has_line_break());
622
- return Simple_Selector::unify_with(rhs);
623
- }
624
-
625
- Compound_Selector_Ptr Id_Selector::unify_with(Compound_Selector_Ptr rhs)
626
- {
627
- for (size_t i = 0, L = rhs->length(); i < L; ++i)
628
- {
629
- if (Id_Selector_Ptr sel = Cast<Id_Selector>(rhs->at(i))) {
630
- if (sel->name() != name()) return 0;
631
- }
632
- }
633
- rhs->has_line_break(has_line_break());
634
- return Simple_Selector::unify_with(rhs);
635
- }
636
-
637
- Compound_Selector_Ptr Pseudo_Selector::unify_with(Compound_Selector_Ptr rhs)
638
- {
639
- if (is_pseudo_element())
640
- {
641
- for (size_t i = 0, L = rhs->length(); i < L; ++i)
642
- {
643
- if (Pseudo_Selector_Ptr sel = Cast<Pseudo_Selector>(rhs->at(i))) {
644
- if (sel->is_pseudo_element() && sel->name() != name()) return 0;
645
- }
646
- }
647
- }
648
- return Simple_Selector::unify_with(rhs);
649
- }
650
-
651
- bool Attribute_Selector::operator< (const Attribute_Selector& rhs) const
652
- {
653
- if (is_ns_eq(rhs)) {
654
- if (name() == rhs.name()) {
655
- if (matcher() == rhs.matcher()) {
656
- bool no_lhs_val = value().isNull();
657
- bool no_rhs_val = rhs.value().isNull();
658
- if (no_lhs_val && no_rhs_val) return false; // equal
659
- else if (no_lhs_val) return true; // lhs is null
660
- else if (no_rhs_val) return false; // rhs is null
661
- return *value() < *rhs.value(); // both are given
662
- } else { return matcher() < rhs.matcher(); }
663
- } else { return name() < rhs.name(); }
664
- } else { return ns() < rhs.ns(); }
665
- }
666
-
667
- bool Attribute_Selector::operator< (const Simple_Selector& rhs) const
668
- {
669
- if (Attribute_Selector_Ptr_Const w = Cast<Attribute_Selector>(&rhs))
670
- {
671
- return *this < *w;
672
- }
673
- if (is_ns_eq(rhs))
674
- { return name() < rhs.name(); }
675
- return ns() < rhs.ns();
676
- }
677
-
678
- bool Attribute_Selector::operator== (const Attribute_Selector& rhs) const
679
- {
680
- // get optional value state
681
- bool no_lhs_val = value().isNull();
682
- bool no_rhs_val = rhs.value().isNull();
683
- // both are null, therefore equal
684
- if (no_lhs_val && no_rhs_val) {
685
- return (name() == rhs.name())
686
- && (matcher() == rhs.matcher())
687
- && (is_ns_eq(rhs));
688
- }
689
- // both are defined, evaluate
690
- if (no_lhs_val == no_rhs_val) {
691
- return (name() == rhs.name())
692
- && (matcher() == rhs.matcher())
693
- && (is_ns_eq(rhs))
694
- && (*value() == *rhs.value());
695
- }
696
- // not equal
697
- return false;
698
-
699
- }
700
-
701
- bool Attribute_Selector::operator== (const Simple_Selector& rhs) const
702
- {
703
- if (Attribute_Selector_Ptr_Const w = Cast<Attribute_Selector>(&rhs))
704
- {
705
- return is_ns_eq(rhs) &&
706
- name() == rhs.name() &&
707
- *this == *w;
708
- }
709
- return false;
710
- }
711
-
712
- bool Element_Selector::operator< (const Element_Selector& rhs) const
713
- {
714
- if (is_ns_eq(rhs))
715
- { return name() < rhs.name(); }
716
- return ns() < rhs.ns();
717
- }
718
-
719
- bool Element_Selector::operator< (const Simple_Selector& rhs) const
720
- {
721
- if (Element_Selector_Ptr_Const w = Cast<Element_Selector>(&rhs))
722
- {
723
- return *this < *w;
724
- }
725
- if (is_ns_eq(rhs))
726
- { return name() < rhs.name(); }
727
- return ns() < rhs.ns();
728
- }
729
-
730
- bool Element_Selector::operator== (const Element_Selector& rhs) const
731
- {
732
- return is_ns_eq(rhs) &&
733
- name() == rhs.name();
734
- }
735
-
736
- bool Element_Selector::operator== (const Simple_Selector& rhs) const
737
- {
738
- if (Element_Selector_Ptr_Const w = Cast<Element_Selector>(&rhs))
739
- {
740
- return is_ns_eq(rhs) &&
741
- name() == rhs.name() &&
742
- *this == *w;
743
- }
744
- return false;
745
- }
746
-
747
- bool Pseudo_Selector::operator== (const Pseudo_Selector& rhs) const
748
- {
749
- if (is_ns_eq(rhs) && name() == rhs.name())
750
- {
751
- String_Obj lhs_ex = expression();
752
- String_Obj rhs_ex = rhs.expression();
753
- if (rhs_ex && lhs_ex) return *lhs_ex == *rhs_ex;
754
- else return lhs_ex.ptr() == rhs_ex.ptr();
755
- }
756
- else return false;
757
- }
758
-
759
- bool Pseudo_Selector::operator== (const Simple_Selector& rhs) const
760
- {
761
- if (Pseudo_Selector_Ptr_Const w = Cast<Pseudo_Selector>(&rhs))
762
- {
763
- return *this == *w;
764
- }
765
- return is_ns_eq(rhs) &&
766
- name() == rhs.name();
767
- }
768
-
769
- bool Pseudo_Selector::operator< (const Pseudo_Selector& rhs) const
770
- {
771
- if (is_ns_eq(rhs) && name() == rhs.name())
772
- {
773
- String_Obj lhs_ex = expression();
774
- String_Obj rhs_ex = rhs.expression();
775
- if (rhs_ex && lhs_ex) return *lhs_ex < *rhs_ex;
776
- else return lhs_ex.ptr() < rhs_ex.ptr();
777
- }
778
- if (is_ns_eq(rhs))
779
- { return name() < rhs.name(); }
780
- return ns() < rhs.ns();
781
- }
782
-
783
- bool Pseudo_Selector::operator< (const Simple_Selector& rhs) const
784
- {
785
- if (Pseudo_Selector_Ptr_Const w = Cast<Pseudo_Selector>(&rhs))
786
- {
787
- return *this < *w;
788
- }
789
- if (is_ns_eq(rhs))
790
- { return name() < rhs.name(); }
791
- return ns() < rhs.ns();
792
- }
793
-
794
- bool Wrapped_Selector::operator== (const Wrapped_Selector& rhs) const
795
- {
796
- if (is_ns_eq(rhs) && name() == rhs.name())
797
- { return *(selector()) == *(rhs.selector()); }
798
- else return false;
799
- }
800
-
801
- bool Wrapped_Selector::operator== (const Simple_Selector& rhs) const
802
- {
803
- if (Wrapped_Selector_Ptr_Const w = Cast<Wrapped_Selector>(&rhs))
804
- {
805
- return *this == *w;
806
- }
807
- return is_ns_eq(rhs) &&
808
- name() == rhs.name();
809
- }
810
-
811
- bool Wrapped_Selector::operator< (const Wrapped_Selector& rhs) const
812
- {
813
- if (is_ns_eq(rhs) && name() == rhs.name())
814
- { return *(selector()) < *(rhs.selector()); }
815
- if (is_ns_eq(rhs))
816
- { return name() < rhs.name(); }
817
- return ns() < rhs.ns();
818
- }
819
-
820
- bool Wrapped_Selector::operator< (const Simple_Selector& rhs) const
821
- {
822
- if (Wrapped_Selector_Ptr_Const w = Cast<Wrapped_Selector>(&rhs))
823
- {
824
- return *this < *w;
825
- }
826
- if (is_ns_eq(rhs))
827
- { return name() < rhs.name(); }
828
- return ns() < rhs.ns();
829
- }
830
-
831
- bool Wrapped_Selector::is_superselector_of(Wrapped_Selector_Obj sub)
832
- {
833
- if (this->name() != sub->name()) return false;
834
- if (this->name() == ":current") return false;
835
- if (Selector_List_Obj rhs_list = Cast<Selector_List>(sub->selector())) {
836
- if (Selector_List_Obj lhs_list = Cast<Selector_List>(selector())) {
837
- return lhs_list->is_superselector_of(rhs_list);
838
- }
839
- }
840
- coreError("is_superselector expected a Selector_List", sub->pstate());
841
- return false;
842
- }
843
-
844
- bool Compound_Selector::is_superselector_of(Selector_List_Obj rhs, std::string wrapped)
845
- {
846
- for (Complex_Selector_Obj item : rhs->elements()) {
847
- if (is_superselector_of(item, wrapped)) return true;
848
- }
849
- return false;
850
- }
851
-
852
- bool Compound_Selector::is_superselector_of(Complex_Selector_Obj rhs, std::string wrapped)
853
- {
854
- if (rhs->head()) return is_superselector_of(rhs->head(), wrapped);
855
- return false;
856
- }
857
-
858
- bool Compound_Selector::is_superselector_of(Compound_Selector_Obj rhs, std::string wrapping)
859
- {
860
- Compound_Selector_Ptr lhs = this;
861
- Simple_Selector_Ptr lbase = lhs->base();
862
- Simple_Selector_Ptr rbase = rhs->base();
863
-
864
- // Check if pseudo-elements are the same between the selectors
865
-
866
- std::set<std::string> lpsuedoset, rpsuedoset;
867
- for (size_t i = 0, L = length(); i < L; ++i)
868
- {
869
- if ((*this)[i]->is_pseudo_element()) {
870
- std::string pseudo((*this)[i]->to_string());
871
- pseudo = pseudo.substr(pseudo.find_first_not_of(":")); // strip off colons to ensure :after matches ::after since ruby sass is forgiving
872
- lpsuedoset.insert(pseudo);
873
- }
874
- }
875
- for (size_t i = 0, L = rhs->length(); i < L; ++i)
876
- {
877
- if ((*rhs)[i]->is_pseudo_element()) {
878
- std::string pseudo((*rhs)[i]->to_string());
879
- pseudo = pseudo.substr(pseudo.find_first_not_of(":")); // strip off colons to ensure :after matches ::after since ruby sass is forgiving
880
- rpsuedoset.insert(pseudo);
881
- }
882
- }
883
- if (lpsuedoset != rpsuedoset) {
884
- return false;
885
- }
886
-
887
- // would like to replace this without stringification
888
- // https://github.com/sass/sass/issues/2229
889
- // SimpleSelectorSet lset, rset;
890
- std::set<std::string> lset, rset;
891
-
892
- if (lbase && rbase)
893
- {
894
- if (lbase->to_string() == rbase->to_string()) {
895
- for (size_t i = 1, L = length(); i < L; ++i)
896
- { lset.insert((*this)[i]->to_string()); }
897
- for (size_t i = 1, L = rhs->length(); i < L; ++i)
898
- { rset.insert((*rhs)[i]->to_string()); }
899
- return includes(rset.begin(), rset.end(), lset.begin(), lset.end());
900
- }
901
- return false;
902
- }
903
-
904
- for (size_t i = 0, iL = length(); i < iL; ++i)
905
- {
906
- Selector_Obj wlhs = (*this)[i];
907
- // very special case for wrapped matches selector
908
- if (Wrapped_Selector_Obj wrapped = Cast<Wrapped_Selector>(wlhs)) {
909
- if (wrapped->name() == ":not") {
910
- if (Selector_List_Obj not_list = Cast<Selector_List>(wrapped->selector())) {
911
- if (not_list->is_superselector_of(rhs, wrapped->name())) return false;
912
- } else {
913
- throw std::runtime_error("wrapped not selector is not a list");
914
- }
915
- }
916
- if (wrapped->name() == ":matches" || wrapped->name() == ":-moz-any") {
917
- wlhs = wrapped->selector();
918
- if (Selector_List_Obj list = Cast<Selector_List>(wrapped->selector())) {
919
- if (Compound_Selector_Obj comp = Cast<Compound_Selector>(rhs)) {
920
- if (!wrapping.empty() && wrapping != wrapped->name()) return false;
921
- if (wrapping.empty() || wrapping != wrapped->name()) {;
922
- if (list->is_superselector_of(comp, wrapped->name())) return true;
923
- }
924
- }
925
- }
926
- }
927
- Simple_Selector_Ptr rhs_sel = NULL;
928
- if (rhs->elements().size() > i) rhs_sel = (*rhs)[i];
929
- if (Wrapped_Selector_Ptr wrapped_r = Cast<Wrapped_Selector>(rhs_sel)) {
930
- if (wrapped->name() == wrapped_r->name()) {
931
- if (wrapped->is_superselector_of(wrapped_r)) {
932
- continue;
933
- }}
934
- }
935
- }
936
- // match from here on as strings
937
- lset.insert(wlhs->to_string());
938
- }
939
-
940
- for (size_t n = 0, nL = rhs->length(); n < nL; ++n)
941
- {
942
- Selector_Obj r = (*rhs)[n];
943
- if (Wrapped_Selector_Obj wrapped = Cast<Wrapped_Selector>(r)) {
944
- if (wrapped->name() == ":not") {
945
- if (Selector_List_Obj ls = Cast<Selector_List>(wrapped->selector())) {
946
- ls->remove_parent_selectors();
947
- if (is_superselector_of(ls, wrapped->name())) return false;
948
- }
949
- }
950
- if (wrapped->name() == ":matches" || wrapped->name() == ":-moz-any") {
951
- if (!wrapping.empty()) {
952
- if (wrapping != wrapped->name()) return false;
953
- }
954
- if (Selector_List_Obj ls = Cast<Selector_List>(wrapped->selector())) {
955
- ls->remove_parent_selectors();
956
- return (is_superselector_of(ls, wrapped->name()));
957
- }
958
- }
959
- }
960
- rset.insert(r->to_string());
961
- }
962
-
963
- //for (auto l : lset) { cerr << "l: " << l << endl; }
964
- //for (auto r : rset) { cerr << "r: " << r << endl; }
965
-
966
- if (lset.empty()) return true;
967
- // return true if rset contains all the elements of lset
968
- return includes(rset.begin(), rset.end(), lset.begin(), lset.end());
969
-
970
- }
971
-
972
- // create complex selector (ancestor of) from compound selector
973
- Complex_Selector_Obj Compound_Selector::to_complex()
974
- {
975
- // create an intermediate complex selector
976
- return SASS_MEMORY_NEW(Complex_Selector,
977
- pstate(),
978
- Complex_Selector::ANCESTOR_OF,
979
- this,
980
- 0);
981
- }
982
-
983
- Selector_List_Ptr Complex_Selector::unify_with(Complex_Selector_Ptr other)
984
- {
985
-
986
- // get last tails (on the right side)
987
- Complex_Selector_Obj l_last = this->last();
988
- Complex_Selector_Obj r_last = other->last();
989
-
990
- // check valid pointers (assertion)
991
- SASS_ASSERT(l_last, "lhs is null");
992
- SASS_ASSERT(r_last, "rhs is null");
993
-
994
- // Not sure about this check, but closest way I could check
995
- // was to see if this is a ruby 'SimpleSequence' equivalent.
996
- // It seems to do the job correctly as some specs react to this
997
- if (l_last->combinator() != Combinator::ANCESTOR_OF) return 0;
998
- if (r_last->combinator() != Combinator::ANCESTOR_OF ) return 0;
999
-
1000
- // get the headers for the last tails
1001
- Compound_Selector_Obj l_last_head = l_last->head();
1002
- Compound_Selector_Obj r_last_head = r_last->head();
1003
-
1004
- // check valid head pointers (assertion)
1005
- SASS_ASSERT(l_last_head, "lhs head is null");
1006
- SASS_ASSERT(r_last_head, "rhs head is null");
1007
-
1008
- // get the unification of the last compound selectors
1009
- Compound_Selector_Obj unified = r_last_head->unify_with(l_last_head);
1010
-
1011
- // abort if we could not unify heads
1012
- if (unified == 0) return 0;
1013
-
1014
- // check for universal (star: `*`) selector
1015
- bool is_universal = l_last_head->is_universal() ||
1016
- r_last_head->is_universal();
1017
-
1018
- if (is_universal)
1019
- {
1020
- // move the head
1021
- l_last->head(0);
1022
- r_last->head(unified);
1023
- }
1024
-
1025
- // create nodes from both selectors
1026
- Node lhsNode = complexSelectorToNode(this);
1027
- Node rhsNode = complexSelectorToNode(other);
1028
-
1029
- // overwrite universal base
1030
- if (!is_universal)
1031
- {
1032
- // create some temporaries to convert to node
1033
- Complex_Selector_Obj fake = unified->to_complex();
1034
- Node unified_node = complexSelectorToNode(fake);
1035
- // add to permutate the list?
1036
- rhsNode.plus(unified_node);
1037
- }
1038
-
1039
- // do some magic we inherit from node and extend
1040
- Node node = subweave(lhsNode, rhsNode);
1041
- Selector_List_Obj result = SASS_MEMORY_NEW(Selector_List, pstate());
1042
- NodeDequePtr col = node.collection(); // move from collection to list
1043
- for (NodeDeque::iterator it = col->begin(), end = col->end(); it != end; it++)
1044
- { result->append(nodeToComplexSelector(Node::naiveTrim(*it))); }
1045
-
1046
- // only return if list has some entries
1047
- return result->length() ? result.detach() : 0;
1048
-
1049
- }
1050
-
1051
- bool Compound_Selector::operator== (const Compound_Selector& rhs) const
1052
- {
1053
- // for array access
1054
- size_t i = 0, n = 0;
1055
- size_t iL = length();
1056
- size_t nL = rhs.length();
1057
- // create temporary vectors and sort them
1058
- std::vector<Simple_Selector_Obj> l_lst = this->elements();
1059
- std::vector<Simple_Selector_Obj> r_lst = rhs.elements();
1060
- std::sort(l_lst.begin(), l_lst.end(), OrderNodes());
1061
- std::sort(r_lst.begin(), r_lst.end(), OrderNodes());
1062
- // process loop
1063
- while (true)
1064
- {
1065
- // first check for valid index
1066
- if (i == iL) return iL == nL;
1067
- else if (n == nL) return iL == nL;
1068
- // the access the vector items
1069
- Simple_Selector_Obj l = l_lst[i];
1070
- Simple_Selector_Obj r = r_lst[n];
1071
- // skip nulls
1072
- if (!l) ++i;
1073
- if (!r) ++n;
1074
- // do the check now
1075
- else if (*l != *r)
1076
- { return false; }
1077
- // advance now
1078
- ++i; ++n;
1079
- }
1080
- // there is no break?!
1081
- }
1082
-
1083
- bool Complex_Selector::is_superselector_of(Compound_Selector_Obj rhs, std::string wrapping)
1084
- {
1085
- return last()->head() && last()->head()->is_superselector_of(rhs, wrapping);
1086
- }
1087
-
1088
- bool Complex_Selector::is_superselector_of(Complex_Selector_Obj rhs, std::string wrapping)
1089
- {
1090
- Complex_Selector_Ptr lhs = this;
1091
- // check for selectors with leading or trailing combinators
1092
- if (!lhs->head() || !rhs->head())
1093
- { return false; }
1094
- Complex_Selector_Obj l_innermost = lhs->innermost();
1095
- if (l_innermost->combinator() != Complex_Selector::ANCESTOR_OF)
1096
- { return false; }
1097
- Complex_Selector_Obj r_innermost = rhs->innermost();
1098
- if (r_innermost->combinator() != Complex_Selector::ANCESTOR_OF)
1099
- { return false; }
1100
- // more complex (i.e., longer) selectors are always more specific
1101
- size_t l_len = lhs->length(), r_len = rhs->length();
1102
- if (l_len > r_len)
1103
- { return false; }
1104
-
1105
- if (l_len == 1)
1106
- { return lhs->head()->is_superselector_of(rhs->last()->head(), wrapping); }
1107
-
1108
- // we have to look one tail deeper, since we cary the
1109
- // combinator around for it (which is important here)
1110
- if (rhs->tail() && lhs->tail() && combinator() != Complex_Selector::ANCESTOR_OF) {
1111
- Complex_Selector_Obj lhs_tail = lhs->tail();
1112
- Complex_Selector_Obj rhs_tail = rhs->tail();
1113
- if (lhs_tail->combinator() != rhs_tail->combinator()) return false;
1114
- if (lhs_tail->head() && !rhs_tail->head()) return false;
1115
- if (!lhs_tail->head() && rhs_tail->head()) return false;
1116
- if (lhs_tail->head() && rhs_tail->head()) {
1117
- if (!lhs_tail->head()->is_superselector_of(rhs_tail->head())) return false;
1118
- }
1119
- }
1120
-
1121
- bool found = false;
1122
- Complex_Selector_Obj marker = rhs;
1123
- for (size_t i = 0, L = rhs->length(); i < L; ++i) {
1124
- if (i == L-1)
1125
- { return false; }
1126
- if (lhs->head() && marker->head() && lhs->head()->is_superselector_of(marker->head(), wrapping))
1127
- { found = true; break; }
1128
- marker = marker->tail();
1129
- }
1130
- if (!found)
1131
- { return false; }
1132
-
1133
- /*
1134
- Hmm, I hope I have the logic right:
1135
-
1136
- if lhs has a combinator:
1137
- if !(marker has a combinator) return false
1138
- if !(lhs.combinator == '~' ? marker.combinator != '>' : lhs.combinator == marker.combinator) return false
1139
- return lhs.tail-without-innermost.is_superselector_of(marker.tail-without-innermost)
1140
- else if marker has a combinator:
1141
- if !(marker.combinator == ">") return false
1142
- return lhs.tail.is_superselector_of(marker.tail)
1143
- else
1144
- return lhs.tail.is_superselector_of(marker.tail)
1145
- */
1146
- if (lhs->combinator() != Complex_Selector::ANCESTOR_OF)
1147
- {
1148
- if (marker->combinator() == Complex_Selector::ANCESTOR_OF)
1149
- { return false; }
1150
- if (!(lhs->combinator() == Complex_Selector::PRECEDES ? marker->combinator() != Complex_Selector::PARENT_OF : lhs->combinator() == marker->combinator()))
1151
- { return false; }
1152
- return lhs->tail()->is_superselector_of(marker->tail());
1153
- }
1154
- else if (marker->combinator() != Complex_Selector::ANCESTOR_OF)
1155
- {
1156
- if (marker->combinator() != Complex_Selector::PARENT_OF)
1157
- { return false; }
1158
- return lhs->tail()->is_superselector_of(marker->tail());
1159
- }
1160
- return lhs->tail()->is_superselector_of(marker->tail());
1161
- }
1162
-
1163
- size_t Complex_Selector::length() const
1164
- {
1165
- // TODO: make this iterative
1166
- if (!tail()) return 1;
1167
- return 1 + tail()->length();
1168
- }
1169
-
1170
- // append another complex selector at the end
1171
- // check if we need to append some headers
1172
- // then we need to check for the combinator
1173
- // only then we can safely set the new tail
1174
- void Complex_Selector::append(Complex_Selector_Obj ss, Backtraces& traces)
1175
- {
1176
-
1177
- Complex_Selector_Obj t = ss->tail();
1178
- Combinator c = ss->combinator();
1179
- String_Obj r = ss->reference();
1180
- Compound_Selector_Obj h = ss->head();
1181
-
1182
- if (ss->has_line_feed()) has_line_feed(true);
1183
- if (ss->has_line_break()) has_line_break(true);
1184
-
1185
- // append old headers
1186
- if (h && h->length()) {
1187
- if (last()->combinator() != ANCESTOR_OF && c != ANCESTOR_OF) {
1188
- traces.push_back(Backtrace(pstate()));
1189
- throw Exception::InvalidParent(this, traces, ss);
1190
- } else if (last()->head_ && last()->head_->length()) {
1191
- Compound_Selector_Obj rh = last()->head();
1192
- size_t i;
1193
- size_t L = h->length();
1194
- if (Cast<Element_Selector>(h->first())) {
1195
- if (Class_Selector_Ptr cs = Cast<Class_Selector>(rh->last())) {
1196
- Class_Selector_Ptr sqs = SASS_MEMORY_COPY(cs);
1197
- sqs->name(sqs->name() + (*h)[0]->name());
1198
- sqs->pstate((*h)[0]->pstate());
1199
- (*rh)[rh->length()-1] = sqs;
1200
- rh->pstate(h->pstate());
1201
- for (i = 1; i < L; ++i) rh->append((*h)[i]);
1202
- } else if (Id_Selector_Ptr is = Cast<Id_Selector>(rh->last())) {
1203
- Id_Selector_Ptr sqs = SASS_MEMORY_COPY(is);
1204
- sqs->name(sqs->name() + (*h)[0]->name());
1205
- sqs->pstate((*h)[0]->pstate());
1206
- (*rh)[rh->length()-1] = sqs;
1207
- rh->pstate(h->pstate());
1208
- for (i = 1; i < L; ++i) rh->append((*h)[i]);
1209
- } else if (Element_Selector_Ptr ts = Cast<Element_Selector>(rh->last())) {
1210
- Element_Selector_Ptr tss = SASS_MEMORY_COPY(ts);
1211
- tss->name(tss->name() + (*h)[0]->name());
1212
- tss->pstate((*h)[0]->pstate());
1213
- (*rh)[rh->length()-1] = tss;
1214
- rh->pstate(h->pstate());
1215
- for (i = 1; i < L; ++i) rh->append((*h)[i]);
1216
- } else if (Placeholder_Selector_Ptr ps = Cast<Placeholder_Selector>(rh->last())) {
1217
- Placeholder_Selector_Ptr pss = SASS_MEMORY_COPY(ps);
1218
- pss->name(pss->name() + (*h)[0]->name());
1219
- pss->pstate((*h)[0]->pstate());
1220
- (*rh)[rh->length()-1] = pss;
1221
- rh->pstate(h->pstate());
1222
- for (i = 1; i < L; ++i) rh->append((*h)[i]);
1223
- } else {
1224
- last()->head_->concat(h);
1225
- }
1226
- } else {
1227
- last()->head_->concat(h);
1228
- }
1229
- } else if (last()->head_) {
1230
- last()->head_->concat(h);
1231
- }
1232
- } else {
1233
- // std::cerr << "has no or empty head\n";
1234
- }
1235
-
1236
- if (last()) {
1237
- if (last()->combinator() != ANCESTOR_OF && c != ANCESTOR_OF) {
1238
- Complex_Selector_Ptr inter = SASS_MEMORY_NEW(Complex_Selector, pstate());
1239
- inter->reference(r);
1240
- inter->combinator(c);
1241
- inter->tail(t);
1242
- last()->tail(inter);
1243
- } else {
1244
- if (last()->combinator() == ANCESTOR_OF) {
1245
- last()->combinator(c);
1246
- last()->reference(r);
1247
- }
1248
- last()->tail(t);
1249
- }
1250
- }
1251
-
1252
- }
1253
-
1254
- Selector_List_Obj Selector_List::eval(Eval& eval)
1255
- {
1256
- Selector_List_Obj list = schema() ?
1257
- eval(schema()) : eval(this);
1258
- list->schema(schema());
1259
- return list;
1260
- }
1261
-
1262
- Selector_List_Ptr Selector_List::resolve_parent_refs(std::vector<Selector_List_Obj>& pstack, Backtraces& traces, bool implicit_parent)
1263
- {
1264
- if (!this->has_parent_ref()) return this;
1265
- Selector_List_Ptr ss = SASS_MEMORY_NEW(Selector_List, pstate());
1266
- Selector_List_Ptr ps = pstack.back();
1267
- for (size_t pi = 0, pL = ps->length(); pi < pL; ++pi) {
1268
- for (size_t si = 0, sL = this->length(); si < sL; ++si) {
1269
- Selector_List_Obj rv = at(si)->resolve_parent_refs(pstack, traces, implicit_parent);
1270
- ss->concat(rv);
1271
- }
1272
- }
1273
- return ss;
1274
- }
1275
-
1276
- Selector_List_Ptr Complex_Selector::resolve_parent_refs(std::vector<Selector_List_Obj>& pstack, Backtraces& traces, bool implicit_parent)
1277
- {
1278
- Complex_Selector_Obj tail = this->tail();
1279
- Compound_Selector_Obj head = this->head();
1280
- Selector_List_Ptr parents = pstack.back();
1281
-
1282
- if (!this->has_real_parent_ref() && !implicit_parent) {
1283
- Selector_List_Ptr retval = SASS_MEMORY_NEW(Selector_List, pstate());
1284
- retval->append(this);
1285
- return retval;
1286
- }
1287
-
1288
- // first resolve_parent_refs the tail (which may return an expanded list)
1289
- Selector_List_Obj tails = tail ? tail->resolve_parent_refs(pstack, traces, implicit_parent) : 0;
1290
-
1291
- if (head && head->length() > 0) {
1292
-
1293
- Selector_List_Obj retval;
1294
- // we have a parent selector in a simple compound list
1295
- // mix parent complex selector into the compound list
1296
- if (Cast<Parent_Selector>((*head)[0])) {
1297
- retval = SASS_MEMORY_NEW(Selector_List, pstate());
1298
-
1299
- // it turns out that real parent references reach
1300
- // across @at-root rules, which comes unexpected
1301
- if (parents == NULL && head->has_real_parent_ref()) {
1302
- int i = pstack.size() - 1;
1303
- while (!parents && i > -1) {
1304
- parents = pstack.at(i--);
1305
- }
1306
- }
1307
-
1308
- if (parents && parents->length()) {
1309
- if (tails && tails->length() > 0) {
1310
- for (size_t n = 0, nL = tails->length(); n < nL; ++n) {
1311
- for (size_t i = 0, iL = parents->length(); i < iL; ++i) {
1312
- Complex_Selector_Obj t = (*tails)[n];
1313
- Complex_Selector_Obj parent = (*parents)[i];
1314
- Complex_Selector_Obj s = SASS_MEMORY_CLONE(parent);
1315
- Complex_Selector_Obj ss = SASS_MEMORY_CLONE(this);
1316
- ss->tail(t ? SASS_MEMORY_CLONE(t) : NULL);
1317
- Compound_Selector_Obj h = SASS_MEMORY_COPY(head_);
1318
- // remove parent selector from sequence
1319
- if (h->length()) {
1320
- h->erase(h->begin());
1321
- ss->head(h);
1322
- } else {
1323
- ss->head(NULL);
1324
- }
1325
- // adjust for parent selector (1 char)
1326
- // if (h->length()) {
1327
- // ParserState state(h->at(0)->pstate());
1328
- // state.offset.column += 1;
1329
- // state.column -= 1;
1330
- // (*h)[0]->pstate(state);
1331
- // }
1332
- // keep old parser state
1333
- s->pstate(pstate());
1334
- // append new tail
1335
- s->append(ss, traces);
1336
- retval->append(s);
1337
- }
1338
- }
1339
- }
1340
- // have no tails but parents
1341
- // loop above is inside out
1342
- else {
1343
- for (size_t i = 0, iL = parents->length(); i < iL; ++i) {
1344
- Complex_Selector_Obj parent = (*parents)[i];
1345
- Complex_Selector_Obj s = SASS_MEMORY_CLONE(parent);
1346
- Complex_Selector_Obj ss = SASS_MEMORY_CLONE(this);
1347
- // this is only if valid if the parent has no trailing op
1348
- // otherwise we cannot append more simple selectors to head
1349
- if (parent->last()->combinator() != ANCESTOR_OF) {
1350
- traces.push_back(Backtrace(pstate()));
1351
- throw Exception::InvalidParent(parent, traces, ss);
1352
- }
1353
- ss->tail(tail ? SASS_MEMORY_CLONE(tail) : NULL);
1354
- Compound_Selector_Obj h = SASS_MEMORY_COPY(head_);
1355
- // remove parent selector from sequence
1356
- if (h->length()) {
1357
- h->erase(h->begin());
1358
- ss->head(h);
1359
- } else {
1360
- ss->head(NULL);
1361
- }
1362
- // \/ IMO ruby sass bug \/
1363
- ss->has_line_feed(false);
1364
- // adjust for parent selector (1 char)
1365
- // if (h->length()) {
1366
- // ParserState state(h->at(0)->pstate());
1367
- // state.offset.column += 1;
1368
- // state.column -= 1;
1369
- // (*h)[0]->pstate(state);
1370
- // }
1371
- // keep old parser state
1372
- s->pstate(pstate());
1373
- // append new tail
1374
- s->append(ss, traces);
1375
- retval->append(s);
1376
- }
1377
- }
1378
- }
1379
- // have no parent but some tails
1380
- else {
1381
- if (tails && tails->length() > 0) {
1382
- for (size_t n = 0, nL = tails->length(); n < nL; ++n) {
1383
- Complex_Selector_Obj cpy = SASS_MEMORY_CLONE(this);
1384
- cpy->tail(SASS_MEMORY_CLONE(tails->at(n)));
1385
- cpy->head(SASS_MEMORY_NEW(Compound_Selector, head->pstate()));
1386
- for (size_t i = 1, L = this->head()->length(); i < L; ++i)
1387
- cpy->head()->append((*this->head())[i]);
1388
- if (!cpy->head()->length()) cpy->head(0);
1389
- retval->append(cpy->skip_empty_reference());
1390
- }
1391
- }
1392
- // have no parent nor tails
1393
- else {
1394
- Complex_Selector_Obj cpy = SASS_MEMORY_CLONE(this);
1395
- cpy->head(SASS_MEMORY_NEW(Compound_Selector, head->pstate()));
1396
- for (size_t i = 1, L = this->head()->length(); i < L; ++i)
1397
- cpy->head()->append((*this->head())[i]);
1398
- if (!cpy->head()->length()) cpy->head(0);
1399
- retval->append(cpy->skip_empty_reference());
1400
- }
1401
- }
1402
- }
1403
- // no parent selector in head
1404
- else {
1405
- retval = this->tails(tails);
1406
- }
1407
-
1408
- for (Simple_Selector_Obj ss : head->elements()) {
1409
- if (Wrapped_Selector_Ptr ws = Cast<Wrapped_Selector>(ss)) {
1410
- if (Selector_List_Ptr sl = Cast<Selector_List>(ws->selector())) {
1411
- if (parents) ws->selector(sl->resolve_parent_refs(pstack, traces, implicit_parent));
1412
- }
1413
- }
1414
- }
1415
-
1416
- return retval.detach();
1417
-
1418
- }
1419
- // has no head
1420
- return this->tails(tails);
1421
- }
1422
-
1423
- Selector_List_Ptr Complex_Selector::tails(Selector_List_Ptr tails)
1424
- {
1425
- Selector_List_Ptr rv = SASS_MEMORY_NEW(Selector_List, pstate_);
1426
- if (tails && tails->length()) {
1427
- for (size_t i = 0, iL = tails->length(); i < iL; ++i) {
1428
- Complex_Selector_Obj pr = SASS_MEMORY_CLONE(this);
1429
- pr->tail(tails->at(i));
1430
- rv->append(pr);
1431
- }
1432
- }
1433
- else {
1434
- rv->append(this);
1435
- }
1436
- return rv;
1437
- }
1438
-
1439
- // return the last tail that is defined
1440
- Complex_Selector_Obj Complex_Selector::first()
1441
- {
1442
- // declare variables used in loop
1443
- Complex_Selector_Obj cur = this;
1444
- Compound_Selector_Obj head;
1445
- // processing loop
1446
- while (cur)
1447
- {
1448
- // get the head
1449
- head = cur->head_;
1450
- // abort (and return) if it is not a parent selector
1451
- if (!head || head->length() != 1 || !Cast<Parent_Selector>((*head)[0])) {
1452
- break;
1453
- }
1454
- // advance to next
1455
- cur = cur->tail_;
1456
- }
1457
- // result
1458
- return cur;
1459
- }
1460
-
1461
- // return the last tail that is defined
1462
- Complex_Selector_Obj Complex_Selector::last()
1463
- {
1464
- Complex_Selector_Ptr cur = this;
1465
- Complex_Selector_Ptr nxt = cur;
1466
- // loop until last
1467
- while (nxt) {
1468
- cur = nxt;
1469
- nxt = cur->tail();
1470
- }
1471
- return cur;
1472
- }
1473
-
1474
- Complex_Selector::Combinator Complex_Selector::clear_innermost()
1475
- {
1476
- Combinator c;
1477
- if (!tail() || tail()->tail() == 0)
1478
- { c = combinator(); combinator(ANCESTOR_OF); tail(0); }
1479
- else
1480
- { c = tail()->clear_innermost(); }
1481
- return c;
1482
- }
1483
-
1484
- void Complex_Selector::set_innermost(Complex_Selector_Obj val, Combinator c)
1485
- {
1486
- if (!tail())
1487
- { tail(val); combinator(c); }
1488
- else
1489
- { tail()->set_innermost(val, c); }
1490
- }
1491
-
1492
- void Complex_Selector::cloneChildren()
1493
- {
1494
- if (head()) head(SASS_MEMORY_CLONE(head()));
1495
- if (tail()) tail(SASS_MEMORY_CLONE(tail()));
1496
- }
1497
-
1498
- void Compound_Selector::cloneChildren()
72
+ const std::string AST_Node::to_string(Sass_Inspect_Options opt) const
1499
73
  {
1500
- for (size_t i = 0, l = length(); i < l; i++) {
1501
- at(i) = SASS_MEMORY_CLONE(at(i));
1502
- }
74
+ Sass_Output_Options out(opt);
75
+ Emitter emitter(out);
76
+ Inspect i(emitter);
77
+ i.in_declaration = true;
78
+ // ToDo: inspect should be const
79
+ const_cast<AST_Node*>(this)->perform(&i);
80
+ return i.get_buffer();
1503
81
  }
1504
82
 
1505
- void Selector_List::cloneChildren()
83
+ const std::string AST_Node::to_string() const
1506
84
  {
1507
- for (size_t i = 0, l = length(); i < l; i++) {
1508
- at(i) = SASS_MEMORY_CLONE(at(i));
1509
- }
85
+ return to_string({ NESTED, 5 });
1510
86
  }
1511
87
 
1512
- void Wrapped_Selector::cloneChildren()
1513
- {
1514
- selector(SASS_MEMORY_CLONE(selector()));
1515
- }
88
+ /////////////////////////////////////////////////////////////////////////
89
+ /////////////////////////////////////////////////////////////////////////
1516
90
 
1517
- // remove parent selector references
1518
- // basically unwraps parsed selectors
1519
- void Selector_List::remove_parent_selectors()
91
+ Expression_Obj Hashed::at(Expression_Obj k) const
1520
92
  {
1521
- // Check every rhs selector against left hand list
1522
- for(size_t i = 0, L = length(); i < L; ++i) {
1523
- if (!(*this)[i]->head()) continue;
1524
- if ((*this)[i]->head()->is_empty_reference()) {
1525
- // simply move to the next tail if we have "no" combinator
1526
- if ((*this)[i]->combinator() == Complex_Selector::ANCESTOR_OF) {
1527
- if ((*this)[i]->tail()) {
1528
- if ((*this)[i]->has_line_feed()) {
1529
- (*this)[i]->tail()->has_line_feed(true);
1530
- }
1531
- (*this)[i] = (*this)[i]->tail();
1532
- }
1533
- }
1534
- // otherwise remove the first item from head
1535
- else {
1536
- (*this)[i]->head()->erase((*this)[i]->head()->begin());
1537
- }
1538
- }
1539
- }
93
+ if (elements_.count(k))
94
+ { return elements_.at(k); }
95
+ else { return {}; }
1540
96
  }
1541
97
 
1542
- size_t Wrapped_Selector::hash()
1543
- {
1544
- if (hash_ == 0) {
1545
- hash_combine(hash_, Simple_Selector::hash());
1546
- if (selector_) hash_combine(hash_, selector_->hash());
1547
- }
1548
- return hash_;
1549
- }
1550
- bool Wrapped_Selector::has_parent_ref() const {
1551
- // if (has_reference()) return true;
1552
- if (!selector()) return false;
1553
- return selector()->has_parent_ref();
1554
- }
1555
- bool Wrapped_Selector::has_real_parent_ref() const {
1556
- // if (has_reference()) return true;
1557
- if (!selector()) return false;
1558
- return selector()->has_real_parent_ref();
1559
- }
1560
- unsigned long Wrapped_Selector::specificity() const
1561
- {
1562
- return selector_ ? selector_->specificity() : 0;
1563
- }
98
+ /////////////////////////////////////////////////////////////////////////
99
+ /////////////////////////////////////////////////////////////////////////
1564
100
 
101
+ Statement::Statement(ParserState pstate, Type st, size_t t)
102
+ : AST_Node(pstate), statement_type_(st), tabs_(t), group_end_(false)
103
+ { }
104
+ Statement::Statement(const Statement* ptr)
105
+ : AST_Node(ptr),
106
+ statement_type_(ptr->statement_type_),
107
+ tabs_(ptr->tabs_),
108
+ group_end_(ptr->group_end_)
109
+ { }
1565
110
 
1566
- bool Selector_List::has_parent_ref() const
111
+ bool Statement::bubbles()
1567
112
  {
1568
- for (Complex_Selector_Obj s : elements()) {
1569
- if (s && s->has_parent_ref()) return true;
1570
- }
1571
113
  return false;
1572
114
  }
1573
115
 
1574
- bool Selector_List::has_real_parent_ref() const
116
+ bool Statement::has_content()
1575
117
  {
1576
- for (Complex_Selector_Obj s : elements()) {
1577
- if (s && s->has_real_parent_ref()) return true;
1578
- }
1579
- return false;
118
+ return statement_type_ == CONTENT;
1580
119
  }
1581
120
 
1582
- bool Selector_Schema::has_parent_ref() const
121
+ bool Statement::is_invisible() const
1583
122
  {
1584
- if (String_Schema_Obj schema = Cast<String_Schema>(contents())) {
1585
- return schema->length() > 0 && Cast<Parent_Selector>(schema->at(0)) != NULL;
1586
- }
1587
123
  return false;
1588
124
  }
1589
125
 
1590
- bool Selector_Schema::has_real_parent_ref() const
126
+ /////////////////////////////////////////////////////////////////////////
127
+ /////////////////////////////////////////////////////////////////////////
128
+
129
+ Block::Block(ParserState pstate, size_t s, bool r)
130
+ : Statement(pstate),
131
+ Vectorized<Statement_Obj>(s),
132
+ is_root_(r)
133
+ { }
134
+ Block::Block(const Block* ptr)
135
+ : Statement(ptr),
136
+ Vectorized<Statement_Obj>(*ptr),
137
+ is_root_(ptr->is_root_)
138
+ { }
139
+
140
+ bool Block::has_content()
1591
141
  {
1592
- if (String_Schema_Obj schema = Cast<String_Schema>(contents())) {
1593
- Parent_Selector_Obj p = Cast<Parent_Selector>(schema->at(0));
1594
- return schema->length() > 0 && p && p->is_real_parent_ref();
142
+ for (size_t i = 0, L = elements().size(); i < L; ++i) {
143
+ if (elements()[i]->has_content()) return true;
1595
144
  }
1596
- return false;
145
+ return Statement::has_content();
1597
146
  }
1598
147
 
1599
- void Selector_List::adjust_after_pushing(Complex_Selector_Obj c)
148
+ /////////////////////////////////////////////////////////////////////////
149
+ /////////////////////////////////////////////////////////////////////////
150
+
151
+ Has_Block::Has_Block(ParserState pstate, Block_Obj b)
152
+ : Statement(pstate), block_(b)
153
+ { }
154
+ Has_Block::Has_Block(const Has_Block* ptr)
155
+ : Statement(ptr), block_(ptr->block_)
156
+ { }
157
+
158
+ bool Has_Block::has_content()
1600
159
  {
1601
- // if (c->has_reference()) has_reference(true);
160
+ return (block_ && block_->has_content()) || Statement::has_content();
1602
161
  }
1603
162
 
1604
- // it's a superselector if every selector of the right side
1605
- // list is a superselector of the given left side selector
1606
- bool Complex_Selector::is_superselector_of(Selector_List_Obj sub, std::string wrapping)
1607
- {
1608
- // Check every rhs selector against left hand list
1609
- for(size_t i = 0, L = sub->length(); i < L; ++i) {
1610
- if (!is_superselector_of((*sub)[i], wrapping)) return false;
163
+ /////////////////////////////////////////////////////////////////////////
164
+ /////////////////////////////////////////////////////////////////////////
165
+
166
+ Ruleset::Ruleset(ParserState pstate, Selector_List_Obj s, Block_Obj b)
167
+ : Has_Block(pstate, b), selector_(s), is_root_(false)
168
+ { statement_type(RULESET); }
169
+ Ruleset::Ruleset(const Ruleset* ptr)
170
+ : Has_Block(ptr),
171
+ selector_(ptr->selector_),
172
+ is_root_(ptr->is_root_)
173
+ { statement_type(RULESET); }
174
+
175
+ bool Ruleset::is_invisible() const {
176
+ if (Selector_List* sl = Cast<Selector_List>(selector())) {
177
+ for (size_t i = 0, L = sl->length(); i < L; ++i)
178
+ if (!(*sl)[i]->has_placeholder()) return false;
1611
179
  }
1612
180
  return true;
1613
181
  }
1614
182
 
1615
- // it's a superselector if every selector of the right side
1616
- // list is a superselector of the given left side selector
1617
- bool Selector_List::is_superselector_of(Selector_List_Obj sub, std::string wrapping)
183
+ /////////////////////////////////////////////////////////////////////////
184
+ /////////////////////////////////////////////////////////////////////////
185
+
186
+ Bubble::Bubble(ParserState pstate, Statement_Obj n, Statement_Obj g, size_t t)
187
+ : Statement(pstate, Statement::BUBBLE, t), node_(n), group_end_(g == 0)
188
+ { }
189
+ Bubble::Bubble(const Bubble* ptr)
190
+ : Statement(ptr),
191
+ node_(ptr->node_),
192
+ group_end_(ptr->group_end_)
193
+ { }
194
+
195
+ bool Bubble::bubbles()
1618
196
  {
1619
- // Check every rhs selector against left hand list
1620
- for(size_t i = 0, L = sub->length(); i < L; ++i) {
1621
- if (!is_superselector_of((*sub)[i], wrapping)) return false;
1622
- }
1623
197
  return true;
1624
198
  }
1625
199
 
1626
- // it's a superselector if every selector on the right side
1627
- // is a superselector of any one of the left side selectors
1628
- bool Selector_List::is_superselector_of(Compound_Selector_Obj sub, std::string wrapping)
1629
- {
1630
- // Check every lhs selector against right hand
1631
- for(size_t i = 0, L = length(); i < L; ++i) {
1632
- if ((*this)[i]->is_superselector_of(sub, wrapping)) return true;
200
+ /////////////////////////////////////////////////////////////////////////
201
+ /////////////////////////////////////////////////////////////////////////
202
+
203
+ Trace::Trace(ParserState pstate, std::string n, Block_Obj b, char type)
204
+ : Has_Block(pstate, b), type_(type), name_(n)
205
+ { }
206
+ Trace::Trace(const Trace* ptr)
207
+ : Has_Block(ptr),
208
+ type_(ptr->type_),
209
+ name_(ptr->name_)
210
+ { }
211
+
212
+ /////////////////////////////////////////////////////////////////////////
213
+ /////////////////////////////////////////////////////////////////////////
214
+
215
+ Media_Block::Media_Block(ParserState pstate, List_Obj mqs, Block_Obj b)
216
+ : Has_Block(pstate, b), media_queries_(mqs)
217
+ { statement_type(MEDIA); }
218
+ Media_Block::Media_Block(const Media_Block* ptr)
219
+ : Has_Block(ptr), media_queries_(ptr->media_queries_)
220
+ { statement_type(MEDIA); }
221
+
222
+ bool Media_Block::is_invisible() const {
223
+ for (size_t i = 0, L = block()->length(); i < L; ++i) {
224
+ Statement_Obj stm = block()->at(i);
225
+ if (!stm->is_invisible()) return false;
1633
226
  }
1634
- return false;
227
+ return true;
1635
228
  }
1636
229
 
1637
- // it's a superselector if every selector on the right side
1638
- // is a superselector of any one of the left side selectors
1639
- bool Selector_List::is_superselector_of(Complex_Selector_Obj sub, std::string wrapping)
230
+ bool Media_Block::bubbles()
1640
231
  {
1641
- // Check every lhs selector against right hand
1642
- for(size_t i = 0, L = length(); i < L; ++i) {
1643
- if ((*this)[i]->is_superselector_of(sub)) return true;
1644
- }
1645
- return false;
232
+ return true;
1646
233
  }
1647
234
 
1648
- Selector_List_Ptr Selector_List::unify_with(Selector_List_Ptr rhs) {
1649
- std::vector<Complex_Selector_Obj> unified_complex_selectors;
1650
- // Unify all of children with RHS's children, storing the results in `unified_complex_selectors`
1651
- for (size_t lhs_i = 0, lhs_L = length(); lhs_i < lhs_L; ++lhs_i) {
1652
- Complex_Selector_Obj seq1 = (*this)[lhs_i];
1653
- for(size_t rhs_i = 0, rhs_L = rhs->length(); rhs_i < rhs_L; ++rhs_i) {
1654
- Complex_Selector_Ptr seq2 = rhs->at(rhs_i);
1655
-
1656
- Selector_List_Obj result = seq1->unify_with(seq2);
1657
- if( result ) {
1658
- for(size_t i = 0, L = result->length(); i < L; ++i) {
1659
- unified_complex_selectors.push_back( (*result)[i] );
1660
- }
1661
- }
1662
- }
1663
- }
235
+ /////////////////////////////////////////////////////////////////////////
236
+ /////////////////////////////////////////////////////////////////////////
237
+
238
+ Directive::Directive(ParserState pstate, std::string kwd, Selector_List_Obj sel, Block_Obj b, Expression_Obj val)
239
+ : Has_Block(pstate, b), keyword_(kwd), selector_(sel), value_(val) // set value manually if needed
240
+ { statement_type(DIRECTIVE); }
241
+ Directive::Directive(const Directive* ptr)
242
+ : Has_Block(ptr),
243
+ keyword_(ptr->keyword_),
244
+ selector_(ptr->selector_),
245
+ value_(ptr->value_) // set value manually if needed
246
+ { statement_type(DIRECTIVE); }
247
+
248
+ bool Directive::bubbles() { return is_keyframes() || is_media(); }
249
+
250
+ bool Directive::is_media() {
251
+ return keyword_.compare("@-webkit-media") == 0 ||
252
+ keyword_.compare("@-moz-media") == 0 ||
253
+ keyword_.compare("@-o-media") == 0 ||
254
+ keyword_.compare("@media") == 0;
255
+ }
256
+ bool Directive::is_keyframes() {
257
+ return keyword_.compare("@-webkit-keyframes") == 0 ||
258
+ keyword_.compare("@-moz-keyframes") == 0 ||
259
+ keyword_.compare("@-o-keyframes") == 0 ||
260
+ keyword_.compare("@keyframes") == 0;
261
+ }
262
+
263
+ /////////////////////////////////////////////////////////////////////////
264
+ /////////////////////////////////////////////////////////////////////////
265
+
266
+ Keyframe_Rule::Keyframe_Rule(ParserState pstate, Block_Obj b)
267
+ : Has_Block(pstate, b), name_()
268
+ { statement_type(KEYFRAMERULE); }
269
+ Keyframe_Rule::Keyframe_Rule(const Keyframe_Rule* ptr)
270
+ : Has_Block(ptr), name_(ptr->name_)
271
+ { statement_type(KEYFRAMERULE); }
272
+
273
+ /////////////////////////////////////////////////////////////////////////
274
+ /////////////////////////////////////////////////////////////////////////
275
+
276
+ Declaration::Declaration(ParserState pstate, String_Obj prop, Expression_Obj val, bool i, bool c, Block_Obj b)
277
+ : Has_Block(pstate, b), property_(prop), value_(val), is_important_(i), is_custom_property_(c), is_indented_(false)
278
+ { statement_type(DECLARATION); }
279
+ Declaration::Declaration(const Declaration* ptr)
280
+ : Has_Block(ptr),
281
+ property_(ptr->property_),
282
+ value_(ptr->value_),
283
+ is_important_(ptr->is_important_),
284
+ is_custom_property_(ptr->is_custom_property_),
285
+ is_indented_(ptr->is_indented_)
286
+ { statement_type(DECLARATION); }
1664
287
 
1665
- // Creates the final Selector_List by combining all the complex selectors
1666
- Selector_List_Ptr final_result = SASS_MEMORY_NEW(Selector_List, pstate());
1667
- for (auto itr = unified_complex_selectors.begin(); itr != unified_complex_selectors.end(); ++itr) {
1668
- final_result->append(*itr);
288
+ bool Declaration::is_invisible() const
289
+ {
290
+ if (is_custom_property()) return false;
291
+ return !(value_ && !Cast<Null>(value_));
292
+ }
293
+
294
+ /////////////////////////////////////////////////////////////////////////
295
+ /////////////////////////////////////////////////////////////////////////
296
+
297
+ Assignment::Assignment(ParserState pstate, std::string var, Expression_Obj val, bool is_default, bool is_global)
298
+ : Statement(pstate), variable_(var), value_(val), is_default_(is_default), is_global_(is_global)
299
+ { statement_type(ASSIGNMENT); }
300
+ Assignment::Assignment(const Assignment* ptr)
301
+ : Statement(ptr),
302
+ variable_(ptr->variable_),
303
+ value_(ptr->value_),
304
+ is_default_(ptr->is_default_),
305
+ is_global_(ptr->is_global_)
306
+ { statement_type(ASSIGNMENT); }
307
+
308
+ /////////////////////////////////////////////////////////////////////////
309
+ /////////////////////////////////////////////////////////////////////////
310
+
311
+ Import::Import(ParserState pstate)
312
+ : Statement(pstate),
313
+ urls_(std::vector<Expression_Obj>()),
314
+ incs_(std::vector<Include>()),
315
+ import_queries_()
316
+ { statement_type(IMPORT); }
317
+ Import::Import(const Import* ptr)
318
+ : Statement(ptr),
319
+ urls_(ptr->urls_),
320
+ incs_(ptr->incs_),
321
+ import_queries_(ptr->import_queries_)
322
+ { statement_type(IMPORT); }
323
+
324
+ std::vector<Include>& Import::incs() { return incs_; }
325
+ std::vector<Expression_Obj>& Import::urls() { return urls_; }
326
+
327
+ /////////////////////////////////////////////////////////////////////////
328
+ /////////////////////////////////////////////////////////////////////////
329
+
330
+ Import_Stub::Import_Stub(ParserState pstate, Include res)
331
+ : Statement(pstate), resource_(res)
332
+ { statement_type(IMPORT_STUB); }
333
+ Import_Stub::Import_Stub(const Import_Stub* ptr)
334
+ : Statement(ptr), resource_(ptr->resource_)
335
+ { statement_type(IMPORT_STUB); }
336
+ Include Import_Stub::resource() { return resource_; };
337
+ std::string Import_Stub::imp_path() { return resource_.imp_path; };
338
+ std::string Import_Stub::abs_path() { return resource_.abs_path; };
339
+
340
+ /////////////////////////////////////////////////////////////////////////
341
+ /////////////////////////////////////////////////////////////////////////
342
+
343
+ Warning::Warning(ParserState pstate, Expression_Obj msg)
344
+ : Statement(pstate), message_(msg)
345
+ { statement_type(WARNING); }
346
+ Warning::Warning(const Warning* ptr)
347
+ : Statement(ptr), message_(ptr->message_)
348
+ { statement_type(WARNING); }
349
+
350
+ /////////////////////////////////////////////////////////////////////////
351
+ /////////////////////////////////////////////////////////////////////////
352
+
353
+ Error::Error(ParserState pstate, Expression_Obj msg)
354
+ : Statement(pstate), message_(msg)
355
+ { statement_type(ERROR); }
356
+ Error::Error(const Error* ptr)
357
+ : Statement(ptr), message_(ptr->message_)
358
+ { statement_type(ERROR); }
359
+
360
+ /////////////////////////////////////////////////////////////////////////
361
+ /////////////////////////////////////////////////////////////////////////
362
+
363
+ Debug::Debug(ParserState pstate, Expression_Obj val)
364
+ : Statement(pstate), value_(val)
365
+ { statement_type(DEBUGSTMT); }
366
+ Debug::Debug(const Debug* ptr)
367
+ : Statement(ptr), value_(ptr->value_)
368
+ { statement_type(DEBUGSTMT); }
369
+
370
+ /////////////////////////////////////////////////////////////////////////
371
+ /////////////////////////////////////////////////////////////////////////
372
+
373
+ Comment::Comment(ParserState pstate, String_Obj txt, bool is_important)
374
+ : Statement(pstate), text_(txt), is_important_(is_important)
375
+ { statement_type(COMMENT); }
376
+ Comment::Comment(const Comment* ptr)
377
+ : Statement(ptr),
378
+ text_(ptr->text_),
379
+ is_important_(ptr->is_important_)
380
+ { statement_type(COMMENT); }
381
+
382
+ bool Comment::is_invisible() const
383
+ {
384
+ return false;
385
+ }
386
+
387
+ /////////////////////////////////////////////////////////////////////////
388
+ /////////////////////////////////////////////////////////////////////////
389
+
390
+ If::If(ParserState pstate, Expression_Obj pred, Block_Obj con, Block_Obj alt)
391
+ : Has_Block(pstate, con), predicate_(pred), alternative_(alt)
392
+ { statement_type(IF); }
393
+ If::If(const If* ptr)
394
+ : Has_Block(ptr),
395
+ predicate_(ptr->predicate_),
396
+ alternative_(ptr->alternative_)
397
+ { statement_type(IF); }
398
+
399
+ bool If::has_content()
400
+ {
401
+ return Has_Block::has_content() || (alternative_ && alternative_->has_content());
402
+ }
403
+
404
+ /////////////////////////////////////////////////////////////////////////
405
+ /////////////////////////////////////////////////////////////////////////
406
+
407
+ For::For(ParserState pstate,
408
+ std::string var, Expression_Obj lo, Expression_Obj hi, Block_Obj b, bool inc)
409
+ : Has_Block(pstate, b),
410
+ variable_(var), lower_bound_(lo), upper_bound_(hi), is_inclusive_(inc)
411
+ { statement_type(FOR); }
412
+ For::For(const For* ptr)
413
+ : Has_Block(ptr),
414
+ variable_(ptr->variable_),
415
+ lower_bound_(ptr->lower_bound_),
416
+ upper_bound_(ptr->upper_bound_),
417
+ is_inclusive_(ptr->is_inclusive_)
418
+ { statement_type(FOR); }
419
+
420
+ /////////////////////////////////////////////////////////////////////////
421
+ /////////////////////////////////////////////////////////////////////////
422
+
423
+ Each::Each(ParserState pstate, std::vector<std::string> vars, Expression_Obj lst, Block_Obj b)
424
+ : Has_Block(pstate, b), variables_(vars), list_(lst)
425
+ { statement_type(EACH); }
426
+ Each::Each(const Each* ptr)
427
+ : Has_Block(ptr), variables_(ptr->variables_), list_(ptr->list_)
428
+ { statement_type(EACH); }
429
+
430
+ /////////////////////////////////////////////////////////////////////////
431
+ /////////////////////////////////////////////////////////////////////////
432
+
433
+ While::While(ParserState pstate, Expression_Obj pred, Block_Obj b)
434
+ : Has_Block(pstate, b), predicate_(pred)
435
+ { statement_type(WHILE); }
436
+ While::While(const While* ptr)
437
+ : Has_Block(ptr), predicate_(ptr->predicate_)
438
+ { statement_type(WHILE); }
439
+
440
+ /////////////////////////////////////////////////////////////////////////
441
+ /////////////////////////////////////////////////////////////////////////
442
+
443
+ Return::Return(ParserState pstate, Expression_Obj val)
444
+ : Statement(pstate), value_(val)
445
+ { statement_type(RETURN); }
446
+ Return::Return(const Return* ptr)
447
+ : Statement(ptr), value_(ptr->value_)
448
+ { statement_type(RETURN); }
449
+
450
+ /////////////////////////////////////////////////////////////////////////
451
+ /////////////////////////////////////////////////////////////////////////
452
+
453
+ Extension::Extension(ParserState pstate, Selector_List_Obj s)
454
+ : Statement(pstate), selector_(s)
455
+ { statement_type(EXTEND); }
456
+ Extension::Extension(const Extension* ptr)
457
+ : Statement(ptr), selector_(ptr->selector_)
458
+ { statement_type(EXTEND); }
459
+
460
+ /////////////////////////////////////////////////////////////////////////
461
+ /////////////////////////////////////////////////////////////////////////
462
+
463
+ Definition::Definition(const Definition* ptr)
464
+ : Has_Block(ptr),
465
+ name_(ptr->name_),
466
+ parameters_(ptr->parameters_),
467
+ environment_(ptr->environment_),
468
+ type_(ptr->type_),
469
+ native_function_(ptr->native_function_),
470
+ c_function_(ptr->c_function_),
471
+ cookie_(ptr->cookie_),
472
+ is_overload_stub_(ptr->is_overload_stub_),
473
+ signature_(ptr->signature_)
474
+ { }
475
+
476
+ Definition::Definition(ParserState pstate,
477
+ std::string n,
478
+ Parameters_Obj params,
479
+ Block_Obj b,
480
+ Type t)
481
+ : Has_Block(pstate, b),
482
+ name_(n),
483
+ parameters_(params),
484
+ environment_(0),
485
+ type_(t),
486
+ native_function_(0),
487
+ c_function_(0),
488
+ cookie_(0),
489
+ is_overload_stub_(false),
490
+ signature_(0)
491
+ { }
492
+
493
+ Definition::Definition(ParserState pstate,
494
+ Signature sig,
495
+ std::string n,
496
+ Parameters_Obj params,
497
+ Native_Function func_ptr,
498
+ bool overload_stub)
499
+ : Has_Block(pstate, {}),
500
+ name_(n),
501
+ parameters_(params),
502
+ environment_(0),
503
+ type_(FUNCTION),
504
+ native_function_(func_ptr),
505
+ c_function_(0),
506
+ cookie_(0),
507
+ is_overload_stub_(overload_stub),
508
+ signature_(sig)
509
+ { }
510
+
511
+ Definition::Definition(ParserState pstate,
512
+ Signature sig,
513
+ std::string n,
514
+ Parameters_Obj params,
515
+ Sass_Function_Entry c_func)
516
+ : Has_Block(pstate, {}),
517
+ name_(n),
518
+ parameters_(params),
519
+ environment_(0),
520
+ type_(FUNCTION),
521
+ native_function_(0),
522
+ c_function_(c_func),
523
+ cookie_(sass_function_get_cookie(c_func)),
524
+ is_overload_stub_(false),
525
+ signature_(sig)
526
+ { }
527
+
528
+ /////////////////////////////////////////////////////////////////////////
529
+ /////////////////////////////////////////////////////////////////////////
530
+
531
+ Mixin_Call::Mixin_Call(ParserState pstate, std::string n, Arguments_Obj args, Parameters_Obj b_params, Block_Obj b)
532
+ : Has_Block(pstate, b), name_(n), arguments_(args), block_parameters_(b_params)
533
+ { }
534
+ Mixin_Call::Mixin_Call(const Mixin_Call* ptr)
535
+ : Has_Block(ptr),
536
+ name_(ptr->name_),
537
+ arguments_(ptr->arguments_),
538
+ block_parameters_(ptr->block_parameters_)
539
+ { }
540
+
541
+ /////////////////////////////////////////////////////////////////////////
542
+ /////////////////////////////////////////////////////////////////////////
543
+
544
+ Content::Content(ParserState pstate, Arguments_Obj args)
545
+ : Statement(pstate),
546
+ arguments_(args)
547
+ { statement_type(CONTENT); }
548
+ Content::Content(const Content* ptr)
549
+ : Statement(ptr),
550
+ arguments_(ptr->arguments_)
551
+ { statement_type(CONTENT); }
552
+
553
+ /////////////////////////////////////////////////////////////////////////
554
+ /////////////////////////////////////////////////////////////////////////
555
+
556
+ Expression::Expression(ParserState pstate, bool d, bool e, bool i, Type ct)
557
+ : AST_Node(pstate),
558
+ is_delayed_(d),
559
+ is_expanded_(e),
560
+ is_interpolant_(i),
561
+ concrete_type_(ct)
562
+ { }
563
+
564
+ Expression::Expression(const Expression* ptr)
565
+ : AST_Node(ptr),
566
+ is_delayed_(ptr->is_delayed_),
567
+ is_expanded_(ptr->is_expanded_),
568
+ is_interpolant_(ptr->is_interpolant_),
569
+ concrete_type_(ptr->concrete_type_)
570
+ { }
571
+
572
+ /////////////////////////////////////////////////////////////////////////
573
+ /////////////////////////////////////////////////////////////////////////
574
+
575
+ Unary_Expression::Unary_Expression(ParserState pstate, Type t, Expression_Obj o)
576
+ : Expression(pstate), optype_(t), operand_(o), hash_(0)
577
+ { }
578
+ Unary_Expression::Unary_Expression(const Unary_Expression* ptr)
579
+ : Expression(ptr),
580
+ optype_(ptr->optype_),
581
+ operand_(ptr->operand_),
582
+ hash_(ptr->hash_)
583
+ { }
584
+ const std::string Unary_Expression::type_name() {
585
+ switch (optype_) {
586
+ case PLUS: return "plus";
587
+ case MINUS: return "minus";
588
+ case SLASH: return "slash";
589
+ case NOT: return "not";
590
+ default: return "invalid";
591
+ }
592
+ }
593
+ bool Unary_Expression::operator==(const Expression& rhs) const
594
+ {
595
+ try
596
+ {
597
+ const Unary_Expression* m = Cast<Unary_Expression>(&rhs);
598
+ if (m == 0) return false;
599
+ return type() == m->type() &&
600
+ *operand() == *m->operand();
601
+ }
602
+ catch (std::bad_cast&)
603
+ {
604
+ return false;
1669
605
  }
1670
- return final_result;
606
+ catch (...) { throw; }
1671
607
  }
1672
-
1673
- void Selector_List::populate_extends(Selector_List_Obj extendee, Subset_Map& extends)
608
+ size_t Unary_Expression::hash() const
1674
609
  {
610
+ if (hash_ == 0) {
611
+ hash_ = std::hash<size_t>()(optype_);
612
+ hash_combine(hash_, operand()->hash());
613
+ };
614
+ return hash_;
615
+ }
1675
616
 
1676
- Selector_List_Ptr extender = this;
1677
- for (auto complex_sel : extendee->elements()) {
1678
- Complex_Selector_Obj c = complex_sel;
1679
-
1680
-
1681
- // Ignore any parent selectors, until we find the first non Selectorerence head
1682
- Compound_Selector_Obj compound_sel = c->head();
1683
- Complex_Selector_Obj pIter = complex_sel;
1684
- while (pIter) {
1685
- Compound_Selector_Obj pHead = pIter->head();
1686
- if (pHead && Cast<Parent_Selector>(pHead->elements()[0]) == NULL) {
1687
- compound_sel = pHead;
1688
- break;
1689
- }
1690
-
1691
- pIter = pIter->tail();
1692
- }
1693
-
1694
- if (!pIter->head() || pIter->tail()) {
1695
- coreError("nested selectors may not be extended", c->pstate());
1696
- }
1697
-
1698
- compound_sel->is_optional(extendee->is_optional());
617
+ /////////////////////////////////////////////////////////////////////////
618
+ /////////////////////////////////////////////////////////////////////////
1699
619
 
1700
- for (size_t i = 0, L = extender->length(); i < L; ++i) {
1701
- extends.put(compound_sel, std::make_pair((*extender)[i], compound_sel));
1702
- }
620
+ Argument::Argument(ParserState pstate, Expression_Obj val, std::string n, bool rest, bool keyword)
621
+ : Expression(pstate), value_(val), name_(n), is_rest_argument_(rest), is_keyword_argument_(keyword), hash_(0)
622
+ {
623
+ if (!name_.empty() && is_rest_argument_) {
624
+ coreError("variable-length argument may not be passed by name", pstate_);
1703
625
  }
1704
- };
1705
-
1706
- void Compound_Selector::append(Simple_Selector_Ptr element)
626
+ }
627
+ Argument::Argument(const Argument* ptr)
628
+ : Expression(ptr),
629
+ value_(ptr->value_),
630
+ name_(ptr->name_),
631
+ is_rest_argument_(ptr->is_rest_argument_),
632
+ is_keyword_argument_(ptr->is_keyword_argument_),
633
+ hash_(ptr->hash_)
1707
634
  {
1708
- Vectorized<Simple_Selector_Obj>::append(element);
1709
- pstate_.offset += element->pstate().offset;
635
+ if (!name_.empty() && is_rest_argument_) {
636
+ coreError("variable-length argument may not be passed by name", pstate_);
637
+ }
1710
638
  }
1711
639
 
1712
- Compound_Selector_Ptr Compound_Selector::minus(Compound_Selector_Ptr rhs)
640
+ void Argument::set_delayed(bool delayed)
1713
641
  {
1714
- Compound_Selector_Ptr result = SASS_MEMORY_NEW(Compound_Selector, pstate());
1715
- // result->has_parent_reference(has_parent_reference());
642
+ if (value_) value_->set_delayed(delayed);
643
+ is_delayed(delayed);
644
+ }
1716
645
 
1717
- // not very efficient because it needs to preserve order
1718
- for (size_t i = 0, L = length(); i < L; ++i)
646
+ bool Argument::operator==(const Expression& rhs) const
647
+ {
648
+ try
1719
649
  {
1720
- bool found = false;
1721
- std::string thisSelector((*this)[i]->to_string());
1722
- for (size_t j = 0, M = rhs->length(); j < M; ++j)
1723
- {
1724
- if (thisSelector == (*rhs)[j]->to_string())
1725
- {
1726
- found = true;
1727
- break;
1728
- }
1729
- }
1730
- if (!found) result->append((*this)[i]);
650
+ const Argument* m = Cast<Argument>(&rhs);
651
+ if (!(m && name() == m->name())) return false;
652
+ return *value() == *m->value();
653
+ }
654
+ catch (std::bad_cast&)
655
+ {
656
+ return false;
1731
657
  }
658
+ catch (...) { throw; }
659
+ }
1732
660
 
1733
- return result;
661
+ size_t Argument::hash() const
662
+ {
663
+ if (hash_ == 0) {
664
+ hash_ = std::hash<std::string>()(name());
665
+ hash_combine(hash_, value()->hash());
666
+ }
667
+ return hash_;
1734
668
  }
1735
669
 
1736
- void Compound_Selector::mergeSources(ComplexSelectorSet& sources)
670
+ /////////////////////////////////////////////////////////////////////////
671
+ /////////////////////////////////////////////////////////////////////////
672
+
673
+ Arguments::Arguments(ParserState pstate)
674
+ : Expression(pstate),
675
+ Vectorized<Argument_Obj>(),
676
+ has_named_arguments_(false),
677
+ has_rest_argument_(false),
678
+ has_keyword_argument_(false)
679
+ { }
680
+ Arguments::Arguments(const Arguments* ptr)
681
+ : Expression(ptr),
682
+ Vectorized<Argument_Obj>(*ptr),
683
+ has_named_arguments_(ptr->has_named_arguments_),
684
+ has_rest_argument_(ptr->has_rest_argument_),
685
+ has_keyword_argument_(ptr->has_keyword_argument_)
686
+ { }
687
+
688
+ void Arguments::set_delayed(bool delayed)
1737
689
  {
1738
- for (ComplexSelectorSet::iterator iterator = sources.begin(), endIterator = sources.end(); iterator != endIterator; ++iterator) {
1739
- this->sources_.insert(SASS_MEMORY_CLONE(*iterator));
690
+ for (Argument_Obj arg : elements()) {
691
+ if (arg) arg->set_delayed(delayed);
1740
692
  }
693
+ is_delayed(delayed);
1741
694
  }
1742
695
 
1743
696
  Argument_Obj Arguments::get_rest_argument()
@@ -1749,7 +702,7 @@ namespace Sass {
1749
702
  }
1750
703
  }
1751
704
  }
1752
- return NULL;
705
+ return {};
1753
706
  }
1754
707
 
1755
708
  Argument_Obj Arguments::get_keyword_argument()
@@ -1761,7 +714,7 @@ namespace Sass {
1761
714
  }
1762
715
  }
1763
716
  }
1764
- return NULL;
717
+ return {};
1765
718
  }
1766
719
 
1767
720
  void Arguments::adjust_after_pushing(Argument_Obj a)
@@ -1797,397 +750,185 @@ namespace Sass {
1797
750
  }
1798
751
  }
1799
752
 
1800
- bool Ruleset::is_invisible() const {
1801
- if (Selector_List_Ptr sl = Cast<Selector_List>(selector())) {
1802
- for (size_t i = 0, L = sl->length(); i < L; ++i)
1803
- if (!(*sl)[i]->has_placeholder()) return false;
1804
- }
1805
- return true;
1806
- }
1807
-
1808
- bool Media_Block::is_invisible() const {
1809
- for (size_t i = 0, L = block()->length(); i < L; ++i) {
1810
- Statement_Obj stm = block()->at(i);
1811
- if (!stm->is_invisible()) return false;
1812
- }
1813
- return true;
1814
- }
753
+ /////////////////////////////////////////////////////////////////////////
754
+ /////////////////////////////////////////////////////////////////////////
755
+
756
+ Media_Query::Media_Query(ParserState pstate, String_Obj t, size_t s, bool n, bool r)
757
+ : Expression(pstate), Vectorized<Media_Query_Expression_Obj>(s),
758
+ media_type_(t), is_negated_(n), is_restricted_(r)
759
+ { }
760
+ Media_Query::Media_Query(const Media_Query* ptr)
761
+ : Expression(ptr),
762
+ Vectorized<Media_Query_Expression_Obj>(*ptr),
763
+ media_type_(ptr->media_type_),
764
+ is_negated_(ptr->is_negated_),
765
+ is_restricted_(ptr->is_restricted_)
766
+ { }
767
+
768
+ /////////////////////////////////////////////////////////////////////////
769
+ /////////////////////////////////////////////////////////////////////////
770
+
771
+ Media_Query_Expression::Media_Query_Expression(ParserState pstate,
772
+ Expression_Obj f, Expression_Obj v, bool i)
773
+ : Expression(pstate), feature_(f), value_(v), is_interpolated_(i)
774
+ { }
775
+ Media_Query_Expression::Media_Query_Expression(const Media_Query_Expression* ptr)
776
+ : Expression(ptr),
777
+ feature_(ptr->feature_),
778
+ value_(ptr->value_),
779
+ is_interpolated_(ptr->is_interpolated_)
780
+ { }
781
+
782
+ /////////////////////////////////////////////////////////////////////////
783
+ /////////////////////////////////////////////////////////////////////////
784
+
785
+ At_Root_Query::At_Root_Query(ParserState pstate, Expression_Obj f, Expression_Obj v, bool i)
786
+ : Expression(pstate), feature_(f), value_(v)
787
+ { }
788
+ At_Root_Query::At_Root_Query(const At_Root_Query* ptr)
789
+ : Expression(ptr),
790
+ feature_(ptr->feature_),
791
+ value_(ptr->value_)
792
+ { }
1815
793
 
1816
- Number::Number(ParserState pstate, double val, std::string u, bool zero)
1817
- : Value(pstate),
1818
- Units(),
1819
- value_(val),
1820
- zero_(zero),
1821
- hash_(0)
794
+ bool At_Root_Query::exclude(std::string str)
1822
795
  {
1823
- size_t l = 0;
1824
- size_t r;
1825
- if (!u.empty()) {
1826
- bool nominator = true;
1827
- while (true) {
1828
- r = u.find_first_of("*/", l);
1829
- std::string unit(u.substr(l, r == std::string::npos ? r : r - l));
1830
- if (!unit.empty()) {
1831
- if (nominator) numerators.push_back(unit);
1832
- else denominators.push_back(unit);
1833
- }
1834
- if (r == std::string::npos) break;
1835
- // ToDo: should error for multiple slashes
1836
- // if (!nominator && u[r] == '/') error(...)
1837
- if (u[r] == '/')
1838
- nominator = false;
1839
- // strange math parsing?
1840
- // else if (u[r] == '*')
1841
- // nominator = true;
1842
- l = r + 1;
796
+ bool with = feature() && unquote(feature()->to_string()).compare("with") == 0;
797
+ List* l = static_cast<List*>(value().ptr());
798
+ std::string v;
799
+
800
+ if (with)
801
+ {
802
+ if (!l || l->length() == 0) return str.compare("rule") != 0;
803
+ for (size_t i = 0, L = l->length(); i < L; ++i)
804
+ {
805
+ v = unquote((*l)[i]->to_string());
806
+ if (v.compare("all") == 0 || v == str) return false;
1843
807
  }
808
+ return true;
809
+ }
810
+ else
811
+ {
812
+ if (!l || !l->length()) return str.compare("rule") == 0;
813
+ for (size_t i = 0, L = l->length(); i < L; ++i)
814
+ {
815
+ v = unquote((*l)[i]->to_string());
816
+ if (v.compare("all") == 0 || v == str) return true;
817
+ }
818
+ return false;
1844
819
  }
1845
- concrete_type(NUMBER);
1846
- }
1847
-
1848
- // cancel out unnecessary units
1849
- void Number::reduce()
1850
- {
1851
- // apply conversion factor
1852
- value_ *= this->Units::reduce();
1853
820
  }
1854
821
 
1855
- void Number::normalize()
1856
- {
1857
- // apply conversion factor
1858
- value_ *= this->Units::normalize();
1859
- }
822
+ /////////////////////////////////////////////////////////////////////////
823
+ /////////////////////////////////////////////////////////////////////////
1860
824
 
1861
- bool Custom_Warning::operator== (const Expression& rhs) const
1862
- {
1863
- if (Custom_Warning_Ptr_Const r = Cast<Custom_Warning>(&rhs)) {
1864
- return message() == r->message();
1865
- }
1866
- return false;
1867
- }
825
+ At_Root_Block::At_Root_Block(ParserState pstate, Block_Obj b, At_Root_Query_Obj e)
826
+ : Has_Block(pstate, b), expression_(e)
827
+ { statement_type(ATROOT); }
828
+ At_Root_Block::At_Root_Block(const At_Root_Block* ptr)
829
+ : Has_Block(ptr), expression_(ptr->expression_)
830
+ { statement_type(ATROOT); }
1868
831
 
1869
- bool Custom_Error::operator== (const Expression& rhs) const
1870
- {
1871
- if (Custom_Error_Ptr_Const r = Cast<Custom_Error>(&rhs)) {
1872
- return message() == r->message();
1873
- }
1874
- return false;
832
+ bool At_Root_Block::bubbles() {
833
+ return true;
1875
834
  }
1876
835
 
1877
- bool Number::operator== (const Expression& rhs) const
1878
- {
1879
- if (auto rhsnr = Cast<Number>(&rhs)) {
1880
- return *this == *rhsnr;
836
+ bool At_Root_Block::exclude_node(Statement_Obj s) {
837
+ if (expression() == 0)
838
+ {
839
+ return s->statement_type() == Statement::RULESET;
1881
840
  }
1882
- return false;
1883
- }
1884
841
 
1885
- bool Number::operator== (const Number& rhs) const
1886
- {
1887
- Number l(*this), r(rhs); l.reduce(); r.reduce();
1888
- size_t lhs_units = l.numerators.size() + l.denominators.size();
1889
- size_t rhs_units = r.numerators.size() + r.denominators.size();
1890
- // unitless and only having one unit seems equivalent (will change in future)
1891
- if (!lhs_units || !rhs_units) {
1892
- return NEAR_EQUAL(l.value(), r.value());
842
+ if (s->statement_type() == Statement::DIRECTIVE)
843
+ {
844
+ if (Directive_Obj dir = Cast<Directive>(s))
845
+ {
846
+ std::string keyword(dir->keyword());
847
+ if (keyword.length() > 0) keyword.erase(0, 1);
848
+ return expression()->exclude(keyword);
849
+ }
1893
850
  }
1894
- l.normalize(); r.normalize();
1895
- Units &lhs_unit = l, &rhs_unit = r;
1896
- return lhs_unit == rhs_unit &&
1897
- NEAR_EQUAL(l.value(), r.value());
1898
- }
1899
-
1900
- bool Number::operator< (const Number& rhs) const
1901
- {
1902
- Number l(*this), r(rhs); l.reduce(); r.reduce();
1903
- size_t lhs_units = l.numerators.size() + l.denominators.size();
1904
- size_t rhs_units = r.numerators.size() + r.denominators.size();
1905
- // unitless and only having one unit seems equivalent (will change in future)
1906
- if (!lhs_units || !rhs_units) {
1907
- return l.value() < r.value();
851
+ if (s->statement_type() == Statement::MEDIA)
852
+ {
853
+ return expression()->exclude("media");
1908
854
  }
1909
- l.normalize(); r.normalize();
1910
- Units &lhs_unit = l, &rhs_unit = r;
1911
- if (!(lhs_unit == rhs_unit)) {
1912
- /* ToDo: do we always get usefull backtraces? */
1913
- throw Exception::IncompatibleUnits(rhs, *this);
855
+ if (s->statement_type() == Statement::RULESET)
856
+ {
857
+ return expression()->exclude("rule");
1914
858
  }
1915
- return lhs_unit < rhs_unit ||
1916
- l.value() < r.value();
1917
- }
1918
-
1919
- bool String_Quoted::operator== (const Expression& rhs) const
1920
- {
1921
- if (String_Quoted_Ptr_Const qstr = Cast<String_Quoted>(&rhs)) {
1922
- return (value() == qstr->value());
1923
- } else if (String_Constant_Ptr_Const cstr = Cast<String_Constant>(&rhs)) {
1924
- return (value() == cstr->value());
859
+ if (s->statement_type() == Statement::SUPPORTS)
860
+ {
861
+ return expression()->exclude("supports");
1925
862
  }
1926
- return false;
1927
- }
1928
-
1929
- bool String_Constant::is_invisible() const {
1930
- return value_.empty() && quote_mark_ == 0;
1931
- }
1932
-
1933
- bool String_Constant::operator== (const Expression& rhs) const
1934
- {
1935
- if (String_Quoted_Ptr_Const qstr = Cast<String_Quoted>(&rhs)) {
1936
- return (value() == qstr->value());
1937
- } else if (String_Constant_Ptr_Const cstr = Cast<String_Constant>(&rhs)) {
1938
- return (value() == cstr->value());
863
+ if (Directive_Obj dir = Cast<Directive>(s))
864
+ {
865
+ if (dir->is_keyframes()) return expression()->exclude("keyframes");
1939
866
  }
1940
867
  return false;
1941
868
  }
1942
869
 
1943
- bool String_Schema::is_left_interpolant(void) const
1944
- {
1945
- return length() && first()->is_left_interpolant();
1946
- }
1947
- bool String_Schema::is_right_interpolant(void) const
1948
- {
1949
- return length() && last()->is_right_interpolant();
1950
- }
870
+ /////////////////////////////////////////////////////////////////////////
871
+ /////////////////////////////////////////////////////////////////////////
1951
872
 
1952
- bool String_Schema::operator== (const Expression& rhs) const
1953
- {
1954
- if (String_Schema_Ptr_Const r = Cast<String_Schema>(&rhs)) {
1955
- if (length() != r->length()) return false;
1956
- for (size_t i = 0, L = length(); i < L; ++i) {
1957
- Expression_Obj rv = (*r)[i];
1958
- Expression_Obj lv = (*this)[i];
1959
- if (!lv || !rv) return false;
1960
- if (!(*lv == *rv)) return false;
1961
- }
1962
- return true;
1963
- }
1964
- return false;
1965
- }
873
+ Parameter::Parameter(ParserState pstate, std::string n, Expression_Obj def, bool rest)
874
+ : AST_Node(pstate), name_(n), default_value_(def), is_rest_parameter_(rest)
875
+ { }
876
+ Parameter::Parameter(const Parameter* ptr)
877
+ : AST_Node(ptr),
878
+ name_(ptr->name_),
879
+ default_value_(ptr->default_value_),
880
+ is_rest_parameter_(ptr->is_rest_parameter_)
881
+ { }
1966
882
 
1967
- bool Boolean::operator== (const Expression& rhs) const
1968
- {
1969
- if (Boolean_Ptr_Const r = Cast<Boolean>(&rhs)) {
1970
- return (value() == r->value());
1971
- }
1972
- return false;
1973
- }
883
+ /////////////////////////////////////////////////////////////////////////
884
+ /////////////////////////////////////////////////////////////////////////
1974
885
 
1975
- bool Color::operator== (const Expression& rhs) const
1976
- {
1977
- if (Color_Ptr_Const r = Cast<Color>(&rhs)) {
1978
- return r_ == r->r() &&
1979
- g_ == r->g() &&
1980
- b_ == r->b() &&
1981
- a_ == r->a();
1982
- }
1983
- return false;
1984
- }
886
+ Parameters::Parameters(ParserState pstate)
887
+ : AST_Node(pstate),
888
+ Vectorized<Parameter_Obj>(),
889
+ has_optional_parameters_(false),
890
+ has_rest_parameter_(false)
891
+ { }
892
+ Parameters::Parameters(const Parameters* ptr)
893
+ : AST_Node(ptr),
894
+ Vectorized<Parameter_Obj>(*ptr),
895
+ has_optional_parameters_(ptr->has_optional_parameters_),
896
+ has_rest_parameter_(ptr->has_rest_parameter_)
897
+ { }
1985
898
 
1986
- bool List::operator== (const Expression& rhs) const
899
+ void Parameters::adjust_after_pushing(Parameter_Obj p)
1987
900
  {
1988
- if (List_Ptr_Const r = Cast<List>(&rhs)) {
1989
- if (length() != r->length()) return false;
1990
- if (separator() != r->separator()) return false;
1991
- if (is_bracketed() != r->is_bracketed()) return false;
1992
- for (size_t i = 0, L = length(); i < L; ++i) {
1993
- Expression_Obj rv = r->at(i);
1994
- Expression_Obj lv = this->at(i);
1995
- if (!lv || !rv) return false;
1996
- if (!(*lv == *rv)) return false;
901
+ if (p->default_value()) {
902
+ if (has_rest_parameter()) {
903
+ coreError("optional parameters may not be combined with variable-length parameters", p->pstate());
1997
904
  }
1998
- return true;
905
+ has_optional_parameters(true);
1999
906
  }
2000
- return false;
2001
- }
2002
-
2003
- bool Map::operator== (const Expression& rhs) const
2004
- {
2005
- if (Map_Ptr_Const r = Cast<Map>(&rhs)) {
2006
- if (length() != r->length()) return false;
2007
- for (auto key : keys()) {
2008
- Expression_Obj lv = at(key);
2009
- Expression_Obj rv = r->at(key);
2010
- if (!rv || !lv) return false;
2011
- if (!(*lv == *rv)) return false;
907
+ else if (p->is_rest_parameter()) {
908
+ if (has_rest_parameter()) {
909
+ coreError("functions and mixins cannot have more than one variable-length parameter", p->pstate());
2012
910
  }
2013
- return true;
2014
- }
2015
- return false;
2016
- }
2017
-
2018
- bool Null::operator== (const Expression& rhs) const
2019
- {
2020
- return rhs.concrete_type() == NULL_VAL;
2021
- }
2022
-
2023
- bool Function::operator== (const Expression& rhs) const
2024
- {
2025
- if (Function_Ptr_Const r = Cast<Function>(&rhs)) {
2026
- Definition_Ptr_Const d1 = Cast<Definition>(definition());
2027
- Definition_Ptr_Const d2 = Cast<Definition>(r->definition());
2028
- return d1 && d2 && d1 == d2 && is_css() == r->is_css();
911
+ has_rest_parameter(true);
2029
912
  }
2030
- return false;
2031
- }
2032
-
2033
- size_t List::size() const {
2034
- if (!is_arglist_) return length();
2035
- // arglist expects a list of arguments
2036
- // so we need to break before keywords
2037
- for (size_t i = 0, L = length(); i < L; ++i) {
2038
- Expression_Obj obj = this->at(i);
2039
- if (Argument_Ptr arg = Cast<Argument>(obj)) {
2040
- if (!arg->name().empty()) return i;
913
+ else {
914
+ if (has_rest_parameter()) {
915
+ coreError("required parameters must precede variable-length parameters", p->pstate());
2041
916
  }
2042
- }
2043
- return length();
2044
- }
2045
-
2046
- Expression_Obj Hashed::at(Expression_Obj k) const
2047
- {
2048
- if (elements_.count(k))
2049
- { return elements_.at(k); }
2050
- else { return NULL; }
2051
- }
2052
-
2053
- bool Binary_Expression::is_left_interpolant(void) const
2054
- {
2055
- return is_interpolant() || (left() && left()->is_left_interpolant());
2056
- }
2057
- bool Binary_Expression::is_right_interpolant(void) const
2058
- {
2059
- return is_interpolant() || (right() && right()->is_right_interpolant());
2060
- }
2061
-
2062
- const std::string AST_Node::to_string(Sass_Inspect_Options opt) const
2063
- {
2064
- Sass_Output_Options out(opt);
2065
- Emitter emitter(out);
2066
- Inspect i(emitter);
2067
- i.in_declaration = true;
2068
- // ToDo: inspect should be const
2069
- const_cast<AST_Node_Ptr>(this)->perform(&i);
2070
- return i.get_buffer();
2071
- }
2072
-
2073
- const std::string AST_Node::to_string() const
2074
- {
2075
- return to_string({ NESTED, 5 });
2076
- }
2077
-
2078
- std::string String_Quoted::inspect() const
2079
- {
2080
- return quote(value_, '*');
2081
- }
2082
-
2083
- std::string String_Constant::inspect() const
2084
- {
2085
- return quote(value_, '*');
2086
- }
2087
-
2088
- bool Declaration::is_invisible() const
2089
- {
2090
- if (is_custom_property()) return false;
2091
-
2092
- return !(value_ && value_->concrete_type() != Expression::NULL_VAL);
2093
- }
2094
-
2095
- //////////////////////////////////////////////////////////////////////////////////////////
2096
- // Additional method on Lists to retrieve values directly or from an encompassed Argument.
2097
- //////////////////////////////////////////////////////////////////////////////////////////
2098
- Expression_Obj List::value_at_index(size_t i) {
2099
- Expression_Obj obj = this->at(i);
2100
- if (is_arglist_) {
2101
- if (Argument_Ptr arg = Cast<Argument>(obj)) {
2102
- return arg->value();
2103
- } else {
2104
- return obj;
917
+ if (has_optional_parameters()) {
918
+ coreError("required parameters must precede optional parameters", p->pstate());
2105
919
  }
2106
- } else {
2107
- return obj;
2108
920
  }
2109
921
  }
2110
922
 
2111
- //////////////////////////////////////////////////////////////////////////////////////////
2112
- // Convert map to (key, value) list.
2113
- //////////////////////////////////////////////////////////////////////////////////////////
2114
- List_Obj Map::to_list(ParserState& pstate) {
2115
- List_Obj ret = SASS_MEMORY_NEW(List, pstate, length(), SASS_COMMA);
2116
-
2117
- for (auto key : keys()) {
2118
- List_Obj l = SASS_MEMORY_NEW(List, pstate, 2);
2119
- l->append(key);
2120
- l->append(at(key));
2121
- ret->append(l);
2122
- }
2123
-
2124
- return ret;
2125
- }
923
+ /////////////////////////////////////////////////////////////////////////
924
+ /////////////////////////////////////////////////////////////////////////
2126
925
 
2127
- //////////////////////////////////////////////////////////////////////////////////////////
2128
- // Copy implementations
2129
- //////////////////////////////////////////////////////////////////////////////////////////
2130
-
2131
- #ifdef DEBUG_SHARED_PTR
2132
-
2133
- #define IMPLEMENT_AST_OPERATORS(klass) \
2134
- klass##_Ptr klass::copy(std::string file, size_t line) const { \
2135
- klass##_Ptr cpy = new klass(this); \
2136
- cpy->trace(file, line); \
2137
- return cpy; \
2138
- } \
2139
- klass##_Ptr klass::clone(std::string file, size_t line) const { \
2140
- klass##_Ptr cpy = copy(file, line); \
2141
- cpy->cloneChildren(); \
2142
- return cpy; \
2143
- } \
2144
-
2145
- #else
2146
-
2147
- #define IMPLEMENT_AST_OPERATORS(klass) \
2148
- klass##_Ptr klass::copy() const { \
2149
- return new klass(this); \
2150
- } \
2151
- klass##_Ptr klass::clone() const { \
2152
- klass##_Ptr cpy = copy(); \
2153
- cpy->cloneChildren(); \
2154
- return cpy; \
2155
- } \
2156
-
2157
- #endif
2158
-
2159
- IMPLEMENT_AST_OPERATORS(Supports_Operator);
2160
- IMPLEMENT_AST_OPERATORS(Supports_Negation);
2161
- IMPLEMENT_AST_OPERATORS(Compound_Selector);
2162
- IMPLEMENT_AST_OPERATORS(Complex_Selector);
2163
- IMPLEMENT_AST_OPERATORS(Element_Selector);
2164
- IMPLEMENT_AST_OPERATORS(Class_Selector);
2165
- IMPLEMENT_AST_OPERATORS(Id_Selector);
2166
- IMPLEMENT_AST_OPERATORS(Pseudo_Selector);
2167
- IMPLEMENT_AST_OPERATORS(Wrapped_Selector);
2168
- IMPLEMENT_AST_OPERATORS(Selector_List);
2169
926
  IMPLEMENT_AST_OPERATORS(Ruleset);
2170
927
  IMPLEMENT_AST_OPERATORS(Media_Block);
2171
- IMPLEMENT_AST_OPERATORS(Custom_Warning);
2172
- IMPLEMENT_AST_OPERATORS(Custom_Error);
2173
- IMPLEMENT_AST_OPERATORS(List);
2174
- IMPLEMENT_AST_OPERATORS(Map);
2175
- IMPLEMENT_AST_OPERATORS(Function);
2176
- IMPLEMENT_AST_OPERATORS(Number);
2177
- IMPLEMENT_AST_OPERATORS(Binary_Expression);
2178
- IMPLEMENT_AST_OPERATORS(String_Schema);
2179
- IMPLEMENT_AST_OPERATORS(String_Constant);
2180
- IMPLEMENT_AST_OPERATORS(String_Quoted);
2181
- IMPLEMENT_AST_OPERATORS(Boolean);
2182
- IMPLEMENT_AST_OPERATORS(Color);
2183
- IMPLEMENT_AST_OPERATORS(Null);
2184
- IMPLEMENT_AST_OPERATORS(Parent_Selector);
2185
928
  IMPLEMENT_AST_OPERATORS(Import);
2186
929
  IMPLEMENT_AST_OPERATORS(Import_Stub);
2187
- IMPLEMENT_AST_OPERATORS(Function_Call);
2188
930
  IMPLEMENT_AST_OPERATORS(Directive);
2189
931
  IMPLEMENT_AST_OPERATORS(At_Root_Block);
2190
- IMPLEMENT_AST_OPERATORS(Supports_Block);
2191
932
  IMPLEMENT_AST_OPERATORS(While);
2192
933
  IMPLEMENT_AST_OPERATORS(Each);
2193
934
  IMPLEMENT_AST_OPERATORS(For);
@@ -2202,25 +943,21 @@ namespace Sass {
2202
943
  IMPLEMENT_AST_OPERATORS(Assignment);
2203
944
  IMPLEMENT_AST_OPERATORS(Return);
2204
945
  IMPLEMENT_AST_OPERATORS(At_Root_Query);
2205
- IMPLEMENT_AST_OPERATORS(Variable);
2206
946
  IMPLEMENT_AST_OPERATORS(Comment);
2207
- IMPLEMENT_AST_OPERATORS(Attribute_Selector);
2208
- IMPLEMENT_AST_OPERATORS(Supports_Interpolation);
2209
- IMPLEMENT_AST_OPERATORS(Supports_Declaration);
2210
- IMPLEMENT_AST_OPERATORS(Supports_Condition);
2211
947
  IMPLEMENT_AST_OPERATORS(Parameters);
2212
948
  IMPLEMENT_AST_OPERATORS(Parameter);
2213
949
  IMPLEMENT_AST_OPERATORS(Arguments);
2214
950
  IMPLEMENT_AST_OPERATORS(Argument);
2215
951
  IMPLEMENT_AST_OPERATORS(Unary_Expression);
2216
- IMPLEMENT_AST_OPERATORS(Function_Call_Schema);
2217
952
  IMPLEMENT_AST_OPERATORS(Block);
2218
953
  IMPLEMENT_AST_OPERATORS(Content);
2219
954
  IMPLEMENT_AST_OPERATORS(Trace);
2220
955
  IMPLEMENT_AST_OPERATORS(Keyframe_Rule);
2221
956
  IMPLEMENT_AST_OPERATORS(Bubble);
2222
- IMPLEMENT_AST_OPERATORS(Selector_Schema);
2223
- IMPLEMENT_AST_OPERATORS(Placeholder_Selector);
2224
957
  IMPLEMENT_AST_OPERATORS(Definition);
2225
958
  IMPLEMENT_AST_OPERATORS(Declaration);
959
+
960
+ /////////////////////////////////////////////////////////////////////////
961
+ /////////////////////////////////////////////////////////////////////////
962
+
2226
963
  }