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
@@ -1,4 +1,7 @@
1
+ // sass.hpp must go before all system headers to get the
2
+ // __EXTENSIONS__ fix on Solaris.
1
3
  #include "sass.hpp"
4
+
2
5
  #include "operators.hpp"
3
6
 
4
7
  namespace Sass {
@@ -54,13 +57,24 @@ namespace Sass {
54
57
  bool lte(Expression_Obj lhs, Expression_Obj rhs) { return cmp(lhs, rhs, Sass_OP::LTE) || eq(lhs, rhs); }
55
58
  bool gte(Expression_Obj lhs, Expression_Obj rhs) { return !cmp(lhs, rhs, Sass_OP::GTE) || eq(lhs, rhs); }
56
59
 
60
+ /* colour math deprecation warning */
61
+ void op_color_deprecation(enum Sass_OP op, std::string lsh, std::string rhs, const ParserState& pstate)
62
+ {
63
+ deprecated(
64
+ "The operation `" + lsh + " " + sass_op_to_name(op) + " " + rhs +
65
+ "` is deprecated and will be an error in future versions.",
66
+ "Consider using Sass's color functions instead.\n"
67
+ "https://sass-lang.com/documentation/Sass/Script/Functions.html#other_color_functions",
68
+ /*with_column=*/false, pstate);
69
+ }
70
+
57
71
  /* static function, throws OperationError, has no traces but optional pstate for returned value */
58
- Value_Ptr op_strings(Sass::Operand operand, Value& lhs, Value& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed)
72
+ Value* op_strings(Sass::Operand operand, Value& lhs, Value& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed)
59
73
  {
60
74
  enum Sass_OP op = operand.operand;
61
75
 
62
- String_Quoted_Ptr lqstr = Cast<String_Quoted>(&lhs);
63
- String_Quoted_Ptr rqstr = Cast<String_Quoted>(&rhs);
76
+ String_Quoted* lqstr = Cast<String_Quoted>(&lhs);
77
+ String_Quoted* rqstr = Cast<String_Quoted>(&rhs);
64
78
 
65
79
  std::string lstr(lqstr ? lqstr->value() : lhs.to_string(opt));
66
80
  std::string rstr(rqstr ? rqstr->value() : rhs.to_string(opt));
@@ -104,16 +118,21 @@ namespace Sass {
104
118
  return SASS_MEMORY_NEW(String_Constant, pstate, lstr + sep + rstr);
105
119
  }
106
120
 
121
+ /* ToDo: allow to operate also with hsla colors */
107
122
  /* static function, throws OperationError, has no traces but optional pstate for returned value */
108
- Value_Ptr op_colors(enum Sass_OP op, const Color& lhs, const Color& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed)
123
+ Value* op_colors(enum Sass_OP op, const Color_RGBA& lhs, const Color_RGBA& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed)
109
124
  {
125
+
110
126
  if (lhs.a() != rhs.a()) {
111
127
  throw Exception::AlphaChannelsNotEqual(&lhs, &rhs, op);
112
128
  }
113
- if (op == Sass_OP::DIV && (!rhs.r() || !rhs.g() || !rhs.b())) {
129
+ if ((op == Sass_OP::DIV || op == Sass_OP::MOD) && (!rhs.r() || !rhs.g() || !rhs.b())) {
114
130
  throw Exception::ZeroDivisionError(lhs, rhs);
115
131
  }
116
- return SASS_MEMORY_NEW(Color,
132
+
133
+ op_color_deprecation(op, lhs.to_string(), rhs.to_string(), pstate);
134
+
135
+ return SASS_MEMORY_NEW(Color_RGBA,
117
136
  pstate,
118
137
  ops[op](lhs.r(), rhs.r()),
119
138
  ops[op](lhs.g(), rhs.g()),
@@ -122,20 +141,20 @@ namespace Sass {
122
141
  }
123
142
 
124
143
  /* static function, throws OperationError, has no traces but optional pstate for returned value */
125
- Value_Ptr op_numbers(enum Sass_OP op, const Number& lhs, const Number& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed)
144
+ Value* op_numbers(enum Sass_OP op, const Number& lhs, const Number& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed)
126
145
  {
127
146
  double lval = lhs.value();
128
147
  double rval = rhs.value();
129
148
 
149
+ if (op == Sass_OP::MOD && rval == 0) {
150
+ return SASS_MEMORY_NEW(String_Quoted, pstate, "NaN");
151
+ }
152
+
130
153
  if (op == Sass_OP::DIV && rval == 0) {
131
154
  std::string result(lval ? "Infinity" : "NaN");
132
155
  return SASS_MEMORY_NEW(String_Quoted, pstate, result);
133
156
  }
134
157
 
135
- if (op == Sass_OP::MOD && rval == 0) {
136
- throw Exception::ZeroDivisionError(lhs, rhs);
137
- }
138
-
139
158
  size_t l_n_units = lhs.numerators.size();
140
159
  size_t l_d_units = lhs.numerators.size();
141
160
  size_t r_n_units = rhs.denominators.size();
@@ -145,7 +164,7 @@ namespace Sass {
145
164
  if (l_n_units + l_d_units <= 1 && r_n_units + r_d_units <= 1) {
146
165
  if (lhs.numerators == rhs.numerators) {
147
166
  if (lhs.denominators == rhs.denominators) {
148
- Number_Ptr v = SASS_MEMORY_COPY(&lhs);
167
+ Number* v = SASS_MEMORY_COPY(&lhs);
149
168
  v->value(ops[op](lval, rval));
150
169
  return v;
151
170
  }
@@ -192,13 +211,15 @@ namespace Sass {
192
211
  }
193
212
 
194
213
  /* static function, throws OperationError, has no traces but optional pstate for returned value */
195
- Value_Ptr op_number_color(enum Sass_OP op, const Number& lhs, const Color& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed)
214
+ Value* op_number_color(enum Sass_OP op, const Number& lhs, const Color_RGBA& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed)
196
215
  {
197
216
  double lval = lhs.value();
217
+
198
218
  switch (op) {
199
219
  case Sass_OP::ADD:
200
220
  case Sass_OP::MUL: {
201
- return SASS_MEMORY_NEW(Color,
221
+ op_color_deprecation(op, lhs.to_string(), rhs.to_string(opt), pstate);
222
+ return SASS_MEMORY_NEW(Color_RGBA,
202
223
  pstate,
203
224
  ops[op](lval, rhs.r()),
204
225
  ops[op](lval, rhs.g()),
@@ -208,6 +229,7 @@ namespace Sass {
208
229
  case Sass_OP::SUB:
209
230
  case Sass_OP::DIV: {
210
231
  std::string color(rhs.to_string(opt));
232
+ op_color_deprecation(op, lhs.to_string(), color, pstate);
211
233
  return SASS_MEMORY_NEW(String_Quoted,
212
234
  pstate,
213
235
  lhs.to_string(opt)
@@ -220,14 +242,18 @@ namespace Sass {
220
242
  }
221
243
 
222
244
  /* static function, throws OperationError, has no traces but optional pstate for returned value */
223
- Value_Ptr op_color_number(enum Sass_OP op, const Color& lhs, const Number& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed)
245
+ Value* op_color_number(enum Sass_OP op, const Color_RGBA& lhs, const Number& rhs, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed)
224
246
  {
225
247
  double rval = rhs.value();
226
- if (op == Sass_OP::DIV && rval == 0) {
248
+
249
+ if ((op == Sass_OP::DIV || op == Sass_OP::DIV) && rval == 0) {
227
250
  // comparison of Fixnum with Float failed?
228
251
  throw Exception::ZeroDivisionError(lhs, rhs);
229
252
  }
230
- return SASS_MEMORY_NEW(Color,
253
+
254
+ op_color_deprecation(op, lhs.to_string(), rhs.to_string(), pstate);
255
+
256
+ return SASS_MEMORY_NEW(Color_RGBA,
231
257
  pstate,
232
258
  ops[op](lhs.r(), rval),
233
259
  ops[op](lhs.g(), rval),
@@ -17,11 +17,11 @@ namespace Sass {
17
17
  bool lte(Expression_Obj, Expression_Obj);
18
18
  bool gte(Expression_Obj, Expression_Obj);
19
19
  // arithmetic for all the combinations that matter
20
- Value_Ptr op_strings(Sass::Operand, Value&, Value&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false);
21
- Value_Ptr op_colors(enum Sass_OP, const Color&, const Color&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false);
22
- Value_Ptr op_numbers(enum Sass_OP, const Number&, const Number&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false);
23
- Value_Ptr op_number_color(enum Sass_OP, const Number&, const Color&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false);
24
- Value_Ptr op_color_number(enum Sass_OP, const Color&, const Number&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false);
20
+ Value* op_strings(Sass::Operand, Value&, Value&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false);
21
+ Value* op_colors(enum Sass_OP, const Color_RGBA&, const Color_RGBA&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false);
22
+ Value* op_numbers(enum Sass_OP, const Number&, const Number&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false);
23
+ Value* op_number_color(enum Sass_OP, const Number&, const Color_RGBA&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false);
24
+ Value* op_color_number(enum Sass_OP, const Color_RGBA&, const Number&, struct Sass_Inspect_Options opt, const ParserState& pstate, bool delayed = false);
25
25
 
26
26
  };
27
27
 
@@ -1,6 +1,10 @@
1
+ // sass.hpp must go before all system headers to get the
2
+ // __EXTENSIONS__ fix on Solaris.
1
3
  #include "sass.hpp"
4
+
2
5
  #include "ast.hpp"
3
6
  #include "output.hpp"
7
+ #include "util.hpp"
4
8
 
5
9
  namespace Sass {
6
10
 
@@ -12,12 +16,12 @@ namespace Sass {
12
16
 
13
17
  Output::~Output() { }
14
18
 
15
- void Output::fallback_impl(AST_Node_Ptr n)
19
+ void Output::fallback_impl(AST_Node* n)
16
20
  {
17
21
  return n->perform(this);
18
22
  }
19
23
 
20
- void Output::operator()(Number_Ptr n)
24
+ void Output::operator()(Number* n)
21
25
  {
22
26
  // check for a valid unit here
23
27
  // includes result for reporting
@@ -31,12 +35,12 @@ namespace Sass {
31
35
  append_token(res, n);
32
36
  }
33
37
 
34
- void Output::operator()(Import_Ptr imp)
38
+ void Output::operator()(Import* imp)
35
39
  {
36
40
  top_nodes.push_back(imp);
37
41
  }
38
42
 
39
- void Output::operator()(Map_Ptr m)
43
+ void Output::operator()(Map* m)
40
44
  {
41
45
  // should be handle in check_expression
42
46
  throw Exception::InvalidValue({}, *m);
@@ -86,9 +90,8 @@ namespace Sass {
86
90
 
87
91
  }
88
92
 
89
- void Output::operator()(Comment_Ptr c)
93
+ void Output::operator()(Comment* c)
90
94
  {
91
- std::string txt = c->text()->to_string(opt);
92
95
  // if (indentation && txt == "/**/") return;
93
96
  bool important = c->is_important();
94
97
  if (output_style() != COMPRESSED || important) {
@@ -108,7 +111,7 @@ namespace Sass {
108
111
  }
109
112
  }
110
113
 
111
- void Output::operator()(Ruleset_Ptr r)
114
+ void Output::operator()(Ruleset* r)
112
115
  {
113
116
  Selector_Obj s = r->selector();
114
117
  Block_Obj b = r->block();
@@ -142,19 +145,19 @@ namespace Sass {
142
145
  Statement_Obj stm = b->at(i);
143
146
  bool bPrintExpression = true;
144
147
  // Check print conditions
145
- if (Declaration_Ptr dec = Cast<Declaration>(stm)) {
146
- if (String_Constant_Ptr valConst = Cast<String_Constant>(dec->value())) {
148
+ if (Declaration* dec = Cast<Declaration>(stm)) {
149
+ if (String_Constant* valConst = Cast<String_Constant>(dec->value())) {
147
150
  std::string val(valConst->value());
148
- if (String_Quoted_Ptr qstr = Cast<String_Quoted>(valConst)) {
151
+ if (String_Quoted* qstr = Cast<String_Quoted>(valConst)) {
149
152
  if (!qstr->quote_mark() && val.empty()) {
150
153
  bPrintExpression = false;
151
154
  }
152
155
  }
153
156
  }
154
- else if (List_Ptr list = Cast<List>(dec->value())) {
157
+ else if (List* list = Cast<List>(dec->value())) {
155
158
  bool all_invisible = true;
156
159
  for (size_t list_i = 0, list_L = list->length(); list_i < list_L; ++list_i) {
157
- Expression_Ptr item = list->at(list_i);
160
+ Expression* item = list->at(list_i);
158
161
  if (!item->is_invisible()) all_invisible = false;
159
162
  }
160
163
  if (all_invisible && !list->is_bracketed()) bPrintExpression = false;
@@ -169,7 +172,7 @@ namespace Sass {
169
172
  append_scope_closer(b);
170
173
 
171
174
  }
172
- void Output::operator()(Keyframe_Rule_Ptr r)
175
+ void Output::operator()(Keyframe_Rule* r)
173
176
  {
174
177
  Block_Obj b = r->block();
175
178
  Selector_Obj v = r->name();
@@ -192,7 +195,7 @@ namespace Sass {
192
195
  append_scope_closer();
193
196
  }
194
197
 
195
- void Output::operator()(Supports_Block_Ptr f)
198
+ void Output::operator()(Supports_Block* f)
196
199
  {
197
200
  if (f->is_invisible()) return;
198
201
 
@@ -229,7 +232,7 @@ namespace Sass {
229
232
 
230
233
  }
231
234
 
232
- void Output::operator()(Media_Block_Ptr m)
235
+ void Output::operator()(Media_Block* m)
233
236
  {
234
237
  if (m->is_invisible()) return;
235
238
 
@@ -266,7 +269,7 @@ namespace Sass {
266
269
  append_scope_closer();
267
270
  }
268
271
 
269
- void Output::operator()(Directive_Ptr a)
272
+ void Output::operator()(Directive* a)
270
273
  {
271
274
  std::string kwd = a->keyword();
272
275
  Selector_Obj s = a->selector();
@@ -309,7 +312,7 @@ namespace Sass {
309
312
  append_scope_closer();
310
313
  }
311
314
 
312
- void Output::operator()(String_Quoted_Ptr s)
315
+ void Output::operator()(String_Quoted* s)
313
316
  {
314
317
  if (s->quote_mark()) {
315
318
  append_token(quote(s->value(), s->quote_mark()), s);
@@ -320,7 +323,7 @@ namespace Sass {
320
323
  }
321
324
  }
322
325
 
323
- void Output::operator()(String_Constant_Ptr s)
326
+ void Output::operator()(String_Constant* s)
324
327
  {
325
328
  std::string value(s->value());
326
329
  if (s->can_compress_whitespace() && output_style() == COMPRESSED) {
@@ -11,13 +11,6 @@
11
11
  namespace Sass {
12
12
  class Context;
13
13
 
14
- // Refactor to make it generic to find linefeed (look behind)
15
- inline bool ends_with(std::string const & value, std::string const & ending)
16
- {
17
- if (ending.size() > value.size()) return false;
18
- return std::equal(ending.rbegin(), ending.rend(), value.rbegin());
19
- }
20
-
21
14
  class Output : public Inspect {
22
15
  protected:
23
16
  using Inspect::operator();
@@ -28,24 +21,24 @@ namespace Sass {
28
21
 
29
22
  protected:
30
23
  std::string charset;
31
- std::vector<AST_Node_Ptr> top_nodes;
24
+ std::vector<AST_Node*> top_nodes;
32
25
 
33
26
  public:
34
27
  OutputBuffer get_buffer(void);
35
28
 
36
- virtual void operator()(Map_Ptr);
37
- virtual void operator()(Ruleset_Ptr);
38
- virtual void operator()(Supports_Block_Ptr);
39
- virtual void operator()(Media_Block_Ptr);
40
- virtual void operator()(Directive_Ptr);
41
- virtual void operator()(Keyframe_Rule_Ptr);
42
- virtual void operator()(Import_Ptr);
43
- virtual void operator()(Comment_Ptr);
44
- virtual void operator()(Number_Ptr);
45
- virtual void operator()(String_Quoted_Ptr);
46
- virtual void operator()(String_Constant_Ptr);
47
-
48
- void fallback_impl(AST_Node_Ptr n);
29
+ virtual void operator()(Map*);
30
+ virtual void operator()(Ruleset*);
31
+ virtual void operator()(Supports_Block*);
32
+ virtual void operator()(Media_Block*);
33
+ virtual void operator()(Directive*);
34
+ virtual void operator()(Keyframe_Rule*);
35
+ virtual void operator()(Import*);
36
+ virtual void operator()(Comment*);
37
+ virtual void operator()(Number*);
38
+ virtual void operator()(String_Quoted*);
39
+ virtual void operator()(String_Constant*);
40
+
41
+ void fallback_impl(AST_Node* n);
49
42
 
50
43
  };
51
44
 
@@ -1,4 +1,7 @@
1
+ // sass.hpp must go before all system headers to get the
2
+ // __EXTENSIONS__ fix on Solaris.
1
3
  #include "sass.hpp"
4
+
2
5
  #include "parser.hpp"
3
6
  #include "file.hpp"
4
7
  #include "inspect.hpp"
@@ -8,6 +11,7 @@
8
11
  #include "color_maps.hpp"
9
12
  #include "sass/functions.h"
10
13
  #include "error_handling.hpp"
14
+ #include "util_string.hpp"
11
15
 
12
16
  // Notes about delayed: some ast nodes can have delayed evaluation so
13
17
  // they can preserve their original semantics if needed. This is most
@@ -30,11 +34,11 @@ namespace Sass {
30
34
  using namespace Constants;
31
35
  using namespace Prelexer;
32
36
 
33
- Parser Parser::from_c_str(const char* beg, Context& ctx, Backtraces traces, ParserState pstate, const char* source)
37
+ Parser Parser::from_c_str(const char* beg, Context& ctx, Backtraces traces, ParserState pstate, const char* source, bool allow_parent)
34
38
  {
35
39
  pstate.offset.column = 0;
36
40
  pstate.offset.line = 0;
37
- Parser p(ctx, pstate, traces);
41
+ Parser p(ctx, pstate, traces, allow_parent);
38
42
  p.source = source ? source : beg;
39
43
  p.position = beg ? beg : p.source;
40
44
  p.end = p.position + strlen(p.position);
@@ -44,11 +48,11 @@ namespace Sass {
44
48
  return p;
45
49
  }
46
50
 
47
- Parser Parser::from_c_str(const char* beg, const char* end, Context& ctx, Backtraces traces, ParserState pstate, const char* source)
51
+ Parser Parser::from_c_str(const char* beg, const char* end, Context& ctx, Backtraces traces, ParserState pstate, const char* source, bool allow_parent)
48
52
  {
49
53
  pstate.offset.column = 0;
50
54
  pstate.offset.line = 0;
51
- Parser p(ctx, pstate, traces);
55
+ Parser p(ctx, pstate, traces, allow_parent);
52
56
  p.source = source ? source : beg;
53
57
  p.position = beg ? beg : p.source;
54
58
  p.end = end ? end : p.position + strlen(p.position);
@@ -66,10 +70,9 @@ namespace Sass {
66
70
  pstate.offset.line = 0;
67
71
  }
68
72
 
69
- Selector_List_Obj Parser::parse_selector(const char* beg, Context& ctx, Backtraces traces, ParserState pstate, const char* source)
73
+ Selector_List_Obj Parser::parse_selector(const char* beg, Context& ctx, Backtraces traces, ParserState pstate, const char* source, bool allow_parent)
70
74
  {
71
- Parser p = Parser::from_c_str(beg, ctx, traces, pstate, source);
72
- // ToDo: ruby sass errors on parent references
75
+ Parser p = Parser::from_c_str(beg, ctx, traces, pstate, source, allow_parent);
73
76
  // ToDo: remap the source-map entries somehow
74
77
  return p.parse_selector_list(false);
75
78
  }
@@ -333,11 +336,11 @@ namespace Sass {
333
336
  do {
334
337
  while (lex< block_comment >());
335
338
  if (lex< quoted_string >()) {
336
- to_import.push_back(std::pair<std::string,Function_Call_Obj>(std::string(lexed), 0));
339
+ to_import.push_back(std::pair<std::string,Function_Call_Obj>(std::string(lexed), {}));
337
340
  }
338
341
  else if (lex< uri_prefix >()) {
339
342
  Arguments_Obj args = SASS_MEMORY_NEW(Arguments, pstate);
340
- Function_Call_Obj result = SASS_MEMORY_NEW(Function_Call, pstate, "url", args);
343
+ Function_Call_Obj result = SASS_MEMORY_NEW(Function_Call, pstate, std::string("url"), args);
341
344
 
342
345
  if (lex< quoted_string >()) {
343
346
  Expression_Obj quoted_url = parse_string();
@@ -479,7 +482,7 @@ namespace Sass {
479
482
  bool is_arglist = false;
480
483
  bool is_keyword = false;
481
484
  Expression_Obj val = parse_space_list();
482
- List_Ptr l = Cast<List>(val);
485
+ List* l = Cast<List>(val);
483
486
  if (lex_css< exactly< ellipsis > >()) {
484
487
  if (val->concrete_type() == Expression::MAP || (
485
488
  (l != NULL && l->separator() == SASS_HASH)
@@ -556,7 +559,7 @@ namespace Sass {
556
559
  lex< optional_spaces >();
557
560
  const char* i = position;
558
561
  // selector schema re-uses string schema implementation
559
- String_Schema_Ptr schema = SASS_MEMORY_NEW(String_Schema, pstate);
562
+ String_Schema* schema = SASS_MEMORY_NEW(String_Schema, pstate);
560
563
  // the selector schema is pretty much just a wrapper for the string schema
561
564
  Selector_Schema_Obj selector_schema = SASS_MEMORY_NEW(Selector_Schema, pstate, schema);
562
565
  selector_schema->connect_parent(chroot == false);
@@ -645,13 +648,27 @@ namespace Sass {
645
648
  // normalize underscores to hyphens
646
649
  std::string name(Util::normalize_underscores(lexed));
647
650
  // create the initial mixin call object
648
- Mixin_Call_Obj call = SASS_MEMORY_NEW(Mixin_Call, pstate, name, 0, 0);
651
+ Mixin_Call_Obj call = SASS_MEMORY_NEW(Mixin_Call, pstate, name, {}, {}, {});
649
652
  // parse mandatory arguments
650
653
  call->arguments(parse_arguments());
654
+ // parse using and optional block parameters
655
+ bool has_parameters = lex< kwd_using >() != nullptr;
656
+
657
+ if (has_parameters) {
658
+ if (!peek< exactly<'('> >()) css_error("Invalid CSS", " after ", ": expected \"(\", was ");
659
+ } else {
660
+ if (peek< exactly<'('> >()) css_error("Invalid CSS", " after ", ": expected \";\", was ");
661
+ }
662
+
663
+ if (has_parameters) call->block_parameters(parse_parameters());
664
+
651
665
  // parse optional block
652
666
  if (peek < exactly <'{'> >()) {
653
667
  call->block(parse_block());
654
668
  }
669
+ else if (has_parameters) {
670
+ css_error("Invalid CSS", " after ", ": expected \"{\", was ");
671
+ }
655
672
  // return ast node
656
673
  return call.detach();
657
674
  }
@@ -706,7 +723,7 @@ namespace Sass {
706
723
  }
707
724
  // update for end position
708
725
  group->update_pstate(pstate);
709
- if (sel) sel->last()->has_line_break(false);
726
+ if (sel) sel->mutable_last()->has_line_break(false);
710
727
  return group.detach();
711
728
  }
712
729
  // EO parse_selector_list
@@ -719,12 +736,12 @@ namespace Sass {
719
736
  {
720
737
 
721
738
  NESTING_GUARD(nestings);
722
- String_Obj reference = 0;
739
+ String_Obj reference;
723
740
  lex < block_comment >();
724
741
  advanceToNextToken();
725
742
  Complex_Selector_Obj sel = SASS_MEMORY_NEW(Complex_Selector, pstate);
726
743
 
727
- if (peek < end_of_file >()) return 0;
744
+ if (peek < end_of_file >()) return {};
728
745
 
729
746
  // parse the left hand side
730
747
  Compound_Selector_Obj lhs;
@@ -743,12 +760,12 @@ namespace Sass {
743
760
  else if (lex< sequence < exactly<'/'>, negate < exactly < '*' > > > >()) {
744
761
  // comments are allowed, but not spaces?
745
762
  combinator = Complex_Selector::REFERENCE;
746
- if (!lex < re_reference_combinator >()) return 0;
763
+ if (!lex < re_reference_combinator >()) return {};
747
764
  reference = SASS_MEMORY_NEW(String_Constant, pstate, lexed);
748
- if (!lex < exactly < '/' > >()) return 0; // ToDo: error msg?
765
+ if (!lex < exactly < '/' > >()) return {}; // ToDo: error msg?
749
766
  }
750
767
 
751
- if (!lhs && combinator == Complex_Selector::ANCESTOR_OF) return 0;
768
+ if (!lhs && combinator == Complex_Selector::ANCESTOR_OF) return {};
752
769
 
753
770
  // lex < block_comment >();
754
771
  sel->head(lhs);
@@ -771,7 +788,7 @@ namespace Sass {
771
788
  if (!sel->has_parent_ref() && !chroot) {
772
789
  // create the objects to wrap parent selector reference
773
790
  Compound_Selector_Obj head = SASS_MEMORY_NEW(Compound_Selector, pstate);
774
- Parent_Selector_Ptr parent = SASS_MEMORY_NEW(Parent_Selector, pstate, false);
791
+ Parent_Selector* parent = SASS_MEMORY_NEW(Parent_Selector, pstate, false);
775
792
  parent->media_block(last_media_block);
776
793
  head->media_block(last_media_block);
777
794
  // add simple selector
@@ -818,6 +835,7 @@ namespace Sass {
818
835
  // parse parent selector
819
836
  else if (lex< exactly<'&'> >(false))
820
837
  {
838
+ if (!allow_parent) error("Parent selectors aren't allowed here.");
821
839
  // this produces a linefeed!?
822
840
  seq->has_parent_reference(true);
823
841
  seq->append(SASS_MEMORY_NEW(Parent_Selector, pstate));
@@ -837,7 +855,7 @@ namespace Sass {
837
855
  // parse type selector
838
856
  else if (lex< re_type_selector >(false))
839
857
  {
840
- seq->append(SASS_MEMORY_NEW(Element_Selector, pstate, lexed));
858
+ seq->append(SASS_MEMORY_NEW(Type_Selector, pstate, lexed));
841
859
  }
842
860
  // peek for abort conditions
843
861
  else if (peek< spaces >()) break;
@@ -847,7 +865,7 @@ namespace Sass {
847
865
  // otherwise parse another simple selector
848
866
  else {
849
867
  Simple_Selector_Obj sel = parse_simple_selector();
850
- if (!sel) return 0;
868
+ if (!sel) return {};
851
869
  seq->append(sel);
852
870
  }
853
871
  }
@@ -872,7 +890,7 @@ namespace Sass {
872
890
  return SASS_MEMORY_NEW(Id_Selector, pstate, lexed);
873
891
  }
874
892
  else if (lex< alternatives < variable, number, static_reference_combinator > >()) {
875
- return SASS_MEMORY_NEW(Element_Selector, pstate, lexed);
893
+ return SASS_MEMORY_NEW(Type_Selector, pstate, lexed);
876
894
  }
877
895
  else if (peek< pseudo_not >()) {
878
896
  return parse_negated_selector();
@@ -887,7 +905,7 @@ namespace Sass {
887
905
  return parse_attribute_selector();
888
906
  }
889
907
  else if (lex< placeholder >()) {
890
- Placeholder_Selector_Ptr sel = SASS_MEMORY_NEW(Placeholder_Selector, pstate, lexed);
908
+ Placeholder_Selector* sel = SASS_MEMORY_NEW(Placeholder_Selector, pstate, lexed);
891
909
  sel->media_block(last_media_block);
892
910
  return sel;
893
911
  }
@@ -895,7 +913,7 @@ namespace Sass {
895
913
  css_error("Invalid CSS", " after ", ": expected selector, was ");
896
914
  }
897
915
  // failed
898
- return 0;
916
+ return {};
899
917
  }
900
918
 
901
919
  Wrapped_Selector_Obj Parser::parse_negated_selector()
@@ -915,7 +933,7 @@ namespace Sass {
915
933
  // it can contain more selectors inside parentheses
916
934
  Simple_Selector_Obj Parser::parse_pseudo_selector() {
917
935
  if (lex< sequence<
918
- optional < pseudo_prefix >,
936
+ pseudo_prefix,
919
937
  // we keep the space within the name, strange enough
920
938
  // ToDo: refactor output to schedule the space for it
921
939
  // or do we really want to keep the real white-space?
@@ -966,7 +984,7 @@ namespace Sass {
966
984
  css_error("Invalid CSS", " after ", ": expected \")\", was ");
967
985
 
968
986
  // unreachable statement
969
- return 0;
987
+ return {};
970
988
  }
971
989
 
972
990
  const char* Parser::re_attr_sensitive_close(const char* src)
@@ -985,11 +1003,11 @@ namespace Sass {
985
1003
  if (!lex_css< attribute_name >()) error("invalid attribute name in attribute selector");
986
1004
  std::string name(lexed);
987
1005
  if (lex_css< re_attr_sensitive_close >()) {
988
- return SASS_MEMORY_NEW(Attribute_Selector, p, name, "", 0, 0);
1006
+ return SASS_MEMORY_NEW(Attribute_Selector, p, name, "", {}, {});
989
1007
  }
990
1008
  else if (lex_css< re_attr_insensitive_close >()) {
991
1009
  char modifier = lexed.begin[0];
992
- return SASS_MEMORY_NEW(Attribute_Selector, p, name, "", 0, modifier);
1010
+ return SASS_MEMORY_NEW(Attribute_Selector, p, name, "", {}, modifier);
993
1011
  }
994
1012
  if (!lex_css< alternatives< exact_match, class_match, dash_match,
995
1013
  prefix_match, suffix_match, substring_match > >()) {
@@ -997,7 +1015,7 @@ namespace Sass {
997
1015
  }
998
1016
  std::string matcher(lexed);
999
1017
 
1000
- String_Obj value = 0;
1018
+ String_Obj value;
1001
1019
  if (lex_css< identifier >()) {
1002
1020
  value = SASS_MEMORY_NEW(String_Constant, p, lexed);
1003
1021
  }
@@ -1016,7 +1034,7 @@ namespace Sass {
1016
1034
  return SASS_MEMORY_NEW(Attribute_Selector, p, name, matcher, value, modifier);
1017
1035
  }
1018
1036
  error("unterminated attribute selector for " + name);
1019
- return NULL; // to satisfy compilers (error must not return)
1037
+ return {}; // to satisfy compilers (error must not return)
1020
1038
  }
1021
1039
 
1022
1040
  /* parse block comment and add to block */
@@ -1072,7 +1090,7 @@ namespace Sass {
1072
1090
  }
1073
1091
  else {
1074
1092
  value = parse_list(DELAYED);
1075
- if (List_Ptr list = Cast<List>(value)) {
1093
+ if (List* list = Cast<List>(value)) {
1076
1094
  if (!list->is_bracketed() && list->length() == 0 && !peek< exactly <'{'> >()) {
1077
1095
  css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");
1078
1096
  }
@@ -1478,7 +1496,7 @@ namespace Sass {
1478
1496
  }
1479
1497
  else if (lex< identifier_schema >()) {
1480
1498
  String_Obj string = parse_identifier_schema();
1481
- if (String_Schema_Ptr schema = Cast<String_Schema>(string)) {
1499
+ if (String_Schema* schema = Cast<String_Schema>(string)) {
1482
1500
  if (lex < exactly < '(' > >()) {
1483
1501
  schema->append(parse_list());
1484
1502
  lex < exactly < ')' > >();
@@ -1493,29 +1511,29 @@ namespace Sass {
1493
1511
  return parse_function_call();
1494
1512
  }
1495
1513
  else if (lex< exactly<'+'> >()) {
1496
- Unary_Expression_Ptr ex = SASS_MEMORY_NEW(Unary_Expression, pstate, Unary_Expression::PLUS, parse_factor());
1514
+ Unary_Expression* ex = SASS_MEMORY_NEW(Unary_Expression, pstate, Unary_Expression::PLUS, parse_factor());
1497
1515
  if (ex && ex->operand()) ex->is_delayed(ex->operand()->is_delayed());
1498
1516
  return ex;
1499
1517
  }
1500
1518
  else if (lex< exactly<'-'> >()) {
1501
- Unary_Expression_Ptr ex = SASS_MEMORY_NEW(Unary_Expression, pstate, Unary_Expression::MINUS, parse_factor());
1519
+ Unary_Expression* ex = SASS_MEMORY_NEW(Unary_Expression, pstate, Unary_Expression::MINUS, parse_factor());
1502
1520
  if (ex && ex->operand()) ex->is_delayed(ex->operand()->is_delayed());
1503
1521
  return ex;
1504
1522
  }
1505
1523
  else if (lex< exactly<'/'> >()) {
1506
- Unary_Expression_Ptr ex = SASS_MEMORY_NEW(Unary_Expression, pstate, Unary_Expression::SLASH, parse_factor());
1524
+ Unary_Expression* ex = SASS_MEMORY_NEW(Unary_Expression, pstate, Unary_Expression::SLASH, parse_factor());
1507
1525
  if (ex && ex->operand()) ex->is_delayed(ex->operand()->is_delayed());
1508
1526
  return ex;
1509
1527
  }
1510
1528
  else if (lex< sequence< kwd_not > >()) {
1511
- Unary_Expression_Ptr ex = SASS_MEMORY_NEW(Unary_Expression, pstate, Unary_Expression::NOT, parse_factor());
1529
+ Unary_Expression* ex = SASS_MEMORY_NEW(Unary_Expression, pstate, Unary_Expression::NOT, parse_factor());
1512
1530
  if (ex && ex->operand()) ex->is_delayed(ex->operand()->is_delayed());
1513
1531
  return ex;
1514
1532
  }
1515
1533
  // this whole branch is never hit via spec tests
1516
1534
  else if (peek < sequence < one_plus < alternatives < css_whitespace, exactly<'-'>, exactly<'+'> > >, number > >()) {
1517
1535
  if (parse_number_prefix()) return parse_value(); // prefix is positive
1518
- Unary_Expression_Ptr ex = SASS_MEMORY_NEW(Unary_Expression, pstate, Unary_Expression::MINUS, parse_value());
1536
+ Unary_Expression* ex = SASS_MEMORY_NEW(Unary_Expression, pstate, Unary_Expression::MINUS, parse_value());
1519
1537
  if (ex->operand()) ex->is_delayed(ex->operand()->is_delayed());
1520
1538
  return ex;
1521
1539
  }
@@ -1533,9 +1551,9 @@ namespace Sass {
1533
1551
  (L > 2 && parsed.substr(0, 3) == "-0.") );
1534
1552
  }
1535
1553
 
1536
- Number_Ptr Parser::lexed_number(const ParserState& pstate, const std::string& parsed)
1554
+ Number* Parser::lexed_number(const ParserState& pstate, const std::string& parsed)
1537
1555
  {
1538
- Number_Ptr nr = SASS_MEMORY_NEW(Number,
1556
+ Number* nr = SASS_MEMORY_NEW(Number,
1539
1557
  pstate,
1540
1558
  sass_strtod(parsed.c_str()),
1541
1559
  "",
@@ -1545,9 +1563,9 @@ namespace Sass {
1545
1563
  return nr;
1546
1564
  }
1547
1565
 
1548
- Number_Ptr Parser::lexed_percentage(const ParserState& pstate, const std::string& parsed)
1566
+ Number* Parser::lexed_percentage(const ParserState& pstate, const std::string& parsed)
1549
1567
  {
1550
- Number_Ptr nr = SASS_MEMORY_NEW(Number,
1568
+ Number* nr = SASS_MEMORY_NEW(Number,
1551
1569
  pstate,
1552
1570
  sass_strtod(parsed.c_str()),
1553
1571
  "%",
@@ -1557,7 +1575,7 @@ namespace Sass {
1557
1575
  return nr;
1558
1576
  }
1559
1577
 
1560
- Number_Ptr Parser::lexed_dimension(const ParserState& pstate, const std::string& parsed)
1578
+ Number* Parser::lexed_dimension(const ParserState& pstate, const std::string& parsed)
1561
1579
  {
1562
1580
  size_t L = parsed.length();
1563
1581
  size_t num_pos = parsed.find_first_not_of(" \n\r\t");
@@ -1568,7 +1586,7 @@ namespace Sass {
1568
1586
  }
1569
1587
  if (unit_pos == std::string::npos) unit_pos = L;
1570
1588
  const std::string& num = parsed.substr(num_pos, unit_pos - num_pos);
1571
- Number_Ptr nr = SASS_MEMORY_NEW(Number,
1589
+ Number* nr = SASS_MEMORY_NEW(Number,
1572
1590
  pstate,
1573
1591
  sass_strtod(num.c_str()),
1574
1592
  Token(number(parsed.c_str())),
@@ -1578,9 +1596,9 @@ namespace Sass {
1578
1596
  return nr;
1579
1597
  }
1580
1598
 
1581
- Expression_Ptr Parser::lexed_hex_color(const ParserState& pstate, const std::string& parsed)
1599
+ Value* Parser::lexed_hex_color(const ParserState& pstate, const std::string& parsed)
1582
1600
  {
1583
- Color_Ptr color = NULL;
1601
+ Color_RGBA* color = NULL;
1584
1602
  if (parsed[0] != '#') {
1585
1603
  return SASS_MEMORY_NEW(String_Quoted, pstate, parsed);
1586
1604
  }
@@ -1590,7 +1608,7 @@ namespace Sass {
1590
1608
  std::string r(2, parsed[1]);
1591
1609
  std::string g(2, parsed[2]);
1592
1610
  std::string b(2, parsed[3]);
1593
- color = SASS_MEMORY_NEW(Color,
1611
+ color = SASS_MEMORY_NEW(Color_RGBA,
1594
1612
  pstate,
1595
1613
  static_cast<double>(strtol(r.c_str(), NULL, 16)),
1596
1614
  static_cast<double>(strtol(g.c_str(), NULL, 16)),
@@ -1598,11 +1616,24 @@ namespace Sass {
1598
1616
  1, // alpha channel
1599
1617
  parsed);
1600
1618
  }
1619
+ else if (parsed.length() == 5) {
1620
+ std::string r(2, parsed[1]);
1621
+ std::string g(2, parsed[2]);
1622
+ std::string b(2, parsed[3]);
1623
+ std::string a(2, parsed[4]);
1624
+ color = SASS_MEMORY_NEW(Color_RGBA,
1625
+ pstate,
1626
+ static_cast<double>(strtol(r.c_str(), NULL, 16)),
1627
+ static_cast<double>(strtol(g.c_str(), NULL, 16)),
1628
+ static_cast<double>(strtol(b.c_str(), NULL, 16)),
1629
+ static_cast<double>(strtol(a.c_str(), NULL, 16)) / 255,
1630
+ parsed);
1631
+ }
1601
1632
  else if (parsed.length() == 7) {
1602
1633
  std::string r(parsed.substr(1,2));
1603
1634
  std::string g(parsed.substr(3,2));
1604
1635
  std::string b(parsed.substr(5,2));
1605
- color = SASS_MEMORY_NEW(Color,
1636
+ color = SASS_MEMORY_NEW(Color_RGBA,
1606
1637
  pstate,
1607
1638
  static_cast<double>(strtol(r.c_str(), NULL, 16)),
1608
1639
  static_cast<double>(strtol(g.c_str(), NULL, 16)),
@@ -1615,7 +1646,7 @@ namespace Sass {
1615
1646
  std::string g(parsed.substr(3,2));
1616
1647
  std::string b(parsed.substr(5,2));
1617
1648
  std::string a(parsed.substr(7,2));
1618
- color = SASS_MEMORY_NEW(Color,
1649
+ color = SASS_MEMORY_NEW(Color_RGBA,
1619
1650
  pstate,
1620
1651
  static_cast<double>(strtol(r.c_str(), NULL, 16)),
1621
1652
  static_cast<double>(strtol(g.c_str(), NULL, 16)),
@@ -1628,6 +1659,19 @@ namespace Sass {
1628
1659
  return color;
1629
1660
  }
1630
1661
 
1662
+ Value* Parser::color_or_string(const std::string& lexed) const
1663
+ {
1664
+ if (auto color = name_to_color(lexed)) {
1665
+ auto c = SASS_MEMORY_NEW(Color_RGBA, color);
1666
+ c->is_delayed(true);
1667
+ c->pstate(pstate);
1668
+ c->disp(lexed);
1669
+ return c;
1670
+ } else {
1671
+ return SASS_MEMORY_NEW(String_Constant, pstate, lexed);
1672
+ }
1673
+ }
1674
+
1631
1675
  // parse one value for a list
1632
1676
  Expression_Obj Parser::parse_value()
1633
1677
  {
@@ -1637,7 +1681,7 @@ namespace Sass {
1637
1681
  if (match< ampersand >()) {
1638
1682
  warning("In Sass, \"&&\" means two copies of the parent selector. You probably want to use \"and\" instead.", pstate);
1639
1683
  }
1640
- return SASS_MEMORY_NEW(Parent_Selector, pstate); }
1684
+ return SASS_MEMORY_NEW(Parent_Reference, pstate); }
1641
1685
 
1642
1686
  if (lex< kwd_important >())
1643
1687
  { return SASS_MEMORY_NEW(String_Constant, pstate, "!important"); }
@@ -1670,7 +1714,7 @@ namespace Sass {
1670
1714
  { return SASS_MEMORY_NEW(Null, pstate); }
1671
1715
 
1672
1716
  if (lex< identifier >()) {
1673
- return SASS_MEMORY_NEW(String_Constant, pstate, lexed);
1717
+ return color_or_string(lexed);
1674
1718
  }
1675
1719
 
1676
1720
  if (lex< percentage >())
@@ -1681,17 +1725,7 @@ namespace Sass {
1681
1725
  { return lexed_hex_color(lexed); }
1682
1726
 
1683
1727
  if (lex< hexa >())
1684
- {
1685
- std::string s = lexed.to_string();
1686
-
1687
- deprecated(
1688
- "The value \""+s+"\" is currently parsed as a string, but it will be parsed as a color in",
1689
- "future versions of Sass. Use \"unquote('"+s+"')\" to continue parsing it as a string.",
1690
- true, pstate
1691
- );
1692
-
1693
- return SASS_MEMORY_NEW(String_Quoted, pstate, lexed);
1694
- }
1728
+ { return lexed_hex_color(lexed); }
1695
1729
 
1696
1730
  if (lex< sequence < exactly <'#'>, identifier > >())
1697
1731
  { return SASS_MEMORY_NEW(String_Quoted, pstate, lexed); }
@@ -1710,14 +1744,10 @@ namespace Sass {
1710
1744
  if (lex< variable >())
1711
1745
  { return SASS_MEMORY_NEW(Variable, pstate, Util::normalize_underscores(lexed)); }
1712
1746
 
1713
- // Special case handling for `%` proceeding an interpolant.
1714
- if (lex< sequence< exactly<'%'>, optional< percentage > > >())
1715
- { return SASS_MEMORY_NEW(String_Constant, pstate, lexed); }
1716
-
1717
1747
  css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");
1718
1748
 
1719
1749
  // unreachable statement
1720
- return 0;
1750
+ return {};
1721
1751
  }
1722
1752
 
1723
1753
  // this parses interpolation inside other strings
@@ -1730,7 +1760,7 @@ namespace Sass {
1730
1760
  find_first_in_interval< exactly<hash_lbrace>, block_comment >(i, chunk.end);
1731
1761
 
1732
1762
  if (!p) {
1733
- String_Quoted_Ptr str_quoted = SASS_MEMORY_NEW(String_Quoted, pstate, std::string(i, chunk.end), 0, false, false, true, css);
1763
+ String_Quoted* str_quoted = SASS_MEMORY_NEW(String_Quoted, pstate, std::string(i, chunk.end), 0, false, false, true, css);
1734
1764
  if (!constant && str_quoted->quote_mark()) str_quoted->quote_mark('*');
1735
1765
  return str_quoted;
1736
1766
  }
@@ -1774,74 +1804,66 @@ namespace Sass {
1774
1804
  return schema.detach();
1775
1805
  }
1776
1806
 
1777
- String_Schema_Obj Parser::parse_css_variable_value(bool top_level)
1807
+ String_Schema_Obj Parser::parse_css_variable_value()
1778
1808
  {
1779
1809
  String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate);
1780
- String_Schema_Obj tok;
1781
- if (!(tok = parse_css_variable_value_token(top_level))) {
1782
- return NULL;
1783
- }
1784
-
1785
- schema->concat(tok);
1786
- while ((tok = parse_css_variable_value_token(top_level))) {
1787
- schema->concat(tok);
1788
- }
1789
-
1790
- return schema.detach();
1791
- }
1792
-
1793
- String_Schema_Obj Parser::parse_css_variable_value_token(bool top_level)
1794
- {
1795
- String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate);
1796
- if (
1797
- (top_level && lex< css_variable_top_level_value >(false)) ||
1798
- (!top_level && lex< css_variable_value >(false))
1799
- ) {
1800
- Token str(lexed);
1801
- schema->append(SASS_MEMORY_NEW(String_Constant, pstate, str));
1802
- }
1803
- else if (Expression_Obj tok = lex_interpolation()) {
1804
- if (String_Schema_Ptr s = Cast<String_Schema>(tok)) {
1805
- schema->concat(s);
1806
- } else {
1807
- schema->append(tok);
1808
- }
1809
- }
1810
- else if (lex< quoted_string >()) {
1811
- Expression_Obj tok = parse_string();
1812
- if (String_Schema_Ptr s = Cast<String_Schema>(tok)) {
1813
- schema->concat(s);
1814
- } else {
1815
- schema->append(tok);
1816
- }
1817
- }
1818
- else {
1819
- if (peek< alternatives< exactly<'('>, exactly<'['>, exactly<'{'> > >()) {
1820
- if (lex< exactly<'('> >()) {
1821
- schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string("(")));
1822
- if (String_Schema_Obj tok = parse_css_variable_value(false)) schema->concat(tok);
1823
- if (!lex< exactly<')'> >()) css_error("Invalid CSS", " after ", ": expected \")\", was ");
1824
- schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(")")));
1810
+ std::vector<char> brackets;
1811
+ while (true) {
1812
+ if (
1813
+ (brackets.empty() && lex< css_variable_top_level_value >(false)) ||
1814
+ (!brackets.empty() && lex< css_variable_value >(false))
1815
+ ) {
1816
+ Token str(lexed);
1817
+ schema->append(SASS_MEMORY_NEW(String_Constant, pstate, str));
1818
+ } else if (Expression_Obj tok = lex_interpolation()) {
1819
+ if (String_Schema* s = Cast<String_Schema>(tok)) {
1820
+ if (s->empty()) break;
1821
+ schema->concat(s);
1822
+ } else {
1823
+ schema->append(tok);
1825
1824
  }
1826
- else if (lex< exactly<'['> >()) {
1827
- schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string("[")));
1828
- if (String_Schema_Obj tok = parse_css_variable_value(false)) schema->concat(tok);
1829
- if (!lex< exactly<']'> >()) css_error("Invalid CSS", " after ", ": expected \"]\", was ");
1830
- schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string("]")));
1825
+ } else if (lex< quoted_string >()) {
1826
+ Expression_Obj tok = parse_string();
1827
+ if (tok.isNull()) break;
1828
+ if (String_Schema* s = Cast<String_Schema>(tok)) {
1829
+ if (s->empty()) break;
1830
+ schema->concat(s);
1831
+ } else {
1832
+ schema->append(tok);
1831
1833
  }
1832
- else if (lex< exactly<'{'> >()) {
1833
- schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string("{")));
1834
- if (String_Schema_Obj tok = parse_css_variable_value(false)) schema->concat(tok);
1835
- if (!lex< exactly<'}'> >()) css_error("Invalid CSS", " after ", ": expected \"}\", was ");
1836
- schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string("}")));
1834
+ } else if (lex< alternatives< exactly<'('>, exactly<'['>, exactly<'{'> > >()) {
1835
+ const char opening_bracket = *(position - 1);
1836
+ brackets.push_back(opening_bracket);
1837
+ schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(1, opening_bracket)));
1838
+ } else if (const char *match = peek< alternatives< exactly<')'>, exactly<']'>, exactly<'}'> > >()) {
1839
+ if (brackets.empty()) break;
1840
+ const char closing_bracket = *(match - 1);
1841
+ if (brackets.back() != Util::opening_bracket_for(closing_bracket)) {
1842
+ std::string message = ": expected \"";
1843
+ message += Util::closing_bracket_for(brackets.back());
1844
+ message += "\", was ";
1845
+ css_error("Invalid CSS", " after ", message);
1837
1846
  }
1847
+ lex< alternatives< exactly<')'>, exactly<']'>, exactly<'}'> > >();
1848
+ schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(1, closing_bracket)));
1849
+ brackets.pop_back();
1850
+ } else {
1851
+ break;
1838
1852
  }
1839
1853
  }
1840
1854
 
1841
- return schema->length() > 0 ? schema.detach() : NULL;
1855
+ if (!brackets.empty()) {
1856
+ std::string message = ": expected \"";
1857
+ message += Util::closing_bracket_for(brackets.back());
1858
+ message += "\", was ";
1859
+ css_error("Invalid CSS", " after ", message);
1860
+ }
1861
+
1862
+ if (schema->empty()) error("Custom property values may not be empty.");
1863
+ return schema.detach();
1842
1864
  }
1843
1865
 
1844
- String_Constant_Obj Parser::parse_static_value()
1866
+ Value_Obj Parser::parse_static_value()
1845
1867
  {
1846
1868
  lex< static_value >();
1847
1869
  Token str(lexed);
@@ -1852,8 +1874,7 @@ namespace Sass {
1852
1874
  --str.end;
1853
1875
  --position;
1854
1876
 
1855
- String_Constant_Ptr str_node = SASS_MEMORY_NEW(String_Constant, pstate, str.time_wspace());
1856
- return str_node;
1877
+ return color_or_string(str.time_wspace());;
1857
1878
  }
1858
1879
 
1859
1880
  String_Obj Parser::parse_string()
@@ -1872,7 +1893,7 @@ namespace Sass {
1872
1893
  return SASS_MEMORY_NEW(String_Quoted, pstate, std::string(str.begin, str.end));
1873
1894
  }
1874
1895
 
1875
- String_Schema_Ptr schema = SASS_MEMORY_NEW(String_Schema, pstate);
1896
+ String_Schema* schema = SASS_MEMORY_NEW(String_Schema, pstate);
1876
1897
  while (i < str.end) {
1877
1898
  p = find_first_in_interval< exactly<hash_lbrace>, block_comment >(i, str.end);
1878
1899
  if (p) {
@@ -1907,7 +1928,7 @@ namespace Sass {
1907
1928
 
1908
1929
  String_Obj Parser::parse_ie_keyword_arg()
1909
1930
  {
1910
- String_Schema_Ptr kwd_arg = SASS_MEMORY_NEW(String_Schema, pstate, 3);
1931
+ String_Schema_Obj kwd_arg = SASS_MEMORY_NEW(String_Schema, pstate, 3);
1911
1932
  if (lex< variable >()) {
1912
1933
  kwd_arg->append(SASS_MEMORY_NEW(Variable, pstate, Util::normalize_underscores(lexed)));
1913
1934
  } else {
@@ -1962,7 +1983,7 @@ namespace Sass {
1962
1983
  if (lex< re_static_expression >()) {
1963
1984
  ex = SASS_MEMORY_NEW(String_Constant, pstate, lexed);
1964
1985
  } else {
1965
- ex = parse_list();
1986
+ ex = parse_list(true);
1966
1987
  }
1967
1988
  ex->is_interpolant(true);
1968
1989
  schema->append(ex);
@@ -1986,7 +2007,7 @@ namespace Sass {
1986
2007
  }
1987
2008
  if (peek < exactly < '-' > >()) break;
1988
2009
  }
1989
- else if (lex< sequence < identifier > >()) {
2010
+ else if (lex< identifier >()) {
1990
2011
  schema->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed));
1991
2012
  if ((*position == '"' || *position == '\'') || peek < alternatives < alpha > >()) {
1992
2013
  // need_space = true;
@@ -2128,7 +2149,7 @@ namespace Sass {
2128
2149
  uri = url_string->to_string({ NESTED, 5 });
2129
2150
  }
2130
2151
 
2131
- if (String_Schema_Ptr schema = Cast<String_Schema>(url_string)) {
2152
+ if (String_Schema* schema = Cast<String_Schema>(url_string)) {
2132
2153
  String_Schema_Obj res = SASS_MEMORY_NEW(String_Schema, pstate);
2133
2154
  res->append(SASS_MEMORY_NEW(String_Constant, pstate, prefix));
2134
2155
  res->append(schema);
@@ -2155,6 +2176,7 @@ namespace Sass {
2155
2176
  while (pp && peek< exactly< hash_lbrace > >(pp)) {
2156
2177
  pp = sequence< interpolant, real_uri_value >(pp);
2157
2178
  }
2179
+ if (!pp) return {};
2158
2180
  position = pp;
2159
2181
  return parse_interpolated_chunk(Token(p, position));
2160
2182
  }
@@ -2163,7 +2185,7 @@ namespace Sass {
2163
2185
  return SASS_MEMORY_NEW(String_Constant, pstate, res);
2164
2186
  }
2165
2187
 
2166
- return 0;
2188
+ return {};
2167
2189
  }
2168
2190
 
2169
2191
  Function_Call_Obj Parser::parse_function_call()
@@ -2179,18 +2201,21 @@ namespace Sass {
2179
2201
  return SASS_MEMORY_NEW(Function_Call, call_pos, name, args);
2180
2202
  }
2181
2203
 
2182
- Function_Call_Schema_Obj Parser::parse_function_call_schema()
2204
+ Function_Call_Obj Parser::parse_function_call_schema()
2183
2205
  {
2184
2206
  String_Obj name = parse_identifier_schema();
2185
2207
  ParserState source_position_of_call = pstate;
2186
2208
  Arguments_Obj args = parse_arguments();
2187
2209
 
2188
- return SASS_MEMORY_NEW(Function_Call_Schema, source_position_of_call, name, args);
2210
+ return SASS_MEMORY_NEW(Function_Call, source_position_of_call, name, args);
2189
2211
  }
2190
2212
 
2191
2213
  Content_Obj Parser::parse_content_directive()
2192
2214
  {
2193
- return SASS_MEMORY_NEW(Content, pstate);
2215
+ ParserState call_pos = pstate;
2216
+ Arguments_Obj args = parse_arguments();
2217
+
2218
+ return SASS_MEMORY_NEW(Content, call_pos, args);
2194
2219
  }
2195
2220
 
2196
2221
  If_Obj Parser::parse_if_directive(bool else_if)
@@ -2200,7 +2225,7 @@ namespace Sass {
2200
2225
  bool root = block_stack.back()->is_root();
2201
2226
  Expression_Obj predicate = parse_list();
2202
2227
  Block_Obj block = parse_block(root);
2203
- Block_Obj alternative = NULL;
2228
+ Block_Obj alternative;
2204
2229
 
2205
2230
  // only throw away comment if we parse a case
2206
2231
  // we want all other comments to be parsed
@@ -2285,7 +2310,7 @@ namespace Sass {
2285
2310
  stack.push_back(Scope::Control);
2286
2311
  bool root = block_stack.back()->is_root();
2287
2312
  // create the initial while call object
2288
- While_Obj call = SASS_MEMORY_NEW(While, pstate, 0, 0);
2313
+ While_Obj call = SASS_MEMORY_NEW(While, pstate, {}, {});
2289
2314
  // parse mandatory predicate
2290
2315
  Expression_Obj predicate = parse_list();
2291
2316
  List_Obj l = Cast<List>(predicate);
@@ -2305,7 +2330,7 @@ namespace Sass {
2305
2330
  Media_Block_Obj Parser::parse_media_block()
2306
2331
  {
2307
2332
  stack.push_back(Scope::Media);
2308
- Media_Block_Obj media_block = SASS_MEMORY_NEW(Media_Block, pstate, 0, 0);
2333
+ Media_Block_Obj media_block = SASS_MEMORY_NEW(Media_Block, pstate, {}, {});
2309
2334
 
2310
2335
  media_block->media_queries(parse_media_queries());
2311
2336
 
@@ -2327,7 +2352,7 @@ namespace Sass {
2327
2352
  return queries.detach();
2328
2353
  }
2329
2354
 
2330
- // Expression_Ptr Parser::parse_media_query()
2355
+ // Expression* Parser::parse_media_query()
2331
2356
  Media_Query_Obj Parser::parse_media_query()
2332
2357
  {
2333
2358
  advanceToNextToken();
@@ -2341,7 +2366,7 @@ namespace Sass {
2341
2366
 
2342
2367
  while (lex_css < kwd_and >()) media_query->append(parse_media_expression());
2343
2368
  if (lex < identifier_schema >()) {
2344
- String_Schema_Ptr schema = SASS_MEMORY_NEW(String_Schema, pstate);
2369
+ String_Schema* schema = SASS_MEMORY_NEW(String_Schema, pstate);
2345
2370
  schema->append(media_query->media_type());
2346
2371
  schema->append(SASS_MEMORY_NEW(String_Constant, pstate, " "));
2347
2372
  schema->append(parse_identifier_schema());
@@ -2358,7 +2383,7 @@ namespace Sass {
2358
2383
  {
2359
2384
  if (lex < identifier_schema >()) {
2360
2385
  String_Obj ss = parse_identifier_schema();
2361
- return SASS_MEMORY_NEW(Media_Query_Expression, pstate, ss, 0, true);
2386
+ return SASS_MEMORY_NEW(Media_Query_Expression, pstate, ss, {}, true);
2362
2387
  }
2363
2388
  if (!lex_css< exactly<'('> >()) {
2364
2389
  error("media query expression must begin with '('");
@@ -2368,7 +2393,7 @@ namespace Sass {
2368
2393
  error("media feature required in media query expression");
2369
2394
  }
2370
2395
  feature = parse_expression();
2371
- Expression_Obj expression = 0;
2396
+ Expression_Obj expression;
2372
2397
  if (lex_css< exactly<':'> >()) {
2373
2398
  expression = parse_list(DELAYED);
2374
2399
  }
@@ -2382,10 +2407,7 @@ namespace Sass {
2382
2407
  // these are very similar to media blocks
2383
2408
  Supports_Block_Obj Parser::parse_supports_directive()
2384
2409
  {
2385
- Supports_Condition_Obj cond = parse_supports_condition();
2386
- if (!cond) {
2387
- css_error("Invalid CSS", " after ", ": expected @supports condition (e.g. (display: flexbox)), was ", false);
2388
- }
2410
+ Supports_Condition_Obj cond = parse_supports_condition(/*top_level=*/true);
2389
2411
  // create the ast node object for the support queries
2390
2412
  Supports_Block_Obj query = SASS_MEMORY_NEW(Supports_Block, pstate, cond);
2391
2413
  // additional block is mandatory
@@ -2397,27 +2419,27 @@ namespace Sass {
2397
2419
 
2398
2420
  // parse one query operation
2399
2421
  // may encounter nested queries
2400
- Supports_Condition_Obj Parser::parse_supports_condition()
2422
+ Supports_Condition_Obj Parser::parse_supports_condition(bool top_level)
2401
2423
  {
2402
2424
  lex < css_whitespace >();
2403
2425
  Supports_Condition_Obj cond;
2404
2426
  if ((cond = parse_supports_negation())) return cond;
2405
- if ((cond = parse_supports_operator())) return cond;
2427
+ if ((cond = parse_supports_operator(top_level))) return cond;
2406
2428
  if ((cond = parse_supports_interpolation())) return cond;
2407
2429
  return cond;
2408
2430
  }
2409
2431
 
2410
2432
  Supports_Condition_Obj Parser::parse_supports_negation()
2411
2433
  {
2412
- if (!lex < kwd_not >()) return 0;
2413
- Supports_Condition_Obj cond = parse_supports_condition_in_parens();
2434
+ if (!lex < kwd_not >()) return {};
2435
+ Supports_Condition_Obj cond = parse_supports_condition_in_parens(/*parens_required=*/true);
2414
2436
  return SASS_MEMORY_NEW(Supports_Negation, pstate, cond);
2415
2437
  }
2416
2438
 
2417
- Supports_Condition_Obj Parser::parse_supports_operator()
2439
+ Supports_Condition_Obj Parser::parse_supports_operator(bool top_level)
2418
2440
  {
2419
- Supports_Condition_Obj cond = parse_supports_condition_in_parens();
2420
- if (cond.isNull()) return 0;
2441
+ Supports_Condition_Obj cond = parse_supports_condition_in_parens(/*parens_required=*/top_level);
2442
+ if (cond.isNull()) return {};
2421
2443
 
2422
2444
  while (true) {
2423
2445
  Supports_Operator::Operand op = Supports_Operator::OR;
@@ -2425,9 +2447,9 @@ namespace Sass {
2425
2447
  else if(!lex < kwd_or >()) { break; }
2426
2448
 
2427
2449
  lex < css_whitespace >();
2428
- Supports_Condition_Obj right = parse_supports_condition_in_parens();
2450
+ Supports_Condition_Obj right = parse_supports_condition_in_parens(/*parens_required=*/true);
2429
2451
 
2430
- // Supports_Condition_Ptr cc = SASS_MEMORY_NEW(Supports_Condition, *static_cast<Supports_Condition_Ptr>(cond));
2452
+ // Supports_Condition* cc = SASS_MEMORY_NEW(Supports_Condition, *static_cast<Supports_Condition*>(cond));
2431
2453
  cond = SASS_MEMORY_NEW(Supports_Operator, pstate, cond, right, op);
2432
2454
  }
2433
2455
  return cond;
@@ -2435,10 +2457,10 @@ namespace Sass {
2435
2457
 
2436
2458
  Supports_Condition_Obj Parser::parse_supports_interpolation()
2437
2459
  {
2438
- if (!lex < interpolant >()) return 0;
2460
+ if (!lex < interpolant >()) return {};
2439
2461
 
2440
2462
  String_Obj interp = parse_interpolated_chunk(lexed);
2441
- if (!interp) return 0;
2463
+ if (!interp) return {};
2442
2464
 
2443
2465
  return SASS_MEMORY_NEW(Supports_Interpolation, pstate, interp);
2444
2466
  }
@@ -2447,10 +2469,10 @@ namespace Sass {
2447
2469
  // look like declarations their semantics differ significantly
2448
2470
  Supports_Condition_Obj Parser::parse_supports_declaration()
2449
2471
  {
2450
- Supports_Condition_Ptr cond;
2472
+ Supports_Condition* cond;
2451
2473
  // parse something declaration like
2452
2474
  Expression_Obj feature = parse_expression();
2453
- Expression_Obj expression = 0;
2475
+ Expression_Obj expression;
2454
2476
  if (lex_css< exactly<':'> >()) {
2455
2477
  expression = parse_list(DELAYED);
2456
2478
  }
@@ -2463,21 +2485,24 @@ namespace Sass {
2463
2485
  return cond;
2464
2486
  }
2465
2487
 
2466
- Supports_Condition_Obj Parser::parse_supports_condition_in_parens()
2488
+ Supports_Condition_Obj Parser::parse_supports_condition_in_parens(bool parens_required)
2467
2489
  {
2468
2490
  Supports_Condition_Obj interp = parse_supports_interpolation();
2469
2491
  if (interp != 0) return interp;
2470
2492
 
2471
- if (!lex < exactly <'('> >()) return 0;
2493
+ if (!lex < exactly <'('> >()) {
2494
+ if (parens_required) {
2495
+ css_error("Invalid CSS", " after ", ": expected @supports condition (e.g. (display: flexbox)), was ", /*trim=*/false);
2496
+ } else {
2497
+ return {};
2498
+ }
2499
+ }
2472
2500
  lex < css_whitespace >();
2473
2501
 
2474
- Supports_Condition_Obj cond = parse_supports_condition();
2475
- if (cond != 0) {
2476
- if (!lex < exactly <')'> >()) error("unclosed parenthesis in @supports declaration");
2477
- } else {
2478
- cond = parse_supports_declaration();
2479
- if (!lex < exactly <')'> >()) error("unclosed parenthesis in @supports declaration");
2480
- }
2502
+ Supports_Condition_Obj cond = parse_supports_condition(/*top_level=*/false);
2503
+ if (cond.isNull()) cond = parse_supports_declaration();
2504
+ if (!lex < exactly <')'> >()) error("unclosed parenthesis in @supports declaration");
2505
+
2481
2506
  lex < css_whitespace >();
2482
2507
  return cond;
2483
2508
  }
@@ -2486,7 +2511,7 @@ namespace Sass {
2486
2511
  {
2487
2512
  stack.push_back(Scope::AtRoot);
2488
2513
  ParserState at_source_position = pstate;
2489
- Block_Obj body = 0;
2514
+ Block_Obj body;
2490
2515
  At_Root_Query_Obj expr;
2491
2516
  Lookahead lookahead_result;
2492
2517
  if (lex_css< exactly<'('> >()) {
@@ -2541,7 +2566,7 @@ namespace Sass {
2541
2566
 
2542
2567
  // this whole branch is never hit via spec tests
2543
2568
 
2544
- Directive_Ptr at_rule = SASS_MEMORY_NEW(Directive, pstate, kwd);
2569
+ Directive* at_rule = SASS_MEMORY_NEW(Directive, pstate, kwd);
2545
2570
  Lookahead lookahead = lookahead_for_include(position);
2546
2571
  if (lookahead.found && !lookahead.has_interpolants) {
2547
2572
  at_rule->selector(parse_selector_list(false));
@@ -2612,7 +2637,7 @@ namespace Sass {
2612
2637
  if (lex < interpolant >(true) != NULL) {
2613
2638
  return parse_interpolated_chunk(lexed, true);
2614
2639
  }
2615
- return 0;
2640
+ return {};
2616
2641
  }
2617
2642
 
2618
2643
  Expression_Obj Parser::lex_interp_uri()
@@ -2678,30 +2703,32 @@ namespace Sass {
2678
2703
  if (match) {
2679
2704
  return SASS_MEMORY_NEW(String_Constant, pstate, lexed);
2680
2705
  }
2681
- return NULL;
2706
+ return {};
2682
2707
  }
2683
2708
 
2684
2709
  Expression_Obj Parser::lex_almost_any_value_token()
2685
2710
  {
2686
2711
  Expression_Obj rv;
2687
- if (*position == 0) return 0;
2712
+ if (*position == 0) return {};
2688
2713
  if ((rv = lex_almost_any_value_chars())) return rv;
2689
2714
  // if ((rv = lex_block_comment())) return rv;
2690
2715
  // if ((rv = lex_single_line_comment())) return rv;
2691
2716
  if ((rv = lex_interp_string())) return rv;
2692
2717
  if ((rv = lex_interp_uri())) return rv;
2693
2718
  if ((rv = lex_interpolation())) return rv;
2694
- return rv;
2719
+ if (lex< alternatives< hex, hex0 > >())
2720
+ { return lexed_hex_color(lexed); }
2721
+ return rv;
2695
2722
  }
2696
2723
 
2697
2724
  String_Schema_Obj Parser::parse_almost_any_value()
2698
2725
  {
2699
2726
 
2700
2727
  String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate);
2701
- if (*position == 0) return 0;
2728
+ if (*position == 0) return {};
2702
2729
  lex < spaces >(false);
2703
2730
  Expression_Obj token = lex_almost_any_value_token();
2704
- if (!token) return 0;
2731
+ if (!token) return {};
2705
2732
  schema->append(token);
2706
2733
  if (*position == 0) {
2707
2734
  schema->rtrim();
@@ -2777,6 +2804,7 @@ namespace Sass {
2777
2804
  >(p)
2778
2805
  ) {
2779
2806
  bool could_be_property = peek< sequence< exactly<'-'>, exactly<'-'> > >(p) != 0;
2807
+ bool could_be_escaped = false;
2780
2808
  while (p < q) {
2781
2809
  // did we have interpolations?
2782
2810
  if (*p == '#' && *(p+1) == '{') {
@@ -2785,9 +2813,10 @@ namespace Sass {
2785
2813
  }
2786
2814
  // A property that's ambiguous with a nested selector is interpreted as a
2787
2815
  // custom property.
2788
- if (*p == ':') {
2816
+ if (*p == ':' && !could_be_escaped) {
2789
2817
  rv.is_custom_property = could_be_property || p+1 == q || peek< space >(p+1);
2790
2818
  }
2819
+ could_be_escaped = *p == '\\';
2791
2820
  ++ p;
2792
2821
  }
2793
2822
  // store anyway }
@@ -2981,7 +3010,7 @@ namespace Sass {
2981
3010
 
2982
3011
  Expression_Obj Parser::fold_operands(Expression_Obj base, std::vector<Expression_Obj>& operands, std::vector<Operand>& ops, size_t i)
2983
3012
  {
2984
- if (String_Schema_Ptr schema = Cast<String_Schema>(base)) {
3013
+ if (String_Schema* schema = Cast<String_Schema>(base)) {
2985
3014
  // return schema;
2986
3015
  if (schema->has_interpolants()) {
2987
3016
  if (i + 1 < operands.size() && (
@@ -3004,7 +3033,7 @@ namespace Sass {
3004
3033
  }
3005
3034
 
3006
3035
  for (size_t S = operands.size(); i < S; ++i) {
3007
- if (String_Schema_Ptr schema = Cast<String_Schema>(operands[i])) {
3036
+ if (String_Schema* schema = Cast<String_Schema>(operands[i])) {
3008
3037
  if (schema->has_interpolants()) {
3009
3038
  if (i + 1 < S) {
3010
3039
  // this whole branch is never hit via spec tests
@@ -3021,13 +3050,13 @@ namespace Sass {
3021
3050
  } else {
3022
3051
  base = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), ops[i], base, operands[i]);
3023
3052
  }
3024
- Binary_Expression_Ptr b = Cast<Binary_Expression>(base.ptr());
3053
+ Binary_Expression* b = Cast<Binary_Expression>(base.ptr());
3025
3054
  if (b && ops[i].operand == Sass_OP::DIV && b->left()->is_delayed() && b->right()->is_delayed()) {
3026
3055
  base->is_delayed(true);
3027
3056
  }
3028
3057
  }
3029
3058
  // nested binary expression are never to be delayed
3030
- if (Binary_Expression_Ptr b = Cast<Binary_Expression>(base)) {
3059
+ if (Binary_Expression* b = Cast<Binary_Expression>(base)) {
3031
3060
  if (Cast<Binary_Expression>(b->left())) base->set_delayed(false);
3032
3061
  if (Cast<Binary_Expression>(b->right())) base->set_delayed(false);
3033
3062
  }
@@ -3038,8 +3067,11 @@ namespace Sass {
3038
3067
  {
3039
3068
  Position p(pos.line ? pos : before_token);
3040
3069
  ParserState pstate(path, source, p, Offset(0, 0));
3070
+ // `pstate.src` may not outlive stack unwind so we must copy it.
3071
+ char *src_copy = sass_copy_c_string(pstate.src);
3072
+ pstate.src = src_copy;
3041
3073
  traces.push_back(Backtrace(pstate));
3042
- throw Exception::InvalidSass(pstate, traces, msg);
3074
+ throw Exception::InvalidSass(pstate, traces, msg, src_copy);
3043
3075
  }
3044
3076
 
3045
3077
  void Parser::error(std::string msg)