zuora_connect_ui 0.8.2 → 0.8.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (449) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/zuora_connect_ui.js +1 -0
  3. data/app/assets/javascripts/zuora_connect_ui/util.js +51 -0
  4. data/app/assets/stylesheets/_zuora_connect_ui.scss +4 -6
  5. data/app/assets/stylesheets/zuora_connect_ui/datatables.scss +3 -3
  6. data/app/helpers/zuora_connect_ui/application_helper.rb +28 -4
  7. data/app/views/partials/_table.html.erb +16 -7
  8. data/lib/zuora_connect_ui/version.rb +1 -1
  9. data/vendor/ruby/2.6.0/cache/autoprefixer-rails-9.6.1.1.gem +0 -0
  10. data/vendor/ruby/2.6.0/cache/parser-2.6.4.1.gem +0 -0
  11. data/vendor/ruby/2.6.0/cache/sassc-2.2.0.gem +0 -0
  12. data/vendor/ruby/2.6.0/cache/zeitwerk-2.1.10.gem +0 -0
  13. data/vendor/ruby/2.6.0/extensions/x86_64-linux/2.6.0/sassc-2.2.0/gem.build_complete +0 -0
  14. data/vendor/ruby/2.6.0/extensions/x86_64-linux/2.6.0/sassc-2.2.0/gem_make.out +75 -0
  15. data/vendor/ruby/2.6.0/extensions/x86_64-linux/2.6.0/sassc-2.2.0/sassc/libsass.so +0 -0
  16. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/CHANGELOG.md +1085 -0
  17. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/Gemfile +10 -0
  18. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/LICENSE +20 -0
  19. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/README.md +237 -0
  20. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/Rakefile +53 -0
  21. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/autoprefixer-rails.gemspec +32 -0
  22. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/lib/autoprefixer-rails.rb +41 -0
  23. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/lib/autoprefixer-rails/processor.rb +194 -0
  24. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/lib/autoprefixer-rails/railtie.rb +50 -0
  25. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/lib/autoprefixer-rails/result.rb +24 -0
  26. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/lib/autoprefixer-rails/sprockets.rb +62 -0
  27. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/lib/autoprefixer-rails/version.rb +3 -0
  28. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/lib/rake/autoprefixer_tasks.rb +28 -0
  29. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/spec/app/Rakefile +2 -0
  30. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/spec/app/app/assets/config/manifest.js +0 -0
  31. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/spec/app/app/assets/stylesheets/evaluate.css.erb +1 -0
  32. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/spec/app/app/assets/stylesheets/loaded.sass +2 -0
  33. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/spec/app/app/assets/stylesheets/sass.sass +1 -0
  34. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/spec/app/app/assets/stylesheets/test.css +3 -0
  35. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/spec/app/app/assets/stylesheets/wrong.css +2 -0
  36. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/spec/app/app/controllers/application_controller.rb +2 -0
  37. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/spec/app/app/controllers/css_controller.rb +6 -0
  38. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/spec/app/config.ru +2 -0
  39. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/spec/app/config/application.rb +16 -0
  40. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/spec/app/config/autoprefixer.yml +2 -0
  41. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/spec/app/config/boot.rb +2 -0
  42. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/spec/app/config/environment.rb +3 -0
  43. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/spec/app/config/environments/test.rb +9 -0
  44. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/spec/app/config/initializers/secret_token.rb +1 -0
  45. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/spec/app/config/routes.rb +3 -0
  46. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/spec/autoprefixer_spec.rb +121 -0
  47. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/spec/processor_spec.rb +25 -0
  48. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/spec/rails_spec.rb +40 -0
  49. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/spec/railtie_spec.rb +29 -0
  50. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/spec/spec_helper.rb +16 -0
  51. data/vendor/ruby/2.6.0/gems/autoprefixer-rails-9.6.1.1/vendor/autoprefixer.js +67195 -0
  52. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/CHANGELOG.md +909 -0
  53. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/CONTRIBUTING.md +17 -0
  54. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/Gemfile +10 -0
  55. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/LICENSE.txt +25 -0
  56. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/README.md +301 -0
  57. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/Rakefile +166 -0
  58. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/bin/ruby-parse +7 -0
  59. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/bin/ruby-rewrite +7 -0
  60. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/ci/run_rubocop_specs +14 -0
  61. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/doc/AST_FORMAT.md +1816 -0
  62. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/doc/CUSTOMIZATION.md +37 -0
  63. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/doc/INTERNALS.md +21 -0
  64. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/doc/css/common.css +68 -0
  65. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/gauntlet_parser.rb +123 -0
  66. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser.rb +82 -0
  67. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/all.rb +12 -0
  68. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/ast/node.rb +40 -0
  69. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/ast/processor.rb +264 -0
  70. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/base.rb +270 -0
  71. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/builders/default.rb +1741 -0
  72. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/clobbering_error.rb +13 -0
  73. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/color.rb +32 -0
  74. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/context.rb +59 -0
  75. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/current.rb +92 -0
  76. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/deprecation.rb +13 -0
  77. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/diagnostic.rb +163 -0
  78. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/diagnostic/engine.rb +105 -0
  79. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/lexer.rb +23546 -0
  80. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/lexer.rl +2503 -0
  81. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/lexer/dedenter.rb +79 -0
  82. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/lexer/explanation.rb +55 -0
  83. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/lexer/literal.rb +269 -0
  84. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/lexer/max_numparam_stack.rb +42 -0
  85. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/lexer/stack_state.rb +49 -0
  86. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/macruby.rb +6124 -0
  87. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/macruby.y +2198 -0
  88. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/messages.rb +90 -0
  89. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/meta.rb +33 -0
  90. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/rewriter.rb +105 -0
  91. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/ruby18.rb +5661 -0
  92. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/ruby18.y +1934 -0
  93. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/ruby19.rb +6084 -0
  94. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/ruby19.y +2175 -0
  95. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/ruby20.rb +6511 -0
  96. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/ruby20.y +2353 -0
  97. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/ruby21.rb +6570 -0
  98. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/ruby21.y +2357 -0
  99. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/ruby22.rb +6605 -0
  100. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/ruby22.y +2364 -0
  101. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/ruby23.rb +6624 -0
  102. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/ruby23.y +2370 -0
  103. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/ruby24.rb +6689 -0
  104. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/ruby24.y +2408 -0
  105. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/ruby25.rb +6656 -0
  106. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/ruby25.y +2405 -0
  107. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/ruby26.rb +6670 -0
  108. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/ruby26.y +2413 -0
  109. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/ruby27.rb +6893 -0
  110. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/ruby27.y +2470 -0
  111. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/rubymotion.rb +6078 -0
  112. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/rubymotion.y +2182 -0
  113. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/runner.rb +253 -0
  114. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/runner/ruby_parse.rb +157 -0
  115. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/runner/ruby_rewrite.rb +101 -0
  116. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/source/buffer.rb +330 -0
  117. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/source/comment.rb +121 -0
  118. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/source/comment/associator.rb +210 -0
  119. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/source/map.rb +186 -0
  120. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/source/map/collection.rb +18 -0
  121. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/source/map/condition.rb +21 -0
  122. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/source/map/constant.rb +32 -0
  123. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/source/map/definition.rb +23 -0
  124. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/source/map/for.rb +19 -0
  125. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/source/map/heredoc.rb +19 -0
  126. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/source/map/index.rb +33 -0
  127. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/source/map/keyword.rb +20 -0
  128. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/source/map/objc_kwarg.rb +19 -0
  129. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/source/map/operator.rb +17 -0
  130. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/source/map/rescue_body.rb +21 -0
  131. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/source/map/send.rb +36 -0
  132. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/source/map/ternary.rb +18 -0
  133. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/source/map/variable.rb +31 -0
  134. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/source/range.rb +310 -0
  135. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/source/rewriter.rb +513 -0
  136. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/source/rewriter/action.rb +44 -0
  137. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/source/tree_rewriter.rb +301 -0
  138. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/source/tree_rewriter/action.rb +133 -0
  139. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/static_environment.rb +46 -0
  140. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/syntax_error.rb +21 -0
  141. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/tree_rewriter.rb +134 -0
  142. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/lib/parser/version.rb +5 -0
  143. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/parser.gemspec +51 -0
  144. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/test/bug_163/fixtures/input.rb +5 -0
  145. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/test/bug_163/fixtures/output.rb +5 -0
  146. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/test/bug_163/rewriter.rb +20 -0
  147. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/test/helper.rb +59 -0
  148. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/test/parse_helper.rb +316 -0
  149. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/test/racc_coverage_helper.rb +133 -0
  150. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/test/test_base.rb +31 -0
  151. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/test/test_current.rb +29 -0
  152. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/test/test_diagnostic.rb +96 -0
  153. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/test/test_diagnostic_engine.rb +62 -0
  154. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/test/test_encoding.rb +99 -0
  155. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/test/test_lexer.rb +3659 -0
  156. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/test/test_lexer_stack_state.rb +78 -0
  157. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/test/test_parse_helper.rb +80 -0
  158. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/test/test_parser.rb +7579 -0
  159. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/test/test_runner_parse.rb +35 -0
  160. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/test/test_runner_rewrite.rb +47 -0
  161. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/test/test_source_buffer.rb +162 -0
  162. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/test/test_source_comment.rb +36 -0
  163. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/test/test_source_comment_associator.rb +367 -0
  164. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/test/test_source_map.rb +15 -0
  165. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/test/test_source_range.rb +172 -0
  166. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/test/test_source_rewriter.rb +541 -0
  167. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/test/test_source_rewriter_action.rb +46 -0
  168. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/test/test_source_tree_rewriter.rb +173 -0
  169. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/test/test_static_environment.rb +45 -0
  170. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/test/using_tree_rewriter/fixtures/input.rb +3 -0
  171. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/test/using_tree_rewriter/fixtures/output.rb +3 -0
  172. data/vendor/ruby/2.6.0/gems/parser-2.6.4.1/test/using_tree_rewriter/using_tree_rewriter.rb +9 -0
  173. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/CHANGELOG.md +77 -0
  174. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/CODE_OF_CONDUCT.md +10 -0
  175. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/Gemfile +2 -0
  176. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/LICENSE.txt +22 -0
  177. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/README.md +68 -0
  178. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/Rakefile +53 -0
  179. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/Makefile +271 -0
  180. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/SharedPtr.o +0 -0
  181. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/ast.o +0 -0
  182. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/ast2c.o +0 -0
  183. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/ast_fwd_decl.o +0 -0
  184. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/ast_sel_cmp.o +0 -0
  185. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/ast_sel_unify.o +0 -0
  186. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/ast_selectors.o +0 -0
  187. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/ast_supports.o +0 -0
  188. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/ast_values.o +0 -0
  189. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/backtrace.o +0 -0
  190. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/base64vlq.o +0 -0
  191. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/bind.o +0 -0
  192. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/c2ast.o +0 -0
  193. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/c99func.o +0 -0
  194. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/cencode.o +0 -0
  195. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/check_nesting.o +0 -0
  196. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/color_maps.o +0 -0
  197. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/constants.o +0 -0
  198. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/context.o +0 -0
  199. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/cssize.o +0 -0
  200. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/depend +4 -0
  201. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/emitter.o +0 -0
  202. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/environment.o +0 -0
  203. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/error_handling.o +0 -0
  204. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/eval.o +0 -0
  205. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/expand.o +0 -0
  206. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/extconf.rb +84 -0
  207. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/extend.o +0 -0
  208. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/file.o +0 -0
  209. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/fn_colors.o +0 -0
  210. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/fn_lists.o +0 -0
  211. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/fn_maps.o +0 -0
  212. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/fn_miscs.o +0 -0
  213. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/fn_numbers.o +0 -0
  214. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/fn_selectors.o +0 -0
  215. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/fn_strings.o +0 -0
  216. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/fn_utils.o +0 -0
  217. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/inspect.o +0 -0
  218. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/json.o +0 -0
  219. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/lexer.o +0 -0
  220. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass.so +0 -0
  221. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/VERSION +1 -0
  222. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/contrib/plugin.cpp +60 -0
  223. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/include/sass.h +15 -0
  224. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/include/sass/base.h +96 -0
  225. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/include/sass/context.h +170 -0
  226. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/include/sass/functions.h +139 -0
  227. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/include/sass/values.h +145 -0
  228. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/include/sass/version.h +12 -0
  229. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/include/sass2scss.h +120 -0
  230. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/ast.cpp +963 -0
  231. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/ast.hpp +905 -0
  232. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/ast2c.cpp +80 -0
  233. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/ast2c.hpp +39 -0
  234. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/ast_def_macros.hpp +132 -0
  235. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/ast_fwd_decl.cpp +30 -0
  236. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/ast_fwd_decl.hpp +341 -0
  237. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/ast_sel_cmp.cpp +909 -0
  238. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/ast_sel_unify.cpp +280 -0
  239. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/ast_selectors.cpp +1475 -0
  240. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/ast_selectors.hpp +568 -0
  241. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/ast_supports.cpp +130 -0
  242. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/ast_supports.hpp +121 -0
  243. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/ast_values.cpp +967 -0
  244. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/ast_values.hpp +489 -0
  245. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/b64/cencode.h +32 -0
  246. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/b64/encode.h +79 -0
  247. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/backtrace.cpp +50 -0
  248. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/backtrace.hpp +29 -0
  249. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/base64vlq.cpp +47 -0
  250. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/base64vlq.hpp +30 -0
  251. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/bind.cpp +312 -0
  252. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/bind.hpp +15 -0
  253. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/c2ast.cpp +64 -0
  254. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/c2ast.hpp +14 -0
  255. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/c99func.c +54 -0
  256. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/cencode.c +108 -0
  257. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/check_nesting.cpp +394 -0
  258. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/check_nesting.hpp +66 -0
  259. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/color_maps.cpp +651 -0
  260. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/color_maps.hpp +331 -0
  261. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/constants.cpp +194 -0
  262. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/constants.hpp +194 -0
  263. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/context.cpp +890 -0
  264. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/context.hpp +152 -0
  265. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/cssize.cpp +604 -0
  266. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/cssize.hpp +77 -0
  267. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/debug.hpp +43 -0
  268. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/debugger.hpp +807 -0
  269. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/emitter.cpp +298 -0
  270. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/emitter.hpp +103 -0
  271. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/environment.cpp +260 -0
  272. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/environment.hpp +119 -0
  273. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/error_handling.cpp +212 -0
  274. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/error_handling.hpp +229 -0
  275. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/eval.cpp +1657 -0
  276. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/eval.hpp +112 -0
  277. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/expand.cpp +822 -0
  278. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/expand.hpp +78 -0
  279. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/extend.cpp +2132 -0
  280. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/extend.hpp +86 -0
  281. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/file.cpp +522 -0
  282. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/file.hpp +133 -0
  283. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/fn_colors.cpp +594 -0
  284. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/fn_colors.hpp +85 -0
  285. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/fn_lists.cpp +284 -0
  286. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/fn_lists.hpp +34 -0
  287. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/fn_maps.cpp +94 -0
  288. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/fn_maps.hpp +30 -0
  289. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/fn_miscs.cpp +256 -0
  290. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/fn_miscs.hpp +40 -0
  291. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/fn_numbers.cpp +220 -0
  292. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/fn_numbers.hpp +45 -0
  293. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/fn_selectors.cpp +235 -0
  294. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/fn_selectors.hpp +35 -0
  295. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/fn_strings.cpp +254 -0
  296. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/fn_strings.hpp +34 -0
  297. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/fn_utils.cpp +156 -0
  298. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/fn_utils.hpp +56 -0
  299. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/inspect.cpp +1087 -0
  300. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/inspect.hpp +99 -0
  301. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/json.cpp +1436 -0
  302. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/json.hpp +117 -0
  303. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/kwd_arg_macros.hpp +28 -0
  304. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/lexer.cpp +184 -0
  305. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/lexer.hpp +315 -0
  306. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/listize.cpp +84 -0
  307. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/listize.hpp +38 -0
  308. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/mapping.hpp +18 -0
  309. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/memory/SharedPtr.cpp +33 -0
  310. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/memory/SharedPtr.hpp +286 -0
  311. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/node.cpp +322 -0
  312. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/node.hpp +118 -0
  313. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/operation.hpp +213 -0
  314. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/operators.cpp +266 -0
  315. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/operators.hpp +30 -0
  316. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/output.cpp +339 -0
  317. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/output.hpp +47 -0
  318. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/parser.cpp +3153 -0
  319. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/parser.hpp +402 -0
  320. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/paths.hpp +71 -0
  321. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/plugins.cpp +188 -0
  322. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/plugins.hpp +57 -0
  323. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/position.cpp +184 -0
  324. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/position.hpp +124 -0
  325. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/prelexer.cpp +1780 -0
  326. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/prelexer.hpp +484 -0
  327. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/remove_placeholders.cpp +87 -0
  328. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/remove_placeholders.hpp +34 -0
  329. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/sass.cpp +155 -0
  330. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/sass.hpp +142 -0
  331. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/sass2scss.cpp +895 -0
  332. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/sass_context.cpp +772 -0
  333. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/sass_context.hpp +129 -0
  334. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/sass_functions.cpp +210 -0
  335. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/sass_functions.hpp +50 -0
  336. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/sass_util.cpp +152 -0
  337. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/sass_util.hpp +256 -0
  338. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/sass_values.cpp +365 -0
  339. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/sass_values.hpp +82 -0
  340. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/source_map.cpp +198 -0
  341. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/source_map.hpp +62 -0
  342. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/subset_map.cpp +58 -0
  343. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/subset_map.hpp +76 -0
  344. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/to_value.cpp +114 -0
  345. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/to_value.hpp +46 -0
  346. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/units.cpp +505 -0
  347. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/units.hpp +110 -0
  348. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/utf8.h +34 -0
  349. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/utf8/checked.h +336 -0
  350. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/utf8/core.h +332 -0
  351. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/utf8/unchecked.h +235 -0
  352. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/utf8_string.cpp +105 -0
  353. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/utf8_string.hpp +37 -0
  354. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/util.cpp +725 -0
  355. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/util.hpp +106 -0
  356. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/util_string.cpp +75 -0
  357. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/util_string.hpp +19 -0
  358. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/values.cpp +140 -0
  359. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/libsass/src/values.hpp +12 -0
  360. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/listize.o +0 -0
  361. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/node.o +0 -0
  362. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/operators.o +0 -0
  363. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/output.o +0 -0
  364. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/parser.o +0 -0
  365. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/plugins.o +0 -0
  366. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/position.o +0 -0
  367. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/prelexer.o +0 -0
  368. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/remove_placeholders.o +0 -0
  369. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/sass.o +0 -0
  370. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/sass2scss.o +0 -0
  371. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/sass_context.o +0 -0
  372. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/sass_functions.o +0 -0
  373. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/sass_util.o +0 -0
  374. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/sass_values.o +0 -0
  375. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/source_map.o +0 -0
  376. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/subset_map.o +0 -0
  377. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/to_value.o +0 -0
  378. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/units.o +0 -0
  379. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/utf8_string.o +0 -0
  380. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/util.o +0 -0
  381. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/util_string.o +0 -0
  382. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/ext/values.o +0 -0
  383. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc.rb +57 -0
  384. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/dependency.rb +17 -0
  385. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/engine.rb +139 -0
  386. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/error.rb +37 -0
  387. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/functions_handler.rb +73 -0
  388. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/import_handler.rb +50 -0
  389. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/importer.rb +31 -0
  390. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/libsass.so +0 -0
  391. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/native.rb +62 -0
  392. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/native/lib_c.rb +21 -0
  393. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/native/native_context_api.rb +147 -0
  394. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/native/native_functions_api.rb +159 -0
  395. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/native/sass2scss_api.rb +10 -0
  396. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/native/sass_input_style.rb +13 -0
  397. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/native/sass_output_style.rb +12 -0
  398. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/native/sass_value.rb +97 -0
  399. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/native/string_list.rb +10 -0
  400. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/sass_2_scss.rb +9 -0
  401. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/script.rb +17 -0
  402. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/script/functions.rb +8 -0
  403. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/script/value.rb +137 -0
  404. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/script/value/bool.rb +32 -0
  405. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/script/value/color.rb +95 -0
  406. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/script/value/list.rb +136 -0
  407. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/script/value/map.rb +69 -0
  408. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/script/value/number.rb +389 -0
  409. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/script/value/string.rb +96 -0
  410. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/script/value_conversion.rb +69 -0
  411. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/script/value_conversion/base.rb +13 -0
  412. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/script/value_conversion/bool.rb +13 -0
  413. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/script/value_conversion/color.rb +18 -0
  414. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/script/value_conversion/list.rb +25 -0
  415. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/script/value_conversion/map.rb +21 -0
  416. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/script/value_conversion/number.rb +13 -0
  417. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/script/value_conversion/string.rb +17 -0
  418. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/util.rb +231 -0
  419. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/util/normalized_map.rb +117 -0
  420. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/lib/sassc/version.rb +5 -0
  421. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/sassc.gemspec +69 -0
  422. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/test/custom_importer_test.rb +127 -0
  423. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/test/engine_test.rb +314 -0
  424. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/test/error_test.rb +29 -0
  425. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/test/fixtures/paths.scss +10 -0
  426. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/test/functions_test.rb +323 -0
  427. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/test/native_test.rb +213 -0
  428. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/test/output_style_test.rb +107 -0
  429. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/test/sass_2_scss_test.rb +14 -0
  430. data/vendor/ruby/2.6.0/gems/sassc-2.2.0/test/test_helper.rb +45 -0
  431. data/vendor/ruby/2.6.0/gems/zeitwerk-2.1.10/README.md +533 -0
  432. data/vendor/ruby/2.6.0/gems/zeitwerk-2.1.10/lib/zeitwerk.rb +12 -0
  433. data/vendor/ruby/2.6.0/gems/zeitwerk-2.1.10/lib/zeitwerk/error.rb +10 -0
  434. data/vendor/ruby/2.6.0/gems/zeitwerk-2.1.10/lib/zeitwerk/explicit_namespace.rb +80 -0
  435. data/vendor/ruby/2.6.0/gems/zeitwerk-2.1.10/lib/zeitwerk/gem_inflector.rb +19 -0
  436. data/vendor/ruby/2.6.0/gems/zeitwerk-2.1.10/lib/zeitwerk/inflector.rb +19 -0
  437. data/vendor/ruby/2.6.0/gems/zeitwerk-2.1.10/lib/zeitwerk/kernel.rb +33 -0
  438. data/vendor/ruby/2.6.0/gems/zeitwerk-2.1.10/lib/zeitwerk/loader.rb +759 -0
  439. data/vendor/ruby/2.6.0/gems/zeitwerk-2.1.10/lib/zeitwerk/loader/callbacks.rb +71 -0
  440. data/vendor/ruby/2.6.0/gems/zeitwerk-2.1.10/lib/zeitwerk/real_mod_name.rb +15 -0
  441. data/vendor/ruby/2.6.0/gems/zeitwerk-2.1.10/lib/zeitwerk/registry.rb +147 -0
  442. data/vendor/ruby/2.6.0/gems/zeitwerk-2.1.10/lib/zeitwerk/version.rb +5 -0
  443. data/vendor/ruby/2.6.0/specifications/autoprefixer-rails-9.6.1.1.gemspec +47 -0
  444. data/vendor/ruby/2.6.0/specifications/parser-2.6.4.1.gemspec +62 -0
  445. data/vendor/ruby/2.6.0/specifications/sassc-2.2.0.gemspec +60 -0
  446. data/vendor/ruby/2.6.0/specifications/zeitwerk-2.1.10.gemspec +21 -0
  447. metadata +441 -4
  448. data/vendor/assets/anjuna/css/anjuna-application.css +0 -2
  449. data/vendor/assets/anjuna/css/anjuna-theme.css +0 -2
@@ -0,0 +1,47 @@
1
+ #ifndef SASS_OUTPUT_H
2
+ #define SASS_OUTPUT_H
3
+
4
+ #include <string>
5
+ #include <vector>
6
+
7
+ #include "util.hpp"
8
+ #include "inspect.hpp"
9
+ #include "operation.hpp"
10
+
11
+ namespace Sass {
12
+ class Context;
13
+
14
+ class Output : public Inspect {
15
+ protected:
16
+ using Inspect::operator();
17
+
18
+ public:
19
+ Output(Sass_Output_Options& opt);
20
+ virtual ~Output();
21
+
22
+ protected:
23
+ std::string charset;
24
+ std::vector<AST_Node*> top_nodes;
25
+
26
+ public:
27
+ OutputBuffer get_buffer(void);
28
+
29
+ virtual void operator()(Map*);
30
+ virtual void operator()(Ruleset*);
31
+ virtual void operator()(Supports_Block*);
32
+ virtual void operator()(Media_Block*);
33
+ virtual void operator()(Directive*);
34
+ virtual void operator()(Keyframe_Rule*);
35
+ virtual void operator()(Import*);
36
+ virtual void operator()(Comment*);
37
+ virtual void operator()(Number*);
38
+ virtual void operator()(String_Quoted*);
39
+ virtual void operator()(String_Constant*);
40
+
41
+ void fallback_impl(AST_Node* n);
42
+
43
+ };
44
+
45
+ }
46
+
47
+ #endif
@@ -0,0 +1,3153 @@
1
+ // sass.hpp must go before all system headers to get the
2
+ // __EXTENSIONS__ fix on Solaris.
3
+ #include "sass.hpp"
4
+
5
+ #include "parser.hpp"
6
+ #include "file.hpp"
7
+ #include "inspect.hpp"
8
+ #include "constants.hpp"
9
+ #include "util.hpp"
10
+ #include "prelexer.hpp"
11
+ #include "color_maps.hpp"
12
+ #include "sass/functions.h"
13
+ #include "error_handling.hpp"
14
+ #include "util_string.hpp"
15
+
16
+ // Notes about delayed: some ast nodes can have delayed evaluation so
17
+ // they can preserve their original semantics if needed. This is most
18
+ // prominently exhibited by the division operation, since it is not
19
+ // only a valid operation, but also a valid css statement (i.e. for
20
+ // fonts, as in `16px/24px`). When parsing lists and expression we
21
+ // unwrap single items from lists and other operations. A nested list
22
+ // must not be delayed, only the items of the first level sometimes
23
+ // are delayed (as with argument lists). To achieve this we need to
24
+ // pass status to the list parser, so this can be set correctly.
25
+ // Another case with delayed values are colors. In compressed mode
26
+ // only processed values get compressed (other are left as written).
27
+
28
+ #include <cstdlib>
29
+ #include <iostream>
30
+ #include <vector>
31
+ #include <typeinfo>
32
+
33
+ namespace Sass {
34
+ using namespace Constants;
35
+ using namespace Prelexer;
36
+
37
+ Parser Parser::from_c_str(const char* beg, Context& ctx, Backtraces traces, ParserState pstate, const char* source, bool allow_parent)
38
+ {
39
+ pstate.offset.column = 0;
40
+ pstate.offset.line = 0;
41
+ Parser p(ctx, pstate, traces, allow_parent);
42
+ p.source = source ? source : beg;
43
+ p.position = beg ? beg : p.source;
44
+ p.end = p.position + strlen(p.position);
45
+ Block_Obj root = SASS_MEMORY_NEW(Block, pstate);
46
+ p.block_stack.push_back(root);
47
+ root->is_root(true);
48
+ return p;
49
+ }
50
+
51
+ Parser Parser::from_c_str(const char* beg, const char* end, Context& ctx, Backtraces traces, ParserState pstate, const char* source, bool allow_parent)
52
+ {
53
+ pstate.offset.column = 0;
54
+ pstate.offset.line = 0;
55
+ Parser p(ctx, pstate, traces, allow_parent);
56
+ p.source = source ? source : beg;
57
+ p.position = beg ? beg : p.source;
58
+ p.end = end ? end : p.position + strlen(p.position);
59
+ Block_Obj root = SASS_MEMORY_NEW(Block, pstate);
60
+ p.block_stack.push_back(root);
61
+ root->is_root(true);
62
+ return p;
63
+ }
64
+
65
+ void Parser::advanceToNextToken() {
66
+ lex < css_comments >(false);
67
+ // advance to position
68
+ pstate += pstate.offset;
69
+ pstate.offset.column = 0;
70
+ pstate.offset.line = 0;
71
+ }
72
+
73
+ Selector_List_Obj Parser::parse_selector(const char* beg, Context& ctx, Backtraces traces, ParserState pstate, const char* source, bool allow_parent)
74
+ {
75
+ Parser p = Parser::from_c_str(beg, ctx, traces, pstate, source, allow_parent);
76
+ // ToDo: remap the source-map entries somehow
77
+ return p.parse_selector_list(false);
78
+ }
79
+
80
+ bool Parser::peek_newline(const char* start)
81
+ {
82
+ return peek_linefeed(start ? start : position)
83
+ && ! peek_css<exactly<'{'>>(start);
84
+ }
85
+
86
+ Parser Parser::from_token(Token t, Context& ctx, Backtraces traces, ParserState pstate, const char* source)
87
+ {
88
+ Parser p(ctx, pstate, traces);
89
+ p.source = source ? source : t.begin;
90
+ p.position = t.begin ? t.begin : p.source;
91
+ p.end = t.end ? t.end : p.position + strlen(p.position);
92
+ Block_Obj root = SASS_MEMORY_NEW(Block, pstate);
93
+ p.block_stack.push_back(root);
94
+ root->is_root(true);
95
+ return p;
96
+ }
97
+
98
+ /* main entry point to parse root block */
99
+ Block_Obj Parser::parse()
100
+ {
101
+
102
+ // consume unicode BOM
103
+ read_bom();
104
+
105
+ // scan the input to find invalid utf8 sequences
106
+ const char* it = utf8::find_invalid(position, end);
107
+
108
+ // report invalid utf8
109
+ if (it != end) {
110
+ pstate += Offset::init(position, it);
111
+ traces.push_back(Backtrace(pstate));
112
+ throw Exception::InvalidSass(pstate, traces, "Invalid UTF-8 sequence");
113
+ }
114
+
115
+ // create a block AST node to hold children
116
+ Block_Obj root = SASS_MEMORY_NEW(Block, pstate, 0, true);
117
+
118
+ // check seems a bit esoteric but works
119
+ if (ctx.resources.size() == 1) {
120
+ // apply headers only on very first include
121
+ ctx.apply_custom_headers(root, path, pstate);
122
+ }
123
+
124
+ // parse children nodes
125
+ block_stack.push_back(root);
126
+ parse_block_nodes(true);
127
+ block_stack.pop_back();
128
+
129
+ // update final position
130
+ root->update_pstate(pstate);
131
+
132
+ if (position != end) {
133
+ css_error("Invalid CSS", " after ", ": expected selector or at-rule, was ");
134
+ }
135
+
136
+ return root;
137
+ }
138
+
139
+
140
+ // convenience function for block parsing
141
+ // will create a new block ad-hoc for you
142
+ // this is the base block parsing function
143
+ Block_Obj Parser::parse_css_block(bool is_root)
144
+ {
145
+
146
+ // parse comments before block
147
+ // lex < optional_css_comments >();
148
+
149
+ // lex mandatory opener or error out
150
+ if (!lex_css < exactly<'{'> >()) {
151
+ css_error("Invalid CSS", " after ", ": expected \"{\", was ");
152
+ }
153
+ // create new block and push to the selector stack
154
+ Block_Obj block = SASS_MEMORY_NEW(Block, pstate, 0, is_root);
155
+ block_stack.push_back(block);
156
+
157
+ if (!parse_block_nodes(is_root)) css_error("Invalid CSS", " after ", ": expected \"}\", was ");
158
+
159
+ if (!lex_css < exactly<'}'> >()) {
160
+ css_error("Invalid CSS", " after ", ": expected \"}\", was ");
161
+ }
162
+
163
+ // update for end position
164
+ // this seems to be done somewhere else
165
+ // but that fixed selector schema issue
166
+ // block->update_pstate(pstate);
167
+
168
+ // parse comments after block
169
+ // lex < optional_css_comments >();
170
+
171
+ block_stack.pop_back();
172
+
173
+ return block;
174
+ }
175
+
176
+ // convenience function for block parsing
177
+ // will create a new block ad-hoc for you
178
+ // also updates the `in_at_root` flag
179
+ Block_Obj Parser::parse_block(bool is_root)
180
+ {
181
+ return parse_css_block(is_root);
182
+ }
183
+
184
+ // the main block parsing function
185
+ // parses stuff between `{` and `}`
186
+ bool Parser::parse_block_nodes(bool is_root)
187
+ {
188
+
189
+ // loop until end of string
190
+ while (position < end) {
191
+
192
+ // we should be able to refactor this
193
+ parse_block_comments();
194
+ lex < css_whitespace >();
195
+
196
+ if (lex < exactly<';'> >()) continue;
197
+ if (peek < end_of_file >()) return true;
198
+ if (peek < exactly<'}'> >()) return true;
199
+
200
+ if (parse_block_node(is_root)) continue;
201
+
202
+ parse_block_comments();
203
+
204
+ if (lex_css < exactly<';'> >()) continue;
205
+ if (peek_css < end_of_file >()) return true;
206
+ if (peek_css < exactly<'}'> >()) return true;
207
+
208
+ // illegal sass
209
+ return false;
210
+ }
211
+ // return success
212
+ return true;
213
+ }
214
+
215
+ // parser for a single node in a block
216
+ // semicolons must be lexed beforehand
217
+ bool Parser::parse_block_node(bool is_root) {
218
+
219
+ Block_Obj block = block_stack.back();
220
+
221
+ parse_block_comments();
222
+
223
+ // throw away white-space
224
+ // includes line comments
225
+ lex < css_whitespace >();
226
+
227
+ Lookahead lookahead_result;
228
+
229
+ // also parse block comments
230
+
231
+ // first parse everything that is allowed in functions
232
+ if (lex < variable >(true)) { block->append(parse_assignment()); }
233
+ else if (lex < kwd_err >(true)) { block->append(parse_error()); }
234
+ else if (lex < kwd_dbg >(true)) { block->append(parse_debug()); }
235
+ else if (lex < kwd_warn >(true)) { block->append(parse_warning()); }
236
+ else if (lex < kwd_if_directive >(true)) { block->append(parse_if_directive()); }
237
+ else if (lex < kwd_for_directive >(true)) { block->append(parse_for_directive()); }
238
+ else if (lex < kwd_each_directive >(true)) { block->append(parse_each_directive()); }
239
+ else if (lex < kwd_while_directive >(true)) { block->append(parse_while_directive()); }
240
+ else if (lex < kwd_return_directive >(true)) { block->append(parse_return_directive()); }
241
+
242
+ // parse imports to process later
243
+ else if (lex < kwd_import >(true)) {
244
+ Scope parent = stack.empty() ? Scope::Rules : stack.back();
245
+ if (parent != Scope::Function && parent != Scope::Root && parent != Scope::Rules && parent != Scope::Media) {
246
+ if (! peek_css< uri_prefix >(position)) { // this seems to go in ruby sass 3.4.20
247
+ error("Import directives may not be used within control directives or mixins.");
248
+ }
249
+ }
250
+ // this puts the parsed doc into sheets
251
+ // import stub will fetch this in expand
252
+ Import_Obj imp = parse_import();
253
+ // if it is a url, we only add the statement
254
+ if (!imp->urls().empty()) block->append(imp);
255
+ // process all resources now (add Import_Stub nodes)
256
+ for (size_t i = 0, S = imp->incs().size(); i < S; ++i) {
257
+ block->append(SASS_MEMORY_NEW(Import_Stub, pstate, imp->incs()[i]));
258
+ }
259
+ }
260
+
261
+ else if (lex < kwd_extend >(true)) {
262
+ Lookahead lookahead = lookahead_for_include(position);
263
+ if (!lookahead.found) css_error("Invalid CSS", " after ", ": expected selector, was ");
264
+ Selector_List_Obj target;
265
+ if (!lookahead.has_interpolants) {
266
+ target = parse_selector_list(true);
267
+ }
268
+ else {
269
+ target = SASS_MEMORY_NEW(Selector_List, pstate);
270
+ target->schema(parse_selector_schema(lookahead.found, true));
271
+ }
272
+
273
+ block->append(SASS_MEMORY_NEW(Extension, pstate, target));
274
+ }
275
+
276
+ // selector may contain interpolations which need delayed evaluation
277
+ else if (
278
+ !(lookahead_result = lookahead_for_selector(position)).error &&
279
+ !lookahead_result.is_custom_property
280
+ )
281
+ {
282
+ block->append(parse_ruleset(lookahead_result));
283
+ }
284
+
285
+ // parse multiple specific keyword directives
286
+ else if (lex < kwd_media >(true)) { block->append(parse_media_block()); }
287
+ else if (lex < kwd_at_root >(true)) { block->append(parse_at_root_block()); }
288
+ else if (lex < kwd_include_directive >(true)) { block->append(parse_include_directive()); }
289
+ else if (lex < kwd_content_directive >(true)) { block->append(parse_content_directive()); }
290
+ else if (lex < kwd_supports_directive >(true)) { block->append(parse_supports_directive()); }
291
+ else if (lex < kwd_mixin >(true)) { block->append(parse_definition(Definition::MIXIN)); }
292
+ else if (lex < kwd_function >(true)) { block->append(parse_definition(Definition::FUNCTION)); }
293
+
294
+ // ignore the @charset directive for now
295
+ else if (lex< kwd_charset_directive >(true)) { parse_charset_directive(); }
296
+
297
+ // generic at keyword (keep last)
298
+ else if (lex< re_special_directive >(true)) { block->append(parse_special_directive()); }
299
+ else if (lex< re_prefixed_directive >(true)) { block->append(parse_prefixed_directive()); }
300
+ else if (lex< at_keyword >(true)) { block->append(parse_directive()); }
301
+
302
+ else if (is_root && stack.back() != Scope::AtRoot /* && block->is_root() */) {
303
+ lex< css_whitespace >();
304
+ if (position >= end) return true;
305
+ css_error("Invalid CSS", " after ", ": expected 1 selector or at-rule, was ");
306
+ }
307
+ // parse a declaration
308
+ else
309
+ {
310
+ // ToDo: how does it handle parse errors?
311
+ // maybe we are expected to parse something?
312
+ Declaration_Obj decl = parse_declaration();
313
+ decl->tabs(indentation);
314
+ block->append(decl);
315
+ // maybe we have a "sub-block"
316
+ if (peek< exactly<'{'> >()) {
317
+ if (decl->is_indented()) ++ indentation;
318
+ // parse a propset that rides on the declaration's property
319
+ stack.push_back(Scope::Properties);
320
+ decl->block(parse_block());
321
+ stack.pop_back();
322
+ if (decl->is_indented()) -- indentation;
323
+ }
324
+ }
325
+ // something matched
326
+ return true;
327
+ }
328
+ // EO parse_block_nodes
329
+
330
+ // parse imports inside the
331
+ Import_Obj Parser::parse_import()
332
+ {
333
+ Import_Obj imp = SASS_MEMORY_NEW(Import, pstate);
334
+ std::vector<std::pair<std::string,Function_Call_Obj>> to_import;
335
+ bool first = true;
336
+ do {
337
+ while (lex< block_comment >());
338
+ if (lex< quoted_string >()) {
339
+ to_import.push_back(std::pair<std::string,Function_Call_Obj>(std::string(lexed), {}));
340
+ }
341
+ else if (lex< uri_prefix >()) {
342
+ Arguments_Obj args = SASS_MEMORY_NEW(Arguments, pstate);
343
+ Function_Call_Obj result = SASS_MEMORY_NEW(Function_Call, pstate, std::string("url"), args);
344
+
345
+ if (lex< quoted_string >()) {
346
+ Expression_Obj quoted_url = parse_string();
347
+ args->append(SASS_MEMORY_NEW(Argument, quoted_url->pstate(), quoted_url));
348
+ }
349
+ else if (String_Obj string_url = parse_url_function_argument()) {
350
+ args->append(SASS_MEMORY_NEW(Argument, string_url->pstate(), string_url));
351
+ }
352
+ else if (peek < skip_over_scopes < exactly < '(' >, exactly < ')' > > >(position)) {
353
+ Expression_Obj braced_url = parse_list(); // parse_interpolated_chunk(lexed);
354
+ args->append(SASS_MEMORY_NEW(Argument, braced_url->pstate(), braced_url));
355
+ }
356
+ else {
357
+ error("malformed URL");
358
+ }
359
+ if (!lex< exactly<')'> >()) error("URI is missing ')'");
360
+ to_import.push_back(std::pair<std::string, Function_Call_Obj>("", result));
361
+ }
362
+ else {
363
+ if (first) error("@import directive requires a url or quoted path");
364
+ else error("expecting another url or quoted path in @import list");
365
+ }
366
+ first = false;
367
+ } while (lex_css< exactly<','> >());
368
+
369
+ if (!peek_css< alternatives< exactly<';'>, exactly<'}'>, end_of_file > >()) {
370
+ List_Obj import_queries = parse_media_queries();
371
+ imp->import_queries(import_queries);
372
+ }
373
+
374
+ for(auto location : to_import) {
375
+ if (location.second) {
376
+ imp->urls().push_back(location.second);
377
+ }
378
+ // check if custom importers want to take over the handling
379
+ else if (!ctx.call_importers(unquote(location.first), path, pstate, imp)) {
380
+ // nobody wants it, so we do our import
381
+ ctx.import_url(imp, location.first, path);
382
+ }
383
+ }
384
+
385
+ return imp;
386
+ }
387
+
388
+ Definition_Obj Parser::parse_definition(Definition::Type which_type)
389
+ {
390
+ std::string which_str(lexed);
391
+ if (!lex< identifier >()) error("invalid name in " + which_str + " definition");
392
+ std::string name(Util::normalize_underscores(lexed));
393
+ if (which_type == Definition::FUNCTION && (name == "and" || name == "or" || name == "not"))
394
+ { error("Invalid function name \"" + name + "\"."); }
395
+ ParserState source_position_of_def = pstate;
396
+ Parameters_Obj params = parse_parameters();
397
+ if (which_type == Definition::MIXIN) stack.push_back(Scope::Mixin);
398
+ else stack.push_back(Scope::Function);
399
+ Block_Obj body = parse_block();
400
+ stack.pop_back();
401
+ return SASS_MEMORY_NEW(Definition, source_position_of_def, name, params, body, which_type);
402
+ }
403
+
404
+ Parameters_Obj Parser::parse_parameters()
405
+ {
406
+ Parameters_Obj params = SASS_MEMORY_NEW(Parameters, pstate);
407
+ if (lex_css< exactly<'('> >()) {
408
+ // if there's anything there at all
409
+ if (!peek_css< exactly<')'> >()) {
410
+ do {
411
+ if (peek< exactly<')'> >()) break;
412
+ params->append(parse_parameter());
413
+ } while (lex_css< exactly<','> >());
414
+ }
415
+ if (!lex_css< exactly<')'> >()) {
416
+ css_error("Invalid CSS", " after ", ": expected \")\", was ");
417
+ }
418
+ }
419
+ return params;
420
+ }
421
+
422
+ Parameter_Obj Parser::parse_parameter()
423
+ {
424
+ if (peek< alternatives< exactly<','>, exactly< '{' >, exactly<';'> > >()) {
425
+ css_error("Invalid CSS", " after ", ": expected variable (e.g. $foo), was ");
426
+ }
427
+ while (lex< alternatives < spaces, block_comment > >());
428
+ lex < variable >();
429
+ std::string name(Util::normalize_underscores(lexed));
430
+ ParserState pos = pstate;
431
+ Expression_Obj val;
432
+ bool is_rest = false;
433
+ while (lex< alternatives < spaces, block_comment > >());
434
+ if (lex< exactly<':'> >()) { // there's a default value
435
+ while (lex< block_comment >());
436
+ val = parse_space_list();
437
+ }
438
+ else if (lex< exactly< ellipsis > >()) {
439
+ is_rest = true;
440
+ }
441
+ return SASS_MEMORY_NEW(Parameter, pos, name, val, is_rest);
442
+ }
443
+
444
+ Arguments_Obj Parser::parse_arguments()
445
+ {
446
+ Arguments_Obj args = SASS_MEMORY_NEW(Arguments, pstate);
447
+ if (lex_css< exactly<'('> >()) {
448
+ // if there's anything there at all
449
+ if (!peek_css< exactly<')'> >()) {
450
+ do {
451
+ if (peek< exactly<')'> >()) break;
452
+ args->append(parse_argument());
453
+ } while (lex_css< exactly<','> >());
454
+ }
455
+ if (!lex_css< exactly<')'> >()) {
456
+ css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");
457
+ }
458
+ }
459
+ return args;
460
+ }
461
+
462
+ Argument_Obj Parser::parse_argument()
463
+ {
464
+ if (peek< alternatives< exactly<','>, exactly< '{' >, exactly<';'> > >()) {
465
+ css_error("Invalid CSS", " after ", ": expected \")\", was ");
466
+ }
467
+ if (peek_css< sequence < exactly< hash_lbrace >, exactly< rbrace > > >()) {
468
+ position += 2;
469
+ css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");
470
+ }
471
+
472
+ Argument_Obj arg;
473
+ if (peek_css< sequence < variable, optional_css_comments, exactly<':'> > >()) {
474
+ lex_css< variable >();
475
+ std::string name(Util::normalize_underscores(lexed));
476
+ ParserState p = pstate;
477
+ lex_css< exactly<':'> >();
478
+ Expression_Obj val = parse_space_list();
479
+ arg = SASS_MEMORY_NEW(Argument, p, val, name);
480
+ }
481
+ else {
482
+ bool is_arglist = false;
483
+ bool is_keyword = false;
484
+ Expression_Obj val = parse_space_list();
485
+ List* l = Cast<List>(val);
486
+ if (lex_css< exactly< ellipsis > >()) {
487
+ if (val->concrete_type() == Expression::MAP || (
488
+ (l != NULL && l->separator() == SASS_HASH)
489
+ )) is_keyword = true;
490
+ else is_arglist = true;
491
+ }
492
+ arg = SASS_MEMORY_NEW(Argument, pstate, val, "", is_arglist, is_keyword);
493
+ }
494
+ return arg;
495
+ }
496
+
497
+ Assignment_Obj Parser::parse_assignment()
498
+ {
499
+ std::string name(Util::normalize_underscores(lexed));
500
+ ParserState var_source_position = pstate;
501
+ if (!lex< exactly<':'> >()) error("expected ':' after " + name + " in assignment statement");
502
+ if (peek_css< alternatives < exactly<';'>, end_of_file > >()) {
503
+ css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");
504
+ }
505
+ Expression_Obj val;
506
+ Lookahead lookahead = lookahead_for_value(position);
507
+ if (lookahead.has_interpolants && lookahead.found) {
508
+ val = parse_value_schema(lookahead.found);
509
+ } else {
510
+ val = parse_list();
511
+ }
512
+ bool is_default = false;
513
+ bool is_global = false;
514
+ while (peek< alternatives < default_flag, global_flag > >()) {
515
+ if (lex< default_flag >()) is_default = true;
516
+ else if (lex< global_flag >()) is_global = true;
517
+ }
518
+ return SASS_MEMORY_NEW(Assignment, var_source_position, name, val, is_default, is_global);
519
+ }
520
+
521
+ // a ruleset connects a selector and a block
522
+ Ruleset_Obj Parser::parse_ruleset(Lookahead lookahead)
523
+ {
524
+ NESTING_GUARD(nestings);
525
+ // inherit is_root from parent block
526
+ Block_Obj parent = block_stack.back();
527
+ bool is_root = parent && parent->is_root();
528
+ // make sure to move up the the last position
529
+ lex < optional_css_whitespace >(false, true);
530
+ // create the connector object (add parts later)
531
+ Ruleset_Obj ruleset = SASS_MEMORY_NEW(Ruleset, pstate);
532
+ // parse selector static or as schema to be evaluated later
533
+ if (lookahead.parsable) ruleset->selector(parse_selector_list(false));
534
+ else {
535
+ Selector_List_Obj list = SASS_MEMORY_NEW(Selector_List, pstate);
536
+ list->schema(parse_selector_schema(lookahead.position, false));
537
+ ruleset->selector(list);
538
+ }
539
+ // then parse the inner block
540
+ stack.push_back(Scope::Rules);
541
+ ruleset->block(parse_block());
542
+ stack.pop_back();
543
+ // update for end position
544
+ ruleset->update_pstate(pstate);
545
+ ruleset->block()->update_pstate(pstate);
546
+ // need this info for sanity checks
547
+ ruleset->is_root(is_root);
548
+ // return AST Node
549
+ return ruleset;
550
+ }
551
+
552
+ // parse a selector schema that will be evaluated in the eval stage
553
+ // uses a string schema internally to do the actual schema handling
554
+ // in the eval stage we will be re-parse it into an actual selector
555
+ Selector_Schema_Obj Parser::parse_selector_schema(const char* end_of_selector, bool chroot)
556
+ {
557
+ NESTING_GUARD(nestings);
558
+ // move up to the start
559
+ lex< optional_spaces >();
560
+ const char* i = position;
561
+ // selector schema re-uses string schema implementation
562
+ String_Schema* schema = SASS_MEMORY_NEW(String_Schema, pstate);
563
+ // the selector schema is pretty much just a wrapper for the string schema
564
+ Selector_Schema_Obj selector_schema = SASS_MEMORY_NEW(Selector_Schema, pstate, schema);
565
+ selector_schema->connect_parent(chroot == false);
566
+ selector_schema->media_block(last_media_block);
567
+
568
+ // process until end
569
+ while (i < end_of_selector) {
570
+ // try to parse mutliple interpolants
571
+ if (const char* p = find_first_in_interval< exactly<hash_lbrace>, block_comment >(i, end_of_selector)) {
572
+ // accumulate the preceding segment if the position has advanced
573
+ if (i < p) {
574
+ std::string parsed(i, p);
575
+ String_Constant_Obj str = SASS_MEMORY_NEW(String_Constant, pstate, parsed);
576
+ pstate += Offset(parsed);
577
+ str->update_pstate(pstate);
578
+ schema->append(str);
579
+ }
580
+
581
+ // skip over all nested inner interpolations up to our own delimiter
582
+ const char* j = skip_over_scopes< exactly<hash_lbrace>, exactly<rbrace> >(p + 2, end_of_selector);
583
+ // check if the interpolation never ends of only contains white-space (error out)
584
+ if (!j || peek < sequence < optional_spaces, exactly<rbrace> > >(p+2)) {
585
+ position = p+2;
586
+ css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");
587
+ }
588
+ // pass inner expression to the parser to resolve nested interpolations
589
+ pstate.add(p, p+2);
590
+ Expression_Obj interpolant = Parser::from_c_str(p+2, j, ctx, traces, pstate).parse_list();
591
+ // set status on the list expression
592
+ interpolant->is_interpolant(true);
593
+ // schema->has_interpolants(true);
594
+ // add to the string schema
595
+ schema->append(interpolant);
596
+ // advance parser state
597
+ pstate.add(p+2, j);
598
+ // advance position
599
+ i = j;
600
+ }
601
+ // no more interpolants have been found
602
+ // add the last segment if there is one
603
+ else {
604
+ // make sure to add the last bits of the string up to the end (if any)
605
+ if (i < end_of_selector) {
606
+ std::string parsed(i, end_of_selector);
607
+ String_Constant_Obj str = SASS_MEMORY_NEW(String_Constant, pstate, parsed);
608
+ pstate += Offset(parsed);
609
+ str->update_pstate(pstate);
610
+ i = end_of_selector;
611
+ schema->append(str);
612
+ }
613
+ // exit loop
614
+ }
615
+ }
616
+ // EO until eos
617
+
618
+ // update position
619
+ position = i;
620
+
621
+ // update for end position
622
+ selector_schema->update_pstate(pstate);
623
+ schema->update_pstate(pstate);
624
+
625
+ after_token = before_token = pstate;
626
+
627
+ // return parsed result
628
+ return selector_schema.detach();
629
+ }
630
+ // EO parse_selector_schema
631
+
632
+ void Parser::parse_charset_directive()
633
+ {
634
+ lex <
635
+ sequence <
636
+ quoted_string,
637
+ optional_spaces,
638
+ exactly <';'>
639
+ >
640
+ >();
641
+ }
642
+
643
+ // called after parsing `kwd_include_directive`
644
+ Mixin_Call_Obj Parser::parse_include_directive()
645
+ {
646
+ // lex identifier into `lexed` var
647
+ lex_identifier(); // may error out
648
+ // normalize underscores to hyphens
649
+ std::string name(Util::normalize_underscores(lexed));
650
+ // create the initial mixin call object
651
+ Mixin_Call_Obj call = SASS_MEMORY_NEW(Mixin_Call, pstate, name, {}, {}, {});
652
+ // parse mandatory arguments
653
+ call->arguments(parse_arguments());
654
+ // parse using and optional block parameters
655
+ bool has_parameters = lex< kwd_using >() != nullptr;
656
+
657
+ if (has_parameters) {
658
+ if (!peek< exactly<'('> >()) css_error("Invalid CSS", " after ", ": expected \"(\", was ");
659
+ } else {
660
+ if (peek< exactly<'('> >()) css_error("Invalid CSS", " after ", ": expected \";\", was ");
661
+ }
662
+
663
+ if (has_parameters) call->block_parameters(parse_parameters());
664
+
665
+ // parse optional block
666
+ if (peek < exactly <'{'> >()) {
667
+ call->block(parse_block());
668
+ }
669
+ else if (has_parameters) {
670
+ css_error("Invalid CSS", " after ", ": expected \"{\", was ");
671
+ }
672
+ // return ast node
673
+ return call.detach();
674
+ }
675
+ // EO parse_include_directive
676
+
677
+ // parse a list of complex selectors
678
+ // this is the main entry point for most
679
+ Selector_List_Obj Parser::parse_selector_list(bool chroot)
680
+ {
681
+ bool reloop;
682
+ bool had_linefeed = false;
683
+ NESTING_GUARD(nestings);
684
+ Complex_Selector_Obj sel;
685
+ Selector_List_Obj group = SASS_MEMORY_NEW(Selector_List, pstate);
686
+ group->media_block(last_media_block);
687
+
688
+ if (peek_css< alternatives < end_of_file, exactly <'{'>, exactly <','> > >()) {
689
+ css_error("Invalid CSS", " after ", ": expected selector, was ");
690
+ }
691
+
692
+ do {
693
+ reloop = false;
694
+
695
+ had_linefeed = had_linefeed || peek_newline();
696
+
697
+ if (peek_css< alternatives < class_char < selector_list_delims > > >())
698
+ break; // in case there are superfluous commas at the end
699
+
700
+ // now parse the complex selector
701
+ sel = parse_complex_selector(chroot);
702
+
703
+ if (!sel) return group.detach();
704
+
705
+ sel->has_line_feed(had_linefeed);
706
+
707
+ had_linefeed = false;
708
+
709
+ while (peek_css< exactly<','> >())
710
+ {
711
+ lex< css_comments >(false);
712
+ // consume everything up and including the comma separator
713
+ reloop = lex< exactly<','> >() != 0;
714
+ // remember line break (also between some commas)
715
+ had_linefeed = had_linefeed || peek_newline();
716
+ // remember line break (also between some commas)
717
+ }
718
+ group->append(sel);
719
+ }
720
+ while (reloop);
721
+ while (lex_css< kwd_optional >()) {
722
+ group->is_optional(true);
723
+ }
724
+ // update for end position
725
+ group->update_pstate(pstate);
726
+ if (sel) sel->mutable_last()->has_line_break(false);
727
+ return group.detach();
728
+ }
729
+ // EO parse_selector_list
730
+
731
+ // a complex selector combines a compound selector with another
732
+ // complex selector, with one of four combinator operations.
733
+ // the compound selector (head) is optional, since the combinator
734
+ // can come first in the whole selector sequence (like `> DIV').
735
+ Complex_Selector_Obj Parser::parse_complex_selector(bool chroot)
736
+ {
737
+
738
+ NESTING_GUARD(nestings);
739
+ String_Obj reference;
740
+ lex < block_comment >();
741
+ advanceToNextToken();
742
+ Complex_Selector_Obj sel = SASS_MEMORY_NEW(Complex_Selector, pstate);
743
+
744
+ if (peek < end_of_file >()) return {};
745
+
746
+ // parse the left hand side
747
+ Compound_Selector_Obj lhs;
748
+ // special case if it starts with combinator ([+~>])
749
+ if (!peek_css< class_char < selector_combinator_ops > >()) {
750
+ // parse the left hand side
751
+ lhs = parse_compound_selector();
752
+ }
753
+
754
+
755
+ // parse combinator between lhs and rhs
756
+ Complex_Selector::Combinator combinator = Complex_Selector::ANCESTOR_OF;
757
+ if (lex< exactly<'+'> >()) combinator = Complex_Selector::ADJACENT_TO;
758
+ else if (lex< exactly<'~'> >()) combinator = Complex_Selector::PRECEDES;
759
+ else if (lex< exactly<'>'> >()) combinator = Complex_Selector::PARENT_OF;
760
+ else if (lex< sequence < exactly<'/'>, negate < exactly < '*' > > > >()) {
761
+ // comments are allowed, but not spaces?
762
+ combinator = Complex_Selector::REFERENCE;
763
+ if (!lex < re_reference_combinator >()) return {};
764
+ reference = SASS_MEMORY_NEW(String_Constant, pstate, lexed);
765
+ if (!lex < exactly < '/' > >()) return {}; // ToDo: error msg?
766
+ }
767
+
768
+ if (!lhs && combinator == Complex_Selector::ANCESTOR_OF) return {};
769
+
770
+ // lex < block_comment >();
771
+ sel->head(lhs);
772
+ sel->combinator(combinator);
773
+ sel->media_block(last_media_block);
774
+
775
+ if (combinator == Complex_Selector::REFERENCE) sel->reference(reference);
776
+ // has linfeed after combinator?
777
+ sel->has_line_break(peek_newline());
778
+ // sel->has_line_feed(has_line_feed);
779
+
780
+ // check if we got the abort condition (ToDo: optimize)
781
+ if (!peek_css< class_char < complex_selector_delims > >()) {
782
+ // parse next selector in sequence
783
+ sel->tail(parse_complex_selector(true));
784
+ }
785
+
786
+ // add a parent selector if we are not in a root
787
+ // also skip adding parent ref if we only have refs
788
+ if (!sel->has_parent_ref() && !chroot) {
789
+ // create the objects to wrap parent selector reference
790
+ Compound_Selector_Obj head = SASS_MEMORY_NEW(Compound_Selector, pstate);
791
+ Parent_Selector* parent = SASS_MEMORY_NEW(Parent_Selector, pstate, false);
792
+ parent->media_block(last_media_block);
793
+ head->media_block(last_media_block);
794
+ // add simple selector
795
+ head->append(parent);
796
+ // selector may not have any head yet
797
+ if (!sel->head()) { sel->head(head); }
798
+ // otherwise we need to create a new complex selector and set the old one as its tail
799
+ else {
800
+ sel = SASS_MEMORY_NEW(Complex_Selector, pstate, Complex_Selector::ANCESTOR_OF, head, sel);
801
+ sel->media_block(last_media_block);
802
+ }
803
+ // peek for linefeed and remember result on head
804
+ // if (peek_newline()) head->has_line_break(true);
805
+ }
806
+
807
+ sel->update_pstate(pstate);
808
+ // complex selector
809
+ return sel;
810
+ }
811
+ // EO parse_complex_selector
812
+
813
+ // parse one compound selector, which is basically
814
+ // a list of simple selectors (directly adjacent)
815
+ // lex them exactly (without skipping white-space)
816
+ Compound_Selector_Obj Parser::parse_compound_selector()
817
+ {
818
+ // init an empty compound selector wrapper
819
+ Compound_Selector_Obj seq = SASS_MEMORY_NEW(Compound_Selector, pstate);
820
+ seq->media_block(last_media_block);
821
+
822
+ // skip initial white-space
823
+ lex< css_whitespace >();
824
+
825
+ // parse list
826
+ while (true)
827
+ {
828
+ // remove all block comments (don't skip white-space)
829
+ lex< delimited_by< slash_star, star_slash, false > >(false);
830
+ // parse functional
831
+ if (match < re_pseudo_selector >())
832
+ {
833
+ seq->append(parse_simple_selector());
834
+ }
835
+ // parse parent selector
836
+ else if (lex< exactly<'&'> >(false))
837
+ {
838
+ if (!allow_parent) error("Parent selectors aren't allowed here.");
839
+ // this produces a linefeed!?
840
+ seq->has_parent_reference(true);
841
+ seq->append(SASS_MEMORY_NEW(Parent_Selector, pstate));
842
+ // parent selector only allowed at start
843
+ // upcoming Sass may allow also trailing
844
+ if (seq->length() > 1) {
845
+ ParserState state(pstate);
846
+ Simple_Selector_Obj cur = (*seq)[seq->length()-1];
847
+ Simple_Selector_Obj prev = (*seq)[seq->length()-2];
848
+ std::string sel(prev->to_string({ NESTED, 5 }));
849
+ std::string found(cur->to_string({ NESTED, 5 }));
850
+ if (lex < identifier >()) { found += std::string(lexed); }
851
+ error("Invalid CSS after \"" + sel + "\": expected \"{\", was \"" + found + "\"\n\n"
852
+ "\"" + found + "\" may only be used at the beginning of a compound selector.", state);
853
+ }
854
+ }
855
+ // parse type selector
856
+ else if (lex< re_type_selector >(false))
857
+ {
858
+ seq->append(SASS_MEMORY_NEW(Type_Selector, pstate, lexed));
859
+ }
860
+ // peek for abort conditions
861
+ else if (peek< spaces >()) break;
862
+ else if (peek< end_of_file >()) { break; }
863
+ else if (peek_css < class_char < selector_combinator_ops > >()) break;
864
+ else if (peek_css < class_char < complex_selector_delims > >()) break;
865
+ // otherwise parse another simple selector
866
+ else {
867
+ Simple_Selector_Obj sel = parse_simple_selector();
868
+ if (!sel) return {};
869
+ seq->append(sel);
870
+ }
871
+ }
872
+
873
+ if (seq && !peek_css<alternatives<end_of_file,exactly<'{'>>>()) {
874
+ seq->has_line_break(peek_newline());
875
+ }
876
+
877
+ // EO while true
878
+ return seq;
879
+
880
+ }
881
+ // EO parse_compound_selector
882
+
883
+ Simple_Selector_Obj Parser::parse_simple_selector()
884
+ {
885
+ lex < css_comments >(false);
886
+ if (lex< class_name >()) {
887
+ return SASS_MEMORY_NEW(Class_Selector, pstate, lexed);
888
+ }
889
+ else if (lex< id_name >()) {
890
+ return SASS_MEMORY_NEW(Id_Selector, pstate, lexed);
891
+ }
892
+ else if (lex< alternatives < variable, number, static_reference_combinator > >()) {
893
+ return SASS_MEMORY_NEW(Type_Selector, pstate, lexed);
894
+ }
895
+ else if (peek< pseudo_not >()) {
896
+ return parse_negated_selector();
897
+ }
898
+ else if (peek< re_pseudo_selector >()) {
899
+ return parse_pseudo_selector();
900
+ }
901
+ else if (peek< exactly<':'> >()) {
902
+ return parse_pseudo_selector();
903
+ }
904
+ else if (lex < exactly<'['> >()) {
905
+ return parse_attribute_selector();
906
+ }
907
+ else if (lex< placeholder >()) {
908
+ Placeholder_Selector* sel = SASS_MEMORY_NEW(Placeholder_Selector, pstate, lexed);
909
+ sel->media_block(last_media_block);
910
+ return sel;
911
+ }
912
+ else {
913
+ css_error("Invalid CSS", " after ", ": expected selector, was ");
914
+ }
915
+ // failed
916
+ return {};
917
+ }
918
+
919
+ Wrapped_Selector_Obj Parser::parse_negated_selector()
920
+ {
921
+ lex< pseudo_not >();
922
+ std::string name(lexed);
923
+ ParserState nsource_position = pstate;
924
+ Selector_List_Obj negated = parse_selector_list(true);
925
+ if (!lex< exactly<')'> >()) {
926
+ error("negated selector is missing ')'");
927
+ }
928
+ name.erase(name.size() - 1);
929
+ return SASS_MEMORY_NEW(Wrapped_Selector, nsource_position, name, negated);
930
+ }
931
+
932
+ // a pseudo selector often starts with one or two colons
933
+ // it can contain more selectors inside parentheses
934
+ Simple_Selector_Obj Parser::parse_pseudo_selector() {
935
+ if (lex< sequence<
936
+ pseudo_prefix,
937
+ // we keep the space within the name, strange enough
938
+ // ToDo: refactor output to schedule the space for it
939
+ // or do we really want to keep the real white-space?
940
+ sequence< identifier, optional < block_comment >, exactly<'('> >
941
+ > >())
942
+ {
943
+
944
+ std::string name(lexed);
945
+ name.erase(name.size() - 1);
946
+ ParserState p = pstate;
947
+
948
+ // specially parse static stuff
949
+ // ToDo: really everything static?
950
+ if (peek_css <
951
+ sequence <
952
+ alternatives <
953
+ static_value,
954
+ binomial
955
+ >,
956
+ optional_css_whitespace,
957
+ exactly<')'>
958
+ >
959
+ >()
960
+ ) {
961
+ lex_css< alternatives < static_value, binomial > >();
962
+ String_Constant_Obj expr = SASS_MEMORY_NEW(String_Constant, pstate, lexed);
963
+ if (lex_css< exactly<')'> >()) {
964
+ expr->can_compress_whitespace(true);
965
+ return SASS_MEMORY_NEW(Pseudo_Selector, p, name, expr);
966
+ }
967
+ }
968
+ else if (Selector_List_Obj wrapped = parse_selector_list(true)) {
969
+ if (wrapped && lex_css< exactly<')'> >()) {
970
+ return SASS_MEMORY_NEW(Wrapped_Selector, p, name, wrapped);
971
+ }
972
+ }
973
+
974
+ }
975
+ // EO if pseudo selector
976
+
977
+ else if (lex < sequence< optional < pseudo_prefix >, identifier > >()) {
978
+ return SASS_MEMORY_NEW(Pseudo_Selector, pstate, lexed);
979
+ }
980
+ else if(lex < pseudo_prefix >()) {
981
+ css_error("Invalid CSS", " after ", ": expected pseudoclass or pseudoelement, was ");
982
+ }
983
+
984
+ css_error("Invalid CSS", " after ", ": expected \")\", was ");
985
+
986
+ // unreachable statement
987
+ return {};
988
+ }
989
+
990
+ const char* Parser::re_attr_sensitive_close(const char* src)
991
+ {
992
+ return alternatives < exactly<']'>, exactly<'/'> >(src);
993
+ }
994
+
995
+ const char* Parser::re_attr_insensitive_close(const char* src)
996
+ {
997
+ return sequence < insensitive<'i'>, re_attr_sensitive_close >(src);
998
+ }
999
+
1000
+ Attribute_Selector_Obj Parser::parse_attribute_selector()
1001
+ {
1002
+ ParserState p = pstate;
1003
+ if (!lex_css< attribute_name >()) error("invalid attribute name in attribute selector");
1004
+ std::string name(lexed);
1005
+ if (lex_css< re_attr_sensitive_close >()) {
1006
+ return SASS_MEMORY_NEW(Attribute_Selector, p, name, "", {}, {});
1007
+ }
1008
+ else if (lex_css< re_attr_insensitive_close >()) {
1009
+ char modifier = lexed.begin[0];
1010
+ return SASS_MEMORY_NEW(Attribute_Selector, p, name, "", {}, modifier);
1011
+ }
1012
+ if (!lex_css< alternatives< exact_match, class_match, dash_match,
1013
+ prefix_match, suffix_match, substring_match > >()) {
1014
+ error("invalid operator in attribute selector for " + name);
1015
+ }
1016
+ std::string matcher(lexed);
1017
+
1018
+ String_Obj value;
1019
+ if (lex_css< identifier >()) {
1020
+ value = SASS_MEMORY_NEW(String_Constant, p, lexed);
1021
+ }
1022
+ else if (lex_css< quoted_string >()) {
1023
+ value = parse_interpolated_chunk(lexed, true); // needed!
1024
+ }
1025
+ else {
1026
+ error("expected a string constant or identifier in attribute selector for " + name);
1027
+ }
1028
+
1029
+ if (lex_css< re_attr_sensitive_close >()) {
1030
+ return SASS_MEMORY_NEW(Attribute_Selector, p, name, matcher, value, 0);
1031
+ }
1032
+ else if (lex_css< re_attr_insensitive_close >()) {
1033
+ char modifier = lexed.begin[0];
1034
+ return SASS_MEMORY_NEW(Attribute_Selector, p, name, matcher, value, modifier);
1035
+ }
1036
+ error("unterminated attribute selector for " + name);
1037
+ return {}; // to satisfy compilers (error must not return)
1038
+ }
1039
+
1040
+ /* parse block comment and add to block */
1041
+ void Parser::parse_block_comments()
1042
+ {
1043
+ Block_Obj block = block_stack.back();
1044
+
1045
+ while (lex< block_comment >()) {
1046
+ bool is_important = lexed.begin[2] == '!';
1047
+ // flag on second param is to skip loosely over comments
1048
+ String_Obj contents = parse_interpolated_chunk(lexed, true, false);
1049
+ block->append(SASS_MEMORY_NEW(Comment, pstate, contents, is_important));
1050
+ }
1051
+ }
1052
+
1053
+ Declaration_Obj Parser::parse_declaration() {
1054
+ String_Obj prop;
1055
+ bool is_custom_property = false;
1056
+ if (lex< sequence< optional< exactly<'*'> >, identifier_schema > >()) {
1057
+ const std::string property(lexed);
1058
+ is_custom_property = property.compare(0, 2, "--") == 0;
1059
+ prop = parse_identifier_schema();
1060
+ }
1061
+ else if (lex< sequence< optional< exactly<'*'> >, identifier, zero_plus< block_comment > > >()) {
1062
+ const std::string property(lexed);
1063
+ is_custom_property = property.compare(0, 2, "--") == 0;
1064
+ prop = SASS_MEMORY_NEW(String_Constant, pstate, lexed);
1065
+ }
1066
+ else {
1067
+ css_error("Invalid CSS", " after ", ": expected \"}\", was ");
1068
+ }
1069
+ bool is_indented = true;
1070
+ const std::string property(lexed);
1071
+ if (!lex_css< one_plus< exactly<':'> > >()) error("property \"" + escape_string(property) + "\" must be followed by a ':'");
1072
+ if (!is_custom_property && match< sequence< optional_css_comments, exactly<';'> > >()) error("style declaration must contain a value");
1073
+ if (match< sequence< optional_css_comments, exactly<'{'> > >()) is_indented = false; // don't indent if value is empty
1074
+ if (is_custom_property) {
1075
+ return SASS_MEMORY_NEW(Declaration, prop->pstate(), prop, parse_css_variable_value(), false, true);
1076
+ }
1077
+ lex < css_comments >(false);
1078
+ if (peek_css< static_value >()) {
1079
+ return SASS_MEMORY_NEW(Declaration, prop->pstate(), prop, parse_static_value()/*, lex<kwd_important>()*/);
1080
+ }
1081
+ else {
1082
+ Expression_Obj value;
1083
+ Lookahead lookahead = lookahead_for_value(position);
1084
+ if (lookahead.found) {
1085
+ if (lookahead.has_interpolants) {
1086
+ value = parse_value_schema(lookahead.found);
1087
+ } else {
1088
+ value = parse_list(DELAYED);
1089
+ }
1090
+ }
1091
+ else {
1092
+ value = parse_list(DELAYED);
1093
+ if (List* list = Cast<List>(value)) {
1094
+ if (!list->is_bracketed() && list->length() == 0 && !peek< exactly <'{'> >()) {
1095
+ css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");
1096
+ }
1097
+ }
1098
+ }
1099
+ lex < css_comments >(false);
1100
+ Declaration_Obj decl = SASS_MEMORY_NEW(Declaration, prop->pstate(), prop, value/*, lex<kwd_important>()*/);
1101
+ decl->is_indented(is_indented);
1102
+ decl->update_pstate(pstate);
1103
+ return decl;
1104
+ }
1105
+ }
1106
+
1107
+ // parse +/- and return false if negative
1108
+ // this is never hit via spec tests
1109
+ bool Parser::parse_number_prefix()
1110
+ {
1111
+ bool positive = true;
1112
+ while(true) {
1113
+ if (lex < block_comment >()) continue;
1114
+ if (lex < number_prefix >()) continue;
1115
+ if (lex < exactly < '-' > >()) {
1116
+ positive = !positive;
1117
+ continue;
1118
+ }
1119
+ break;
1120
+ }
1121
+ return positive;
1122
+ }
1123
+
1124
+ Expression_Obj Parser::parse_map()
1125
+ {
1126
+ NESTING_GUARD(nestings);
1127
+ Expression_Obj key = parse_list();
1128
+ List_Obj map = SASS_MEMORY_NEW(List, pstate, 0, SASS_HASH);
1129
+
1130
+ // it's not a map so return the lexed value as a list value
1131
+ if (!lex_css< exactly<':'> >())
1132
+ { return key; }
1133
+
1134
+ List_Obj l = Cast<List>(key);
1135
+ if (l && l->separator() == SASS_COMMA) {
1136
+ css_error("Invalid CSS", " after ", ": expected \")\", was ");
1137
+ }
1138
+
1139
+ Expression_Obj value = parse_space_list();
1140
+
1141
+ map->append(key);
1142
+ map->append(value);
1143
+
1144
+ while (lex_css< exactly<','> >())
1145
+ {
1146
+ // allow trailing commas - #495
1147
+ if (peek_css< exactly<')'> >(position))
1148
+ { break; }
1149
+
1150
+ key = parse_space_list();
1151
+
1152
+ if (!(lex< exactly<':'> >()))
1153
+ { css_error("Invalid CSS", " after ", ": expected \":\", was "); }
1154
+
1155
+ value = parse_space_list();
1156
+
1157
+ map->append(key);
1158
+ map->append(value);
1159
+ }
1160
+
1161
+ ParserState ps = map->pstate();
1162
+ ps.offset = pstate - ps + pstate.offset;
1163
+ map->pstate(ps);
1164
+
1165
+ return map;
1166
+ }
1167
+
1168
+ Expression_Obj Parser::parse_bracket_list()
1169
+ {
1170
+ NESTING_GUARD(nestings);
1171
+ // check if we have an empty list
1172
+ // return the empty list as such
1173
+ if (peek_css< list_terminator >(position))
1174
+ {
1175
+ // return an empty list (nothing to delay)
1176
+ return SASS_MEMORY_NEW(List, pstate, 0, SASS_SPACE, false, true);
1177
+ }
1178
+
1179
+ bool has_paren = peek_css< exactly<'('> >() != NULL;
1180
+
1181
+ // now try to parse a space list
1182
+ Expression_Obj list = parse_space_list();
1183
+ // if it's a singleton, return it (don't wrap it)
1184
+ if (!peek_css< exactly<','> >(position)) {
1185
+ List_Obj l = Cast<List>(list);
1186
+ if (!l || l->is_bracketed() || has_paren) {
1187
+ List_Obj bracketed_list = SASS_MEMORY_NEW(List, pstate, 1, SASS_SPACE, false, true);
1188
+ bracketed_list->append(list);
1189
+ return bracketed_list;
1190
+ }
1191
+ l->is_bracketed(true);
1192
+ return l;
1193
+ }
1194
+
1195
+ // if we got so far, we actually do have a comma list
1196
+ List_Obj bracketed_list = SASS_MEMORY_NEW(List, pstate, 2, SASS_COMMA, false, true);
1197
+ // wrap the first expression
1198
+ bracketed_list->append(list);
1199
+
1200
+ while (lex_css< exactly<','> >())
1201
+ {
1202
+ // check for abort condition
1203
+ if (peek_css< list_terminator >(position)
1204
+ ) { break; }
1205
+ // otherwise add another expression
1206
+ bracketed_list->append(parse_space_list());
1207
+ }
1208
+ // return the list
1209
+ return bracketed_list;
1210
+ }
1211
+
1212
+ // parse list returns either a space separated list,
1213
+ // a comma separated list or any bare expression found.
1214
+ // so to speak: we unwrap items from lists if possible here!
1215
+ Expression_Obj Parser::parse_list(bool delayed)
1216
+ {
1217
+ NESTING_GUARD(nestings);
1218
+ return parse_comma_list(delayed);
1219
+ }
1220
+
1221
+ // will return singletons unwrapped
1222
+ Expression_Obj Parser::parse_comma_list(bool delayed)
1223
+ {
1224
+ NESTING_GUARD(nestings);
1225
+ // check if we have an empty list
1226
+ // return the empty list as such
1227
+ if (peek_css< list_terminator >(position))
1228
+ {
1229
+ // return an empty list (nothing to delay)
1230
+ return SASS_MEMORY_NEW(List, pstate, 0);
1231
+ }
1232
+
1233
+ // now try to parse a space list
1234
+ Expression_Obj list = parse_space_list();
1235
+ // if it's a singleton, return it (don't wrap it)
1236
+ if (!peek_css< exactly<','> >(position)) {
1237
+ // set_delay doesn't apply to list children
1238
+ // so this will only undelay single values
1239
+ if (!delayed) list->set_delayed(false);
1240
+ return list;
1241
+ }
1242
+
1243
+ // if we got so far, we actually do have a comma list
1244
+ List_Obj comma_list = SASS_MEMORY_NEW(List, pstate, 2, SASS_COMMA);
1245
+ // wrap the first expression
1246
+ comma_list->append(list);
1247
+
1248
+ while (lex_css< exactly<','> >())
1249
+ {
1250
+ // check for abort condition
1251
+ if (peek_css< list_terminator >(position)
1252
+ ) { break; }
1253
+ // otherwise add another expression
1254
+ comma_list->append(parse_space_list());
1255
+ }
1256
+ // return the list
1257
+ return comma_list;
1258
+ }
1259
+ // EO parse_comma_list
1260
+
1261
+ // will return singletons unwrapped
1262
+ Expression_Obj Parser::parse_space_list()
1263
+ {
1264
+ NESTING_GUARD(nestings);
1265
+ Expression_Obj disj1 = parse_disjunction();
1266
+ // if it's a singleton, return it (don't wrap it)
1267
+ if (peek_css< space_list_terminator >(position)
1268
+ ) {
1269
+ return disj1; }
1270
+
1271
+ List_Obj space_list = SASS_MEMORY_NEW(List, pstate, 2, SASS_SPACE);
1272
+ space_list->append(disj1);
1273
+
1274
+ while (
1275
+ !(peek_css< space_list_terminator >(position)) &&
1276
+ peek_css< optional_css_whitespace >() != end
1277
+ ) {
1278
+ // the space is parsed implicitly?
1279
+ space_list->append(parse_disjunction());
1280
+ }
1281
+ // return the list
1282
+ return space_list;
1283
+ }
1284
+ // EO parse_space_list
1285
+
1286
+ // parse logical OR operation
1287
+ Expression_Obj Parser::parse_disjunction()
1288
+ {
1289
+ NESTING_GUARD(nestings);
1290
+ advanceToNextToken();
1291
+ ParserState state(pstate);
1292
+ // parse the left hand side conjunction
1293
+ Expression_Obj conj = parse_conjunction();
1294
+ // parse multiple right hand sides
1295
+ std::vector<Expression_Obj> operands;
1296
+ while (lex_css< kwd_or >())
1297
+ operands.push_back(parse_conjunction());
1298
+ // if it's a singleton, return it directly
1299
+ if (operands.size() == 0) return conj;
1300
+ // fold all operands into one binary expression
1301
+ Expression_Obj ex = fold_operands(conj, operands, { Sass_OP::OR });
1302
+ state.offset = pstate - state + pstate.offset;
1303
+ ex->pstate(state);
1304
+ return ex;
1305
+ }
1306
+ // EO parse_disjunction
1307
+
1308
+ // parse logical AND operation
1309
+ Expression_Obj Parser::parse_conjunction()
1310
+ {
1311
+ NESTING_GUARD(nestings);
1312
+ advanceToNextToken();
1313
+ ParserState state(pstate);
1314
+ // parse the left hand side relation
1315
+ Expression_Obj rel = parse_relation();
1316
+ // parse multiple right hand sides
1317
+ std::vector<Expression_Obj> operands;
1318
+ while (lex_css< kwd_and >()) {
1319
+ operands.push_back(parse_relation());
1320
+ }
1321
+ // if it's a singleton, return it directly
1322
+ if (operands.size() == 0) return rel;
1323
+ // fold all operands into one binary expression
1324
+ Expression_Obj ex = fold_operands(rel, operands, { Sass_OP::AND });
1325
+ state.offset = pstate - state + pstate.offset;
1326
+ ex->pstate(state);
1327
+ return ex;
1328
+ }
1329
+ // EO parse_conjunction
1330
+
1331
+ // parse comparison operations
1332
+ Expression_Obj Parser::parse_relation()
1333
+ {
1334
+ NESTING_GUARD(nestings);
1335
+ advanceToNextToken();
1336
+ ParserState state(pstate);
1337
+ // parse the left hand side expression
1338
+ Expression_Obj lhs = parse_expression();
1339
+ std::vector<Expression_Obj> operands;
1340
+ std::vector<Operand> operators;
1341
+ // if it's a singleton, return it (don't wrap it)
1342
+ while (peek< alternatives <
1343
+ kwd_eq,
1344
+ kwd_neq,
1345
+ kwd_gte,
1346
+ kwd_gt,
1347
+ kwd_lte,
1348
+ kwd_lt
1349
+ > >(position))
1350
+ {
1351
+ // is directly adjancent to expression?
1352
+ bool left_ws = peek < css_comments >() != NULL;
1353
+ // parse the operator
1354
+ enum Sass_OP op
1355
+ = lex<kwd_eq>() ? Sass_OP::EQ
1356
+ : lex<kwd_neq>() ? Sass_OP::NEQ
1357
+ : lex<kwd_gte>() ? Sass_OP::GTE
1358
+ : lex<kwd_lte>() ? Sass_OP::LTE
1359
+ : lex<kwd_gt>() ? Sass_OP::GT
1360
+ : lex<kwd_lt>() ? Sass_OP::LT
1361
+ // we checked the possibilities on top of fn
1362
+ : Sass_OP::EQ;
1363
+ // is directly adjacent to expression?
1364
+ bool right_ws = peek < css_comments >() != NULL;
1365
+ operators.push_back({ op, left_ws, right_ws });
1366
+ operands.push_back(parse_expression());
1367
+ }
1368
+ // we are called recursively for list, so we first
1369
+ // fold inner binary expression which has delayed
1370
+ // correctly set to zero. After folding we also unwrap
1371
+ // single nested items. So we cannot set delay on the
1372
+ // returned result here, as we have lost nestings ...
1373
+ Expression_Obj ex = fold_operands(lhs, operands, operators);
1374
+ state.offset = pstate - state + pstate.offset;
1375
+ ex->pstate(state);
1376
+ return ex;
1377
+ }
1378
+ // parse_relation
1379
+
1380
+ // parse expression valid for operations
1381
+ // called from parse_relation
1382
+ // called from parse_for_directive
1383
+ // called from parse_media_expression
1384
+ // parse addition and subtraction operations
1385
+ Expression_Obj Parser::parse_expression()
1386
+ {
1387
+ NESTING_GUARD(nestings);
1388
+ advanceToNextToken();
1389
+ ParserState state(pstate);
1390
+ // parses multiple add and subtract operations
1391
+ // NOTE: make sure that identifiers starting with
1392
+ // NOTE: dashes do NOT count as subtract operation
1393
+ Expression_Obj lhs = parse_operators();
1394
+ // if it's a singleton, return it (don't wrap it)
1395
+ if (!(peek_css< exactly<'+'> >(position) ||
1396
+ // condition is a bit misterious, but some combinations should not be counted as operations
1397
+ (peek< no_spaces >(position) && peek< sequence< negate< unsigned_number >, exactly<'-'>, negate< space > > >(position)) ||
1398
+ (peek< sequence< negate< unsigned_number >, exactly<'-'>, negate< unsigned_number > > >(position))) ||
1399
+ peek< sequence < zero_plus < exactly <'-' > >, identifier > >(position))
1400
+ { return lhs; }
1401
+
1402
+ std::vector<Expression_Obj> operands;
1403
+ std::vector<Operand> operators;
1404
+ bool left_ws = peek < css_comments >() != NULL;
1405
+ while (
1406
+ lex_css< exactly<'+'> >() ||
1407
+
1408
+ (
1409
+ ! peek_css< sequence < zero_plus < exactly <'-' > >, identifier > >(position)
1410
+ && lex_css< sequence< negate< digit >, exactly<'-'> > >()
1411
+ )
1412
+
1413
+ ) {
1414
+
1415
+ bool right_ws = peek < css_comments >() != NULL;
1416
+ operators.push_back({ lexed.to_string() == "+" ? Sass_OP::ADD : Sass_OP::SUB, left_ws, right_ws });
1417
+ operands.push_back(parse_operators());
1418
+ left_ws = peek < css_comments >() != NULL;
1419
+ }
1420
+
1421
+ if (operands.size() == 0) return lhs;
1422
+ Expression_Obj ex = fold_operands(lhs, operands, operators);
1423
+ state.offset = pstate - state + pstate.offset;
1424
+ ex->pstate(state);
1425
+ return ex;
1426
+ }
1427
+
1428
+ // parse addition and subtraction operations
1429
+ Expression_Obj Parser::parse_operators()
1430
+ {
1431
+ NESTING_GUARD(nestings);
1432
+ advanceToNextToken();
1433
+ ParserState state(pstate);
1434
+ Expression_Obj factor = parse_factor();
1435
+ // if it's a singleton, return it (don't wrap it)
1436
+ std::vector<Expression_Obj> operands; // factors
1437
+ std::vector<Operand> operators; // ops
1438
+ // lex operations to apply to lhs
1439
+ const char* left_ws = peek < css_comments >();
1440
+ while (lex_css< class_char< static_ops > >()) {
1441
+ const char* right_ws = peek < css_comments >();
1442
+ switch(*lexed.begin) {
1443
+ case '*': operators.push_back({ Sass_OP::MUL, left_ws != 0, right_ws != 0 }); break;
1444
+ case '/': operators.push_back({ Sass_OP::DIV, left_ws != 0, right_ws != 0 }); break;
1445
+ case '%': operators.push_back({ Sass_OP::MOD, left_ws != 0, right_ws != 0 }); break;
1446
+ default: throw std::runtime_error("unknown static op parsed");
1447
+ }
1448
+ operands.push_back(parse_factor());
1449
+ left_ws = peek < css_comments >();
1450
+ }
1451
+ // operands and operators to binary expression
1452
+ Expression_Obj ex = fold_operands(factor, operands, operators);
1453
+ state.offset = pstate - state + pstate.offset;
1454
+ ex->pstate(state);
1455
+ return ex;
1456
+ }
1457
+ // EO parse_operators
1458
+
1459
+
1460
+ // called from parse_operators
1461
+ // called from parse_value_schema
1462
+ Expression_Obj Parser::parse_factor()
1463
+ {
1464
+ NESTING_GUARD(nestings);
1465
+ lex < css_comments >(false);
1466
+ if (lex_css< exactly<'('> >()) {
1467
+ // parse_map may return a list
1468
+ Expression_Obj value = parse_map();
1469
+ // lex the expected closing parenthesis
1470
+ if (!lex_css< exactly<')'> >()) error("unclosed parenthesis");
1471
+ // expression can be evaluated
1472
+ return value;
1473
+ }
1474
+ else if (lex_css< exactly<'['> >()) {
1475
+ // explicit bracketed
1476
+ Expression_Obj value = parse_bracket_list();
1477
+ // lex the expected closing square bracket
1478
+ if (!lex_css< exactly<']'> >()) error("unclosed squared bracket");
1479
+ return value;
1480
+ }
1481
+ // string may be interpolated
1482
+ // if (lex< quoted_string >()) {
1483
+ // return &parse_string();
1484
+ // }
1485
+ else if (peek< ie_property >()) {
1486
+ return parse_ie_property();
1487
+ }
1488
+ else if (peek< ie_keyword_arg >()) {
1489
+ return parse_ie_keyword_arg();
1490
+ }
1491
+ else if (peek< sequence < calc_fn_call, exactly <'('> > >()) {
1492
+ return parse_calc_function();
1493
+ }
1494
+ else if (lex < functional_schema >()) {
1495
+ return parse_function_call_schema();
1496
+ }
1497
+ else if (lex< identifier_schema >()) {
1498
+ String_Obj string = parse_identifier_schema();
1499
+ if (String_Schema* schema = Cast<String_Schema>(string)) {
1500
+ if (lex < exactly < '(' > >()) {
1501
+ schema->append(parse_list());
1502
+ lex < exactly < ')' > >();
1503
+ }
1504
+ }
1505
+ return string;
1506
+ }
1507
+ else if (peek< sequence< uri_prefix, W, real_uri_value > >()) {
1508
+ return parse_url_function_string();
1509
+ }
1510
+ else if (peek< re_functional >()) {
1511
+ return parse_function_call();
1512
+ }
1513
+ else if (lex< exactly<'+'> >()) {
1514
+ Unary_Expression* ex = SASS_MEMORY_NEW(Unary_Expression, pstate, Unary_Expression::PLUS, parse_factor());
1515
+ if (ex && ex->operand()) ex->is_delayed(ex->operand()->is_delayed());
1516
+ return ex;
1517
+ }
1518
+ else if (lex< exactly<'-'> >()) {
1519
+ Unary_Expression* ex = SASS_MEMORY_NEW(Unary_Expression, pstate, Unary_Expression::MINUS, parse_factor());
1520
+ if (ex && ex->operand()) ex->is_delayed(ex->operand()->is_delayed());
1521
+ return ex;
1522
+ }
1523
+ else if (lex< exactly<'/'> >()) {
1524
+ Unary_Expression* ex = SASS_MEMORY_NEW(Unary_Expression, pstate, Unary_Expression::SLASH, parse_factor());
1525
+ if (ex && ex->operand()) ex->is_delayed(ex->operand()->is_delayed());
1526
+ return ex;
1527
+ }
1528
+ else if (lex< sequence< kwd_not > >()) {
1529
+ Unary_Expression* ex = SASS_MEMORY_NEW(Unary_Expression, pstate, Unary_Expression::NOT, parse_factor());
1530
+ if (ex && ex->operand()) ex->is_delayed(ex->operand()->is_delayed());
1531
+ return ex;
1532
+ }
1533
+ // this whole branch is never hit via spec tests
1534
+ else if (peek < sequence < one_plus < alternatives < css_whitespace, exactly<'-'>, exactly<'+'> > >, number > >()) {
1535
+ if (parse_number_prefix()) return parse_value(); // prefix is positive
1536
+ Unary_Expression* ex = SASS_MEMORY_NEW(Unary_Expression, pstate, Unary_Expression::MINUS, parse_value());
1537
+ if (ex->operand()) ex->is_delayed(ex->operand()->is_delayed());
1538
+ return ex;
1539
+ }
1540
+ else {
1541
+ return parse_value();
1542
+ }
1543
+ }
1544
+
1545
+ bool number_has_zero(const std::string& parsed)
1546
+ {
1547
+ size_t L = parsed.length();
1548
+ return !( (L > 0 && parsed.substr(0, 1) == ".") ||
1549
+ (L > 1 && parsed.substr(0, 2) == "0.") ||
1550
+ (L > 1 && parsed.substr(0, 2) == "-.") ||
1551
+ (L > 2 && parsed.substr(0, 3) == "-0.") );
1552
+ }
1553
+
1554
+ Number* Parser::lexed_number(const ParserState& pstate, const std::string& parsed)
1555
+ {
1556
+ Number* nr = SASS_MEMORY_NEW(Number,
1557
+ pstate,
1558
+ sass_strtod(parsed.c_str()),
1559
+ "",
1560
+ number_has_zero(parsed));
1561
+ nr->is_interpolant(false);
1562
+ nr->is_delayed(true);
1563
+ return nr;
1564
+ }
1565
+
1566
+ Number* Parser::lexed_percentage(const ParserState& pstate, const std::string& parsed)
1567
+ {
1568
+ Number* nr = SASS_MEMORY_NEW(Number,
1569
+ pstate,
1570
+ sass_strtod(parsed.c_str()),
1571
+ "%",
1572
+ true);
1573
+ nr->is_interpolant(false);
1574
+ nr->is_delayed(true);
1575
+ return nr;
1576
+ }
1577
+
1578
+ Number* Parser::lexed_dimension(const ParserState& pstate, const std::string& parsed)
1579
+ {
1580
+ size_t L = parsed.length();
1581
+ size_t num_pos = parsed.find_first_not_of(" \n\r\t");
1582
+ if (num_pos == std::string::npos) num_pos = L;
1583
+ size_t unit_pos = parsed.find_first_not_of("-+0123456789.", num_pos);
1584
+ if (parsed[unit_pos] == 'e' && is_number(parsed[unit_pos+1]) ) {
1585
+ unit_pos = parsed.find_first_not_of("-+0123456789.", ++ unit_pos);
1586
+ }
1587
+ if (unit_pos == std::string::npos) unit_pos = L;
1588
+ const std::string& num = parsed.substr(num_pos, unit_pos - num_pos);
1589
+ Number* nr = SASS_MEMORY_NEW(Number,
1590
+ pstate,
1591
+ sass_strtod(num.c_str()),
1592
+ Token(number(parsed.c_str())),
1593
+ number_has_zero(parsed));
1594
+ nr->is_interpolant(false);
1595
+ nr->is_delayed(true);
1596
+ return nr;
1597
+ }
1598
+
1599
+ Value* Parser::lexed_hex_color(const ParserState& pstate, const std::string& parsed)
1600
+ {
1601
+ Color_RGBA* color = NULL;
1602
+ if (parsed[0] != '#') {
1603
+ return SASS_MEMORY_NEW(String_Quoted, pstate, parsed);
1604
+ }
1605
+ // chop off the '#'
1606
+ std::string hext(parsed.substr(1));
1607
+ if (parsed.length() == 4) {
1608
+ std::string r(2, parsed[1]);
1609
+ std::string g(2, parsed[2]);
1610
+ std::string b(2, parsed[3]);
1611
+ color = SASS_MEMORY_NEW(Color_RGBA,
1612
+ pstate,
1613
+ static_cast<double>(strtol(r.c_str(), NULL, 16)),
1614
+ static_cast<double>(strtol(g.c_str(), NULL, 16)),
1615
+ static_cast<double>(strtol(b.c_str(), NULL, 16)),
1616
+ 1, // alpha channel
1617
+ parsed);
1618
+ }
1619
+ else if (parsed.length() == 5) {
1620
+ std::string r(2, parsed[1]);
1621
+ std::string g(2, parsed[2]);
1622
+ std::string b(2, parsed[3]);
1623
+ std::string a(2, parsed[4]);
1624
+ color = SASS_MEMORY_NEW(Color_RGBA,
1625
+ pstate,
1626
+ static_cast<double>(strtol(r.c_str(), NULL, 16)),
1627
+ static_cast<double>(strtol(g.c_str(), NULL, 16)),
1628
+ static_cast<double>(strtol(b.c_str(), NULL, 16)),
1629
+ static_cast<double>(strtol(a.c_str(), NULL, 16)) / 255,
1630
+ parsed);
1631
+ }
1632
+ else if (parsed.length() == 7) {
1633
+ std::string r(parsed.substr(1,2));
1634
+ std::string g(parsed.substr(3,2));
1635
+ std::string b(parsed.substr(5,2));
1636
+ color = SASS_MEMORY_NEW(Color_RGBA,
1637
+ pstate,
1638
+ static_cast<double>(strtol(r.c_str(), NULL, 16)),
1639
+ static_cast<double>(strtol(g.c_str(), NULL, 16)),
1640
+ static_cast<double>(strtol(b.c_str(), NULL, 16)),
1641
+ 1, // alpha channel
1642
+ parsed);
1643
+ }
1644
+ else if (parsed.length() == 9) {
1645
+ std::string r(parsed.substr(1,2));
1646
+ std::string g(parsed.substr(3,2));
1647
+ std::string b(parsed.substr(5,2));
1648
+ std::string a(parsed.substr(7,2));
1649
+ color = SASS_MEMORY_NEW(Color_RGBA,
1650
+ pstate,
1651
+ static_cast<double>(strtol(r.c_str(), NULL, 16)),
1652
+ static_cast<double>(strtol(g.c_str(), NULL, 16)),
1653
+ static_cast<double>(strtol(b.c_str(), NULL, 16)),
1654
+ static_cast<double>(strtol(a.c_str(), NULL, 16)) / 255,
1655
+ parsed);
1656
+ }
1657
+ color->is_interpolant(false);
1658
+ color->is_delayed(false);
1659
+ return color;
1660
+ }
1661
+
1662
+ Value* Parser::color_or_string(const std::string& lexed) const
1663
+ {
1664
+ if (auto color = name_to_color(lexed)) {
1665
+ auto c = SASS_MEMORY_NEW(Color_RGBA, color);
1666
+ c->is_delayed(true);
1667
+ c->pstate(pstate);
1668
+ c->disp(lexed);
1669
+ return c;
1670
+ } else {
1671
+ return SASS_MEMORY_NEW(String_Constant, pstate, lexed);
1672
+ }
1673
+ }
1674
+
1675
+ // parse one value for a list
1676
+ Expression_Obj Parser::parse_value()
1677
+ {
1678
+ lex< css_comments >(false);
1679
+ if (lex< ampersand >())
1680
+ {
1681
+ if (match< ampersand >()) {
1682
+ warning("In Sass, \"&&\" means two copies of the parent selector. You probably want to use \"and\" instead.", pstate);
1683
+ }
1684
+ return SASS_MEMORY_NEW(Parent_Reference, pstate); }
1685
+
1686
+ if (lex< kwd_important >())
1687
+ { return SASS_MEMORY_NEW(String_Constant, pstate, "!important"); }
1688
+
1689
+ // parse `10%4px` into separated items and not a schema
1690
+ if (lex< sequence < percentage, lookahead < number > > >())
1691
+ { return lexed_percentage(lexed); }
1692
+
1693
+ if (lex< sequence < number, lookahead< sequence < op, number > > > >())
1694
+ { return lexed_number(lexed); }
1695
+
1696
+ // string may be interpolated
1697
+ if (lex< sequence < quoted_string, lookahead < exactly <'-'> > > >())
1698
+ { return parse_string(); }
1699
+
1700
+ if (const char* stop = peek< value_schema >())
1701
+ { return parse_value_schema(stop); }
1702
+
1703
+ // string may be interpolated
1704
+ if (lex< quoted_string >())
1705
+ { return parse_string(); }
1706
+
1707
+ if (lex< kwd_true >())
1708
+ { return SASS_MEMORY_NEW(Boolean, pstate, true); }
1709
+
1710
+ if (lex< kwd_false >())
1711
+ { return SASS_MEMORY_NEW(Boolean, pstate, false); }
1712
+
1713
+ if (lex< kwd_null >())
1714
+ { return SASS_MEMORY_NEW(Null, pstate); }
1715
+
1716
+ if (lex< identifier >()) {
1717
+ return color_or_string(lexed);
1718
+ }
1719
+
1720
+ if (lex< percentage >())
1721
+ { return lexed_percentage(lexed); }
1722
+
1723
+ // match hex number first because 0x000 looks like a number followed by an identifier
1724
+ if (lex< sequence < alternatives< hex, hex0 >, negate < exactly<'-'> > > >())
1725
+ { return lexed_hex_color(lexed); }
1726
+
1727
+ if (lex< hexa >())
1728
+ { return lexed_hex_color(lexed); }
1729
+
1730
+ if (lex< sequence < exactly <'#'>, identifier > >())
1731
+ { return SASS_MEMORY_NEW(String_Quoted, pstate, lexed); }
1732
+
1733
+ // also handle the 10em- foo special case
1734
+ // alternatives < exactly < '.' >, .. > -- `1.5em-.75em` is split into a list, not a binary expression
1735
+ if (lex< sequence< dimension, optional< sequence< exactly<'-'>, lookahead< alternatives < space > > > > > >())
1736
+ { return lexed_dimension(lexed); }
1737
+
1738
+ if (lex< sequence< static_component, one_plus< strict_identifier > > >())
1739
+ { return SASS_MEMORY_NEW(String_Constant, pstate, lexed); }
1740
+
1741
+ if (lex< number >())
1742
+ { return lexed_number(lexed); }
1743
+
1744
+ if (lex< variable >())
1745
+ { return SASS_MEMORY_NEW(Variable, pstate, Util::normalize_underscores(lexed)); }
1746
+
1747
+ css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");
1748
+
1749
+ // unreachable statement
1750
+ return {};
1751
+ }
1752
+
1753
+ // this parses interpolation inside other strings
1754
+ // means the result should later be quoted again
1755
+ String_Obj Parser::parse_interpolated_chunk(Token chunk, bool constant, bool css)
1756
+ {
1757
+ const char* i = chunk.begin;
1758
+ // see if there any interpolants
1759
+ const char* p = constant ? find_first_in_interval< exactly<hash_lbrace> >(i, chunk.end) :
1760
+ find_first_in_interval< exactly<hash_lbrace>, block_comment >(i, chunk.end);
1761
+
1762
+ if (!p) {
1763
+ String_Quoted* str_quoted = SASS_MEMORY_NEW(String_Quoted, pstate, std::string(i, chunk.end), 0, false, false, true, css);
1764
+ if (!constant && str_quoted->quote_mark()) str_quoted->quote_mark('*');
1765
+ return str_quoted;
1766
+ }
1767
+
1768
+ String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate, 0, css);
1769
+ schema->is_interpolant(true);
1770
+ while (i < chunk.end) {
1771
+ p = constant ? find_first_in_interval< exactly<hash_lbrace> >(i, chunk.end) :
1772
+ find_first_in_interval< exactly<hash_lbrace>, block_comment >(i, chunk.end);
1773
+ if (p) {
1774
+ if (i < p) {
1775
+ // accumulate the preceding segment if it's nonempty
1776
+ schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(i, p), css));
1777
+ }
1778
+ // we need to skip anything inside strings
1779
+ // create a new target in parser/prelexer
1780
+ if (peek < sequence < optional_spaces, exactly<rbrace> > >(p+2)) { position = p+2;
1781
+ css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");
1782
+ }
1783
+ const char* j = skip_over_scopes< exactly<hash_lbrace>, exactly<rbrace> >(p + 2, chunk.end); // find the closing brace
1784
+ if (j) { --j;
1785
+ // parse the interpolant and accumulate it
1786
+ Expression_Obj interp_node = Parser::from_token(Token(p+2, j), ctx, traces, pstate, source).parse_list();
1787
+ interp_node->is_interpolant(true);
1788
+ schema->append(interp_node);
1789
+ i = j;
1790
+ }
1791
+ else {
1792
+ // throw an error if the interpolant is unterminated
1793
+ error("unterminated interpolant inside string constant " + chunk.to_string());
1794
+ }
1795
+ }
1796
+ else { // no interpolants left; add the last segment if nonempty
1797
+ // check if we need quotes here (was not sure after merge)
1798
+ if (i < chunk.end) schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(i, chunk.end), css));
1799
+ break;
1800
+ }
1801
+ ++ i;
1802
+ }
1803
+
1804
+ return schema.detach();
1805
+ }
1806
+
1807
+ String_Schema_Obj Parser::parse_css_variable_value()
1808
+ {
1809
+ String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate);
1810
+ std::vector<char> brackets;
1811
+ while (true) {
1812
+ if (
1813
+ (brackets.empty() && lex< css_variable_top_level_value >(false)) ||
1814
+ (!brackets.empty() && lex< css_variable_value >(false))
1815
+ ) {
1816
+ Token str(lexed);
1817
+ schema->append(SASS_MEMORY_NEW(String_Constant, pstate, str));
1818
+ } else if (Expression_Obj tok = lex_interpolation()) {
1819
+ if (String_Schema* s = Cast<String_Schema>(tok)) {
1820
+ if (s->empty()) break;
1821
+ schema->concat(s);
1822
+ } else {
1823
+ schema->append(tok);
1824
+ }
1825
+ } else if (lex< quoted_string >()) {
1826
+ Expression_Obj tok = parse_string();
1827
+ if (tok.isNull()) break;
1828
+ if (String_Schema* s = Cast<String_Schema>(tok)) {
1829
+ if (s->empty()) break;
1830
+ schema->concat(s);
1831
+ } else {
1832
+ schema->append(tok);
1833
+ }
1834
+ } else if (lex< alternatives< exactly<'('>, exactly<'['>, exactly<'{'> > >()) {
1835
+ const char opening_bracket = *(position - 1);
1836
+ brackets.push_back(opening_bracket);
1837
+ schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(1, opening_bracket)));
1838
+ } else if (const char *match = peek< alternatives< exactly<')'>, exactly<']'>, exactly<'}'> > >()) {
1839
+ if (brackets.empty()) break;
1840
+ const char closing_bracket = *(match - 1);
1841
+ if (brackets.back() != Util::opening_bracket_for(closing_bracket)) {
1842
+ std::string message = ": expected \"";
1843
+ message += Util::closing_bracket_for(brackets.back());
1844
+ message += "\", was ";
1845
+ css_error("Invalid CSS", " after ", message);
1846
+ }
1847
+ lex< alternatives< exactly<')'>, exactly<']'>, exactly<'}'> > >();
1848
+ schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(1, closing_bracket)));
1849
+ brackets.pop_back();
1850
+ } else {
1851
+ break;
1852
+ }
1853
+ }
1854
+
1855
+ if (!brackets.empty()) {
1856
+ std::string message = ": expected \"";
1857
+ message += Util::closing_bracket_for(brackets.back());
1858
+ message += "\", was ";
1859
+ css_error("Invalid CSS", " after ", message);
1860
+ }
1861
+
1862
+ if (schema->empty()) error("Custom property values may not be empty.");
1863
+ return schema.detach();
1864
+ }
1865
+
1866
+ Value_Obj Parser::parse_static_value()
1867
+ {
1868
+ lex< static_value >();
1869
+ Token str(lexed);
1870
+ // static values always have trailing white-
1871
+ // space and end delimiter (\s*[;]$) included
1872
+ --pstate.offset.column;
1873
+ --after_token.column;
1874
+ --str.end;
1875
+ --position;
1876
+
1877
+ return color_or_string(str.time_wspace());;
1878
+ }
1879
+
1880
+ String_Obj Parser::parse_string()
1881
+ {
1882
+ return parse_interpolated_chunk(Token(lexed));
1883
+ }
1884
+
1885
+ String_Obj Parser::parse_ie_property()
1886
+ {
1887
+ lex< ie_property >();
1888
+ Token str(lexed);
1889
+ const char* i = str.begin;
1890
+ // see if there any interpolants
1891
+ const char* p = find_first_in_interval< exactly<hash_lbrace>, block_comment >(str.begin, str.end);
1892
+ if (!p) {
1893
+ return SASS_MEMORY_NEW(String_Quoted, pstate, std::string(str.begin, str.end));
1894
+ }
1895
+
1896
+ String_Schema* schema = SASS_MEMORY_NEW(String_Schema, pstate);
1897
+ while (i < str.end) {
1898
+ p = find_first_in_interval< exactly<hash_lbrace>, block_comment >(i, str.end);
1899
+ if (p) {
1900
+ if (i < p) {
1901
+ schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(i, p))); // accumulate the preceding segment if it's nonempty
1902
+ }
1903
+ if (peek < sequence < optional_spaces, exactly<rbrace> > >(p+2)) { position = p+2;
1904
+ css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");
1905
+ }
1906
+ const char* j = skip_over_scopes< exactly<hash_lbrace>, exactly<rbrace> >(p+2, str.end); // find the closing brace
1907
+ if (j) {
1908
+ // parse the interpolant and accumulate it
1909
+ Expression_Obj interp_node = Parser::from_token(Token(p+2, j), ctx, traces, pstate, source).parse_list();
1910
+ interp_node->is_interpolant(true);
1911
+ schema->append(interp_node);
1912
+ i = j;
1913
+ }
1914
+ else {
1915
+ // throw an error if the interpolant is unterminated
1916
+ error("unterminated interpolant inside IE function " + str.to_string());
1917
+ }
1918
+ }
1919
+ else { // no interpolants left; add the last segment if nonempty
1920
+ if (i < str.end) {
1921
+ schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(i, str.end)));
1922
+ }
1923
+ break;
1924
+ }
1925
+ }
1926
+ return schema;
1927
+ }
1928
+
1929
+ String_Obj Parser::parse_ie_keyword_arg()
1930
+ {
1931
+ String_Schema_Obj kwd_arg = SASS_MEMORY_NEW(String_Schema, pstate, 3);
1932
+ if (lex< variable >()) {
1933
+ kwd_arg->append(SASS_MEMORY_NEW(Variable, pstate, Util::normalize_underscores(lexed)));
1934
+ } else {
1935
+ lex< alternatives< identifier_schema, identifier > >();
1936
+ kwd_arg->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed));
1937
+ }
1938
+ lex< exactly<'='> >();
1939
+ kwd_arg->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed));
1940
+ if (peek< variable >()) kwd_arg->append(parse_list());
1941
+ else if (lex< number >()) {
1942
+ std::string parsed(lexed);
1943
+ Util::normalize_decimals(parsed);
1944
+ kwd_arg->append(lexed_number(parsed));
1945
+ }
1946
+ else if (peek < ie_keyword_arg_value >()) { kwd_arg->append(parse_list()); }
1947
+ return kwd_arg;
1948
+ }
1949
+
1950
+ String_Schema_Obj Parser::parse_value_schema(const char* stop)
1951
+ {
1952
+ // initialize the string schema object to add tokens
1953
+ String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate);
1954
+
1955
+ if (peek<exactly<'}'>>()) {
1956
+ css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");
1957
+ }
1958
+
1959
+ const char* e;
1960
+ const char* ee = end;
1961
+ end = stop;
1962
+ size_t num_items = 0;
1963
+ bool need_space = false;
1964
+ while (position < stop) {
1965
+ // parse space between tokens
1966
+ if (lex< spaces >() && num_items) {
1967
+ need_space = true;
1968
+ }
1969
+ if (need_space) {
1970
+ need_space = false;
1971
+ // schema->append(SASS_MEMORY_NEW(String_Constant, pstate, " "));
1972
+ }
1973
+ if ((e = peek< re_functional >()) && e < stop) {
1974
+ schema->append(parse_function_call());
1975
+ }
1976
+ // lex an interpolant /#{...}/
1977
+ else if (lex< exactly < hash_lbrace > >()) {
1978
+ // Try to lex static expression first
1979
+ if (peek< exactly< rbrace > >()) {
1980
+ css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");
1981
+ }
1982
+ Expression_Obj ex;
1983
+ if (lex< re_static_expression >()) {
1984
+ ex = SASS_MEMORY_NEW(String_Constant, pstate, lexed);
1985
+ } else {
1986
+ ex = parse_list(true);
1987
+ }
1988
+ ex->is_interpolant(true);
1989
+ schema->append(ex);
1990
+ if (!lex < exactly < rbrace > >()) {
1991
+ css_error("Invalid CSS", " after ", ": expected \"}\", was ");
1992
+ }
1993
+ }
1994
+ // lex some string constants or other valid token
1995
+ // Note: [-+] chars are left over from i.e. `#{3}+3`
1996
+ else if (lex< alternatives < exactly<'%'>, exactly < '-' >, exactly < '+' > > >()) {
1997
+ schema->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed));
1998
+ }
1999
+ // lex a quoted string
2000
+ else if (lex< quoted_string >()) {
2001
+ // need_space = true;
2002
+ // if (schema->length()) schema->append(SASS_MEMORY_NEW(String_Constant, pstate, " "));
2003
+ // else need_space = true;
2004
+ schema->append(parse_string());
2005
+ if ((*position == '"' || *position == '\'') || peek < alternatives < alpha > >()) {
2006
+ // need_space = true;
2007
+ }
2008
+ if (peek < exactly < '-' > >()) break;
2009
+ }
2010
+ else if (lex< identifier >()) {
2011
+ schema->append(SASS_MEMORY_NEW(String_Constant, pstate, lexed));
2012
+ if ((*position == '"' || *position == '\'') || peek < alternatives < alpha > >()) {
2013
+ // need_space = true;
2014
+ }
2015
+ }
2016
+ // lex (normalized) variable
2017
+ else if (lex< variable >()) {
2018
+ std::string name(Util::normalize_underscores(lexed));
2019
+ schema->append(SASS_MEMORY_NEW(Variable, pstate, name));
2020
+ }
2021
+ // lex percentage value
2022
+ else if (lex< percentage >()) {
2023
+ schema->append(lexed_percentage(lexed));
2024
+ }
2025
+ // lex dimension value
2026
+ else if (lex< dimension >()) {
2027
+ schema->append(lexed_dimension(lexed));
2028
+ }
2029
+ // lex number value
2030
+ else if (lex< number >()) {
2031
+ schema->append(lexed_number(lexed));
2032
+ }
2033
+ // lex hex color value
2034
+ else if (lex< sequence < hex, negate < exactly < '-' > > > >()) {
2035
+ schema->append(lexed_hex_color(lexed));
2036
+ }
2037
+ else if (lex< sequence < exactly <'#'>, identifier > >()) {
2038
+ schema->append(SASS_MEMORY_NEW(String_Quoted, pstate, lexed));
2039
+ }
2040
+ // lex a value in parentheses
2041
+ else if (peek< parenthese_scope >()) {
2042
+ schema->append(parse_factor());
2043
+ }
2044
+ else {
2045
+ break;
2046
+ }
2047
+ ++num_items;
2048
+ }
2049
+ if (position != stop) {
2050
+ schema->append(SASS_MEMORY_NEW(String_Constant, pstate, std::string(position, stop)));
2051
+ position = stop;
2052
+ }
2053
+ end = ee;
2054
+ return schema;
2055
+ }
2056
+
2057
+ // this parses interpolation outside other strings
2058
+ // means the result must not be quoted again later
2059
+ String_Obj Parser::parse_identifier_schema()
2060
+ {
2061
+ Token id(lexed);
2062
+ const char* i = id.begin;
2063
+ // see if there any interpolants
2064
+ const char* p = find_first_in_interval< exactly<hash_lbrace>, block_comment >(id.begin, id.end);
2065
+ if (!p) {
2066
+ return SASS_MEMORY_NEW(String_Constant, pstate, std::string(id.begin, id.end));
2067
+ }
2068
+
2069
+ String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate);
2070
+ while (i < id.end) {
2071
+ p = find_first_in_interval< exactly<hash_lbrace>, block_comment >(i, id.end);
2072
+ if (p) {
2073
+ if (i < p) {
2074
+ // accumulate the preceding segment if it's nonempty
2075
+ const char* o = position; position = i;
2076
+ schema->append(parse_value_schema(p));
2077
+ position = o;
2078
+ }
2079
+ // we need to skip anything inside strings
2080
+ // create a new target in parser/prelexer
2081
+ if (peek < sequence < optional_spaces, exactly<rbrace> > >(p+2)) { position = p;
2082
+ css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ");
2083
+ }
2084
+ const char* j = skip_over_scopes< exactly<hash_lbrace>, exactly<rbrace> >(p+2, id.end); // find the closing brace
2085
+ if (j) {
2086
+ // parse the interpolant and accumulate it
2087
+ Expression_Obj interp_node = Parser::from_token(Token(p+2, j), ctx, traces, pstate, source).parse_list(DELAYED);
2088
+ interp_node->is_interpolant(true);
2089
+ schema->append(interp_node);
2090
+ // schema->has_interpolants(true);
2091
+ i = j;
2092
+ }
2093
+ else {
2094
+ // throw an error if the interpolant is unterminated
2095
+ error("unterminated interpolant inside interpolated identifier " + id.to_string());
2096
+ }
2097
+ }
2098
+ else { // no interpolants left; add the last segment if nonempty
2099
+ if (i < end) {
2100
+ const char* o = position; position = i;
2101
+ schema->append(parse_value_schema(id.end));
2102
+ position = o;
2103
+ }
2104
+ break;
2105
+ }
2106
+ }
2107
+ return schema ? schema.detach() : 0;
2108
+ }
2109
+
2110
+ // calc functions should preserve arguments
2111
+ Function_Call_Obj Parser::parse_calc_function()
2112
+ {
2113
+ lex< identifier >();
2114
+ std::string name(lexed);
2115
+ ParserState call_pos = pstate;
2116
+ lex< exactly<'('> >();
2117
+ ParserState arg_pos = pstate;
2118
+ const char* arg_beg = position;
2119
+ parse_list();
2120
+ const char* arg_end = position;
2121
+ lex< skip_over_scopes <
2122
+ exactly < '(' >,
2123
+ exactly < ')' >
2124
+ > >();
2125
+
2126
+ Argument_Obj arg = SASS_MEMORY_NEW(Argument, arg_pos, parse_interpolated_chunk(Token(arg_beg, arg_end)));
2127
+ Arguments_Obj args = SASS_MEMORY_NEW(Arguments, arg_pos);
2128
+ args->append(arg);
2129
+ return SASS_MEMORY_NEW(Function_Call, call_pos, name, args);
2130
+ }
2131
+
2132
+ String_Obj Parser::parse_url_function_string()
2133
+ {
2134
+ std::string prefix("");
2135
+ if (lex< uri_prefix >()) {
2136
+ prefix = std::string(lexed);
2137
+ }
2138
+
2139
+ lex < optional_spaces >();
2140
+ String_Obj url_string = parse_url_function_argument();
2141
+
2142
+ std::string suffix("");
2143
+ if (lex< real_uri_suffix >()) {
2144
+ suffix = std::string(lexed);
2145
+ }
2146
+
2147
+ std::string uri("");
2148
+ if (url_string) {
2149
+ uri = url_string->to_string({ NESTED, 5 });
2150
+ }
2151
+
2152
+ if (String_Schema* schema = Cast<String_Schema>(url_string)) {
2153
+ String_Schema_Obj res = SASS_MEMORY_NEW(String_Schema, pstate);
2154
+ res->append(SASS_MEMORY_NEW(String_Constant, pstate, prefix));
2155
+ res->append(schema);
2156
+ res->append(SASS_MEMORY_NEW(String_Constant, pstate, suffix));
2157
+ return res;
2158
+ } else {
2159
+ std::string res = prefix + uri + suffix;
2160
+ return SASS_MEMORY_NEW(String_Constant, pstate, res);
2161
+ }
2162
+ }
2163
+
2164
+ String_Obj Parser::parse_url_function_argument()
2165
+ {
2166
+ const char* p = position;
2167
+
2168
+ std::string uri("");
2169
+ if (lex< real_uri_value >(false)) {
2170
+ uri = lexed.to_string();
2171
+ }
2172
+
2173
+ if (peek< exactly< hash_lbrace > >()) {
2174
+ const char* pp = position;
2175
+ // TODO: error checking for unclosed interpolants
2176
+ while (pp && peek< exactly< hash_lbrace > >(pp)) {
2177
+ pp = sequence< interpolant, real_uri_value >(pp);
2178
+ }
2179
+ if (!pp) return {};
2180
+ position = pp;
2181
+ return parse_interpolated_chunk(Token(p, position));
2182
+ }
2183
+ else if (uri != "") {
2184
+ std::string res = Util::rtrim(uri);
2185
+ return SASS_MEMORY_NEW(String_Constant, pstate, res);
2186
+ }
2187
+
2188
+ return {};
2189
+ }
2190
+
2191
+ Function_Call_Obj Parser::parse_function_call()
2192
+ {
2193
+ lex< identifier >();
2194
+ std::string name(lexed);
2195
+
2196
+ if (Util::normalize_underscores(name) == "content-exists" && stack.back() != Scope::Mixin)
2197
+ { error("Cannot call content-exists() except within a mixin."); }
2198
+
2199
+ ParserState call_pos = pstate;
2200
+ Arguments_Obj args = parse_arguments();
2201
+ return SASS_MEMORY_NEW(Function_Call, call_pos, name, args);
2202
+ }
2203
+
2204
+ Function_Call_Obj Parser::parse_function_call_schema()
2205
+ {
2206
+ String_Obj name = parse_identifier_schema();
2207
+ ParserState source_position_of_call = pstate;
2208
+ Arguments_Obj args = parse_arguments();
2209
+
2210
+ return SASS_MEMORY_NEW(Function_Call, source_position_of_call, name, args);
2211
+ }
2212
+
2213
+ Content_Obj Parser::parse_content_directive()
2214
+ {
2215
+ ParserState call_pos = pstate;
2216
+ Arguments_Obj args = parse_arguments();
2217
+
2218
+ return SASS_MEMORY_NEW(Content, call_pos, args);
2219
+ }
2220
+
2221
+ If_Obj Parser::parse_if_directive(bool else_if)
2222
+ {
2223
+ stack.push_back(Scope::Control);
2224
+ ParserState if_source_position = pstate;
2225
+ bool root = block_stack.back()->is_root();
2226
+ Expression_Obj predicate = parse_list();
2227
+ Block_Obj block = parse_block(root);
2228
+ Block_Obj alternative;
2229
+
2230
+ // only throw away comment if we parse a case
2231
+ // we want all other comments to be parsed
2232
+ if (lex_css< elseif_directive >()) {
2233
+ alternative = SASS_MEMORY_NEW(Block, pstate);
2234
+ alternative->append(parse_if_directive(true));
2235
+ }
2236
+ else if (lex_css< kwd_else_directive >()) {
2237
+ alternative = parse_block(root);
2238
+ }
2239
+ stack.pop_back();
2240
+ return SASS_MEMORY_NEW(If, if_source_position, predicate, block, alternative);
2241
+ }
2242
+
2243
+ For_Obj Parser::parse_for_directive()
2244
+ {
2245
+ stack.push_back(Scope::Control);
2246
+ ParserState for_source_position = pstate;
2247
+ bool root = block_stack.back()->is_root();
2248
+ lex_variable();
2249
+ std::string var(Util::normalize_underscores(lexed));
2250
+ if (!lex< kwd_from >()) error("expected 'from' keyword in @for directive");
2251
+ Expression_Obj lower_bound = parse_expression();
2252
+ bool inclusive = false;
2253
+ if (lex< kwd_through >()) inclusive = true;
2254
+ else if (lex< kwd_to >()) inclusive = false;
2255
+ else error("expected 'through' or 'to' keyword in @for directive");
2256
+ Expression_Obj upper_bound = parse_expression();
2257
+ Block_Obj body = parse_block(root);
2258
+ stack.pop_back();
2259
+ return SASS_MEMORY_NEW(For, for_source_position, var, lower_bound, upper_bound, body, inclusive);
2260
+ }
2261
+
2262
+ // helper to parse a var token
2263
+ Token Parser::lex_variable()
2264
+ {
2265
+ // peek for dollar sign first
2266
+ if (!peek< exactly <'$'> >()) {
2267
+ css_error("Invalid CSS", " after ", ": expected \"$\", was ");
2268
+ }
2269
+ // we expect a simple identifier as the call name
2270
+ if (!lex< sequence < exactly <'$'>, identifier > >()) {
2271
+ lex< exactly <'$'> >(); // move pstate and position up
2272
+ css_error("Invalid CSS", " after ", ": expected identifier, was ");
2273
+ }
2274
+ // return object
2275
+ return token;
2276
+ }
2277
+ // helper to parse identifier
2278
+ Token Parser::lex_identifier()
2279
+ {
2280
+ // we expect a simple identifier as the call name
2281
+ if (!lex< identifier >()) { // ToDo: pstate wrong?
2282
+ css_error("Invalid CSS", " after ", ": expected identifier, was ");
2283
+ }
2284
+ // return object
2285
+ return token;
2286
+ }
2287
+
2288
+ Each_Obj Parser::parse_each_directive()
2289
+ {
2290
+ stack.push_back(Scope::Control);
2291
+ ParserState each_source_position = pstate;
2292
+ bool root = block_stack.back()->is_root();
2293
+ std::vector<std::string> vars;
2294
+ lex_variable();
2295
+ vars.push_back(Util::normalize_underscores(lexed));
2296
+ while (lex< exactly<','> >()) {
2297
+ if (!lex< variable >()) error("@each directive requires an iteration variable");
2298
+ vars.push_back(Util::normalize_underscores(lexed));
2299
+ }
2300
+ if (!lex< kwd_in >()) error("expected 'in' keyword in @each directive");
2301
+ Expression_Obj list = parse_list();
2302
+ Block_Obj body = parse_block(root);
2303
+ stack.pop_back();
2304
+ return SASS_MEMORY_NEW(Each, each_source_position, vars, list, body);
2305
+ }
2306
+
2307
+ // called after parsing `kwd_while_directive`
2308
+ While_Obj Parser::parse_while_directive()
2309
+ {
2310
+ stack.push_back(Scope::Control);
2311
+ bool root = block_stack.back()->is_root();
2312
+ // create the initial while call object
2313
+ While_Obj call = SASS_MEMORY_NEW(While, pstate, {}, {});
2314
+ // parse mandatory predicate
2315
+ Expression_Obj predicate = parse_list();
2316
+ List_Obj l = Cast<List>(predicate);
2317
+ if (!predicate || (l && !l->length())) {
2318
+ css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was ", false);
2319
+ }
2320
+ call->predicate(predicate);
2321
+ // parse mandatory block
2322
+ call->block(parse_block(root));
2323
+ // return ast node
2324
+ stack.pop_back();
2325
+ // return ast node
2326
+ return call.detach();
2327
+ }
2328
+
2329
+ // EO parse_while_directive
2330
+ Media_Block_Obj Parser::parse_media_block()
2331
+ {
2332
+ stack.push_back(Scope::Media);
2333
+ Media_Block_Obj media_block = SASS_MEMORY_NEW(Media_Block, pstate, {}, {});
2334
+
2335
+ media_block->media_queries(parse_media_queries());
2336
+
2337
+ Media_Block_Obj prev_media_block = last_media_block;
2338
+ last_media_block = media_block;
2339
+ media_block->block(parse_css_block());
2340
+ last_media_block = prev_media_block;
2341
+ stack.pop_back();
2342
+ return media_block.detach();
2343
+ }
2344
+
2345
+ List_Obj Parser::parse_media_queries()
2346
+ {
2347
+ advanceToNextToken();
2348
+ List_Obj queries = SASS_MEMORY_NEW(List, pstate, 0, SASS_COMMA);
2349
+ if (!peek_css < exactly <'{'> >()) queries->append(parse_media_query());
2350
+ while (lex_css < exactly <','> >()) queries->append(parse_media_query());
2351
+ queries->update_pstate(pstate);
2352
+ return queries.detach();
2353
+ }
2354
+
2355
+ // Expression* Parser::parse_media_query()
2356
+ Media_Query_Obj Parser::parse_media_query()
2357
+ {
2358
+ advanceToNextToken();
2359
+ Media_Query_Obj media_query = SASS_MEMORY_NEW(Media_Query, pstate);
2360
+ if (lex < kwd_not >()) { media_query->is_negated(true); lex < css_comments >(false); }
2361
+ else if (lex < kwd_only >()) { media_query->is_restricted(true); lex < css_comments >(false); }
2362
+
2363
+ if (lex < identifier_schema >()) media_query->media_type(parse_identifier_schema());
2364
+ else if (lex < identifier >()) media_query->media_type(parse_interpolated_chunk(lexed));
2365
+ else media_query->append(parse_media_expression());
2366
+
2367
+ while (lex_css < kwd_and >()) media_query->append(parse_media_expression());
2368
+ if (lex < identifier_schema >()) {
2369
+ String_Schema* schema = SASS_MEMORY_NEW(String_Schema, pstate);
2370
+ schema->append(media_query->media_type());
2371
+ schema->append(SASS_MEMORY_NEW(String_Constant, pstate, " "));
2372
+ schema->append(parse_identifier_schema());
2373
+ media_query->media_type(schema);
2374
+ }
2375
+ while (lex_css < kwd_and >()) media_query->append(parse_media_expression());
2376
+
2377
+ media_query->update_pstate(pstate);
2378
+
2379
+ return media_query;
2380
+ }
2381
+
2382
+ Media_Query_Expression_Obj Parser::parse_media_expression()
2383
+ {
2384
+ if (lex < identifier_schema >()) {
2385
+ String_Obj ss = parse_identifier_schema();
2386
+ return SASS_MEMORY_NEW(Media_Query_Expression, pstate, ss, {}, true);
2387
+ }
2388
+ if (!lex_css< exactly<'('> >()) {
2389
+ error("media query expression must begin with '('");
2390
+ }
2391
+ Expression_Obj feature;
2392
+ if (peek_css< exactly<')'> >()) {
2393
+ error("media feature required in media query expression");
2394
+ }
2395
+ feature = parse_expression();
2396
+ Expression_Obj expression;
2397
+ if (lex_css< exactly<':'> >()) {
2398
+ expression = parse_list(DELAYED);
2399
+ }
2400
+ if (!lex_css< exactly<')'> >()) {
2401
+ error("unclosed parenthesis in media query expression");
2402
+ }
2403
+ return SASS_MEMORY_NEW(Media_Query_Expression, feature->pstate(), feature, expression);
2404
+ }
2405
+
2406
+ // lexed after `kwd_supports_directive`
2407
+ // these are very similar to media blocks
2408
+ Supports_Block_Obj Parser::parse_supports_directive()
2409
+ {
2410
+ Supports_Condition_Obj cond = parse_supports_condition(/*top_level=*/true);
2411
+ // create the ast node object for the support queries
2412
+ Supports_Block_Obj query = SASS_MEMORY_NEW(Supports_Block, pstate, cond);
2413
+ // additional block is mandatory
2414
+ // parse inner block
2415
+ query->block(parse_block());
2416
+ // return ast node
2417
+ return query;
2418
+ }
2419
+
2420
+ // parse one query operation
2421
+ // may encounter nested queries
2422
+ Supports_Condition_Obj Parser::parse_supports_condition(bool top_level)
2423
+ {
2424
+ lex < css_whitespace >();
2425
+ Supports_Condition_Obj cond;
2426
+ if ((cond = parse_supports_negation())) return cond;
2427
+ if ((cond = parse_supports_operator(top_level))) return cond;
2428
+ if ((cond = parse_supports_interpolation())) return cond;
2429
+ return cond;
2430
+ }
2431
+
2432
+ Supports_Condition_Obj Parser::parse_supports_negation()
2433
+ {
2434
+ if (!lex < kwd_not >()) return {};
2435
+ Supports_Condition_Obj cond = parse_supports_condition_in_parens(/*parens_required=*/true);
2436
+ return SASS_MEMORY_NEW(Supports_Negation, pstate, cond);
2437
+ }
2438
+
2439
+ Supports_Condition_Obj Parser::parse_supports_operator(bool top_level)
2440
+ {
2441
+ Supports_Condition_Obj cond = parse_supports_condition_in_parens(/*parens_required=*/top_level);
2442
+ if (cond.isNull()) return {};
2443
+
2444
+ while (true) {
2445
+ Supports_Operator::Operand op = Supports_Operator::OR;
2446
+ if (lex < kwd_and >()) { op = Supports_Operator::AND; }
2447
+ else if(!lex < kwd_or >()) { break; }
2448
+
2449
+ lex < css_whitespace >();
2450
+ Supports_Condition_Obj right = parse_supports_condition_in_parens(/*parens_required=*/true);
2451
+
2452
+ // Supports_Condition* cc = SASS_MEMORY_NEW(Supports_Condition, *static_cast<Supports_Condition*>(cond));
2453
+ cond = SASS_MEMORY_NEW(Supports_Operator, pstate, cond, right, op);
2454
+ }
2455
+ return cond;
2456
+ }
2457
+
2458
+ Supports_Condition_Obj Parser::parse_supports_interpolation()
2459
+ {
2460
+ if (!lex < interpolant >()) return {};
2461
+
2462
+ String_Obj interp = parse_interpolated_chunk(lexed);
2463
+ if (!interp) return {};
2464
+
2465
+ return SASS_MEMORY_NEW(Supports_Interpolation, pstate, interp);
2466
+ }
2467
+
2468
+ // TODO: This needs some major work. Although feature conditions
2469
+ // look like declarations their semantics differ significantly
2470
+ Supports_Condition_Obj Parser::parse_supports_declaration()
2471
+ {
2472
+ Supports_Condition* cond;
2473
+ // parse something declaration like
2474
+ Expression_Obj feature = parse_expression();
2475
+ Expression_Obj expression;
2476
+ if (lex_css< exactly<':'> >()) {
2477
+ expression = parse_list(DELAYED);
2478
+ }
2479
+ if (!feature || !expression) error("@supports condition expected declaration");
2480
+ cond = SASS_MEMORY_NEW(Supports_Declaration,
2481
+ feature->pstate(),
2482
+ feature,
2483
+ expression);
2484
+ // ToDo: maybe we need an additional error condition?
2485
+ return cond;
2486
+ }
2487
+
2488
+ Supports_Condition_Obj Parser::parse_supports_condition_in_parens(bool parens_required)
2489
+ {
2490
+ Supports_Condition_Obj interp = parse_supports_interpolation();
2491
+ if (interp != nullptr) return interp;
2492
+
2493
+ if (!lex < exactly <'('> >()) {
2494
+ if (parens_required) {
2495
+ css_error("Invalid CSS", " after ", ": expected @supports condition (e.g. (display: flexbox)), was ", /*trim=*/false);
2496
+ } else {
2497
+ return {};
2498
+ }
2499
+ }
2500
+ lex < css_whitespace >();
2501
+
2502
+ Supports_Condition_Obj cond = parse_supports_condition(/*top_level=*/false);
2503
+ if (cond.isNull()) cond = parse_supports_declaration();
2504
+ if (!lex < exactly <')'> >()) error("unclosed parenthesis in @supports declaration");
2505
+
2506
+ lex < css_whitespace >();
2507
+ return cond;
2508
+ }
2509
+
2510
+ At_Root_Block_Obj Parser::parse_at_root_block()
2511
+ {
2512
+ stack.push_back(Scope::AtRoot);
2513
+ ParserState at_source_position = pstate;
2514
+ Block_Obj body;
2515
+ At_Root_Query_Obj expr;
2516
+ Lookahead lookahead_result;
2517
+ if (lex_css< exactly<'('> >()) {
2518
+ expr = parse_at_root_query();
2519
+ }
2520
+ if (peek_css < exactly<'{'> >()) {
2521
+ lex <optional_spaces>();
2522
+ body = parse_block(true);
2523
+ }
2524
+ else if ((lookahead_result = lookahead_for_selector(position)).found) {
2525
+ Ruleset_Obj r = parse_ruleset(lookahead_result);
2526
+ body = SASS_MEMORY_NEW(Block, r->pstate(), 1, true);
2527
+ body->append(r);
2528
+ }
2529
+ At_Root_Block_Obj at_root = SASS_MEMORY_NEW(At_Root_Block, at_source_position, body);
2530
+ if (!expr.isNull()) at_root->expression(expr);
2531
+ stack.pop_back();
2532
+ return at_root;
2533
+ }
2534
+
2535
+ At_Root_Query_Obj Parser::parse_at_root_query()
2536
+ {
2537
+ if (peek< exactly<')'> >()) error("at-root feature required in at-root expression");
2538
+
2539
+ if (!peek< alternatives< kwd_with_directive, kwd_without_directive > >()) {
2540
+ css_error("Invalid CSS", " after ", ": expected \"with\" or \"without\", was ");
2541
+ }
2542
+
2543
+ Expression_Obj feature = parse_list();
2544
+ if (!lex_css< exactly<':'> >()) error("style declaration must contain a value");
2545
+ Expression_Obj expression = parse_list();
2546
+ List_Obj value = SASS_MEMORY_NEW(List, feature->pstate(), 1);
2547
+
2548
+ if (expression->concrete_type() == Expression::LIST) {
2549
+ value = Cast<List>(expression);
2550
+ }
2551
+ else value->append(expression);
2552
+
2553
+ At_Root_Query_Obj cond = SASS_MEMORY_NEW(At_Root_Query,
2554
+ value->pstate(),
2555
+ feature,
2556
+ value);
2557
+ if (!lex_css< exactly<')'> >()) error("unclosed parenthesis in @at-root expression");
2558
+ return cond;
2559
+ }
2560
+
2561
+ Directive_Obj Parser::parse_special_directive()
2562
+ {
2563
+ std::string kwd(lexed);
2564
+
2565
+ if (lexed == "@else") error("Invalid CSS: @else must come after @if");
2566
+
2567
+ // this whole branch is never hit via spec tests
2568
+
2569
+ Directive* at_rule = SASS_MEMORY_NEW(Directive, pstate, kwd);
2570
+ Lookahead lookahead = lookahead_for_include(position);
2571
+ if (lookahead.found && !lookahead.has_interpolants) {
2572
+ at_rule->selector(parse_selector_list(false));
2573
+ }
2574
+
2575
+ lex < css_comments >(false);
2576
+
2577
+ if (lex < static_property >()) {
2578
+ at_rule->value(parse_interpolated_chunk(Token(lexed)));
2579
+ } else if (!(peek < alternatives < exactly<'{'>, exactly<'}'>, exactly<';'> > >())) {
2580
+ at_rule->value(parse_list());
2581
+ }
2582
+
2583
+ lex < css_comments >(false);
2584
+
2585
+ if (peek< exactly<'{'> >()) {
2586
+ at_rule->block(parse_block());
2587
+ }
2588
+
2589
+ return at_rule;
2590
+ }
2591
+
2592
+ // this whole branch is never hit via spec tests
2593
+ Directive_Obj Parser::parse_prefixed_directive()
2594
+ {
2595
+ std::string kwd(lexed);
2596
+
2597
+ if (lexed == "@else") error("Invalid CSS: @else must come after @if");
2598
+
2599
+ Directive_Obj at_rule = SASS_MEMORY_NEW(Directive, pstate, kwd);
2600
+ Lookahead lookahead = lookahead_for_include(position);
2601
+ if (lookahead.found && !lookahead.has_interpolants) {
2602
+ at_rule->selector(parse_selector_list(false));
2603
+ }
2604
+
2605
+ lex < css_comments >(false);
2606
+
2607
+ if (lex < static_property >()) {
2608
+ at_rule->value(parse_interpolated_chunk(Token(lexed)));
2609
+ } else if (!(peek < alternatives < exactly<'{'>, exactly<'}'>, exactly<';'> > >())) {
2610
+ at_rule->value(parse_list());
2611
+ }
2612
+
2613
+ lex < css_comments >(false);
2614
+
2615
+ if (peek< exactly<'{'> >()) {
2616
+ at_rule->block(parse_block());
2617
+ }
2618
+
2619
+ return at_rule;
2620
+ }
2621
+
2622
+
2623
+ Directive_Obj Parser::parse_directive()
2624
+ {
2625
+ Directive_Obj directive = SASS_MEMORY_NEW(Directive, pstate, lexed);
2626
+ String_Schema_Obj val = parse_almost_any_value();
2627
+ // strip left and right if they are of type string
2628
+ directive->value(val);
2629
+ if (peek< exactly<'{'> >()) {
2630
+ directive->block(parse_block());
2631
+ }
2632
+ return directive;
2633
+ }
2634
+
2635
+ Expression_Obj Parser::lex_interpolation()
2636
+ {
2637
+ if (lex < interpolant >(true) != NULL) {
2638
+ return parse_interpolated_chunk(lexed, true);
2639
+ }
2640
+ return {};
2641
+ }
2642
+
2643
+ Expression_Obj Parser::lex_interp_uri()
2644
+ {
2645
+ // create a string schema by lexing optional interpolations
2646
+ return lex_interp< re_string_uri_open, re_string_uri_close >();
2647
+ }
2648
+
2649
+ Expression_Obj Parser::lex_interp_string()
2650
+ {
2651
+ Expression_Obj rv;
2652
+ if ((rv = lex_interp< re_string_double_open, re_string_double_close >())) return rv;
2653
+ if ((rv = lex_interp< re_string_single_open, re_string_single_close >())) return rv;
2654
+ return rv;
2655
+ }
2656
+
2657
+ Expression_Obj Parser::lex_almost_any_value_chars()
2658
+ {
2659
+ const char* match =
2660
+ lex <
2661
+ one_plus <
2662
+ alternatives <
2663
+ sequence <
2664
+ exactly <'\\'>,
2665
+ any_char
2666
+ >,
2667
+ sequence <
2668
+ negate <
2669
+ sequence <
2670
+ exactly < url_kwd >,
2671
+ exactly <'('>
2672
+ >
2673
+ >,
2674
+ neg_class_char <
2675
+ almost_any_value_class
2676
+ >
2677
+ >,
2678
+ sequence <
2679
+ exactly <'/'>,
2680
+ negate <
2681
+ alternatives <
2682
+ exactly <'/'>,
2683
+ exactly <'*'>
2684
+ >
2685
+ >
2686
+ >,
2687
+ sequence <
2688
+ exactly <'\\'>,
2689
+ exactly <'#'>,
2690
+ negate <
2691
+ exactly <'{'>
2692
+ >
2693
+ >,
2694
+ sequence <
2695
+ exactly <'!'>,
2696
+ negate <
2697
+ alpha
2698
+ >
2699
+ >
2700
+ >
2701
+ >
2702
+ >(false);
2703
+ if (match) {
2704
+ return SASS_MEMORY_NEW(String_Constant, pstate, lexed);
2705
+ }
2706
+ return {};
2707
+ }
2708
+
2709
+ Expression_Obj Parser::lex_almost_any_value_token()
2710
+ {
2711
+ Expression_Obj rv;
2712
+ if (*position == 0) return {};
2713
+ if ((rv = lex_almost_any_value_chars())) return rv;
2714
+ // if ((rv = lex_block_comment())) return rv;
2715
+ // if ((rv = lex_single_line_comment())) return rv;
2716
+ if ((rv = lex_interp_string())) return rv;
2717
+ if ((rv = lex_interp_uri())) return rv;
2718
+ if ((rv = lex_interpolation())) return rv;
2719
+ if (lex< alternatives< hex, hex0 > >())
2720
+ { return lexed_hex_color(lexed); }
2721
+ return rv;
2722
+ }
2723
+
2724
+ String_Schema_Obj Parser::parse_almost_any_value()
2725
+ {
2726
+
2727
+ String_Schema_Obj schema = SASS_MEMORY_NEW(String_Schema, pstate);
2728
+ if (*position == 0) return {};
2729
+ lex < spaces >(false);
2730
+ Expression_Obj token = lex_almost_any_value_token();
2731
+ if (!token) return {};
2732
+ schema->append(token);
2733
+ if (*position == 0) {
2734
+ schema->rtrim();
2735
+ return schema.detach();
2736
+ }
2737
+
2738
+ while ((token = lex_almost_any_value_token())) {
2739
+ schema->append(token);
2740
+ }
2741
+
2742
+ lex < css_whitespace >();
2743
+
2744
+ schema->rtrim();
2745
+
2746
+ return schema.detach();
2747
+ }
2748
+
2749
+ Warning_Obj Parser::parse_warning()
2750
+ {
2751
+ if (stack.back() != Scope::Root &&
2752
+ stack.back() != Scope::Function &&
2753
+ stack.back() != Scope::Mixin &&
2754
+ stack.back() != Scope::Control &&
2755
+ stack.back() != Scope::Rules) {
2756
+ error("Illegal nesting: Only properties may be nested beneath properties.");
2757
+ }
2758
+ return SASS_MEMORY_NEW(Warning, pstate, parse_list(DELAYED));
2759
+ }
2760
+
2761
+ Error_Obj Parser::parse_error()
2762
+ {
2763
+ if (stack.back() != Scope::Root &&
2764
+ stack.back() != Scope::Function &&
2765
+ stack.back() != Scope::Mixin &&
2766
+ stack.back() != Scope::Control &&
2767
+ stack.back() != Scope::Rules) {
2768
+ error("Illegal nesting: Only properties may be nested beneath properties.");
2769
+ }
2770
+ return SASS_MEMORY_NEW(Error, pstate, parse_list(DELAYED));
2771
+ }
2772
+
2773
+ Debug_Obj Parser::parse_debug()
2774
+ {
2775
+ if (stack.back() != Scope::Root &&
2776
+ stack.back() != Scope::Function &&
2777
+ stack.back() != Scope::Mixin &&
2778
+ stack.back() != Scope::Control &&
2779
+ stack.back() != Scope::Rules) {
2780
+ error("Illegal nesting: Only properties may be nested beneath properties.");
2781
+ }
2782
+ return SASS_MEMORY_NEW(Debug, pstate, parse_list(DELAYED));
2783
+ }
2784
+
2785
+ Return_Obj Parser::parse_return_directive()
2786
+ {
2787
+ // check that we do not have an empty list (ToDo: check if we got all cases)
2788
+ if (peek_css < alternatives < exactly < ';' >, exactly < '}' >, end_of_file > >())
2789
+ { css_error("Invalid CSS", " after ", ": expected expression (e.g. 1px, bold), was "); }
2790
+ return SASS_MEMORY_NEW(Return, pstate, parse_list());
2791
+ }
2792
+
2793
+ Lookahead Parser::lookahead_for_selector(const char* start)
2794
+ {
2795
+ // init result struct
2796
+ Lookahead rv = Lookahead();
2797
+ // get start position
2798
+ const char* p = start ? start : position;
2799
+ // match in one big "regex"
2800
+ rv.error = p;
2801
+ if (const char* q =
2802
+ peek <
2803
+ re_selector_list
2804
+ >(p)
2805
+ ) {
2806
+ bool could_be_property = peek< sequence< exactly<'-'>, exactly<'-'> > >(p) != 0;
2807
+ bool could_be_escaped = false;
2808
+ while (p < q) {
2809
+ // did we have interpolations?
2810
+ if (*p == '#' && *(p+1) == '{') {
2811
+ rv.has_interpolants = true;
2812
+ p = q; break;
2813
+ }
2814
+ // A property that's ambiguous with a nested selector is interpreted as a
2815
+ // custom property.
2816
+ if (*p == ':' && !could_be_escaped) {
2817
+ rv.is_custom_property = could_be_property || p+1 == q || peek< space >(p+1);
2818
+ }
2819
+ could_be_escaped = *p == '\\';
2820
+ ++ p;
2821
+ }
2822
+ // store anyway }
2823
+
2824
+
2825
+ // ToDo: remove
2826
+ rv.error = q;
2827
+ rv.position = q;
2828
+ // check expected opening bracket
2829
+ // only after successfull matching
2830
+ if (peek < exactly<'{'> >(q)) rv.found = q;
2831
+ // else if (peek < end_of_file >(q)) rv.found = q;
2832
+ else if (peek < exactly<'('> >(q)) rv.found = q;
2833
+ // else if (peek < exactly<';'> >(q)) rv.found = q;
2834
+ // else if (peek < exactly<'}'> >(q)) rv.found = q;
2835
+ if (rv.found || *p == 0) rv.error = 0;
2836
+ }
2837
+
2838
+ rv.parsable = ! rv.has_interpolants;
2839
+
2840
+ // return result
2841
+ return rv;
2842
+
2843
+ }
2844
+ // EO lookahead_for_selector
2845
+
2846
+ // used in parse_block_nodes and parse_special_directive
2847
+ // ToDo: actual usage is still not really clear to me?
2848
+ Lookahead Parser::lookahead_for_include(const char* start)
2849
+ {
2850
+ // we actually just lookahead for a selector
2851
+ Lookahead rv = lookahead_for_selector(start);
2852
+ // but the "found" rules are different
2853
+ if (const char* p = rv.position) {
2854
+ // check for additional abort condition
2855
+ if (peek < exactly<';'> >(p)) rv.found = p;
2856
+ else if (peek < exactly<'}'> >(p)) rv.found = p;
2857
+ }
2858
+ // return result
2859
+ return rv;
2860
+ }
2861
+ // EO lookahead_for_include
2862
+
2863
+ // look ahead for a token with interpolation in it
2864
+ // we mostly use the result if there is an interpolation
2865
+ // everything that passes here gets parsed as one schema
2866
+ // meaning it will not be parsed as a space separated list
2867
+ Lookahead Parser::lookahead_for_value(const char* start)
2868
+ {
2869
+ // init result struct
2870
+ Lookahead rv = Lookahead();
2871
+ // get start position
2872
+ const char* p = start ? start : position;
2873
+ // match in one big "regex"
2874
+ if (const char* q =
2875
+ peek <
2876
+ non_greedy <
2877
+ alternatives <
2878
+ // consume whitespace
2879
+ block_comment, // spaces,
2880
+ // main tokens
2881
+ sequence <
2882
+ interpolant,
2883
+ optional <
2884
+ quoted_string
2885
+ >
2886
+ >,
2887
+ identifier,
2888
+ variable,
2889
+ // issue #442
2890
+ sequence <
2891
+ parenthese_scope,
2892
+ interpolant,
2893
+ optional <
2894
+ quoted_string
2895
+ >
2896
+ >
2897
+ >,
2898
+ sequence <
2899
+ // optional_spaces,
2900
+ alternatives <
2901
+ // end_of_file,
2902
+ exactly<'{'>,
2903
+ exactly<'}'>,
2904
+ exactly<';'>
2905
+ >
2906
+ >
2907
+ >
2908
+ >(p)
2909
+ ) {
2910
+ if (p == q) return rv;
2911
+ while (p < q) {
2912
+ // did we have interpolations?
2913
+ if (*p == '#' && *(p+1) == '{') {
2914
+ rv.has_interpolants = true;
2915
+ p = q; break;
2916
+ }
2917
+ ++ p;
2918
+ }
2919
+ // store anyway
2920
+ // ToDo: remove
2921
+ rv.position = q;
2922
+ // check expected opening bracket
2923
+ // only after successful matching
2924
+ if (peek < exactly<'{'> >(q)) rv.found = q;
2925
+ else if (peek < exactly<';'> >(q)) rv.found = q;
2926
+ else if (peek < exactly<'}'> >(q)) rv.found = q;
2927
+ }
2928
+
2929
+ // return result
2930
+ return rv;
2931
+ }
2932
+ // EO lookahead_for_value
2933
+
2934
+ void Parser::read_bom()
2935
+ {
2936
+ size_t skip = 0;
2937
+ std::string encoding;
2938
+ bool utf_8 = false;
2939
+ switch ((unsigned char) source[0]) {
2940
+ case 0xEF:
2941
+ skip = check_bom_chars(source, end, utf_8_bom, 3);
2942
+ encoding = "UTF-8";
2943
+ utf_8 = true;
2944
+ break;
2945
+ case 0xFE:
2946
+ skip = check_bom_chars(source, end, utf_16_bom_be, 2);
2947
+ encoding = "UTF-16 (big endian)";
2948
+ break;
2949
+ case 0xFF:
2950
+ skip = check_bom_chars(source, end, utf_16_bom_le, 2);
2951
+ skip += (skip ? check_bom_chars(source, end, utf_32_bom_le, 4) : 0);
2952
+ encoding = (skip == 2 ? "UTF-16 (little endian)" : "UTF-32 (little endian)");
2953
+ break;
2954
+ case 0x00:
2955
+ skip = check_bom_chars(source, end, utf_32_bom_be, 4);
2956
+ encoding = "UTF-32 (big endian)";
2957
+ break;
2958
+ case 0x2B:
2959
+ skip = check_bom_chars(source, end, utf_7_bom_1, 4)
2960
+ | check_bom_chars(source, end, utf_7_bom_2, 4)
2961
+ | check_bom_chars(source, end, utf_7_bom_3, 4)
2962
+ | check_bom_chars(source, end, utf_7_bom_4, 4)
2963
+ | check_bom_chars(source, end, utf_7_bom_5, 5);
2964
+ encoding = "UTF-7";
2965
+ break;
2966
+ case 0xF7:
2967
+ skip = check_bom_chars(source, end, utf_1_bom, 3);
2968
+ encoding = "UTF-1";
2969
+ break;
2970
+ case 0xDD:
2971
+ skip = check_bom_chars(source, end, utf_ebcdic_bom, 4);
2972
+ encoding = "UTF-EBCDIC";
2973
+ break;
2974
+ case 0x0E:
2975
+ skip = check_bom_chars(source, end, scsu_bom, 3);
2976
+ encoding = "SCSU";
2977
+ break;
2978
+ case 0xFB:
2979
+ skip = check_bom_chars(source, end, bocu_1_bom, 3);
2980
+ encoding = "BOCU-1";
2981
+ break;
2982
+ case 0x84:
2983
+ skip = check_bom_chars(source, end, gb_18030_bom, 4);
2984
+ encoding = "GB-18030";
2985
+ break;
2986
+ default: break;
2987
+ }
2988
+ if (skip > 0 && !utf_8) error("only UTF-8 documents are currently supported; your document appears to be " + encoding);
2989
+ position += skip;
2990
+ }
2991
+
2992
+ size_t check_bom_chars(const char* src, const char *end, const unsigned char* bom, size_t len)
2993
+ {
2994
+ size_t skip = 0;
2995
+ if (src + len > end) return 0;
2996
+ for (size_t i = 0; i < len; ++i, ++skip) {
2997
+ if ((unsigned char) src[i] != bom[i]) return 0;
2998
+ }
2999
+ return skip;
3000
+ }
3001
+
3002
+
3003
+ Expression_Obj Parser::fold_operands(Expression_Obj base, std::vector<Expression_Obj>& operands, Operand op)
3004
+ {
3005
+ for (size_t i = 0, S = operands.size(); i < S; ++i) {
3006
+ base = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), op, base, operands[i]);
3007
+ }
3008
+ return base;
3009
+ }
3010
+
3011
+ Expression_Obj Parser::fold_operands(Expression_Obj base, std::vector<Expression_Obj>& operands, std::vector<Operand>& ops, size_t i)
3012
+ {
3013
+ if (String_Schema* schema = Cast<String_Schema>(base)) {
3014
+ // return schema;
3015
+ if (schema->has_interpolants()) {
3016
+ if (i + 1 < operands.size() && (
3017
+ (ops[0].operand == Sass_OP::EQ)
3018
+ || (ops[0].operand == Sass_OP::ADD)
3019
+ || (ops[0].operand == Sass_OP::DIV)
3020
+ || (ops[0].operand == Sass_OP::MUL)
3021
+ || (ops[0].operand == Sass_OP::NEQ)
3022
+ || (ops[0].operand == Sass_OP::LT)
3023
+ || (ops[0].operand == Sass_OP::GT)
3024
+ || (ops[0].operand == Sass_OP::LTE)
3025
+ || (ops[0].operand == Sass_OP::GTE)
3026
+ )) {
3027
+ Expression_Obj rhs = fold_operands(operands[i], operands, ops, i + 1);
3028
+ rhs = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), ops[0], schema, rhs);
3029
+ return rhs;
3030
+ }
3031
+ // return schema;
3032
+ }
3033
+ }
3034
+
3035
+ for (size_t S = operands.size(); i < S; ++i) {
3036
+ if (String_Schema* schema = Cast<String_Schema>(operands[i])) {
3037
+ if (schema->has_interpolants()) {
3038
+ if (i + 1 < S) {
3039
+ // this whole branch is never hit via spec tests
3040
+ Expression_Obj rhs = fold_operands(operands[i+1], operands, ops, i + 2);
3041
+ rhs = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), ops[i], schema, rhs);
3042
+ base = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), ops[i], base, rhs);
3043
+ return base;
3044
+ }
3045
+ base = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), ops[i], base, operands[i]);
3046
+ return base;
3047
+ } else {
3048
+ base = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), ops[i], base, operands[i]);
3049
+ }
3050
+ } else {
3051
+ base = SASS_MEMORY_NEW(Binary_Expression, base->pstate(), ops[i], base, operands[i]);
3052
+ }
3053
+ Binary_Expression* b = Cast<Binary_Expression>(base.ptr());
3054
+ if (b && ops[i].operand == Sass_OP::DIV && b->left()->is_delayed() && b->right()->is_delayed()) {
3055
+ base->is_delayed(true);
3056
+ }
3057
+ }
3058
+ // nested binary expression are never to be delayed
3059
+ if (Binary_Expression* b = Cast<Binary_Expression>(base)) {
3060
+ if (Cast<Binary_Expression>(b->left())) base->set_delayed(false);
3061
+ if (Cast<Binary_Expression>(b->right())) base->set_delayed(false);
3062
+ }
3063
+ return base;
3064
+ }
3065
+
3066
+ void Parser::error(std::string msg, Position pos)
3067
+ {
3068
+ Position p(pos.line ? pos : before_token);
3069
+ ParserState pstate(path, source, p, Offset(0, 0));
3070
+ // `pstate.src` may not outlive stack unwind so we must copy it.
3071
+ char *src_copy = sass_copy_c_string(pstate.src);
3072
+ pstate.src = src_copy;
3073
+ traces.push_back(Backtrace(pstate));
3074
+ throw Exception::InvalidSass(pstate, traces, msg, src_copy);
3075
+ }
3076
+
3077
+ void Parser::error(std::string msg)
3078
+ {
3079
+ error(msg, pstate);
3080
+ }
3081
+
3082
+ // print a css parsing error with actual context information from parsed source
3083
+ void Parser::css_error(const std::string& msg, const std::string& prefix, const std::string& middle, const bool trim)
3084
+ {
3085
+ int max_len = 18;
3086
+ const char* end = this->end;
3087
+ while (*end != 0) ++ end;
3088
+ const char* pos = peek < optional_spaces >();
3089
+ if (!pos) pos = position;
3090
+
3091
+ const char* last_pos(pos);
3092
+ if (last_pos > source) {
3093
+ utf8::prior(last_pos, source);
3094
+ }
3095
+ // backup position to last significant char
3096
+ while (trim && last_pos > source && last_pos < end) {
3097
+ if (!Prelexer::is_space(*last_pos)) break;
3098
+ utf8::prior(last_pos, source);
3099
+ }
3100
+
3101
+ bool ellipsis_left = false;
3102
+ const char* pos_left(last_pos);
3103
+ const char* end_left(last_pos);
3104
+
3105
+ if (*pos_left) utf8::next(pos_left, end);
3106
+ if (*end_left) utf8::next(end_left, end);
3107
+ while (pos_left > source) {
3108
+ if (utf8::distance(pos_left, end_left) >= max_len) {
3109
+ utf8::prior(pos_left, source);
3110
+ ellipsis_left = *(pos_left) != '\n' &&
3111
+ *(pos_left) != '\r';
3112
+ utf8::next(pos_left, end);
3113
+ break;
3114
+ }
3115
+
3116
+ const char* prev = pos_left;
3117
+ utf8::prior(prev, source);
3118
+ if (*prev == '\r') break;
3119
+ if (*prev == '\n') break;
3120
+ pos_left = prev;
3121
+ }
3122
+ if (pos_left < source) {
3123
+ pos_left = source;
3124
+ }
3125
+
3126
+ bool ellipsis_right = false;
3127
+ const char* end_right(pos);
3128
+ const char* pos_right(pos);
3129
+ while (end_right < end) {
3130
+ if (utf8::distance(pos_right, end_right) > max_len) {
3131
+ ellipsis_left = *(pos_right) != '\n' &&
3132
+ *(pos_right) != '\r';
3133
+ break;
3134
+ }
3135
+ if (*end_right == '\r') break;
3136
+ if (*end_right == '\n') break;
3137
+ utf8::next(end_right, end);
3138
+ }
3139
+ // if (*end_right == 0) end_right ++;
3140
+
3141
+ std::string left(pos_left, end_left);
3142
+ std::string right(pos_right, end_right);
3143
+ size_t left_subpos = left.size() > 15 ? left.size() - 15 : 0;
3144
+ size_t right_subpos = right.size() > 15 ? right.size() - 15 : 0;
3145
+ if (left_subpos && ellipsis_left) left = ellipsis + left.substr(left_subpos);
3146
+ if (right_subpos && ellipsis_right) right = right.substr(right_subpos) + ellipsis;
3147
+ // Hotfix when source is null, probably due to interpolation parsing!?
3148
+ if (source == NULL || *source == 0) source = pstate.src;
3149
+ // now pass new message to the more generic error function
3150
+ error(msg + prefix + quote(left) + middle + quote(right));
3151
+ }
3152
+
3153
+ }