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