sassc 2.0.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.gitmodules +1 -1
  4. data/.travis.yml +9 -3
  5. data/CHANGELOG.md +36 -0
  6. data/CODE_OF_CONDUCT.md +1 -1
  7. data/README.md +1 -1
  8. data/Rakefile +43 -7
  9. data/ext/depend +4 -0
  10. data/ext/extconf.rb +92 -0
  11. data/ext/libsass/VERSION +1 -0
  12. data/ext/libsass/include/sass/base.h +9 -1
  13. data/ext/libsass/include/sass/context.h +5 -1
  14. data/ext/libsass/src/MurmurHash2.hpp +91 -0
  15. data/ext/libsass/src/ast.cpp +755 -2028
  16. data/ext/libsass/src/ast.hpp +492 -2477
  17. data/ext/libsass/src/{to_c.cpp → ast2c.cpp} +22 -16
  18. data/ext/libsass/src/ast2c.hpp +39 -0
  19. data/ext/libsass/src/ast_def_macros.hpp +70 -10
  20. data/ext/libsass/src/ast_fwd_decl.cpp +5 -3
  21. data/ext/libsass/src/ast_fwd_decl.hpp +107 -296
  22. data/ext/libsass/src/ast_helpers.hpp +292 -0
  23. data/ext/libsass/src/ast_sel_cmp.cpp +396 -0
  24. data/ext/libsass/src/ast_sel_super.cpp +539 -0
  25. data/ext/libsass/src/ast_sel_unify.cpp +275 -0
  26. data/ext/libsass/src/ast_sel_weave.cpp +616 -0
  27. data/ext/libsass/src/ast_selectors.cpp +1043 -0
  28. data/ext/libsass/src/ast_selectors.hpp +522 -0
  29. data/ext/libsass/src/ast_supports.cpp +114 -0
  30. data/ext/libsass/src/ast_supports.hpp +121 -0
  31. data/ext/libsass/src/ast_values.cpp +1154 -0
  32. data/ext/libsass/src/ast_values.hpp +498 -0
  33. data/ext/libsass/src/backtrace.cpp +11 -7
  34. data/ext/libsass/src/backtrace.hpp +5 -5
  35. data/ext/libsass/src/base64vlq.cpp +5 -2
  36. data/ext/libsass/src/base64vlq.hpp +1 -1
  37. data/ext/libsass/src/bind.cpp +35 -34
  38. data/ext/libsass/src/bind.hpp +3 -1
  39. data/ext/libsass/src/c2ast.cpp +64 -0
  40. data/ext/libsass/src/c2ast.hpp +14 -0
  41. data/ext/libsass/src/cencode.c +4 -6
  42. data/ext/libsass/src/check_nesting.cpp +83 -88
  43. data/ext/libsass/src/check_nesting.hpp +39 -34
  44. data/ext/libsass/src/color_maps.cpp +168 -164
  45. data/ext/libsass/src/color_maps.hpp +152 -160
  46. data/ext/libsass/src/constants.cpp +20 -0
  47. data/ext/libsass/src/constants.hpp +19 -0
  48. data/ext/libsass/src/context.cpp +104 -121
  49. data/ext/libsass/src/context.hpp +43 -55
  50. data/ext/libsass/src/cssize.cpp +103 -188
  51. data/ext/libsass/src/cssize.hpp +45 -51
  52. data/ext/libsass/src/dart_helpers.hpp +199 -0
  53. data/ext/libsass/src/debugger.hpp +524 -361
  54. data/ext/libsass/src/emitter.cpp +26 -26
  55. data/ext/libsass/src/emitter.hpp +20 -18
  56. data/ext/libsass/src/environment.cpp +41 -27
  57. data/ext/libsass/src/environment.hpp +33 -22
  58. data/ext/libsass/src/error_handling.cpp +92 -94
  59. data/ext/libsass/src/error_handling.hpp +73 -50
  60. data/ext/libsass/src/eval.cpp +380 -515
  61. data/ext/libsass/src/eval.hpp +64 -57
  62. data/ext/libsass/src/eval_selectors.cpp +75 -0
  63. data/ext/libsass/src/expand.cpp +322 -263
  64. data/ext/libsass/src/expand.hpp +55 -39
  65. data/ext/libsass/src/extender.cpp +1188 -0
  66. data/ext/libsass/src/extender.hpp +399 -0
  67. data/ext/libsass/src/extension.cpp +43 -0
  68. data/ext/libsass/src/extension.hpp +89 -0
  69. data/ext/libsass/src/file.cpp +134 -88
  70. data/ext/libsass/src/file.hpp +28 -37
  71. data/ext/libsass/src/fn_colors.cpp +596 -0
  72. data/ext/libsass/src/fn_colors.hpp +85 -0
  73. data/ext/libsass/src/fn_lists.cpp +285 -0
  74. data/ext/libsass/src/fn_lists.hpp +34 -0
  75. data/ext/libsass/src/fn_maps.cpp +94 -0
  76. data/ext/libsass/src/fn_maps.hpp +30 -0
  77. data/ext/libsass/src/fn_miscs.cpp +244 -0
  78. data/ext/libsass/src/fn_miscs.hpp +40 -0
  79. data/ext/libsass/src/fn_numbers.cpp +227 -0
  80. data/ext/libsass/src/fn_numbers.hpp +45 -0
  81. data/ext/libsass/src/fn_selectors.cpp +205 -0
  82. data/ext/libsass/src/fn_selectors.hpp +35 -0
  83. data/ext/libsass/src/fn_strings.cpp +268 -0
  84. data/ext/libsass/src/fn_strings.hpp +34 -0
  85. data/ext/libsass/src/fn_utils.cpp +158 -0
  86. data/ext/libsass/src/fn_utils.hpp +62 -0
  87. data/ext/libsass/src/inspect.cpp +253 -266
  88. data/ext/libsass/src/inspect.hpp +72 -74
  89. data/ext/libsass/src/json.cpp +2 -2
  90. data/ext/libsass/src/lexer.cpp +25 -84
  91. data/ext/libsass/src/lexer.hpp +5 -16
  92. data/ext/libsass/src/listize.cpp +27 -43
  93. data/ext/libsass/src/listize.hpp +14 -11
  94. data/ext/libsass/src/mapping.hpp +1 -0
  95. data/ext/libsass/src/memory.hpp +12 -0
  96. data/ext/libsass/src/memory/allocator.cpp +48 -0
  97. data/ext/libsass/src/memory/allocator.hpp +138 -0
  98. data/ext/libsass/src/memory/config.hpp +20 -0
  99. data/ext/libsass/src/memory/memory_pool.hpp +186 -0
  100. data/ext/libsass/src/memory/shared_ptr.cpp +33 -0
  101. data/ext/libsass/src/memory/shared_ptr.hpp +332 -0
  102. data/ext/libsass/src/operation.hpp +193 -143
  103. data/ext/libsass/src/operators.cpp +56 -29
  104. data/ext/libsass/src/operators.hpp +11 -11
  105. data/ext/libsass/src/ordered_map.hpp +112 -0
  106. data/ext/libsass/src/output.cpp +59 -75
  107. data/ext/libsass/src/output.hpp +15 -22
  108. data/ext/libsass/src/parser.cpp +662 -818
  109. data/ext/libsass/src/parser.hpp +96 -100
  110. data/ext/libsass/src/parser_selectors.cpp +189 -0
  111. data/ext/libsass/src/permutate.hpp +164 -0
  112. data/ext/libsass/src/plugins.cpp +12 -8
  113. data/ext/libsass/src/plugins.hpp +8 -8
  114. data/ext/libsass/src/position.cpp +10 -26
  115. data/ext/libsass/src/position.hpp +44 -21
  116. data/ext/libsass/src/prelexer.cpp +14 -8
  117. data/ext/libsass/src/prelexer.hpp +9 -9
  118. data/ext/libsass/src/remove_placeholders.cpp +59 -57
  119. data/ext/libsass/src/remove_placeholders.hpp +20 -18
  120. data/ext/libsass/src/sass.cpp +25 -18
  121. data/ext/libsass/src/sass.hpp +22 -14
  122. data/ext/libsass/src/sass2scss.cpp +49 -18
  123. data/ext/libsass/src/sass_context.cpp +104 -132
  124. data/ext/libsass/src/sass_context.hpp +2 -2
  125. data/ext/libsass/src/sass_functions.cpp +7 -4
  126. data/ext/libsass/src/sass_functions.hpp +1 -1
  127. data/ext/libsass/src/sass_values.cpp +26 -21
  128. data/ext/libsass/src/settings.hpp +19 -0
  129. data/ext/libsass/src/source.cpp +69 -0
  130. data/ext/libsass/src/source.hpp +95 -0
  131. data/ext/libsass/src/source_data.hpp +32 -0
  132. data/ext/libsass/src/source_map.cpp +27 -20
  133. data/ext/libsass/src/source_map.hpp +14 -11
  134. data/ext/libsass/src/stylesheet.cpp +22 -0
  135. data/ext/libsass/src/stylesheet.hpp +57 -0
  136. data/ext/libsass/src/to_value.cpp +24 -22
  137. data/ext/libsass/src/to_value.hpp +18 -22
  138. data/ext/libsass/src/units.cpp +28 -22
  139. data/ext/libsass/src/units.hpp +9 -8
  140. data/ext/libsass/src/utf8/checked.h +12 -10
  141. data/ext/libsass/src/utf8/core.h +3 -0
  142. data/ext/libsass/src/utf8_string.cpp +12 -10
  143. data/ext/libsass/src/utf8_string.hpp +7 -6
  144. data/ext/libsass/src/util.cpp +97 -107
  145. data/ext/libsass/src/util.hpp +74 -30
  146. data/ext/libsass/src/util_string.cpp +125 -0
  147. data/ext/libsass/src/util_string.hpp +73 -0
  148. data/ext/libsass/src/values.cpp +33 -24
  149. data/ext/libsass/src/values.hpp +2 -2
  150. data/lib/sassc.rb +24 -0
  151. data/lib/sassc/engine.rb +7 -5
  152. data/lib/sassc/functions_handler.rb +11 -13
  153. data/lib/sassc/native.rb +10 -9
  154. data/lib/sassc/native/native_functions_api.rb +0 -5
  155. data/lib/sassc/script.rb +4 -6
  156. data/lib/sassc/version.rb +1 -1
  157. data/sassc.gemspec +32 -12
  158. data/test/engine_test.rb +32 -2
  159. data/test/functions_test.rb +38 -1
  160. data/test/native_test.rb +4 -4
  161. metadata +95 -109
  162. data/ext/Rakefile +0 -3
  163. data/ext/libsass/.editorconfig +0 -15
  164. data/ext/libsass/.gitattributes +0 -2
  165. data/ext/libsass/.github/CONTRIBUTING.md +0 -65
  166. data/ext/libsass/.github/ISSUE_TEMPLATE.md +0 -54
  167. data/ext/libsass/.gitignore +0 -85
  168. data/ext/libsass/.travis.yml +0 -64
  169. data/ext/libsass/COPYING +0 -25
  170. data/ext/libsass/GNUmakefile.am +0 -88
  171. data/ext/libsass/INSTALL +0 -1
  172. data/ext/libsass/LICENSE +0 -25
  173. data/ext/libsass/Makefile +0 -351
  174. data/ext/libsass/Makefile.conf +0 -55
  175. data/ext/libsass/Readme.md +0 -104
  176. data/ext/libsass/SECURITY.md +0 -10
  177. data/ext/libsass/appveyor.yml +0 -91
  178. data/ext/libsass/configure.ac +0 -138
  179. data/ext/libsass/contrib/libsass.spec +0 -66
  180. data/ext/libsass/docs/README.md +0 -20
  181. data/ext/libsass/docs/api-context-example.md +0 -45
  182. data/ext/libsass/docs/api-context-internal.md +0 -163
  183. data/ext/libsass/docs/api-context.md +0 -295
  184. data/ext/libsass/docs/api-doc.md +0 -215
  185. data/ext/libsass/docs/api-function-example.md +0 -67
  186. data/ext/libsass/docs/api-function-internal.md +0 -8
  187. data/ext/libsass/docs/api-function.md +0 -74
  188. data/ext/libsass/docs/api-importer-example.md +0 -112
  189. data/ext/libsass/docs/api-importer-internal.md +0 -20
  190. data/ext/libsass/docs/api-importer.md +0 -86
  191. data/ext/libsass/docs/api-value-example.md +0 -55
  192. data/ext/libsass/docs/api-value-internal.md +0 -76
  193. data/ext/libsass/docs/api-value.md +0 -154
  194. data/ext/libsass/docs/build-on-darwin.md +0 -27
  195. data/ext/libsass/docs/build-on-gentoo.md +0 -55
  196. data/ext/libsass/docs/build-on-windows.md +0 -139
  197. data/ext/libsass/docs/build-shared-library.md +0 -35
  198. data/ext/libsass/docs/build-with-autotools.md +0 -78
  199. data/ext/libsass/docs/build-with-makefiles.md +0 -68
  200. data/ext/libsass/docs/build-with-mingw.md +0 -107
  201. data/ext/libsass/docs/build-with-visual-studio.md +0 -90
  202. data/ext/libsass/docs/build.md +0 -97
  203. data/ext/libsass/docs/compatibility-plan.md +0 -48
  204. data/ext/libsass/docs/contributing.md +0 -17
  205. data/ext/libsass/docs/custom-functions-internal.md +0 -122
  206. data/ext/libsass/docs/dev-ast-memory.md +0 -223
  207. data/ext/libsass/docs/implementations.md +0 -56
  208. data/ext/libsass/docs/plugins.md +0 -47
  209. data/ext/libsass/docs/setup-environment.md +0 -68
  210. data/ext/libsass/docs/source-map-internals.md +0 -51
  211. data/ext/libsass/docs/trace.md +0 -26
  212. data/ext/libsass/docs/triage.md +0 -17
  213. data/ext/libsass/docs/unicode.md +0 -39
  214. data/ext/libsass/extconf.rb +0 -6
  215. data/ext/libsass/include/sass/version.h.in +0 -12
  216. data/ext/libsass/m4/.gitkeep +0 -0
  217. data/ext/libsass/m4/m4-ax_cxx_compile_stdcxx_11.m4 +0 -167
  218. data/ext/libsass/res/resource.rc +0 -35
  219. data/ext/libsass/script/bootstrap +0 -13
  220. data/ext/libsass/script/branding +0 -10
  221. data/ext/libsass/script/ci-build-libsass +0 -134
  222. data/ext/libsass/script/ci-build-plugin +0 -62
  223. data/ext/libsass/script/ci-install-compiler +0 -6
  224. data/ext/libsass/script/ci-install-deps +0 -20
  225. data/ext/libsass/script/ci-report-coverage +0 -42
  226. data/ext/libsass/script/spec +0 -5
  227. data/ext/libsass/script/tap-driver +0 -652
  228. data/ext/libsass/script/tap-runner +0 -1
  229. data/ext/libsass/script/test-leaks.pl +0 -103
  230. data/ext/libsass/src/GNUmakefile.am +0 -54
  231. data/ext/libsass/src/extend.cpp +0 -2130
  232. data/ext/libsass/src/extend.hpp +0 -86
  233. data/ext/libsass/src/functions.cpp +0 -2234
  234. data/ext/libsass/src/functions.hpp +0 -198
  235. data/ext/libsass/src/memory/SharedPtr.cpp +0 -114
  236. data/ext/libsass/src/memory/SharedPtr.hpp +0 -206
  237. data/ext/libsass/src/node.cpp +0 -319
  238. data/ext/libsass/src/node.hpp +0 -118
  239. data/ext/libsass/src/paths.hpp +0 -71
  240. data/ext/libsass/src/sass_util.cpp +0 -149
  241. data/ext/libsass/src/sass_util.hpp +0 -256
  242. data/ext/libsass/src/subset_map.cpp +0 -55
  243. data/ext/libsass/src/subset_map.hpp +0 -76
  244. data/ext/libsass/src/support/libsass.pc.in +0 -11
  245. data/ext/libsass/src/to_c.hpp +0 -39
  246. data/ext/libsass/test/test_node.cpp +0 -94
  247. data/ext/libsass/test/test_paths.cpp +0 -28
  248. data/ext/libsass/test/test_selector_difference.cpp +0 -25
  249. data/ext/libsass/test/test_specificity.cpp +0 -25
  250. data/ext/libsass/test/test_subset_map.cpp +0 -472
  251. data/ext/libsass/test/test_superselector.cpp +0 -69
  252. data/ext/libsass/test/test_unification.cpp +0 -31
  253. data/ext/libsass/version.sh +0 -10
  254. data/ext/libsass/win/libsass.sln +0 -39
  255. data/ext/libsass/win/libsass.sln.DotSettings +0 -9
  256. data/ext/libsass/win/libsass.targets +0 -118
  257. data/ext/libsass/win/libsass.vcxproj +0 -188
  258. data/ext/libsass/win/libsass.vcxproj.filters +0 -357
  259. data/lib/sassc/native/lib_c.rb +0 -21
  260. data/lib/tasks/libsass.rb +0 -33
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 728b06267e365e493048b5367d344608392997c5beee20e7606d763b655514e7
4
- data.tar.gz: c418fc06a5d8badec39fe2abf134c8297fa7d96679fa3af145f9718004b3e35b
3
+ metadata.gz: 75155de90eb3449ed2a1214ca6ab2b82ffe69b144c2a8eaf8a6a4fd522b58ea4
4
+ data.tar.gz: 8575ebe24a2d56a9bea0e4574ebd23753e283d3b34bf571489f318a357bce2b9
5
5
  SHA512:
6
- metadata.gz: 37937f49272650f5efc95eda412f8487050171a6fe31eae775cdf6ff03aa293458388a22a352a5dd59f3f4141d83a7f32f91b571513cdb14468a11f6176b69ea
7
- data.tar.gz: e25e7d5a7b9049802c35e456cb35e22c801028ca93c5efceaea1e7cf80c14ba84ec3ceb7660d6323146cc5b09a9fb8e1843aa678bc3076d2231cf48d84bae197
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,39 @@
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)
35
+ - **2.0.1**
36
+ - [Relax FFI dependency](https://github.com/sass/sassc-ruby/pull/102)
1
37
  - **2.0.0**
2
38
  - [Remove dependency on Ruby Sass](https://github.com/sass/sassc-ruby/pull/85)
3
39
  - [frozen_string_literal all files](https://github.com/sass/sassc-ruby/pull/85)
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
  }