sassc 2.0.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
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
  }