sassc 2.0.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.gitmodules +1 -1
  4. data/.travis.yml +9 -3
  5. data/CHANGELOG.md +36 -0
  6. data/CODE_OF_CONDUCT.md +1 -1
  7. data/README.md +1 -1
  8. data/Rakefile +43 -7
  9. data/ext/depend +4 -0
  10. data/ext/extconf.rb +92 -0
  11. data/ext/libsass/VERSION +1 -0
  12. data/ext/libsass/include/sass/base.h +9 -1
  13. data/ext/libsass/include/sass/context.h +5 -1
  14. data/ext/libsass/src/MurmurHash2.hpp +91 -0
  15. data/ext/libsass/src/ast.cpp +755 -2028
  16. data/ext/libsass/src/ast.hpp +492 -2477
  17. data/ext/libsass/src/{to_c.cpp → ast2c.cpp} +22 -16
  18. data/ext/libsass/src/ast2c.hpp +39 -0
  19. data/ext/libsass/src/ast_def_macros.hpp +70 -10
  20. data/ext/libsass/src/ast_fwd_decl.cpp +5 -3
  21. data/ext/libsass/src/ast_fwd_decl.hpp +107 -296
  22. data/ext/libsass/src/ast_helpers.hpp +292 -0
  23. data/ext/libsass/src/ast_sel_cmp.cpp +396 -0
  24. data/ext/libsass/src/ast_sel_super.cpp +539 -0
  25. data/ext/libsass/src/ast_sel_unify.cpp +275 -0
  26. data/ext/libsass/src/ast_sel_weave.cpp +616 -0
  27. data/ext/libsass/src/ast_selectors.cpp +1043 -0
  28. data/ext/libsass/src/ast_selectors.hpp +522 -0
  29. data/ext/libsass/src/ast_supports.cpp +114 -0
  30. data/ext/libsass/src/ast_supports.hpp +121 -0
  31. data/ext/libsass/src/ast_values.cpp +1154 -0
  32. data/ext/libsass/src/ast_values.hpp +498 -0
  33. data/ext/libsass/src/backtrace.cpp +11 -7
  34. data/ext/libsass/src/backtrace.hpp +5 -5
  35. data/ext/libsass/src/base64vlq.cpp +5 -2
  36. data/ext/libsass/src/base64vlq.hpp +1 -1
  37. data/ext/libsass/src/bind.cpp +35 -34
  38. data/ext/libsass/src/bind.hpp +3 -1
  39. data/ext/libsass/src/c2ast.cpp +64 -0
  40. data/ext/libsass/src/c2ast.hpp +14 -0
  41. data/ext/libsass/src/cencode.c +4 -6
  42. data/ext/libsass/src/check_nesting.cpp +83 -88
  43. data/ext/libsass/src/check_nesting.hpp +39 -34
  44. data/ext/libsass/src/color_maps.cpp +168 -164
  45. data/ext/libsass/src/color_maps.hpp +152 -160
  46. data/ext/libsass/src/constants.cpp +20 -0
  47. data/ext/libsass/src/constants.hpp +19 -0
  48. data/ext/libsass/src/context.cpp +104 -121
  49. data/ext/libsass/src/context.hpp +43 -55
  50. data/ext/libsass/src/cssize.cpp +103 -188
  51. data/ext/libsass/src/cssize.hpp +45 -51
  52. data/ext/libsass/src/dart_helpers.hpp +199 -0
  53. data/ext/libsass/src/debugger.hpp +524 -361
  54. data/ext/libsass/src/emitter.cpp +26 -26
  55. data/ext/libsass/src/emitter.hpp +20 -18
  56. data/ext/libsass/src/environment.cpp +41 -27
  57. data/ext/libsass/src/environment.hpp +33 -22
  58. data/ext/libsass/src/error_handling.cpp +92 -94
  59. data/ext/libsass/src/error_handling.hpp +73 -50
  60. data/ext/libsass/src/eval.cpp +380 -515
  61. data/ext/libsass/src/eval.hpp +64 -57
  62. data/ext/libsass/src/eval_selectors.cpp +75 -0
  63. data/ext/libsass/src/expand.cpp +322 -263
  64. data/ext/libsass/src/expand.hpp +55 -39
  65. data/ext/libsass/src/extender.cpp +1188 -0
  66. data/ext/libsass/src/extender.hpp +399 -0
  67. data/ext/libsass/src/extension.cpp +43 -0
  68. data/ext/libsass/src/extension.hpp +89 -0
  69. data/ext/libsass/src/file.cpp +134 -88
  70. data/ext/libsass/src/file.hpp +28 -37
  71. data/ext/libsass/src/fn_colors.cpp +596 -0
  72. data/ext/libsass/src/fn_colors.hpp +85 -0
  73. data/ext/libsass/src/fn_lists.cpp +285 -0
  74. data/ext/libsass/src/fn_lists.hpp +34 -0
  75. data/ext/libsass/src/fn_maps.cpp +94 -0
  76. data/ext/libsass/src/fn_maps.hpp +30 -0
  77. data/ext/libsass/src/fn_miscs.cpp +244 -0
  78. data/ext/libsass/src/fn_miscs.hpp +40 -0
  79. data/ext/libsass/src/fn_numbers.cpp +227 -0
  80. data/ext/libsass/src/fn_numbers.hpp +45 -0
  81. data/ext/libsass/src/fn_selectors.cpp +205 -0
  82. data/ext/libsass/src/fn_selectors.hpp +35 -0
  83. data/ext/libsass/src/fn_strings.cpp +268 -0
  84. data/ext/libsass/src/fn_strings.hpp +34 -0
  85. data/ext/libsass/src/fn_utils.cpp +158 -0
  86. data/ext/libsass/src/fn_utils.hpp +62 -0
  87. data/ext/libsass/src/inspect.cpp +253 -266
  88. data/ext/libsass/src/inspect.hpp +72 -74
  89. data/ext/libsass/src/json.cpp +2 -2
  90. data/ext/libsass/src/lexer.cpp +25 -84
  91. data/ext/libsass/src/lexer.hpp +5 -16
  92. data/ext/libsass/src/listize.cpp +27 -43
  93. data/ext/libsass/src/listize.hpp +14 -11
  94. data/ext/libsass/src/mapping.hpp +1 -0
  95. data/ext/libsass/src/memory.hpp +12 -0
  96. data/ext/libsass/src/memory/allocator.cpp +48 -0
  97. data/ext/libsass/src/memory/allocator.hpp +138 -0
  98. data/ext/libsass/src/memory/config.hpp +20 -0
  99. data/ext/libsass/src/memory/memory_pool.hpp +186 -0
  100. data/ext/libsass/src/memory/shared_ptr.cpp +33 -0
  101. data/ext/libsass/src/memory/shared_ptr.hpp +332 -0
  102. data/ext/libsass/src/operation.hpp +193 -143
  103. data/ext/libsass/src/operators.cpp +56 -29
  104. data/ext/libsass/src/operators.hpp +11 -11
  105. data/ext/libsass/src/ordered_map.hpp +112 -0
  106. data/ext/libsass/src/output.cpp +59 -75
  107. data/ext/libsass/src/output.hpp +15 -22
  108. data/ext/libsass/src/parser.cpp +662 -818
  109. data/ext/libsass/src/parser.hpp +96 -100
  110. data/ext/libsass/src/parser_selectors.cpp +189 -0
  111. data/ext/libsass/src/permutate.hpp +164 -0
  112. data/ext/libsass/src/plugins.cpp +12 -8
  113. data/ext/libsass/src/plugins.hpp +8 -8
  114. data/ext/libsass/src/position.cpp +10 -26
  115. data/ext/libsass/src/position.hpp +44 -21
  116. data/ext/libsass/src/prelexer.cpp +14 -8
  117. data/ext/libsass/src/prelexer.hpp +9 -9
  118. data/ext/libsass/src/remove_placeholders.cpp +59 -57
  119. data/ext/libsass/src/remove_placeholders.hpp +20 -18
  120. data/ext/libsass/src/sass.cpp +25 -18
  121. data/ext/libsass/src/sass.hpp +22 -14
  122. data/ext/libsass/src/sass2scss.cpp +49 -18
  123. data/ext/libsass/src/sass_context.cpp +104 -132
  124. data/ext/libsass/src/sass_context.hpp +2 -2
  125. data/ext/libsass/src/sass_functions.cpp +7 -4
  126. data/ext/libsass/src/sass_functions.hpp +1 -1
  127. data/ext/libsass/src/sass_values.cpp +26 -21
  128. data/ext/libsass/src/settings.hpp +19 -0
  129. data/ext/libsass/src/source.cpp +69 -0
  130. data/ext/libsass/src/source.hpp +95 -0
  131. data/ext/libsass/src/source_data.hpp +32 -0
  132. data/ext/libsass/src/source_map.cpp +27 -20
  133. data/ext/libsass/src/source_map.hpp +14 -11
  134. data/ext/libsass/src/stylesheet.cpp +22 -0
  135. data/ext/libsass/src/stylesheet.hpp +57 -0
  136. data/ext/libsass/src/to_value.cpp +24 -22
  137. data/ext/libsass/src/to_value.hpp +18 -22
  138. data/ext/libsass/src/units.cpp +28 -22
  139. data/ext/libsass/src/units.hpp +9 -8
  140. data/ext/libsass/src/utf8/checked.h +12 -10
  141. data/ext/libsass/src/utf8/core.h +3 -0
  142. data/ext/libsass/src/utf8_string.cpp +12 -10
  143. data/ext/libsass/src/utf8_string.hpp +7 -6
  144. data/ext/libsass/src/util.cpp +97 -107
  145. data/ext/libsass/src/util.hpp +74 -30
  146. data/ext/libsass/src/util_string.cpp +125 -0
  147. data/ext/libsass/src/util_string.hpp +73 -0
  148. data/ext/libsass/src/values.cpp +33 -24
  149. data/ext/libsass/src/values.hpp +2 -2
  150. data/lib/sassc.rb +24 -0
  151. data/lib/sassc/engine.rb +7 -5
  152. data/lib/sassc/functions_handler.rb +11 -13
  153. data/lib/sassc/native.rb +10 -9
  154. data/lib/sassc/native/native_functions_api.rb +0 -5
  155. data/lib/sassc/script.rb +4 -6
  156. data/lib/sassc/version.rb +1 -1
  157. data/sassc.gemspec +32 -12
  158. data/test/engine_test.rb +32 -2
  159. data/test/functions_test.rb +38 -1
  160. data/test/native_test.rb +4 -4
  161. metadata +95 -109
  162. data/ext/Rakefile +0 -3
  163. data/ext/libsass/.editorconfig +0 -15
  164. data/ext/libsass/.gitattributes +0 -2
  165. data/ext/libsass/.github/CONTRIBUTING.md +0 -65
  166. data/ext/libsass/.github/ISSUE_TEMPLATE.md +0 -54
  167. data/ext/libsass/.gitignore +0 -85
  168. data/ext/libsass/.travis.yml +0 -64
  169. data/ext/libsass/COPYING +0 -25
  170. data/ext/libsass/GNUmakefile.am +0 -88
  171. data/ext/libsass/INSTALL +0 -1
  172. data/ext/libsass/LICENSE +0 -25
  173. data/ext/libsass/Makefile +0 -351
  174. data/ext/libsass/Makefile.conf +0 -55
  175. data/ext/libsass/Readme.md +0 -104
  176. data/ext/libsass/SECURITY.md +0 -10
  177. data/ext/libsass/appveyor.yml +0 -91
  178. data/ext/libsass/configure.ac +0 -138
  179. data/ext/libsass/contrib/libsass.spec +0 -66
  180. data/ext/libsass/docs/README.md +0 -20
  181. data/ext/libsass/docs/api-context-example.md +0 -45
  182. data/ext/libsass/docs/api-context-internal.md +0 -163
  183. data/ext/libsass/docs/api-context.md +0 -295
  184. data/ext/libsass/docs/api-doc.md +0 -215
  185. data/ext/libsass/docs/api-function-example.md +0 -67
  186. data/ext/libsass/docs/api-function-internal.md +0 -8
  187. data/ext/libsass/docs/api-function.md +0 -74
  188. data/ext/libsass/docs/api-importer-example.md +0 -112
  189. data/ext/libsass/docs/api-importer-internal.md +0 -20
  190. data/ext/libsass/docs/api-importer.md +0 -86
  191. data/ext/libsass/docs/api-value-example.md +0 -55
  192. data/ext/libsass/docs/api-value-internal.md +0 -76
  193. data/ext/libsass/docs/api-value.md +0 -154
  194. data/ext/libsass/docs/build-on-darwin.md +0 -27
  195. data/ext/libsass/docs/build-on-gentoo.md +0 -55
  196. data/ext/libsass/docs/build-on-windows.md +0 -139
  197. data/ext/libsass/docs/build-shared-library.md +0 -35
  198. data/ext/libsass/docs/build-with-autotools.md +0 -78
  199. data/ext/libsass/docs/build-with-makefiles.md +0 -68
  200. data/ext/libsass/docs/build-with-mingw.md +0 -107
  201. data/ext/libsass/docs/build-with-visual-studio.md +0 -90
  202. data/ext/libsass/docs/build.md +0 -97
  203. data/ext/libsass/docs/compatibility-plan.md +0 -48
  204. data/ext/libsass/docs/contributing.md +0 -17
  205. data/ext/libsass/docs/custom-functions-internal.md +0 -122
  206. data/ext/libsass/docs/dev-ast-memory.md +0 -223
  207. data/ext/libsass/docs/implementations.md +0 -56
  208. data/ext/libsass/docs/plugins.md +0 -47
  209. data/ext/libsass/docs/setup-environment.md +0 -68
  210. data/ext/libsass/docs/source-map-internals.md +0 -51
  211. data/ext/libsass/docs/trace.md +0 -26
  212. data/ext/libsass/docs/triage.md +0 -17
  213. data/ext/libsass/docs/unicode.md +0 -39
  214. data/ext/libsass/extconf.rb +0 -6
  215. data/ext/libsass/include/sass/version.h.in +0 -12
  216. data/ext/libsass/m4/.gitkeep +0 -0
  217. data/ext/libsass/m4/m4-ax_cxx_compile_stdcxx_11.m4 +0 -167
  218. data/ext/libsass/res/resource.rc +0 -35
  219. data/ext/libsass/script/bootstrap +0 -13
  220. data/ext/libsass/script/branding +0 -10
  221. data/ext/libsass/script/ci-build-libsass +0 -134
  222. data/ext/libsass/script/ci-build-plugin +0 -62
  223. data/ext/libsass/script/ci-install-compiler +0 -6
  224. data/ext/libsass/script/ci-install-deps +0 -20
  225. data/ext/libsass/script/ci-report-coverage +0 -42
  226. data/ext/libsass/script/spec +0 -5
  227. data/ext/libsass/script/tap-driver +0 -652
  228. data/ext/libsass/script/tap-runner +0 -1
  229. data/ext/libsass/script/test-leaks.pl +0 -103
  230. data/ext/libsass/src/GNUmakefile.am +0 -54
  231. data/ext/libsass/src/extend.cpp +0 -2130
  232. data/ext/libsass/src/extend.hpp +0 -86
  233. data/ext/libsass/src/functions.cpp +0 -2234
  234. data/ext/libsass/src/functions.hpp +0 -198
  235. data/ext/libsass/src/memory/SharedPtr.cpp +0 -114
  236. data/ext/libsass/src/memory/SharedPtr.hpp +0 -206
  237. data/ext/libsass/src/node.cpp +0 -319
  238. data/ext/libsass/src/node.hpp +0 -118
  239. data/ext/libsass/src/paths.hpp +0 -71
  240. data/ext/libsass/src/sass_util.cpp +0 -149
  241. data/ext/libsass/src/sass_util.hpp +0 -256
  242. data/ext/libsass/src/subset_map.cpp +0 -55
  243. data/ext/libsass/src/subset_map.hpp +0 -76
  244. data/ext/libsass/src/support/libsass.pc.in +0 -11
  245. data/ext/libsass/src/to_c.hpp +0 -39
  246. data/ext/libsass/test/test_node.cpp +0 -94
  247. data/ext/libsass/test/test_paths.cpp +0 -28
  248. data/ext/libsass/test/test_selector_difference.cpp +0 -25
  249. data/ext/libsass/test/test_specificity.cpp +0 -25
  250. data/ext/libsass/test/test_subset_map.cpp +0 -472
  251. data/ext/libsass/test/test_superselector.cpp +0 -69
  252. data/ext/libsass/test/test_unification.cpp +0 -31
  253. data/ext/libsass/version.sh +0 -10
  254. data/ext/libsass/win/libsass.sln +0 -39
  255. data/ext/libsass/win/libsass.sln.DotSettings +0 -9
  256. data/ext/libsass/win/libsass.targets +0 -118
  257. data/ext/libsass/win/libsass.vcxproj +0 -188
  258. data/ext/libsass/win/libsass.vcxproj.filters +0 -357
  259. data/lib/sassc/native/lib_c.rb +0 -21
  260. data/lib/tasks/libsass.rb +0 -33
@@ -1,7 +1,11 @@
1
1
  #ifndef SASS_EVAL_H
2
2
  #define SASS_EVAL_H
3
3
 
4
+ // sass.hpp must go before all system headers to get the
5
+ // __EXTENSIONS__ fix on Solaris.
6
+ #include "sass.hpp"
4
7
  #include "ast.hpp"
8
+
5
9
  #include "context.hpp"
6
10
  #include "listize.hpp"
7
11
  #include "operation.hpp"
@@ -12,10 +16,7 @@ namespace Sass {
12
16
  class Expand;
13
17
  class Context;
14
18
 
15
- class Eval : public Operation_CRTP<Expression_Ptr, Eval> {
16
-
17
- private:
18
- Expression_Ptr fallback_impl(AST_Node_Ptr n);
19
+ class Eval : public Operation_CRTP<Expression*, Eval> {
19
20
 
20
21
  public:
21
22
  Expand& exp;
@@ -32,72 +33,78 @@ namespace Sass {
32
33
  Boolean_Obj bool_false;
33
34
 
34
35
  Env* environment();
35
- Selector_List_Obj selector();
36
+ EnvStack& env_stack();
37
+ const sass::string cwd();
38
+ CalleeStack& callee_stack();
39
+ struct Sass_Inspect_Options& options();
40
+ struct Sass_Compiler* compiler();
36
41
 
37
42
  // for evaluating function bodies
38
- Expression_Ptr operator()(Block_Ptr);
39
- Expression_Ptr operator()(Assignment_Ptr);
40
- Expression_Ptr operator()(If_Ptr);
41
- Expression_Ptr operator()(For_Ptr);
42
- Expression_Ptr operator()(Each_Ptr);
43
- Expression_Ptr operator()(While_Ptr);
44
- Expression_Ptr operator()(Return_Ptr);
45
- Expression_Ptr operator()(Warning_Ptr);
46
- Expression_Ptr operator()(Error_Ptr);
47
- Expression_Ptr operator()(Debug_Ptr);
48
-
49
- Expression_Ptr operator()(List_Ptr);
50
- Expression_Ptr operator()(Map_Ptr);
51
- Expression_Ptr operator()(Binary_Expression_Ptr);
52
- Expression_Ptr operator()(Unary_Expression_Ptr);
53
- Expression_Ptr operator()(Function_Call_Ptr);
54
- Expression_Ptr operator()(Function_Call_Schema_Ptr);
55
- Expression_Ptr operator()(Variable_Ptr);
56
- Expression_Ptr operator()(Number_Ptr);
57
- Expression_Ptr operator()(Color_Ptr);
58
- Expression_Ptr operator()(Boolean_Ptr);
59
- Expression_Ptr operator()(String_Schema_Ptr);
60
- Expression_Ptr operator()(String_Quoted_Ptr);
61
- Expression_Ptr operator()(String_Constant_Ptr);
62
- // Expression_Ptr operator()(Selector_List_Ptr);
63
- Media_Query_Ptr operator()(Media_Query_Ptr);
64
- Expression_Ptr operator()(Media_Query_Expression_Ptr);
65
- Expression_Ptr operator()(At_Root_Query_Ptr);
66
- Expression_Ptr operator()(Supports_Operator_Ptr);
67
- Expression_Ptr operator()(Supports_Negation_Ptr);
68
- Expression_Ptr operator()(Supports_Declaration_Ptr);
69
- Expression_Ptr operator()(Supports_Interpolation_Ptr);
70
- Expression_Ptr operator()(Null_Ptr);
71
- Expression_Ptr operator()(Argument_Ptr);
72
- Expression_Ptr operator()(Arguments_Ptr);
73
- Expression_Ptr operator()(Comment_Ptr);
43
+ Expression* operator()(Block*);
44
+ Expression* operator()(Assignment*);
45
+ Expression* operator()(If*);
46
+ Expression* operator()(ForRule*);
47
+ Expression* operator()(EachRule*);
48
+ Expression* operator()(WhileRule*);
49
+ Expression* operator()(Return*);
50
+ Expression* operator()(WarningRule*);
51
+ Expression* operator()(ErrorRule*);
52
+ Expression* operator()(DebugRule*);
53
+
54
+ Expression* operator()(List*);
55
+ Expression* operator()(Map*);
56
+ Expression* operator()(Binary_Expression*);
57
+ Expression* operator()(Unary_Expression*);
58
+ Expression* operator()(Function_Call*);
59
+ Expression* operator()(Variable*);
60
+ Expression* operator()(Number*);
61
+ Expression* operator()(Color_RGBA*);
62
+ Expression* operator()(Color_HSLA*);
63
+ Expression* operator()(Boolean*);
64
+ Expression* operator()(String_Schema*);
65
+ Expression* operator()(String_Quoted*);
66
+ Expression* operator()(String_Constant*);
67
+ Media_Query* operator()(Media_Query*);
68
+ Expression* operator()(Media_Query_Expression*);
69
+ Expression* operator()(At_Root_Query*);
70
+ Expression* operator()(SupportsOperation*);
71
+ Expression* operator()(SupportsNegation*);
72
+ Expression* operator()(SupportsDeclaration*);
73
+ Expression* operator()(Supports_Interpolation*);
74
+ Expression* operator()(Null*);
75
+ Expression* operator()(Argument*);
76
+ Expression* operator()(Arguments*);
77
+ Expression* operator()(Comment*);
74
78
 
75
79
  // these will return selectors
76
- Selector_List_Ptr operator()(Selector_List_Ptr);
77
- Selector_List_Ptr operator()(Complex_Selector_Ptr);
78
- Compound_Selector_Ptr operator()(Compound_Selector_Ptr);
79
- Simple_Selector_Ptr operator()(Simple_Selector_Ptr s);
80
- Wrapped_Selector_Ptr operator()(Wrapped_Selector_Ptr s);
80
+ SelectorList* operator()(SelectorList*);
81
+ SelectorList* operator()(ComplexSelector*);
82
+ CompoundSelector* operator()(CompoundSelector*);
83
+ SelectorComponent* operator()(SelectorComponent*);
84
+ SimpleSelector* operator()(SimpleSelector* s);
85
+ PseudoSelector* operator()(PseudoSelector* s);
86
+
81
87
  // they don't have any specific implementation (yet)
82
- // Element_Selector_Ptr operator()(Element_Selector_Ptr s) { return s; };
83
- // Pseudo_Selector_Ptr operator()(Pseudo_Selector_Ptr s) { return s; };
84
- // Class_Selector_Ptr operator()(Class_Selector_Ptr s) { return s; };
85
- // Id_Selector_Ptr operator()(Id_Selector_Ptr s) { return s; };
86
- // Placeholder_Selector_Ptr operator()(Placeholder_Selector_Ptr s) { return s; };
88
+ IDSelector* operator()(IDSelector* s) { return s; };
89
+ ClassSelector* operator()(ClassSelector* s) { return s; };
90
+ TypeSelector* operator()(TypeSelector* s) { return s; };
91
+ AttributeSelector* operator()(AttributeSelector* s) { return s; };
92
+ PlaceholderSelector* operator()(PlaceholderSelector* s) { return s; };
93
+
87
94
  // actual evaluated selectors
88
- Selector_List_Ptr operator()(Selector_Schema_Ptr);
89
- Expression_Ptr operator()(Parent_Selector_Ptr);
95
+ SelectorList* operator()(Selector_Schema*);
96
+ Expression* operator()(Parent_Reference*);
90
97
 
98
+ // generic fallback
91
99
  template <typename U>
92
- Expression_Ptr fallback(U x) { return fallback_impl(x); }
100
+ Expression* fallback(U x)
101
+ { return Cast<Expression>(x); }
93
102
 
94
103
  private:
95
- void interpolation(Context& ctx, std::string& res, Expression_Obj ex, bool into_quotes, bool was_itpl = false);
104
+ void interpolation(Context& ctx, sass::string& res, ExpressionObj ex, bool into_quotes, bool was_itpl = false);
96
105
 
97
106
  };
98
107
 
99
- Expression_Ptr cval_to_astnode(union Sass_Value* v, Backtraces traces, ParserState pstate = ParserState("[AST]"));
100
-
101
108
  }
102
109
 
103
110
  #endif
@@ -0,0 +1,75 @@
1
+ // sass.hpp must go before all system headers to get the
2
+ // __EXTENSIONS__ fix on Solaris.
3
+ #include "sass.hpp"
4
+ #include "expand.hpp"
5
+ #include "eval.hpp"
6
+ #include "ast.hpp"
7
+
8
+
9
+ namespace Sass {
10
+
11
+ SelectorList* Eval::operator()(SelectorList* s)
12
+ {
13
+ sass::vector<SelectorListObj> rv;
14
+ SelectorListObj sl = SASS_MEMORY_NEW(SelectorList, s->pstate());
15
+ for (size_t i = 0, iL = s->length(); i < iL; ++i) {
16
+ rv.push_back(operator()(s->get(i)));
17
+ }
18
+
19
+ // we should actually permutate parent first
20
+ // but here we have permutated the selector first
21
+ size_t round = 0;
22
+ while (round != sass::string::npos) {
23
+ bool abort = true;
24
+ for (size_t i = 0, iL = rv.size(); i < iL; ++i) {
25
+ if (rv[i]->length() > round) {
26
+ sl->append((*rv[i])[round]);
27
+ abort = false;
28
+ }
29
+ }
30
+ if (abort) {
31
+ round = sass::string::npos;
32
+ }
33
+ else {
34
+ ++round;
35
+ }
36
+
37
+ }
38
+ return sl.detach();
39
+ }
40
+
41
+ SelectorComponent* Eval::operator()(SelectorComponent* s)
42
+ {
43
+ return {};
44
+ }
45
+
46
+ SelectorList* Eval::operator()(ComplexSelector* s)
47
+ {
48
+ bool implicit_parent = !exp.old_at_root_without_rule;
49
+ if (is_in_selector_schema) exp.pushNullSelector();
50
+ SelectorListObj other = s->resolve_parent_refs(
51
+ exp.getOriginalStack(), traces, implicit_parent);
52
+ if (is_in_selector_schema) exp.popNullSelector();
53
+
54
+ for (size_t i = 0; i < other->length(); i++) {
55
+ ComplexSelectorObj sel = other->at(i);
56
+ for (size_t n = 0; n < sel->length(); n++) {
57
+ if (CompoundSelectorObj comp = Cast<CompoundSelector>(sel->at(n))) {
58
+ sel->at(n) = operator()(comp);
59
+ }
60
+ }
61
+ }
62
+
63
+ return other.detach();
64
+ }
65
+
66
+ CompoundSelector* Eval::operator()(CompoundSelector* s)
67
+ {
68
+ for (size_t i = 0; i < s->length(); i++) {
69
+ SimpleSelector* ss = s->at(i);
70
+ // skip parents here (called via resolve_parent_refs)
71
+ s->at(i) = Cast<SimpleSelector>(ss->perform(this));
72
+ }
73
+ return s;
74
+ }
75
+ }
@@ -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 <iostream>
3
6
  #include <typeinfo>
4
7
 
@@ -10,13 +13,14 @@
10
13
  #include "context.hpp"
11
14
  #include "parser.hpp"
12
15
  #include "sass_functions.hpp"
16
+ #include "error_handling.hpp"
13
17
 
14
18
  namespace Sass {
15
19
 
16
20
  // simple endless recursion protection
17
21
  const size_t maxRecursion = 500;
18
22
 
19
- Expand::Expand(Context& ctx, Env* env, std::vector<Selector_List_Obj>* stack)
23
+ Expand::Expand(Context& ctx, Env* env, SelectorStack* stack, SelectorStack* originals)
20
24
  : ctx(ctx),
21
25
  traces(ctx.traces),
22
26
  eval(Eval(*this)),
@@ -24,19 +28,32 @@ namespace Sass {
24
28
  in_keyframes(false),
25
29
  at_root_without_rule(false),
26
30
  old_at_root_without_rule(false),
27
- env_stack(std::vector<Env*>()),
28
- block_stack(std::vector<Block_Ptr>()),
29
- call_stack(std::vector<AST_Node_Obj>()),
30
- selector_stack(std::vector<Selector_List_Obj>()),
31
- media_block_stack(std::vector<Media_Block_Ptr>())
31
+ env_stack(),
32
+ block_stack(),
33
+ call_stack(),
34
+ selector_stack(),
35
+ originalStack(),
36
+ mediaStack()
32
37
  {
33
- env_stack.push_back(0);
38
+ env_stack.push_back(nullptr);
34
39
  env_stack.push_back(env);
35
- block_stack.push_back(0);
36
- call_stack.push_back(0);
37
- if (stack == NULL) { selector_stack.push_back(0); }
38
- else { selector_stack.insert(selector_stack.end(), stack->begin(), stack->end()); }
39
- media_block_stack.push_back(0);
40
+ block_stack.push_back(nullptr);
41
+ call_stack.push_back({});
42
+ if (stack == NULL) { pushToSelectorStack({}); }
43
+ else {
44
+ for (auto item : *stack) {
45
+ if (item.isNull()) pushToSelectorStack({});
46
+ else pushToSelectorStack(item);
47
+ }
48
+ }
49
+ if (originals == NULL) { pushToOriginalStack({}); }
50
+ else {
51
+ for (auto item : *stack) {
52
+ if (item.isNull()) pushToOriginalStack({});
53
+ else pushToOriginalStack(item);
54
+ }
55
+ }
56
+ mediaStack.push_back({});
40
57
  }
41
58
 
42
59
  Env* Expand::environment()
@@ -46,15 +63,84 @@ namespace Sass {
46
63
  return 0;
47
64
  }
48
65
 
49
- Selector_List_Obj Expand::selector()
66
+ void Expand::pushNullSelector()
50
67
  {
51
- if (selector_stack.size() > 0)
52
- return selector_stack.back();
53
- return 0;
68
+ pushToSelectorStack({});
69
+ pushToOriginalStack({});
70
+ }
71
+
72
+ void Expand::popNullSelector()
73
+ {
74
+ popFromOriginalStack();
75
+ popFromSelectorStack();
76
+ }
77
+
78
+ SelectorStack Expand::getOriginalStack()
79
+ {
80
+ return originalStack;
81
+ }
82
+
83
+ SelectorStack Expand::getSelectorStack()
84
+ {
85
+ return selector_stack;
86
+ }
87
+
88
+ SelectorListObj& Expand::selector()
89
+ {
90
+ if (selector_stack.size() > 0) {
91
+ auto& sel = selector_stack.back();
92
+ if (sel.isNull()) return sel;
93
+ return sel;
94
+ }
95
+ // Avoid the need to return copies
96
+ // We always want an empty first item
97
+ selector_stack.push_back({});
98
+ return selector_stack.back();;
99
+ }
100
+
101
+ SelectorListObj& Expand::original()
102
+ {
103
+ if (originalStack.size() > 0) {
104
+ auto& sel = originalStack.back();
105
+ if (sel.isNull()) return sel;
106
+ return sel;
107
+ }
108
+ // Avoid the need to return copies
109
+ // We always want an empty first item
110
+ originalStack.push_back({});
111
+ return originalStack.back();
112
+ }
113
+
114
+ SelectorListObj Expand::popFromSelectorStack()
115
+ {
116
+ SelectorListObj last = selector_stack.back();
117
+ if (selector_stack.size() > 0)
118
+ selector_stack.pop_back();
119
+ if (last.isNull()) return {};
120
+ return last;
121
+ }
122
+
123
+ void Expand::pushToSelectorStack(SelectorListObj selector)
124
+ {
125
+ selector_stack.push_back(selector);
126
+ }
127
+
128
+ SelectorListObj Expand::popFromOriginalStack()
129
+ {
130
+ SelectorListObj last = originalStack.back();
131
+ if (originalStack.size() > 0)
132
+ originalStack.pop_back();
133
+ if (last.isNull()) return {};
134
+ return last;
135
+ }
136
+
137
+ void Expand::pushToOriginalStack(SelectorListObj selector)
138
+ {
139
+ originalStack.push_back(selector);
54
140
  }
55
141
 
56
142
  // blocks create new variable scopes
57
- Block_Ptr Expand::operator()(Block_Ptr b)
143
+ Block* Expand::operator()(Block* b)
58
144
  {
59
145
  // create new local environment
60
146
  // set the current env as parent
@@ -77,76 +163,62 @@ namespace Sass {
77
163
  return bb.detach();
78
164
  }
79
165
 
80
- Statement_Ptr Expand::operator()(Ruleset_Ptr r)
166
+ Statement* Expand::operator()(StyleRule* r)
81
167
  {
82
168
  LOCAL_FLAG(old_at_root_without_rule, at_root_without_rule);
83
169
 
84
170
  if (in_keyframes) {
85
- Block_Ptr bb = operator()(r->block());
171
+ Block* bb = operator()(r->block());
86
172
  Keyframe_Rule_Obj k = SASS_MEMORY_NEW(Keyframe_Rule, r->pstate(), bb);
87
- if (r->selector()) {
88
- if (Selector_List_Ptr s = r->selector()) {
89
- selector_stack.push_back(0);
90
- k->name(s->eval(eval));
91
- selector_stack.pop_back();
173
+ if (r->schema()) {
174
+ pushNullSelector();
175
+ k->name(eval(r->schema()));
176
+ popNullSelector();
177
+ }
178
+ else if (r->selector()) {
179
+ if (SelectorListObj s = r->selector()) {
180
+ pushNullSelector();
181
+ k->name(eval(s));
182
+ popNullSelector();
92
183
  }
93
184
  }
185
+
94
186
  return k.detach();
95
187
  }
96
188
 
97
- // reset when leaving scope
98
- LOCAL_FLAG(at_root_without_rule, false);
99
-
100
- // `&` is allowed in `@at-root`!
101
- bool has_parent_selector = false;
102
- for (size_t i = 0, L = selector_stack.size(); i < L && !has_parent_selector; i++) {
103
- Selector_List_Obj ll = selector_stack.at(i);
104
- has_parent_selector = ll != 0 && ll->length() > 0;
105
- }
106
-
107
- Selector_List_Obj sel = r->selector();
108
- if (sel) sel = sel->eval(eval);
109
-
110
- // check for parent selectors in base level rules
111
- if (r->is_root() || (block_stack.back() && block_stack.back()->is_root())) {
112
- if (Selector_List_Ptr selector_list = Cast<Selector_List>(r->selector())) {
113
- for (Complex_Selector_Obj complex_selector : selector_list->elements()) {
114
- Complex_Selector_Ptr tail = complex_selector;
115
- while (tail) {
116
- if (tail->head()) for (Simple_Selector_Obj header : tail->head()->elements()) {
117
- Parent_Selector_Ptr ptr = Cast<Parent_Selector>(header);
118
- if (ptr == NULL || (!ptr->real() || has_parent_selector)) continue;
119
- std::string sel_str(complex_selector->to_string(ctx.c_options));
120
- error("Base-level rules cannot contain the parent-selector-referencing character '&'.", header->pstate(), traces);
121
- }
122
- tail = tail->tail();
123
- }
124
- }
125
- }
126
- }
127
- else {
128
- if (sel->length() == 0 || sel->has_parent_ref()) {
129
- if (sel->has_real_parent_ref() && !has_parent_selector) {
130
- error("Base-level rules cannot contain the parent-selector-referencing character '&'.", sel->pstate(), traces);
131
- }
189
+ if (r->schema()) {
190
+ SelectorListObj sel = eval(r->schema());
191
+ r->selector(sel);
192
+ for (auto complex : sel->elements()) {
193
+ // ToDo: maybe we can get rid of chroots?
194
+ complex->chroots(complex->has_real_parent_ref());
132
195
  }
196
+
133
197
  }
134
198
 
199
+ // reset when leaving scope
200
+ LOCAL_FLAG(at_root_without_rule, false);
201
+
202
+ SelectorListObj evaled = eval(r->selector());
135
203
  // do not connect parent again
136
- sel->remove_parent_selectors();
137
- selector_stack.push_back(sel);
138
204
  Env env(environment());
139
205
  if (block_stack.back()->is_root()) {
140
206
  env_stack.push_back(&env);
141
207
  }
142
- sel->set_media_block(media_block_stack.back());
143
- Block_Obj blk = 0;
208
+ Block_Obj blk;
209
+ pushToSelectorStack(evaled);
210
+ // The copy is needed for parent reference evaluation
211
+ // dart-sass stores it as `originalSelector` member
212
+ pushToOriginalStack(SASS_MEMORY_COPY(evaled));
213
+ ctx.extender.addSelector(evaled, mediaStack.back());
144
214
  if (r->block()) blk = operator()(r->block());
145
- Ruleset_Ptr rr = SASS_MEMORY_NEW(Ruleset,
215
+ popFromOriginalStack();
216
+ popFromSelectorStack();
217
+ StyleRule* rr = SASS_MEMORY_NEW(StyleRule,
146
218
  r->pstate(),
147
- sel,
219
+ evaled,
148
220
  blk);
149
- selector_stack.pop_back();
221
+
150
222
  if (block_stack.back()->is_root()) {
151
223
  env_stack.pop_back();
152
224
  }
@@ -157,76 +229,89 @@ namespace Sass {
157
229
  return rr;
158
230
  }
159
231
 
160
- Statement_Ptr Expand::operator()(Supports_Block_Ptr f)
232
+ Statement* Expand::operator()(SupportsRule* f)
161
233
  {
162
- Expression_Obj condition = f->condition()->perform(&eval);
163
- Supports_Block_Obj ff = SASS_MEMORY_NEW(Supports_Block,
234
+ ExpressionObj condition = f->condition()->perform(&eval);
235
+ SupportsRuleObj ff = SASS_MEMORY_NEW(SupportsRule,
164
236
  f->pstate(),
165
- Cast<Supports_Condition>(condition),
237
+ Cast<SupportsCondition>(condition),
166
238
  operator()(f->block()));
167
239
  return ff.detach();
168
240
  }
169
241
 
170
- Statement_Ptr Expand::operator()(Media_Block_Ptr m)
171
- {
172
- Media_Block_Obj cpy = SASS_MEMORY_COPY(m);
173
- // Media_Blocks are prone to have circular references
174
- // Copy could leak memory if it does not get picked up
175
- // Looks like we are able to reset block reference for copy
176
- // Good as it will ensure a low memory overhead for this fix
177
- // So this is a cheap solution with a minimal price
178
- ctx.ast_gc.push_back(cpy); cpy->block(0);
179
- Expression_Obj mq = eval(m->media_queries());
180
- std::string str_mq(mq->to_string(ctx.c_options));
181
- char* str = sass_copy_c_string(str_mq.c_str());
182
- ctx.strings.push_back(str);
183
- Parser p(Parser::from_c_str(str, ctx, traces, mq->pstate()));
184
- mq = p.parse_media_queries(); // re-assign now
185
- cpy->media_queries(mq);
186
- media_block_stack.push_back(cpy);
187
- Block_Obj blk = operator()(m->block());
188
- Media_Block_Ptr mm = SASS_MEMORY_NEW(Media_Block,
189
- m->pstate(),
190
- mq,
191
- blk);
192
- media_block_stack.pop_back();
193
- mm->tabs(m->tabs());
194
- return mm;
195
- }
196
-
197
- Statement_Ptr Expand::operator()(At_Root_Block_Ptr a)
242
+ sass::vector<CssMediaQuery_Obj> Expand::mergeMediaQueries(
243
+ const sass::vector<CssMediaQuery_Obj>& lhs,
244
+ const sass::vector<CssMediaQuery_Obj>& rhs)
245
+ {
246
+ sass::vector<CssMediaQuery_Obj> queries;
247
+ for (CssMediaQuery_Obj query1 : lhs) {
248
+ for (CssMediaQuery_Obj query2 : rhs) {
249
+ CssMediaQuery_Obj result = query1->merge(query2);
250
+ if (result && !result->empty()) {
251
+ queries.push_back(result);
252
+ }
253
+ }
254
+ }
255
+ return queries;
256
+ }
257
+
258
+ Statement* Expand::operator()(MediaRule* m)
259
+ {
260
+ ExpressionObj mq = eval(m->schema());
261
+ sass::string str_mq(mq->to_css(ctx.c_options));
262
+ ItplFile* source = SASS_MEMORY_NEW(ItplFile,
263
+ str_mq.c_str(), m->pstate());
264
+ Parser parser(source, ctx, traces);
265
+ // Create a new CSS only representation of the media rule
266
+ CssMediaRuleObj css = SASS_MEMORY_NEW(CssMediaRule, m->pstate(), m->block());
267
+ sass::vector<CssMediaQuery_Obj> parsed = parser.parseCssMediaQueries();
268
+ if (mediaStack.size() && mediaStack.back()) {
269
+ auto& parent = mediaStack.back()->elements();
270
+ css->concat(mergeMediaQueries(parent, parsed));
271
+ }
272
+ else {
273
+ css->concat(parsed);
274
+ }
275
+ mediaStack.push_back(css);
276
+ css->block(operator()(m->block()));
277
+ mediaStack.pop_back();
278
+ return css.detach();
279
+
280
+ }
281
+
282
+ Statement* Expand::operator()(AtRootRule* a)
198
283
  {
199
284
  Block_Obj ab = a->block();
200
- Expression_Obj ae = a->expression();
285
+ ExpressionObj ae = a->expression();
201
286
 
202
287
  if (ae) ae = ae->perform(&eval);
203
288
  else ae = SASS_MEMORY_NEW(At_Root_Query, a->pstate());
204
289
 
205
- LOCAL_FLAG(at_root_without_rule, true);
290
+ LOCAL_FLAG(at_root_without_rule, Cast<At_Root_Query>(ae)->exclude("rule"));
206
291
  LOCAL_FLAG(in_keyframes, false);
207
292
 
208
293
  ;
209
294
 
210
295
  Block_Obj bb = ab ? operator()(ab) : NULL;
211
- At_Root_Block_Obj aa = SASS_MEMORY_NEW(At_Root_Block,
296
+ AtRootRuleObj aa = SASS_MEMORY_NEW(AtRootRule,
212
297
  a->pstate(),
213
298
  bb,
214
299
  Cast<At_Root_Query>(ae));
215
300
  return aa.detach();
216
301
  }
217
302
 
218
- Statement_Ptr Expand::operator()(Directive_Ptr a)
303
+ Statement* Expand::operator()(AtRule* a)
219
304
  {
220
305
  LOCAL_FLAG(in_keyframes, a->is_keyframes());
221
- Block_Ptr ab = a->block();
222
- Selector_List_Ptr as = a->selector();
223
- Expression_Ptr av = a->value();
224
- selector_stack.push_back(0);
306
+ Block* ab = a->block();
307
+ SelectorList* as = a->selector();
308
+ Expression* av = a->value();
309
+ pushNullSelector();
225
310
  if (av) av = av->perform(&eval);
226
311
  if (as) as = eval(as);
227
- selector_stack.pop_back();
228
- Block_Ptr bb = ab ? operator()(ab) : NULL;
229
- Directive_Ptr aa = SASS_MEMORY_NEW(Directive,
312
+ popNullSelector();
313
+ Block* bb = ab ? operator()(ab) : NULL;
314
+ AtRule* aa = SASS_MEMORY_NEW(AtRule,
230
315
  a->pstate(),
231
316
  a->keyword(),
232
317
  as,
@@ -235,23 +320,30 @@ namespace Sass {
235
320
  return aa;
236
321
  }
237
322
 
238
- Statement_Ptr Expand::operator()(Declaration_Ptr d)
323
+ Statement* Expand::operator()(Declaration* d)
239
324
  {
240
325
  Block_Obj ab = d->block();
241
326
  String_Obj old_p = d->property();
242
- Expression_Obj prop = old_p->perform(&eval);
327
+ ExpressionObj prop = old_p->perform(&eval);
243
328
  String_Obj new_p = Cast<String>(prop);
244
329
  // we might get a color back
245
330
  if (!new_p) {
246
- std::string str(prop->to_string(ctx.c_options));
331
+ sass::string str(prop->to_string(ctx.c_options));
247
332
  new_p = SASS_MEMORY_NEW(String_Constant, old_p->pstate(), str);
248
333
  }
249
- Expression_Obj value = d->value()->perform(&eval);
334
+ ExpressionObj value = d->value();
335
+ if (value) value = value->perform(&eval);
250
336
  Block_Obj bb = ab ? operator()(ab) : NULL;
251
337
  if (!bb) {
252
- if (!value || (value->is_invisible() && !d->is_important())) return 0;
338
+ if (!value || (value->is_invisible() && !d->is_important())) {
339
+ if (d->is_custom_property()) {
340
+ error("Custom property values may not be empty.", d->value()->pstate(), traces);
341
+ } else {
342
+ return nullptr;
343
+ }
344
+ }
253
345
  }
254
- Declaration_Ptr decl = SASS_MEMORY_NEW(Declaration,
346
+ Declaration* decl = SASS_MEMORY_NEW(Declaration,
255
347
  d->pstate(),
256
348
  new_p,
257
349
  value,
@@ -262,14 +354,20 @@ namespace Sass {
262
354
  return decl;
263
355
  }
264
356
 
265
- Statement_Ptr Expand::operator()(Assignment_Ptr a)
357
+ Statement* Expand::operator()(Assignment* a)
266
358
  {
267
359
  Env* env = environment();
268
- const std::string& var(a->variable());
360
+ const sass::string& var(a->variable());
269
361
  if (a->is_global()) {
362
+ if (!env->has_global(var)) {
363
+ deprecated(
364
+ "!global assignments won't be able to declare new variables in future versions.",
365
+ "Consider adding `" + var + ": null` at the top level.",
366
+ true, a->pstate());
367
+ }
270
368
  if (a->is_default()) {
271
369
  if (env->has_global(var)) {
272
- Expression_Obj e = Cast<Expression>(env->get_global(var));
370
+ ExpressionObj e = Cast<Expression>(env->get_global(var));
273
371
  if (!e || e->concrete_type() == Expression::NULL_VAL) {
274
372
  env->set_global(var, a->value()->perform(&eval));
275
373
  }
@@ -288,7 +386,7 @@ namespace Sass {
288
386
  while (cur && cur->is_lexical()) {
289
387
  if (cur->has_local(var)) {
290
388
  if (AST_Node_Obj node = cur->get_local(var)) {
291
- Expression_Obj e = Cast<Expression>(node);
389
+ ExpressionObj e = Cast<Expression>(node);
292
390
  if (!e || e->concrete_type() == Expression::NULL_VAL) {
293
391
  cur->set_local(var, a->value()->perform(&eval));
294
392
  }
@@ -304,7 +402,7 @@ namespace Sass {
304
402
  }
305
403
  else if (env->has_global(var)) {
306
404
  if (AST_Node_Obj node = env->get_global(var)) {
307
- Expression_Obj e = Cast<Expression>(node);
405
+ ExpressionObj e = Cast<Expression>(node);
308
406
  if (!e || e->concrete_type() == Expression::NULL_VAL) {
309
407
  env->set_global(var, a->value()->perform(&eval));
310
408
  }
@@ -323,11 +421,11 @@ namespace Sass {
323
421
  return 0;
324
422
  }
325
423
 
326
- Statement_Ptr Expand::operator()(Import_Ptr imp)
424
+ Statement* Expand::operator()(Import* imp)
327
425
  {
328
426
  Import_Obj result = SASS_MEMORY_NEW(Import, imp->pstate());
329
427
  if (imp->import_queries() && imp->import_queries()->size()) {
330
- Expression_Obj ex = imp->import_queries()->perform(&eval);
428
+ ExpressionObj ex = imp->import_queries()->perform(&eval);
331
429
  result->import_queries(Cast<List>(ex));
332
430
  }
333
431
  for ( size_t i = 0, S = imp->urls().size(); i < S; ++i) {
@@ -338,7 +436,7 @@ namespace Sass {
338
436
  return result.detach();
339
437
  }
340
438
 
341
- Statement_Ptr Expand::operator()(Import_Stub_Ptr i)
439
+ Statement* Expand::operator()(Import_Stub* i)
342
440
  {
343
441
  traces.push_back(Backtrace(i->pstate()));
344
442
  // get parent node from call stack
@@ -359,7 +457,7 @@ namespace Sass {
359
457
  block_stack.back()->append(trace);
360
458
  block_stack.push_back(trace_block);
361
459
 
362
- const std::string& abs_path(i->resource().abs_path);
460
+ const sass::string& abs_path(i->resource().abs_path);
363
461
  append_block(ctx.sheets.at(abs_path).root);
364
462
  sass_delete_import(ctx.import_stack.back());
365
463
  ctx.import_stack.pop_back();
@@ -368,28 +466,28 @@ namespace Sass {
368
466
  return 0;
369
467
  }
370
468
 
371
- Statement_Ptr Expand::operator()(Warning_Ptr w)
469
+ Statement* Expand::operator()(WarningRule* w)
372
470
  {
373
471
  // eval handles this too, because warnings may occur in functions
374
472
  w->perform(&eval);
375
473
  return 0;
376
474
  }
377
475
 
378
- Statement_Ptr Expand::operator()(Error_Ptr e)
476
+ Statement* Expand::operator()(ErrorRule* e)
379
477
  {
380
478
  // eval handles this too, because errors may occur in functions
381
479
  e->perform(&eval);
382
480
  return 0;
383
481
  }
384
482
 
385
- Statement_Ptr Expand::operator()(Debug_Ptr d)
483
+ Statement* Expand::operator()(DebugRule* d)
386
484
  {
387
485
  // eval handles this too, because warnings may occur in functions
388
486
  d->perform(&eval);
389
487
  return 0;
390
488
  }
391
489
 
392
- Statement_Ptr Expand::operator()(Comment_Ptr c)
490
+ Statement* Expand::operator()(Comment* c)
393
491
  {
394
492
  if (ctx.output_style() == COMPRESSED) {
395
493
  // comments should not be evaluated in compact
@@ -397,23 +495,23 @@ namespace Sass {
397
495
  if (!c->is_important()) return NULL;
398
496
  }
399
497
  eval.is_in_comment = true;
400
- Comment_Ptr rv = SASS_MEMORY_NEW(Comment, c->pstate(), Cast<String>(c->text()->perform(&eval)), c->is_important());
498
+ Comment* rv = SASS_MEMORY_NEW(Comment, c->pstate(), Cast<String>(c->text()->perform(&eval)), c->is_important());
401
499
  eval.is_in_comment = false;
402
500
  // TODO: eval the text, once we're parsing/storing it as a String_Schema
403
501
  return rv;
404
502
  }
405
503
 
406
- Statement_Ptr Expand::operator()(If_Ptr i)
504
+ Statement* Expand::operator()(If* i)
407
505
  {
408
506
  Env env(environment(), true);
409
507
  env_stack.push_back(&env);
410
508
  call_stack.push_back(i);
411
- Expression_Obj rv = i->predicate()->perform(&eval);
509
+ ExpressionObj rv = i->predicate()->perform(&eval);
412
510
  if (*rv) {
413
511
  append_block(i->block());
414
512
  }
415
513
  else {
416
- Block_Ptr alt = i->alternative();
514
+ Block* alt = i->alternative();
417
515
  if (alt) append_block(alt);
418
516
  }
419
517
  call_stack.pop_back();
@@ -423,15 +521,15 @@ namespace Sass {
423
521
 
424
522
  // For does not create a new env scope
425
523
  // But iteration vars are reset afterwards
426
- Statement_Ptr Expand::operator()(For_Ptr f)
524
+ Statement* Expand::operator()(ForRule* f)
427
525
  {
428
- std::string variable(f->variable());
429
- Expression_Obj low = f->lower_bound()->perform(&eval);
526
+ sass::string variable(f->variable());
527
+ ExpressionObj low = f->lower_bound()->perform(&eval);
430
528
  if (low->concrete_type() != Expression::NUMBER) {
431
529
  traces.push_back(Backtrace(low->pstate()));
432
530
  throw Exception::TypeMismatch(traces, *low, "integer");
433
531
  }
434
- Expression_Obj high = f->upper_bound()->perform(&eval);
532
+ ExpressionObj high = f->upper_bound()->perform(&eval);
435
533
  if (high->concrete_type() != Expression::NUMBER) {
436
534
  traces.push_back(Backtrace(high->pstate()));
437
535
  throw Exception::TypeMismatch(traces, *high, "integer");
@@ -440,7 +538,7 @@ namespace Sass {
440
538
  Number_Obj sass_end = Cast<Number>(high);
441
539
  // check if units are valid for sequence
442
540
  if (sass_start->unit() != sass_end->unit()) {
443
- std::stringstream msg; msg << "Incompatible units: '"
541
+ sass::ostream msg; msg << "Incompatible units: '"
444
542
  << sass_start->unit() << "' and '"
445
543
  << sass_end->unit() << "'.";
446
544
  error(msg.str(), low->pstate(), traces);
@@ -451,7 +549,7 @@ namespace Sass {
451
549
  Env env(environment(), true);
452
550
  env_stack.push_back(&env);
453
551
  call_stack.push_back(f);
454
- Block_Ptr body = f->block();
552
+ Block* body = f->block();
455
553
  if (start < end) {
456
554
  if (f->is_inclusive()) ++end;
457
555
  for (double i = start;
@@ -478,18 +576,17 @@ namespace Sass {
478
576
 
479
577
  // Eval does not create a new env scope
480
578
  // But iteration vars are reset afterwards
481
- Statement_Ptr Expand::operator()(Each_Ptr e)
579
+ Statement* Expand::operator()(EachRule* e)
482
580
  {
483
- std::vector<std::string> variables(e->variables());
484
- Expression_Obj expr = e->list()->perform(&eval);
485
- List_Obj list = 0;
581
+ sass::vector<sass::string> variables(e->variables());
582
+ ExpressionObj expr = e->list()->perform(&eval);
583
+ List_Obj list;
486
584
  Map_Obj map;
487
585
  if (expr->concrete_type() == Expression::MAP) {
488
586
  map = Cast<Map>(expr);
489
587
  }
490
- else if (Selector_List_Ptr ls = Cast<Selector_List>(expr)) {
491
- Listize listize;
492
- Expression_Obj rv = ls->perform(&listize);
588
+ else if (SelectorList * ls = Cast<SelectorList>(expr)) {
589
+ ExpressionObj rv = Listize::perform(ls);
493
590
  list = Cast<List>(rv);
494
591
  }
495
592
  else if (expr->concrete_type() != Expression::LIST) {
@@ -503,12 +600,12 @@ namespace Sass {
503
600
  Env env(environment(), true);
504
601
  env_stack.push_back(&env);
505
602
  call_stack.push_back(e);
506
- Block_Ptr body = e->block();
603
+ Block* body = e->block();
507
604
 
508
605
  if (map) {
509
606
  for (auto key : map->keys()) {
510
- Expression_Obj k = key->perform(&eval);
511
- Expression_Obj v = map->at(key)->perform(&eval);
607
+ ExpressionObj k = key->perform(&eval);
608
+ ExpressionObj v = map->at(key)->perform(&eval);
512
609
 
513
610
  if (variables.size() == 1) {
514
611
  List_Obj variable = SASS_MEMORY_NEW(List, map->pstate(), 2, SASS_SPACE);
@@ -524,11 +621,11 @@ namespace Sass {
524
621
  }
525
622
  else {
526
623
  // bool arglist = list->is_arglist();
527
- if (list->length() == 1 && Cast<Selector_List>(list)) {
624
+ if (list->length() == 1 && Cast<SelectorList>(list)) {
528
625
  list = Cast<List>(list);
529
626
  }
530
627
  for (size_t i = 0, L = list->length(); i < L; ++i) {
531
- Expression_Obj item = list->at(i);
628
+ ExpressionObj item = list->at(i);
532
629
  // unwrap value if the expression is an argument
533
630
  if (Argument_Obj arg = Cast<Argument>(item)) item = arg->value();
534
631
  // check if we got passed a list of args (investigate)
@@ -539,17 +636,16 @@ namespace Sass {
539
636
  env.set_local(variables[0], var);
540
637
  } else {
541
638
  for (size_t j = 0, K = variables.size(); j < K; ++j) {
542
- Expression_Obj res = j >= scalars->length()
639
+ env.set_local(variables[j], j >= scalars->length()
543
640
  ? SASS_MEMORY_NEW(Null, expr->pstate())
544
- : (*scalars)[j]->perform(&eval);
545
- env.set_local(variables[j], res);
641
+ : (*scalars)[j]->perform(&eval));
546
642
  }
547
643
  }
548
644
  } else {
549
645
  if (variables.size() > 0) {
550
646
  env.set_local(variables.at(0), item);
551
647
  for (size_t j = 1, K = variables.size(); j < K; ++j) {
552
- Expression_Obj res = SASS_MEMORY_NEW(Null, expr->pstate());
648
+ ExpressionObj res = SASS_MEMORY_NEW(Null, expr->pstate());
553
649
  env.set_local(variables[j], res);
554
650
  }
555
651
  }
@@ -562,14 +658,14 @@ namespace Sass {
562
658
  return 0;
563
659
  }
564
660
 
565
- Statement_Ptr Expand::operator()(While_Ptr w)
661
+ Statement* Expand::operator()(WhileRule* w)
566
662
  {
567
- Expression_Obj pred = w->predicate();
568
- Block_Ptr body = w->block();
663
+ ExpressionObj pred = w->predicate();
664
+ Block* body = w->block();
569
665
  Env env(environment(), true);
570
666
  env_stack.push_back(&env);
571
667
  call_stack.push_back(w);
572
- Expression_Obj cond = pred->perform(&eval);
668
+ ExpressionObj cond = pred->perform(&eval);
573
669
  while (!cond->is_false()) {
574
670
  append_block(body);
575
671
  cond = pred->perform(&eval);
@@ -579,96 +675,72 @@ namespace Sass {
579
675
  return 0;
580
676
  }
581
677
 
582
- Statement_Ptr Expand::operator()(Return_Ptr r)
678
+ Statement* Expand::operator()(Return* r)
583
679
  {
584
680
  error("@return may only be used within a function", r->pstate(), traces);
585
681
  return 0;
586
682
  }
587
683
 
684
+ Statement* Expand::operator()(ExtendRule* e)
685
+ {
588
686
 
589
- void Expand::expand_selector_list(Selector_Obj s, Selector_List_Obj extender) {
590
-
591
- if (Selector_List_Obj sl = Cast<Selector_List>(s)) {
592
- for (Complex_Selector_Obj complex_selector : sl->elements()) {
593
- Complex_Selector_Obj tail = complex_selector;
594
- while (tail) {
595
- if (tail->head()) for (Simple_Selector_Obj header : tail->head()->elements()) {
596
- if (Cast<Parent_Selector>(header) == NULL) continue; // skip all others
597
- std::string sel_str(complex_selector->to_string(ctx.c_options));
598
- error("Can't extend " + sel_str + ": can't extend parent selectors", header->pstate(), traces);
599
- }
600
- tail = tail->tail();
601
- }
602
- }
687
+ // evaluate schema first
688
+ if (e->schema()) {
689
+ e->selector(eval(e->schema()));
690
+ e->isOptional(e->selector()->is_optional());
603
691
  }
692
+ // evaluate the selector
693
+ e->selector(eval(e->selector()));
604
694
 
695
+ if (e->selector()) {
605
696
 
606
- Selector_List_Obj contextualized = Cast<Selector_List>(s->perform(&eval));
607
- if (contextualized == false) return;
608
- for (auto complex_sel : contextualized->elements()) {
609
- Complex_Selector_Obj c = complex_sel;
610
- if (!c->head() || c->tail()) {
611
- std::string sel_str(contextualized->to_string(ctx.c_options));
612
- error("Can't extend " + sel_str + ": can't extend nested selectors", c->pstate(), traces);
613
- }
614
- Compound_Selector_Obj target = c->head();
615
- if (contextualized->is_optional()) target->is_optional(true);
616
- for (size_t i = 0, L = extender->length(); i < L; ++i) {
617
- Complex_Selector_Obj sel = (*extender)[i];
618
- if (!(sel->head() && sel->head()->length() > 0 &&
619
- Cast<Parent_Selector>((*sel->head())[0])))
620
- {
621
- Compound_Selector_Obj hh = SASS_MEMORY_NEW(Compound_Selector, (*extender)[i]->pstate());
622
- hh->media_block((*extender)[i]->media_block());
623
- Complex_Selector_Obj ssel = SASS_MEMORY_NEW(Complex_Selector, (*extender)[i]->pstate());
624
- ssel->media_block((*extender)[i]->media_block());
625
- if (sel->has_line_feed()) ssel->has_line_feed(true);
626
- Parent_Selector_Obj ps = SASS_MEMORY_NEW(Parent_Selector, (*extender)[i]->pstate());
627
- ps->media_block((*extender)[i]->media_block());
628
- hh->append(ps);
629
- ssel->tail(sel);
630
- ssel->head(hh);
631
- sel = ssel;
697
+ for (auto complex : e->selector()->elements()) {
698
+
699
+ if (complex->length() != 1) {
700
+ error("complex selectors may not be extended.", complex->pstate(), traces);
632
701
  }
633
- // if (c->has_line_feed()) sel->has_line_feed(true);
634
- ctx.subset_map.put(target, std::make_pair(sel, target));
635
- }
636
- }
637
702
 
638
- }
703
+ if (const CompoundSelector* compound = complex->first()->getCompound()) {
704
+
705
+ if (compound->length() != 1) {
706
+
707
+ sass::ostream sels; bool addComma = false;
708
+ sels << "Compound selectors may no longer be extended.\n";
709
+ sels << "Consider `@extend ";
710
+ for (auto sel : compound->elements()) {
711
+ if (addComma) sels << ", ";
712
+ sels << sel->to_sass();
713
+ addComma = true;
714
+ }
715
+ sels << "` instead.\n";
716
+ sels << "See http://bit.ly/ExtendCompound for details.";
717
+
718
+ warning(sels.str(), compound->pstate());
719
+
720
+ // Make this an error once deprecation is over
721
+ for (SimpleSelectorObj simple : compound->elements()) {
722
+ // Pass every selector we ever see to extender (to make them findable for extend)
723
+ ctx.extender.addExtension(selector(), simple, mediaStack.back(), e->isOptional());
724
+ }
725
+
726
+ }
727
+ else {
728
+ // Pass every selector we ever see to extender (to make them findable for extend)
729
+ ctx.extender.addExtension(selector(), compound->first(), mediaStack.back(), e->isOptional());
730
+ }
639
731
 
640
- Statement* Expand::operator()(Extension_Ptr e)
641
- {
642
- if (Selector_List_Ptr extender = selector()) {
643
- Selector_List_Ptr sl = e->selector();
644
- // abort on invalid selector
645
- if (sl == NULL) return NULL;
646
- if (Selector_Schema_Ptr schema = sl->schema()) {
647
- if (schema->has_real_parent_ref()) {
648
- // put root block on stack again (ignore parents)
649
- // selector schema must not connect in eval!
650
- block_stack.push_back(block_stack.at(1));
651
- sl = eval(sl->schema());
652
- block_stack.pop_back();
653
- } else {
654
- selector_stack.push_back(0);
655
- sl = eval(sl->schema());
656
- selector_stack.pop_back();
657
732
  }
658
- }
659
- for (Complex_Selector_Obj cs : sl->elements()) {
660
- if (!cs.isNull() && !cs->head().isNull()) {
661
- cs->head()->media_block(media_block_stack.back());
733
+ else {
734
+ error("complex selectors may not be extended.", complex->pstate(), traces);
662
735
  }
663
736
  }
664
- selector_stack.push_back(0);
665
- expand_selector_list(sl, extender);
666
- selector_stack.pop_back();
667
737
  }
668
- return 0;
738
+
739
+ return nullptr;
740
+
669
741
  }
670
742
 
671
- Statement_Ptr Expand::operator()(Definition_Ptr d)
743
+ Statement* Expand::operator()(Definition* d)
672
744
  {
673
745
  Env* env = environment();
674
746
  Definition_Obj dd = SASS_MEMORY_COPY(d);
@@ -693,8 +765,9 @@ namespace Sass {
693
765
  return 0;
694
766
  }
695
767
 
696
- Statement_Ptr Expand::operator()(Mixin_Call_Ptr c)
768
+ Statement* Expand::operator()(Mixin_Call* c)
697
769
  {
770
+
698
771
  if (recursions > maxRecursion) {
699
772
  throw Exception::StackError(traces, *c);
700
773
  }
@@ -702,7 +775,7 @@ namespace Sass {
702
775
  recursions ++;
703
776
 
704
777
  Env* env = environment();
705
- std::string full_name(c->name() + "[m]");
778
+ sass::string full_name(c->name() + "[m]");
706
779
  if (!env->has(full_name)) {
707
780
  error("no mixin named " + c->name(), c->pstate(), traces);
708
781
  }
@@ -713,15 +786,15 @@ namespace Sass {
713
786
  if (c->block() && c->name() != "@content" && !body->has_content()) {
714
787
  error("Mixin \"" + c->name() + "\" does not accept a content block.", c->pstate(), traces);
715
788
  }
716
- Expression_Obj rv = c->arguments()->perform(&eval);
789
+ ExpressionObj rv = c->arguments()->perform(&eval);
717
790
  Arguments_Obj args = Cast<Arguments>(rv);
718
- std::string msg(", in mixin `" + c->name() + "`");
791
+ sass::string msg(", in mixin `" + c->name() + "`");
719
792
  traces.push_back(Backtrace(c->pstate(), msg));
720
793
  ctx.callee_stack.push_back({
721
794
  c->name().c_str(),
722
- c->pstate().path,
723
- c->pstate().line + 1,
724
- c->pstate().column + 1,
795
+ c->pstate().getPath(),
796
+ c->pstate().getLine(),
797
+ c->pstate().getColumn(),
725
798
  SASS_CALLEE_MIXIN,
726
799
  { env }
727
800
  });
@@ -729,29 +802,31 @@ namespace Sass {
729
802
  Env new_env(def->environment());
730
803
  env_stack.push_back(&new_env);
731
804
  if (c->block()) {
805
+ Parameters_Obj params = c->block_parameters();
806
+ if (!params) params = SASS_MEMORY_NEW(Parameters, c->pstate());
732
807
  // represent mixin content blocks as thunks/closures
733
808
  Definition_Obj thunk = SASS_MEMORY_NEW(Definition,
734
809
  c->pstate(),
735
810
  "@content",
736
- SASS_MEMORY_NEW(Parameters, c->pstate()),
811
+ params,
737
812
  c->block(),
738
813
  Definition::MIXIN);
739
814
  thunk->environment(env);
740
815
  new_env.local_frame()["@content[m]"] = thunk;
741
816
  }
742
817
 
743
- bind(std::string("Mixin"), c->name(), params, args, &ctx, &new_env, &eval);
818
+ bind(sass::string("Mixin"), c->name(), params, args, &new_env, &eval, traces);
744
819
 
745
820
  Block_Obj trace_block = SASS_MEMORY_NEW(Block, c->pstate());
746
821
  Trace_Obj trace = SASS_MEMORY_NEW(Trace, c->pstate(), c->name(), trace_block);
747
822
 
748
823
  env->set_global("is_in_mixin", bool_true);
749
- if (Block_Ptr pr = block_stack.back()) {
824
+ if (Block* pr = block_stack.back()) {
750
825
  trace_block->is_root(pr->is_root());
751
826
  }
752
827
  block_stack.push_back(trace_block);
753
828
  for (auto bb : body->elements()) {
754
- if (Ruleset_Ptr r = Cast<Ruleset>(bb)) {
829
+ if (StyleRule* r = Cast<StyleRule>(bb)) {
755
830
  r->is_root(trace_block->is_root());
756
831
  }
757
832
  Statement_Obj ith = bb->perform(this);
@@ -768,45 +843,29 @@ namespace Sass {
768
843
  return trace.detach();
769
844
  }
770
845
 
771
- Statement_Ptr Expand::operator()(Content_Ptr c)
846
+ Statement* Expand::operator()(Content* c)
772
847
  {
773
848
  Env* env = environment();
774
849
  // convert @content directives into mixin calls to the underlying thunk
775
850
  if (!env->has("@content[m]")) return 0;
776
-
777
- if (block_stack.back()->is_root()) {
778
- selector_stack.push_back(0);
779
- }
851
+ Arguments_Obj args = c->arguments();
852
+ if (!args) args = SASS_MEMORY_NEW(Arguments, c->pstate());
780
853
 
781
854
  Mixin_Call_Obj call = SASS_MEMORY_NEW(Mixin_Call,
782
855
  c->pstate(),
783
856
  "@content",
784
- SASS_MEMORY_NEW(Arguments, c->pstate()));
857
+ args);
785
858
 
786
859
  Trace_Obj trace = Cast<Trace>(call->perform(this));
787
-
788
- if (block_stack.back()->is_root()) {
789
- selector_stack.pop_back();
790
- }
791
-
792
860
  return trace.detach();
793
861
  }
794
862
 
795
- // produce an error if something is not implemented
796
- inline Statement_Ptr Expand::fallback_impl(AST_Node_Ptr n)
797
- {
798
- std::string err =std:: string("`Expand` doesn't handle ") + typeid(*n).name();
799
- String_Quoted_Obj msg = SASS_MEMORY_NEW(String_Quoted, ParserState("[WARN]"), err);
800
- error("unknown internal error; please contact the LibSass maintainers", n->pstate(), traces);
801
- return SASS_MEMORY_NEW(Warning, ParserState("[WARN]"), msg);
802
- }
803
-
804
863
  // process and add to last block on stack
805
- inline void Expand::append_block(Block_Ptr b)
864
+ inline void Expand::append_block(Block* b)
806
865
  {
807
866
  if (b->is_root()) call_stack.push_back(b);
808
867
  for (size_t i = 0, L = b->length(); i < L; ++i) {
809
- Statement_Ptr stm = b->at(i);
868
+ Statement* stm = b->at(i);
810
869
  Statement_Obj ith = stm->perform(this);
811
870
  if (ith) block_stack.back()->append(ith);
812
871
  }