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
@@ -0,0 +1,34 @@
1
+ #ifndef SASS_FN_STRINGS_H
2
+ #define SASS_FN_STRINGS_H
3
+
4
+ #include "fn_utils.hpp"
5
+
6
+ namespace Sass {
7
+
8
+ namespace Functions {
9
+
10
+ extern Signature unquote_sig;
11
+ extern Signature quote_sig;
12
+ extern Signature str_length_sig;
13
+ extern Signature str_insert_sig;
14
+ extern Signature str_index_sig;
15
+ extern Signature str_slice_sig;
16
+ extern Signature to_upper_case_sig;
17
+ extern Signature to_lower_case_sig;
18
+ extern Signature length_sig;
19
+
20
+ BUILT_IN(sass_unquote);
21
+ BUILT_IN(sass_quote);
22
+ BUILT_IN(str_length);
23
+ BUILT_IN(str_insert);
24
+ BUILT_IN(str_index);
25
+ BUILT_IN(str_slice);
26
+ BUILT_IN(to_upper_case);
27
+ BUILT_IN(to_lower_case);
28
+ BUILT_IN(length);
29
+
30
+ }
31
+
32
+ }
33
+
34
+ #endif
@@ -0,0 +1,158 @@
1
+ // sass.hpp must go before all system headers to get the
2
+ // __EXTENSIONS__ fix on Solaris.
3
+ #include "sass.hpp"
4
+
5
+ #include "parser.hpp"
6
+ #include "fn_utils.hpp"
7
+ #include "util_string.hpp"
8
+
9
+ namespace Sass {
10
+
11
+ Definition* make_native_function(Signature sig, Native_Function func, Context& ctx)
12
+ {
13
+ SourceFile* source = SASS_MEMORY_NEW(SourceFile, "[built-in function]", sig, std::string::npos);
14
+ Parser sig_parser(source, ctx, ctx.traces);
15
+ sig_parser.lex<Prelexer::identifier>();
16
+ sass::string name(Util::normalize_underscores(sig_parser.lexed));
17
+ Parameters_Obj params = sig_parser.parse_parameters();
18
+ return SASS_MEMORY_NEW(Definition,
19
+ SourceSpan(source),
20
+ sig,
21
+ name,
22
+ params,
23
+ func,
24
+ false);
25
+ }
26
+
27
+ Definition* make_c_function(Sass_Function_Entry c_func, Context& ctx)
28
+ {
29
+ using namespace Prelexer;
30
+ const char* sig = sass_function_get_signature(c_func);
31
+ SourceFile* source = SASS_MEMORY_NEW(SourceFile, "[c function]", sig, std::string::npos);
32
+ Parser sig_parser(source, ctx, ctx.traces);
33
+ // allow to overload generic callback plus @warn, @error and @debug with custom functions
34
+ sig_parser.lex < alternatives < identifier, exactly <'*'>,
35
+ exactly < Constants::warn_kwd >,
36
+ exactly < Constants::error_kwd >,
37
+ exactly < Constants::debug_kwd >
38
+ > >();
39
+ sass::string name(Util::normalize_underscores(sig_parser.lexed));
40
+ Parameters_Obj params = sig_parser.parse_parameters();
41
+ return SASS_MEMORY_NEW(Definition,
42
+ SourceSpan(source),
43
+ sig,
44
+ name,
45
+ params,
46
+ c_func);
47
+ }
48
+
49
+ namespace Functions {
50
+
51
+ sass::string function_name(Signature sig)
52
+ {
53
+ sass::string str(sig);
54
+ return str.substr(0, str.find('('));
55
+ }
56
+
57
+ Map* get_arg_m(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces)
58
+ {
59
+ AST_Node* value = env[argname];
60
+ if (Map* map = Cast<Map>(value)) return map;
61
+ List* list = Cast<List>(value);
62
+ if (list && list->length() == 0) {
63
+ return SASS_MEMORY_NEW(Map, pstate, 0);
64
+ }
65
+ return get_arg<Map>(argname, env, sig, pstate, traces);
66
+ }
67
+
68
+ double get_arg_r(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces, double lo, double hi)
69
+ {
70
+ Number* val = get_arg<Number>(argname, env, sig, pstate, traces);
71
+ Number tmpnr(val);
72
+ tmpnr.reduce();
73
+ double v = tmpnr.value();
74
+ if (!(lo <= v && v <= hi)) {
75
+ sass::ostream msg;
76
+ msg << "argument `" << argname << "` of `" << sig << "` must be between ";
77
+ msg << lo << " and " << hi;
78
+ error(msg.str(), pstate, traces);
79
+ }
80
+ return v;
81
+ }
82
+
83
+ Number* get_arg_n(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces)
84
+ {
85
+ Number* val = get_arg<Number>(argname, env, sig, pstate, traces);
86
+ val = SASS_MEMORY_COPY(val);
87
+ val->reduce();
88
+ return val;
89
+ }
90
+
91
+ double get_arg_val(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces)
92
+ {
93
+ Number* val = get_arg<Number>(argname, env, sig, pstate, traces);
94
+ Number tmpnr(val);
95
+ tmpnr.reduce();
96
+ return tmpnr.value();
97
+ }
98
+
99
+ double color_num(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces)
100
+ {
101
+ Number* val = get_arg<Number>(argname, env, sig, pstate, traces);
102
+ Number tmpnr(val);
103
+ tmpnr.reduce();
104
+ if (tmpnr.unit() == "%") {
105
+ return std::min(std::max(tmpnr.value() * 255 / 100.0, 0.0), 255.0);
106
+ } else {
107
+ return std::min(std::max(tmpnr.value(), 0.0), 255.0);
108
+ }
109
+ }
110
+
111
+ double alpha_num(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces) {
112
+ Number* val = get_arg<Number>(argname, env, sig, pstate, traces);
113
+ Number tmpnr(val);
114
+ tmpnr.reduce();
115
+ if (tmpnr.unit() == "%") {
116
+ return std::min(std::max(tmpnr.value(), 0.0), 100.0);
117
+ } else {
118
+ return std::min(std::max(tmpnr.value(), 0.0), 1.0);
119
+ }
120
+ }
121
+
122
+ SelectorListObj get_arg_sels(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces, Context& ctx) {
123
+ ExpressionObj exp = ARG(argname, Expression);
124
+ if (exp->concrete_type() == Expression::NULL_VAL) {
125
+ sass::ostream msg;
126
+ msg << argname << ": null is not a valid selector: it must be a string,\n";
127
+ msg << "a list of strings, or a list of lists of strings for `" << function_name(sig) << "'";
128
+ error(msg.str(), exp->pstate(), traces);
129
+ }
130
+ if (String_Constant* str = Cast<String_Constant>(exp)) {
131
+ str->quote_mark(0);
132
+ }
133
+ sass::string exp_src = exp->to_string(ctx.c_options);
134
+ ItplFile* source = SASS_MEMORY_NEW(ItplFile, exp_src.c_str(), exp->pstate());
135
+ return Parser::parse_selector(source, ctx, traces, false);
136
+ }
137
+
138
+ CompoundSelectorObj get_arg_sel(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces, Context& ctx) {
139
+ ExpressionObj exp = ARG(argname, Expression);
140
+ if (exp->concrete_type() == Expression::NULL_VAL) {
141
+ sass::ostream msg;
142
+ msg << argname << ": null is not a string for `" << function_name(sig) << "'";
143
+ error(msg.str(), exp->pstate(), traces);
144
+ }
145
+ if (String_Constant* str = Cast<String_Constant>(exp)) {
146
+ str->quote_mark(0);
147
+ }
148
+ sass::string exp_src = exp->to_string(ctx.c_options);
149
+ ItplFile* source = SASS_MEMORY_NEW(ItplFile, exp_src.c_str(), exp->pstate());
150
+ SelectorListObj sel_list = Parser::parse_selector(source, ctx, traces, false);
151
+ if (sel_list->length() == 0) return {};
152
+ return sel_list->first()->first();
153
+ }
154
+
155
+
156
+ }
157
+
158
+ }
@@ -0,0 +1,62 @@
1
+ #ifndef SASS_FN_UTILS_H
2
+ #define SASS_FN_UTILS_H
3
+
4
+ // sass.hpp must go before all system headers to get the
5
+ // __EXTENSIONS__ fix on Solaris.
6
+ #include "sass.hpp"
7
+
8
+ #include "units.hpp"
9
+ #include "backtrace.hpp"
10
+ #include "environment.hpp"
11
+ #include "ast_fwd_decl.hpp"
12
+ #include "error_handling.hpp"
13
+
14
+ namespace Sass {
15
+
16
+ #define FN_PROTOTYPE \
17
+ Env& env, \
18
+ Env& d_env, \
19
+ Context& ctx, \
20
+ Signature sig, \
21
+ SourceSpan pstate, \
22
+ Backtraces& traces, \
23
+ SelectorStack selector_stack, \
24
+ SelectorStack original_stack \
25
+
26
+ typedef const char* Signature;
27
+ typedef PreValue* (*Native_Function)(FN_PROTOTYPE);
28
+ #define BUILT_IN(name) PreValue* name(FN_PROTOTYPE)
29
+
30
+ #define ARG(argname, argtype) get_arg<argtype>(argname, env, sig, pstate, traces)
31
+ // special function for weird hsla percent (10px == 10% == 10 != 0.1)
32
+ #define ARGVAL(argname) get_arg_val(argname, env, sig, pstate, traces) // double
33
+
34
+ Definition* make_native_function(Signature, Native_Function, Context& ctx);
35
+ Definition* make_c_function(Sass_Function_Entry c_func, Context& ctx);
36
+
37
+ namespace Functions {
38
+
39
+ template <typename T>
40
+ T* get_arg(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces)
41
+ {
42
+ T* val = Cast<T>(env[argname]);
43
+ if (!val) {
44
+ error("argument `" + argname + "` of `" + sig + "` must be a " + T::type_name(), pstate, traces);
45
+ }
46
+ return val;
47
+ }
48
+
49
+ Map* get_arg_m(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces); // maps only
50
+ Number* get_arg_n(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces); // numbers only
51
+ double alpha_num(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces); // colors only
52
+ double color_num(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces); // colors only
53
+ double get_arg_r(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces, double lo, double hi); // colors only
54
+ double get_arg_val(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces); // shared
55
+ SelectorListObj get_arg_sels(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces, Context& ctx); // selectors only
56
+ CompoundSelectorObj get_arg_sel(const sass::string& argname, Env& env, Signature sig, SourceSpan pstate, Backtraces traces, Context& ctx); // selectors only
57
+
58
+ }
59
+
60
+ }
61
+
62
+ #endif
@@ -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 <cmath>
3
6
  #include <string>
4
7
  #include <iostream>
@@ -21,7 +24,7 @@ namespace Sass {
21
24
  Inspect::~Inspect() { }
22
25
 
23
26
  // statements
24
- void Inspect::operator()(Block_Ptr block)
27
+ void Inspect::operator()(Block* block)
25
28
  {
26
29
  if (!block->is_root()) {
27
30
  add_open_mapping(block);
@@ -39,25 +42,23 @@ namespace Sass {
39
42
 
40
43
  }
41
44
 
42
- void Inspect::operator()(Ruleset_Ptr ruleset)
45
+ void Inspect::operator()(StyleRule* ruleset)
43
46
  {
44
47
  if (ruleset->selector()) {
45
- opt.in_selector = true;
46
48
  ruleset->selector()->perform(this);
47
- opt.in_selector = false;
48
49
  }
49
50
  if (ruleset->block()) {
50
51
  ruleset->block()->perform(this);
51
52
  }
52
53
  }
53
54
 
54
- void Inspect::operator()(Keyframe_Rule_Ptr rule)
55
+ void Inspect::operator()(Keyframe_Rule* rule)
55
56
  {
56
57
  if (rule->name()) rule->name()->perform(this);
57
58
  if (rule->block()) rule->block()->perform(this);
58
59
  }
59
60
 
60
- void Inspect::operator()(Bubble_Ptr bubble)
61
+ void Inspect::operator()(Bubble* bubble)
61
62
  {
62
63
  append_indentation();
63
64
  append_token("::BUBBLE", bubble);
@@ -66,18 +67,64 @@ namespace Sass {
66
67
  append_scope_closer();
67
68
  }
68
69
 
69
- void Inspect::operator()(Media_Block_Ptr media_block)
70
+ void Inspect::operator()(MediaRule* rule)
71
+ {
72
+ append_indentation();
73
+ append_token("@media", rule);
74
+ append_mandatory_space();
75
+ if (rule->block()) {
76
+ rule->block()->perform(this);
77
+ }
78
+ }
79
+
80
+ void Inspect::operator()(CssMediaRule* rule)
70
81
  {
82
+ if (output_style() == NESTED)
83
+ indentation += rule->tabs();
71
84
  append_indentation();
72
- append_token("@media", media_block);
85
+ append_token("@media", rule);
73
86
  append_mandatory_space();
74
87
  in_media_block = true;
75
- media_block->media_queries()->perform(this);
88
+ bool joinIt = false;
89
+ for (auto query : rule->elements()) {
90
+ if (joinIt) {
91
+ append_comma_separator();
92
+ append_optional_space();
93
+ }
94
+ operator()(query);
95
+ joinIt = true;
96
+ }
97
+ if (rule->block()) {
98
+ rule->block()->perform(this);
99
+ }
76
100
  in_media_block = false;
77
- media_block->block()->perform(this);
101
+ if (output_style() == NESTED)
102
+ indentation -= rule->tabs();
103
+ }
104
+
105
+ void Inspect::operator()(CssMediaQuery* query)
106
+ {
107
+ bool joinIt = false;
108
+ if (!query->modifier().empty()) {
109
+ append_string(query->modifier());
110
+ append_mandatory_space();
111
+ }
112
+ if (!query->type().empty()) {
113
+ append_string(query->type());
114
+ joinIt = true;
115
+ }
116
+ for (auto feature : query->features()) {
117
+ if (joinIt) {
118
+ append_mandatory_space();
119
+ append_string("and");
120
+ append_mandatory_space();
121
+ }
122
+ append_string(feature);
123
+ joinIt = true;
124
+ }
78
125
  }
79
126
 
80
- void Inspect::operator()(Supports_Block_Ptr feature_block)
127
+ void Inspect::operator()(SupportsRule* feature_block)
81
128
  {
82
129
  append_indentation();
83
130
  append_token("@supports", feature_block);
@@ -86,7 +133,7 @@ namespace Sass {
86
133
  feature_block->block()->perform(this);
87
134
  }
88
135
 
89
- void Inspect::operator()(At_Root_Block_Ptr at_root_block)
136
+ void Inspect::operator()(AtRootRule* at_root_block)
90
137
  {
91
138
  append_indentation();
92
139
  append_token("@at-root ", at_root_block);
@@ -95,7 +142,7 @@ namespace Sass {
95
142
  if(at_root_block->block()) at_root_block->block()->perform(this);
96
143
  }
97
144
 
98
- void Inspect::operator()(Directive_Ptr at_rule)
145
+ void Inspect::operator()(AtRule* at_rule)
99
146
  {
100
147
  append_indentation();
101
148
  append_token(at_rule->keyword(), at_rule);
@@ -118,7 +165,7 @@ namespace Sass {
118
165
  }
119
166
  }
120
167
 
121
- void Inspect::operator()(Declaration_Ptr dec)
168
+ void Inspect::operator()(Declaration* dec)
122
169
  {
123
170
  if (dec->value()->concrete_type() == Expression::NULL_VAL) return;
124
171
  bool was_decl = in_declaration;
@@ -133,8 +180,7 @@ namespace Sass {
133
180
  append_colon_separator();
134
181
 
135
182
  if (dec->value()->concrete_type() == Expression::SELECTOR) {
136
- Listize listize;
137
- Expression_Obj ls = dec->value()->perform(&listize);
183
+ ExpressionObj ls = Listize::perform(dec->value());
138
184
  ls->perform(this);
139
185
  } else {
140
186
  dec->value()->perform(this);
@@ -150,7 +196,7 @@ namespace Sass {
150
196
  in_declaration = was_decl;
151
197
  }
152
198
 
153
- void Inspect::operator()(Assignment_Ptr assn)
199
+ void Inspect::operator()(Assignment* assn)
154
200
  {
155
201
  append_token(assn->variable(), assn);
156
202
  append_colon_separator();
@@ -162,7 +208,7 @@ namespace Sass {
162
208
  append_delimiter();
163
209
  }
164
210
 
165
- void Inspect::operator()(Import_Ptr import)
211
+ void Inspect::operator()(Import* import)
166
212
  {
167
213
  if (!import->urls().empty()) {
168
214
  append_token("@import", import);
@@ -193,7 +239,7 @@ namespace Sass {
193
239
  }
194
240
  }
195
241
 
196
- void Inspect::operator()(Import_Stub_Ptr import)
242
+ void Inspect::operator()(Import_Stub* import)
197
243
  {
198
244
  append_indentation();
199
245
  append_token("@import", import);
@@ -202,7 +248,7 @@ namespace Sass {
202
248
  append_delimiter();
203
249
  }
204
250
 
205
- void Inspect::operator()(Warning_Ptr warning)
251
+ void Inspect::operator()(WarningRule* warning)
206
252
  {
207
253
  append_indentation();
208
254
  append_token("@warn", warning);
@@ -211,7 +257,7 @@ namespace Sass {
211
257
  append_delimiter();
212
258
  }
213
259
 
214
- void Inspect::operator()(Error_Ptr error)
260
+ void Inspect::operator()(ErrorRule* error)
215
261
  {
216
262
  append_indentation();
217
263
  append_token("@error", error);
@@ -220,7 +266,7 @@ namespace Sass {
220
266
  append_delimiter();
221
267
  }
222
268
 
223
- void Inspect::operator()(Debug_Ptr debug)
269
+ void Inspect::operator()(DebugRule* debug)
224
270
  {
225
271
  append_indentation();
226
272
  append_token("@debug", debug);
@@ -229,14 +275,14 @@ namespace Sass {
229
275
  append_delimiter();
230
276
  }
231
277
 
232
- void Inspect::operator()(Comment_Ptr comment)
278
+ void Inspect::operator()(Comment* comment)
233
279
  {
234
280
  in_comment = true;
235
281
  comment->text()->perform(this);
236
282
  in_comment = false;
237
283
  }
238
284
 
239
- void Inspect::operator()(If_Ptr cond)
285
+ void Inspect::operator()(If* cond)
240
286
  {
241
287
  append_indentation();
242
288
  append_token("@if", cond);
@@ -251,7 +297,7 @@ namespace Sass {
251
297
  }
252
298
  }
253
299
 
254
- void Inspect::operator()(For_Ptr loop)
300
+ void Inspect::operator()(ForRule* loop)
255
301
  {
256
302
  append_indentation();
257
303
  append_token("@for", loop);
@@ -264,7 +310,7 @@ namespace Sass {
264
310
  loop->block()->perform(this);
265
311
  }
266
312
 
267
- void Inspect::operator()(Each_Ptr loop)
313
+ void Inspect::operator()(EachRule* loop)
268
314
  {
269
315
  append_indentation();
270
316
  append_token("@each", loop);
@@ -279,7 +325,7 @@ namespace Sass {
279
325
  loop->block()->perform(this);
280
326
  }
281
327
 
282
- void Inspect::operator()(While_Ptr loop)
328
+ void Inspect::operator()(WhileRule* loop)
283
329
  {
284
330
  append_indentation();
285
331
  append_token("@while", loop);
@@ -288,7 +334,7 @@ namespace Sass {
288
334
  loop->block()->perform(this);
289
335
  }
290
336
 
291
- void Inspect::operator()(Return_Ptr ret)
337
+ void Inspect::operator()(Return* ret)
292
338
  {
293
339
  append_indentation();
294
340
  append_token("@return", ret);
@@ -297,7 +343,7 @@ namespace Sass {
297
343
  append_delimiter();
298
344
  }
299
345
 
300
- void Inspect::operator()(Extension_Ptr extend)
346
+ void Inspect::operator()(ExtendRule* extend)
301
347
  {
302
348
  append_indentation();
303
349
  append_token("@extend", extend);
@@ -306,7 +352,7 @@ namespace Sass {
306
352
  append_delimiter();
307
353
  }
308
354
 
309
- void Inspect::operator()(Definition_Ptr def)
355
+ void Inspect::operator()(Definition* def)
310
356
  {
311
357
  append_indentation();
312
358
  if (def->type() == Definition::MIXIN) {
@@ -321,7 +367,7 @@ namespace Sass {
321
367
  def->block()->perform(this);
322
368
  }
323
369
 
324
- void Inspect::operator()(Mixin_Call_Ptr call)
370
+ void Inspect::operator()(Mixin_Call* call)
325
371
  {
326
372
  append_indentation();
327
373
  append_token("@include", call);
@@ -337,14 +383,14 @@ namespace Sass {
337
383
  if (!call->block()) append_delimiter();
338
384
  }
339
385
 
340
- void Inspect::operator()(Content_Ptr content)
386
+ void Inspect::operator()(Content* content)
341
387
  {
342
388
  append_indentation();
343
389
  append_token("@content", content);
344
390
  append_delimiter();
345
391
  }
346
392
 
347
- void Inspect::operator()(Map_Ptr map)
393
+ void Inspect::operator()(Map* map)
348
394
  {
349
395
  if (output_style() == TO_SASS && map->empty()) {
350
396
  append_string("()");
@@ -366,22 +412,22 @@ namespace Sass {
366
412
  append_string(")");
367
413
  }
368
414
 
369
- std::string Inspect::lbracket(List_Ptr list) {
415
+ sass::string Inspect::lbracket(List* list) {
370
416
  return list->is_bracketed() ? "[" : "(";
371
417
  }
372
418
 
373
- std::string Inspect::rbracket(List_Ptr list) {
419
+ sass::string Inspect::rbracket(List* list) {
374
420
  return list->is_bracketed() ? "]" : ")";
375
421
  }
376
422
 
377
- void Inspect::operator()(List_Ptr list)
423
+ void Inspect::operator()(List* list)
378
424
  {
379
425
  if (list->empty() && (output_style() == TO_SASS || list->is_bracketed())) {
380
426
  append_string(lbracket(list));
381
427
  append_string(rbracket(list));
382
428
  return;
383
429
  }
384
- std::string sep(list->separator() == SASS_SPACE ? " " : ",");
430
+ sass::string sep(list->separator() == SASS_SPACE ? " " : ",");
385
431
  if ((output_style() != COMPRESSED) && sep == ",") sep += " ";
386
432
  else if (in_media_block && sep != " ") sep += " "; // verified
387
433
  if (list->empty()) return;
@@ -398,7 +444,7 @@ namespace Sass {
398
444
  list->length() == 1 &&
399
445
  !list->from_selector() &&
400
446
  !Cast<List>(list->at(0)) &&
401
- !Cast<Selector_List>(list->at(0))
447
+ !Cast<SelectorList>(list->at(0))
402
448
  ) {
403
449
  append_string(lbracket(list));
404
450
  }
@@ -415,7 +461,7 @@ namespace Sass {
415
461
  for (size_t i = 0, L = list->size(); i < L; ++i) {
416
462
  if (list->separator() == SASS_HASH)
417
463
  { sep[0] = i % 2 ? ':' : ','; }
418
- Expression_Obj list_item = list->at(i);
464
+ ExpressionObj list_item = list->at(i);
419
465
  if (output_style() != TO_SASS) {
420
466
  if (list_item->is_invisible()) {
421
467
  // this fixes an issue with "" in a list
@@ -448,7 +494,7 @@ namespace Sass {
448
494
  list->length() == 1 &&
449
495
  !list->from_selector() &&
450
496
  !Cast<List>(list->at(0)) &&
451
- !Cast<Selector_List>(list->at(0))
497
+ !Cast<SelectorList>(list->at(0))
452
498
  ) {
453
499
  append_string(",");
454
500
  append_string(rbracket(list));
@@ -462,7 +508,7 @@ namespace Sass {
462
508
 
463
509
  }
464
510
 
465
- void Inspect::operator()(Binary_Expression_Ptr expr)
511
+ void Inspect::operator()(Binary_Expression* expr)
466
512
  {
467
513
  expr->left()->perform(this);
468
514
  if ( in_media_block ||
@@ -499,7 +545,7 @@ namespace Sass {
499
545
  expr->right()->perform(this);
500
546
  }
501
547
 
502
- void Inspect::operator()(Unary_Expression_Ptr expr)
548
+ void Inspect::operator()(Unary_Expression* expr)
503
549
  {
504
550
  if (expr->optype() == Unary_Expression::PLUS) append_string("+");
505
551
  else if (expr->optype() == Unary_Expression::SLASH) append_string("/");
@@ -507,91 +553,42 @@ namespace Sass {
507
553
  expr->operand()->perform(this);
508
554
  }
509
555
 
510
- void Inspect::operator()(Function_Call_Ptr call)
556
+ void Inspect::operator()(Function_Call* call)
511
557
  {
512
558
  append_token(call->name(), call);
513
559
  call->arguments()->perform(this);
514
560
  }
515
561
 
516
- void Inspect::operator()(Function_Call_Schema_Ptr call)
517
- {
518
- call->name()->perform(this);
519
- call->arguments()->perform(this);
520
- }
521
-
522
- void Inspect::operator()(Variable_Ptr var)
562
+ void Inspect::operator()(Variable* var)
523
563
  {
524
564
  append_token(var->name(), var);
525
565
  }
526
566
 
527
- void Inspect::operator()(Number_Ptr n)
567
+ void Inspect::operator()(Number* n)
528
568
  {
529
569
 
530
- std::string res;
531
-
532
570
  // reduce units
533
571
  n->reduce();
534
572
 
535
- // check if the fractional part of the value equals to zero
536
- // neat trick from http://stackoverflow.com/a/1521682/1550314
537
- // double int_part; bool is_int = modf(value, &int_part) == 0.0;
538
-
539
- // this all cannot be done with one run only, since fixed
540
- // output differs from normal output and regular output
541
- // can contain scientific notation which we do not want!
573
+ sass::ostream ss;
574
+ ss.precision(opt.precision);
575
+ ss << std::fixed << n->value();
542
576
 
543
- // first sample
544
- std::stringstream ss;
545
- ss.precision(12);
546
- ss << n->value();
577
+ sass::string res = ss.str();
578
+ size_t s = res.length();
547
579
 
548
- // check if we got scientific notation in result
549
- if (ss.str().find_first_of("e") != std::string::npos) {
550
- ss.clear(); ss.str(std::string());
551
- ss.precision(std::max(12, opt.precision));
552
- ss << std::fixed << n->value();
553
- }
554
-
555
- std::string tmp = ss.str();
556
- size_t pos_point = tmp.find_first_of(".,");
557
- size_t pos_fract = tmp.find_last_not_of("0");
558
- bool is_int = pos_point == pos_fract ||
559
- pos_point == std::string::npos;
560
-
561
- // reset stream for another run
562
- ss.clear(); ss.str(std::string());
563
-
564
- // take a shortcut for integers
565
- if (is_int)
580
+ // delete trailing zeros
581
+ for(s = s - 1; s > 0; --s)
566
582
  {
567
- ss.precision(0);
568
- ss << std::fixed << n->value();
569
- res = std::string(ss.str());
570
- }
571
- // process floats
572
- else
573
- {
574
- // do we have have too much precision?
575
- if (pos_fract < opt.precision + pos_point)
576
- { ss.precision((int)(pos_fract - pos_point)); }
577
- else { ss.precision(opt.precision); }
578
- // round value again
579
- ss << std::fixed << n->value();
580
- res = std::string(ss.str());
581
- // maybe we truncated up to decimal point
582
- size_t pos = res.find_last_not_of("0");
583
- // handle case where we have a "0"
584
- if (pos == std::string::npos) {
585
- res = "0.0";
586
- } else {
587
- bool at_dec_point = res[pos] == '.' ||
588
- res[pos] == ',';
589
- // don't leave a blank point
590
- if (at_dec_point) ++ pos;
591
- res.resize (pos + 1);
592
- }
583
+ if(res[s] == '0') {
584
+ res.erase(s, 1);
585
+ }
586
+ else break;
593
587
  }
594
588
 
589
+ // delete trailing decimal separator
590
+ if(res[s] == '.') res.erase(s, 1);
591
+
595
592
  // some final cosmetics
596
593
  if (res == "0.0") res = "0";
597
594
  else if (res == "") res = "0";
@@ -599,15 +596,22 @@ namespace Sass {
599
596
  else if (res == "-0.0") res = "0";
600
597
  else if (opt.output_style == COMPRESSED)
601
598
  {
602
- // check if handling negative nr
603
- size_t off = res[0] == '-' ? 1 : 0;
604
- // remove leading zero from floating point in compressed mode
605
- if (n->zero() && res[off] == '0' && res[off+1] == '.') res.erase(off, 1);
599
+ if (n->zero()) {
600
+ // check if handling negative nr
601
+ size_t off = res[0] == '-' ? 1 : 0;
602
+ // remove leading zero from floating point in compressed mode
603
+ if (res[off] == '0' && res[off+1] == '.') res.erase(off, 1);
604
+ }
606
605
  }
607
606
 
608
607
  // add unit now
609
608
  res += n->unit();
610
609
 
610
+ if (opt.output_style == TO_CSS && !n->is_valid_css_unit()) {
611
+ // traces.push_back(Backtrace(nr->pstate()));
612
+ throw Exception::InvalidValue({}, *n);
613
+ }
614
+
611
615
  // output the final token
612
616
  append_token(res, n);
613
617
  }
@@ -620,22 +624,17 @@ namespace Sass {
620
624
  else return c;
621
625
  }
622
626
 
623
- void Inspect::operator()(Color_Ptr c)
627
+ void Inspect::operator()(Color_RGBA* c)
624
628
  {
625
629
  // output the final token
626
- std::stringstream ss;
630
+ sass::ostream ss;
627
631
 
628
632
  // original color name
629
633
  // maybe an unknown token
630
- std::string name = c->disp();
631
-
632
- if (opt.in_selector && name != "") {
633
- append_token(name, c);
634
- return;
635
- }
634
+ sass::string name = c->disp();
636
635
 
637
636
  // resolved color
638
- std::string res_name = name;
637
+ sass::string res_name = name;
639
638
 
640
639
  double r = Sass::round(cap_channel<0xff>(c->r()), opt.precision);
641
640
  double g = Sass::round(cap_channel<0xff>(c->g()), opt.precision);
@@ -644,7 +643,7 @@ namespace Sass {
644
643
 
645
644
  // get color from given name (if one was given at all)
646
645
  if (name != "" && name_to_color(name)) {
647
- Color_Ptr_Const n = name_to_color(name);
646
+ const Color_RGBA* n = name_to_color(name);
648
647
  r = Sass::round(cap_channel<0xff>(n->r()), opt.precision);
649
648
  g = Sass::round(cap_channel<0xff>(n->g()), opt.precision);
650
649
  b = Sass::round(cap_channel<0xff>(n->b()), opt.precision);
@@ -657,7 +656,10 @@ namespace Sass {
657
656
  res_name = color_to_name(numval);
658
657
  }
659
658
 
660
- std::stringstream hexlet;
659
+ sass::ostream hexlet;
660
+ // dart sass compressed all colors in regular css always
661
+ // ruby sass and libsass does it only when not delayed
662
+ // since color math is going to be removed, this can go too
661
663
  bool compressed = opt.output_style == COMPRESSED;
662
664
  hexlet << '#' << std::setw(1) << std::setfill('0');
663
665
  // create a short color hexlet if there is any need for it
@@ -681,9 +683,6 @@ namespace Sass {
681
683
  if (name != "") {
682
684
  ss << name;
683
685
  }
684
- else if (r == 0 && g == 0 && b == 0 && a == 0) {
685
- ss << "transparent";
686
- }
687
686
  else if (a >= 1) {
688
687
  if (res_name != "") {
689
688
  if (compressed && hexlet.str().size() < res_name.size()) {
@@ -711,13 +710,19 @@ namespace Sass {
711
710
 
712
711
  }
713
712
 
714
- void Inspect::operator()(Boolean_Ptr b)
713
+ void Inspect::operator()(Color_HSLA* c)
714
+ {
715
+ Color_RGBA_Obj rgba = c->toRGBA();
716
+ operator()(rgba);
717
+ }
718
+
719
+ void Inspect::operator()(Boolean* b)
715
720
  {
716
721
  // output the final token
717
722
  append_token(b->value() ? "true" : "false", b);
718
723
  }
719
724
 
720
- void Inspect::operator()(String_Schema_Ptr ss)
725
+ void Inspect::operator()(String_Schema* ss)
721
726
  {
722
727
  // Evaluation should turn these into String_Constants,
723
728
  // so this method is only for inspection purposes.
@@ -728,12 +733,12 @@ namespace Sass {
728
733
  }
729
734
  }
730
735
 
731
- void Inspect::operator()(String_Constant_Ptr s)
736
+ void Inspect::operator()(String_Constant* s)
732
737
  {
733
738
  append_token(s->value(), s);
734
739
  }
735
740
 
736
- void Inspect::operator()(String_Quoted_Ptr s)
741
+ void Inspect::operator()(String_Quoted* s)
737
742
  {
738
743
  if (const char q = s->quote_mark()) {
739
744
  append_token(quote(s->value(), q), s);
@@ -742,28 +747,28 @@ namespace Sass {
742
747
  }
743
748
  }
744
749
 
745
- void Inspect::operator()(Custom_Error_Ptr e)
750
+ void Inspect::operator()(Custom_Error* e)
746
751
  {
747
752
  append_token(e->message(), e);
748
753
  }
749
754
 
750
- void Inspect::operator()(Custom_Warning_Ptr w)
755
+ void Inspect::operator()(Custom_Warning* w)
751
756
  {
752
757
  append_token(w->message(), w);
753
758
  }
754
759
 
755
- void Inspect::operator()(Supports_Operator_Ptr so)
760
+ void Inspect::operator()(SupportsOperation* so)
756
761
  {
757
762
 
758
763
  if (so->needs_parens(so->left())) append_string("(");
759
764
  so->left()->perform(this);
760
765
  if (so->needs_parens(so->left())) append_string(")");
761
766
 
762
- if (so->operand() == Supports_Operator::AND) {
767
+ if (so->operand() == SupportsOperation::AND) {
763
768
  append_mandatory_space();
764
769
  append_token("and", so);
765
770
  append_mandatory_space();
766
- } else if (so->operand() == Supports_Operator::OR) {
771
+ } else if (so->operand() == SupportsOperation::OR) {
767
772
  append_mandatory_space();
768
773
  append_token("or", so);
769
774
  append_mandatory_space();
@@ -774,7 +779,7 @@ namespace Sass {
774
779
  if (so->needs_parens(so->right())) append_string(")");
775
780
  }
776
781
 
777
- void Inspect::operator()(Supports_Negation_Ptr sn)
782
+ void Inspect::operator()(SupportsNegation* sn)
778
783
  {
779
784
  append_token("not", sn);
780
785
  append_mandatory_space();
@@ -783,7 +788,7 @@ namespace Sass {
783
788
  if (sn->needs_parens(sn->condition())) append_string(")");
784
789
  }
785
790
 
786
- void Inspect::operator()(Supports_Declaration_Ptr sd)
791
+ void Inspect::operator()(SupportsDeclaration* sd)
787
792
  {
788
793
  append_string("(");
789
794
  sd->feature()->perform(this);
@@ -792,12 +797,12 @@ namespace Sass {
792
797
  append_string(")");
793
798
  }
794
799
 
795
- void Inspect::operator()(Supports_Interpolation_Ptr sd)
800
+ void Inspect::operator()(Supports_Interpolation* sd)
796
801
  {
797
802
  sd->value()->perform(this);
798
803
  }
799
804
 
800
- void Inspect::operator()(Media_Query_Ptr mq)
805
+ void Inspect::operator()(Media_Query* mq)
801
806
  {
802
807
  size_t i = 0;
803
808
  if (mq->media_type()) {
@@ -814,7 +819,7 @@ namespace Sass {
814
819
  }
815
820
  }
816
821
 
817
- void Inspect::operator()(Media_Query_Expression_Ptr mqe)
822
+ void Inspect::operator()(Media_Query_Expression* mqe)
818
823
  {
819
824
  if (mqe->is_interpolated()) {
820
825
  mqe->feature()->perform(this);
@@ -830,7 +835,7 @@ namespace Sass {
830
835
  }
831
836
  }
832
837
 
833
- void Inspect::operator()(At_Root_Query_Ptr ae)
838
+ void Inspect::operator()(At_Root_Query* ae)
834
839
  {
835
840
  if (ae->feature()) {
836
841
  append_string("(");
@@ -843,7 +848,7 @@ namespace Sass {
843
848
  }
844
849
  }
845
850
 
846
- void Inspect::operator()(Function_Ptr f)
851
+ void Inspect::operator()(Function* f)
847
852
  {
848
853
  append_token("get-function", f);
849
854
  append_string("(");
@@ -851,14 +856,14 @@ namespace Sass {
851
856
  append_string(")");
852
857
  }
853
858
 
854
- void Inspect::operator()(Null_Ptr n)
859
+ void Inspect::operator()(Null* n)
855
860
  {
856
861
  // output the final token
857
862
  append_token("null", n);
858
863
  }
859
864
 
860
865
  // parameters and arguments
861
- void Inspect::operator()(Parameter_Ptr p)
866
+ void Inspect::operator()(Parameter* p)
862
867
  {
863
868
  append_token(p->name(), p);
864
869
  if (p->default_value()) {
@@ -870,7 +875,7 @@ namespace Sass {
870
875
  }
871
876
  }
872
877
 
873
- void Inspect::operator()(Parameters_Ptr p)
878
+ void Inspect::operator()(Parameters* p)
874
879
  {
875
880
  append_string("(");
876
881
  if (!p->empty()) {
@@ -883,7 +888,7 @@ namespace Sass {
883
888
  append_string(")");
884
889
  }
885
890
 
886
- void Inspect::operator()(Argument_Ptr a)
891
+ void Inspect::operator()(Argument* a)
887
892
  {
888
893
  if (!a->name().empty()) {
889
894
  append_token(a->name(), a);
@@ -895,7 +900,7 @@ namespace Sass {
895
900
  return;
896
901
  }
897
902
  if (a->value()->concrete_type() == Expression::STRING) {
898
- String_Constant_Ptr s = Cast<String_Constant>(a->value());
903
+ String_Constant* s = Cast<String_Constant>(a->value());
899
904
  if (s) s->perform(this);
900
905
  } else {
901
906
  a->value()->perform(this);
@@ -905,7 +910,7 @@ namespace Sass {
905
910
  }
906
911
  }
907
912
 
908
- void Inspect::operator()(Arguments_Ptr a)
913
+ void Inspect::operator()(Arguments* a)
909
914
  {
910
915
  append_string("(");
911
916
  if (!a->empty()) {
@@ -919,46 +924,38 @@ namespace Sass {
919
924
  append_string(")");
920
925
  }
921
926
 
922
- void Inspect::operator()(Selector_Schema_Ptr s)
927
+ void Inspect::operator()(Selector_Schema* s)
923
928
  {
924
- opt.in_selector = true;
925
929
  s->contents()->perform(this);
926
- opt.in_selector = false;
927
930
  }
928
931
 
929
- void Inspect::operator()(Parent_Selector_Ptr p)
932
+ void Inspect::operator()(Parent_Reference* p)
930
933
  {
931
- if (p->is_real_parent_ref()) append_string("&");
934
+ append_string("&");
932
935
  }
933
936
 
934
- void Inspect::operator()(Placeholder_Selector_Ptr s)
937
+ void Inspect::operator()(PlaceholderSelector* s)
935
938
  {
936
939
  append_token(s->name(), s);
937
- if (s->has_line_break()) append_optional_linefeed();
938
- if (s->has_line_break()) append_indentation();
939
940
 
940
941
  }
941
942
 
942
- void Inspect::operator()(Element_Selector_Ptr s)
943
+ void Inspect::operator()(TypeSelector* s)
943
944
  {
944
945
  append_token(s->ns_name(), s);
945
946
  }
946
947
 
947
- void Inspect::operator()(Class_Selector_Ptr s)
948
+ void Inspect::operator()(ClassSelector* s)
948
949
  {
949
950
  append_token(s->ns_name(), s);
950
- if (s->has_line_break()) append_optional_linefeed();
951
- if (s->has_line_break()) append_indentation();
952
951
  }
953
952
 
954
- void Inspect::operator()(Id_Selector_Ptr s)
953
+ void Inspect::operator()(IDSelector* s)
955
954
  {
956
955
  append_token(s->ns_name(), s);
957
- if (s->has_line_break()) append_optional_linefeed();
958
- if (s->has_line_break()) append_indentation();
959
956
  }
960
957
 
961
- void Inspect::operator()(Attribute_Selector_Ptr s)
958
+ void Inspect::operator()(AttributeSelector* s)
962
959
  {
963
960
  append_string("[");
964
961
  add_open_mapping(s);
@@ -977,111 +974,38 @@ namespace Sass {
977
974
  append_string("]");
978
975
  }
979
976
 
980
- void Inspect::operator()(Pseudo_Selector_Ptr s)
977
+ void Inspect::operator()(PseudoSelector* s)
981
978
  {
982
- append_token(s->ns_name(), s);
983
- if (s->expression()) {
984
- append_string("(");
985
- s->expression()->perform(this);
986
- append_string(")");
987
- }
988
- }
989
979
 
990
- void Inspect::operator()(Wrapped_Selector_Ptr s)
991
- {
992
- if (s->name() == " ") {
993
- append_string("");
994
- } else {
995
- bool was = in_wrapped;
996
- in_wrapped = true;
997
- append_token(s->name(), s);
998
- append_string("(");
999
- bool was_comma_array = in_comma_array;
1000
- in_comma_array = false;
1001
- s->selector()->perform(this);
1002
- in_comma_array = was_comma_array;
1003
- append_string(")");
1004
- in_wrapped = was;
1005
- }
1006
- }
1007
-
1008
- void Inspect::operator()(Compound_Selector_Ptr s)
1009
- {
1010
- for (size_t i = 0, L = s->length(); i < L; ++i) {
1011
- (*s)[i]->perform(this);
1012
- }
1013
- if (s->has_line_break()) {
1014
- if (output_style() != COMPACT) {
1015
- append_optional_linefeed();
1016
- }
1017
- }
1018
- }
1019
-
1020
- void Inspect::operator()(Complex_Selector_Ptr c)
1021
- {
1022
- Compound_Selector_Obj head = c->head();
1023
- Complex_Selector_Obj tail = c->tail();
1024
- Complex_Selector::Combinator comb = c->combinator();
1025
-
1026
- if (comb == Complex_Selector::ANCESTOR_OF && (!head || head->empty())) {
1027
- if (tail) tail->perform(this);
1028
- return;
1029
- }
1030
-
1031
- if (c->has_line_feed()) {
1032
- if (!(c->has_parent_ref())) {
1033
- append_optional_linefeed();
1034
- append_indentation();
980
+ if (s->name() != "") {
981
+ append_string(":");
982
+ if (s->isSyntacticElement()) {
983
+ append_string(":");
1035
984
  }
1036
- }
1037
-
1038
- if (head && head->length() != 0) head->perform(this);
1039
- bool is_empty = !head || head->length() == 0 || head->is_empty_reference();
1040
- bool is_tail = head && !head->is_empty_reference() && tail;
1041
- if (output_style() == COMPRESSED && comb != Complex_Selector::ANCESTOR_OF) scheduled_space = 0;
1042
-
1043
- switch (comb) {
1044
- case Complex_Selector::ANCESTOR_OF:
1045
- if (is_tail) append_mandatory_space();
1046
- break;
1047
- case Complex_Selector::PARENT_OF:
1048
- append_optional_space();
1049
- append_string(">");
1050
- append_optional_space();
1051
- break;
1052
- case Complex_Selector::ADJACENT_TO:
1053
- append_optional_space();
1054
- append_string("+");
1055
- append_optional_space();
1056
- break;
1057
- case Complex_Selector::REFERENCE:
1058
- append_mandatory_space();
1059
- append_string("/");
1060
- c->reference()->perform(this);
1061
- append_string("/");
1062
- append_mandatory_space();
1063
- break;
1064
- case Complex_Selector::PRECEDES:
1065
- if (is_empty) append_optional_space();
1066
- else append_mandatory_space();
1067
- append_string("~");
1068
- if (tail) append_mandatory_space();
1069
- else append_optional_space();
1070
- break;
1071
- default: break;
1072
- }
1073
- if (tail && comb != Complex_Selector::ANCESTOR_OF) {
1074
- if (c->has_line_break()) append_optional_linefeed();
1075
- }
1076
- if (tail) tail->perform(this);
1077
- if (!tail && c->has_line_break()) {
1078
- if (output_style() == COMPACT) {
1079
- append_mandatory_space();
985
+ append_token(s->ns_name(), s);
986
+ if (s->selector() || s->argument()) {
987
+ bool was = in_wrapped;
988
+ in_wrapped = true;
989
+ append_string("(");
990
+ if (s->argument()) {
991
+ s->argument()->perform(this);
992
+ }
993
+ if (s->selector() && s->argument()) {
994
+ append_mandatory_space();
995
+ }
996
+ bool was_comma_array = in_comma_array;
997
+ in_comma_array = false;
998
+ if (s->selector()) {
999
+ s->selector()->perform(this);
1000
+ }
1001
+ in_comma_array = was_comma_array;
1002
+ append_string(")");
1003
+ in_wrapped = was;
1080
1004
  }
1081
1005
  }
1082
1006
  }
1083
1007
 
1084
- void Inspect::operator()(Selector_List_Ptr g)
1008
+ void Inspect::operator()(SelectorList* g)
1085
1009
  {
1086
1010
 
1087
1011
  if (g->empty()) {
@@ -1096,7 +1020,7 @@ namespace Sass {
1096
1020
  // probably ruby sass eqivalent of element_needs_parens
1097
1021
  if (output_style() == TO_SASS && g->length() == 1 &&
1098
1022
  (!Cast<List>((*g)[0]) &&
1099
- !Cast<Selector_List>((*g)[0]))) {
1023
+ !Cast<SelectorList>((*g)[0]))) {
1100
1024
  append_string("(");
1101
1025
  }
1102
1026
  else if (!in_declaration && in_comma_array) {
@@ -1106,8 +1030,10 @@ namespace Sass {
1106
1030
  if (in_declaration) in_comma_array = true;
1107
1031
 
1108
1032
  for (size_t i = 0, L = g->length(); i < L; ++i) {
1033
+
1109
1034
  if (!in_wrapped && i == 0) append_indentation();
1110
- if ((*g)[i] == 0) continue;
1035
+ if ((*g)[i] == nullptr) continue;
1036
+ if (g->at(i)->length() == 0) continue;
1111
1037
  schedule_mapping(g->at(i)->last());
1112
1038
  // add_open_mapping((*g)[i]->last());
1113
1039
  (*g)[i]->perform(this);
@@ -1122,7 +1048,7 @@ namespace Sass {
1122
1048
  // probably ruby sass eqivalent of element_needs_parens
1123
1049
  if (output_style() == TO_SASS && g->length() == 1 &&
1124
1050
  (!Cast<List>((*g)[0]) &&
1125
- !Cast<Selector_List>((*g)[0]))) {
1051
+ !Cast<SelectorList>((*g)[0]))) {
1126
1052
  append_string(",)");
1127
1053
  }
1128
1054
  else if (!in_declaration && in_comma_array) {
@@ -1130,9 +1056,70 @@ namespace Sass {
1130
1056
  }
1131
1057
 
1132
1058
  }
1059
+ void Inspect::operator()(ComplexSelector* sel)
1060
+ {
1061
+ if (sel->hasPreLineFeed()) {
1062
+ append_optional_linefeed();
1063
+ if (!in_wrapped && output_style() == NESTED) {
1064
+ append_indentation();
1065
+ }
1066
+ }
1067
+ const SelectorComponent* prev = nullptr;
1068
+ for (auto& item : sel->elements()) {
1069
+ if (prev != nullptr) {
1070
+ if (item->getCombinator() || prev->getCombinator()) {
1071
+ append_optional_space();
1072
+ } else {
1073
+ append_mandatory_space();
1074
+ }
1075
+ }
1076
+ item->perform(this);
1077
+ prev = item.ptr();
1078
+ }
1079
+ }
1133
1080
 
1134
- void Inspect::fallback_impl(AST_Node_Ptr n)
1081
+ void Inspect::operator()(SelectorComponent* sel)
1135
1082
  {
1083
+ // You should probably never call this method directly
1084
+ // But in case anyone does, we will do the upcasting
1085
+ if (auto comp = Cast<CompoundSelector>(sel)) operator()(comp);
1086
+ if (auto comb = Cast<SelectorCombinator>(sel)) operator()(comb);
1087
+ }
1088
+
1089
+ void Inspect::operator()(CompoundSelector* sel)
1090
+ {
1091
+ if (sel->hasRealParent()) {
1092
+ append_string("&");
1093
+ }
1094
+ sel->sortChildren();
1095
+ for (auto& item : sel->elements()) {
1096
+ item->perform(this);
1097
+ }
1098
+ // Add the post line break (from ruby sass)
1099
+ // Dart sass uses another logic for newlines
1100
+ if (sel->hasPostLineBreak()) {
1101
+ if (output_style() != COMPACT) {
1102
+ append_optional_linefeed();
1103
+ }
1104
+ }
1105
+ }
1106
+
1107
+ void Inspect::operator()(SelectorCombinator* sel)
1108
+ {
1109
+ append_optional_space();
1110
+ switch (sel->combinator()) {
1111
+ case SelectorCombinator::Combinator::CHILD: append_string(">"); break;
1112
+ case SelectorCombinator::Combinator::GENERAL: append_string("~"); break;
1113
+ case SelectorCombinator::Combinator::ADJACENT: append_string("+"); break;
1114
+ }
1115
+ append_optional_space();
1116
+ // Add the post line break (from ruby sass)
1117
+ // Dart sass uses another logic for newlines
1118
+ if (sel->hasPostLineBreak()) {
1119
+ if (output_style() != COMPACT) {
1120
+ // append_optional_linefeed();
1121
+ }
1122
+ }
1136
1123
  }
1137
1124
 
1138
1125
  }