brakeman 4.4.0 → 4.5.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of brakeman might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGES.md +17 -0
- data/bundle/load.rb +7 -8
- data/bundle/ruby/2.5.0/gems/{ruby2ruby-2.4.1 → ruby2ruby-2.4.2}/History.rdoc +8 -0
- data/bundle/ruby/2.5.0/gems/{ruby2ruby-2.4.1 → ruby2ruby-2.4.2}/Manifest.txt +0 -0
- data/bundle/ruby/2.5.0/gems/{ruby2ruby-2.4.1 → ruby2ruby-2.4.2}/README.rdoc +0 -0
- data/bundle/ruby/2.5.0/gems/{ruby2ruby-2.4.1 → ruby2ruby-2.4.2}/lib/ruby2ruby.rb +34 -36
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.12.0 → ruby_parser-3.13.0}/History.rdoc +47 -0
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.12.0 → ruby_parser-3.13.0}/Manifest.txt +5 -4
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.12.0 → ruby_parser-3.13.0}/README.rdoc +0 -0
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.12.0 → ruby_parser-3.13.0}/compare/normalize.rb +29 -2
- data/bundle/ruby/2.5.0/gems/ruby_parser-3.13.0/debugging.md +18 -0
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.12.0 → ruby_parser-3.13.0}/lib/rp_extensions.rb +0 -7
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.12.0 → ruby_parser-3.13.0}/lib/rp_stringscanner.rb +0 -0
- data/bundle/ruby/2.5.0/gems/ruby_parser-3.13.0/lib/ruby20_parser.rb +6874 -0
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.12.0 → ruby_parser-3.13.0}/lib/ruby20_parser.y +284 -201
- data/bundle/ruby/2.5.0/gems/ruby_parser-3.13.0/lib/ruby21_parser.rb +6952 -0
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.12.0 → ruby_parser-3.13.0}/lib/ruby21_parser.y +281 -197
- data/bundle/ruby/2.5.0/gems/ruby_parser-3.13.0/lib/ruby22_parser.rb +6983 -0
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.12.0/lib/ruby_parser.yy → ruby_parser-3.13.0/lib/ruby22_parser.y} +280 -306
- data/bundle/ruby/2.5.0/gems/ruby_parser-3.13.0/lib/ruby23_parser.rb +6982 -0
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.12.0 → ruby_parser-3.13.0}/lib/ruby23_parser.y +282 -203
- data/bundle/ruby/2.5.0/gems/ruby_parser-3.13.0/lib/ruby24_parser.rb +6982 -0
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.12.0 → ruby_parser-3.13.0}/lib/ruby24_parser.y +282 -203
- data/bundle/ruby/2.5.0/gems/ruby_parser-3.13.0/lib/ruby25_parser.rb +6981 -0
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.12.0 → ruby_parser-3.13.0}/lib/ruby25_parser.y +282 -203
- data/bundle/ruby/2.5.0/gems/ruby_parser-3.13.0/lib/ruby26_parser.rb +6999 -0
- data/bundle/ruby/2.5.0/gems/ruby_parser-3.13.0/lib/ruby26_parser.y +2469 -0
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.12.0 → ruby_parser-3.13.0}/lib/ruby_lexer.rb +116 -118
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.12.0 → ruby_parser-3.13.0}/lib/ruby_lexer.rex +10 -8
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.12.0 → ruby_parser-3.13.0}/lib/ruby_lexer.rex.rb +8 -8
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.12.0 → ruby_parser-3.13.0}/lib/ruby_parser.rb +5 -7
- data/bundle/ruby/2.5.0/gems/ruby_parser-3.13.0/lib/ruby_parser.yy +2571 -0
- data/bundle/ruby/2.5.0/gems/ruby_parser-3.13.0/lib/ruby_parser_extras.rb +1360 -0
- data/bundle/ruby/2.5.0/gems/ruby_parser-3.13.0/tools/munge.rb +216 -0
- data/bundle/ruby/2.5.0/gems/ruby_parser-3.13.0/tools/ripper.rb +23 -0
- data/bundle/ruby/2.5.0/gems/ruby_parser-legacy-1.0.0/History.rdoc +6 -0
- data/bundle/ruby/2.5.0/gems/ruby_parser-legacy-1.0.0/Manifest.txt +19 -0
- data/bundle/ruby/2.5.0/gems/ruby_parser-legacy-1.0.0/README.rdoc +54 -0
- data/bundle/ruby/2.5.0/gems/ruby_parser-legacy-1.0.0/lib/ruby_parser/legacy.rb +5 -0
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.12.0/lib → ruby_parser-legacy-1.0.0/lib/ruby_parser/legacy}/ruby18_parser.rb +7 -6
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.12.0/lib → ruby_parser-legacy-1.0.0/lib/ruby_parser/legacy}/ruby18_parser.y +5 -4
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.12.0/lib → ruby_parser-legacy-1.0.0/lib/ruby_parser/legacy}/ruby19_parser.rb +7 -6
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.12.0/lib → ruby_parser-legacy-1.0.0/lib/ruby_parser/legacy}/ruby19_parser.y +5 -4
- data/bundle/ruby/2.5.0/gems/ruby_parser-legacy-1.0.0/lib/ruby_parser/legacy/ruby_lexer.rb +1412 -0
- data/bundle/ruby/2.5.0/gems/ruby_parser-legacy-1.0.0/lib/ruby_parser/legacy/ruby_lexer.rex +179 -0
- data/bundle/ruby/2.5.0/gems/ruby_parser-legacy-1.0.0/lib/ruby_parser/legacy/ruby_lexer.rex.rb +323 -0
- data/bundle/ruby/2.5.0/gems/ruby_parser-legacy-1.0.0/lib/ruby_parser/legacy/ruby_parser.rb +30 -0
- data/bundle/ruby/2.5.0/gems/{ruby_parser-3.12.0/lib → ruby_parser-legacy-1.0.0/lib/ruby_parser/legacy}/ruby_parser_extras.rb +43 -33
- data/bundle/ruby/2.5.0/gems/{safe_yaml-1.0.4 → safe_yaml-1.0.5}/CHANGES.md +5 -0
- data/bundle/ruby/2.5.0/gems/{safe_yaml-1.0.4 → safe_yaml-1.0.5}/Gemfile +0 -0
- data/bundle/ruby/2.5.0/gems/{safe_yaml-1.0.4 → safe_yaml-1.0.5}/LICENSE.txt +0 -0
- data/bundle/ruby/2.5.0/gems/{safe_yaml-1.0.4 → safe_yaml-1.0.5}/README.md +0 -0
- data/bundle/ruby/2.5.0/gems/{safe_yaml-1.0.4 → safe_yaml-1.0.5}/bundle_install_all_ruby_versions.sh +0 -0
- data/bundle/ruby/2.5.0/gems/{safe_yaml-1.0.4 → safe_yaml-1.0.5}/lib/safe_yaml.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{safe_yaml-1.0.4 → safe_yaml-1.0.5}/lib/safe_yaml/deep.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{safe_yaml-1.0.4 → safe_yaml-1.0.5}/lib/safe_yaml/libyaml_checker.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{safe_yaml-1.0.4 → safe_yaml-1.0.5}/lib/safe_yaml/load.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{safe_yaml-1.0.4 → safe_yaml-1.0.5}/lib/safe_yaml/parse/date.rb +2 -0
- data/bundle/ruby/2.5.0/gems/{safe_yaml-1.0.4 → safe_yaml-1.0.5}/lib/safe_yaml/parse/hexadecimal.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{safe_yaml-1.0.4 → safe_yaml-1.0.5}/lib/safe_yaml/parse/sexagesimal.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{safe_yaml-1.0.4 → safe_yaml-1.0.5}/lib/safe_yaml/psych_handler.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{safe_yaml-1.0.4 → safe_yaml-1.0.5}/lib/safe_yaml/psych_resolver.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{safe_yaml-1.0.4 → safe_yaml-1.0.5}/lib/safe_yaml/resolver.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{safe_yaml-1.0.4 → safe_yaml-1.0.5}/lib/safe_yaml/safe_to_ruby_visitor.rb +0 -0
- data/bundle/ruby/2.5.0/gems/safe_yaml-1.0.5/lib/safe_yaml/store.rb +39 -0
- data/bundle/ruby/2.5.0/gems/{safe_yaml-1.0.4 → safe_yaml-1.0.5}/lib/safe_yaml/syck_hack.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{safe_yaml-1.0.4 → safe_yaml-1.0.5}/lib/safe_yaml/syck_node_monkeypatch.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{safe_yaml-1.0.4 → safe_yaml-1.0.5}/lib/safe_yaml/syck_resolver.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{safe_yaml-1.0.4 → safe_yaml-1.0.5}/lib/safe_yaml/transform.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{safe_yaml-1.0.4 → safe_yaml-1.0.5}/lib/safe_yaml/transform/to_boolean.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{safe_yaml-1.0.4 → safe_yaml-1.0.5}/lib/safe_yaml/transform/to_date.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{safe_yaml-1.0.4 → safe_yaml-1.0.5}/lib/safe_yaml/transform/to_float.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{safe_yaml-1.0.4 → safe_yaml-1.0.5}/lib/safe_yaml/transform/to_integer.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{safe_yaml-1.0.4 → safe_yaml-1.0.5}/lib/safe_yaml/transform/to_nil.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{safe_yaml-1.0.4 → safe_yaml-1.0.5}/lib/safe_yaml/transform/to_symbol.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{safe_yaml-1.0.4 → safe_yaml-1.0.5}/lib/safe_yaml/transform/transformation_map.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{safe_yaml-1.0.4 → safe_yaml-1.0.5}/lib/safe_yaml/version.rb +1 -1
- data/bundle/ruby/2.5.0/gems/{safe_yaml-1.0.4 → safe_yaml-1.0.5}/run_specs_all_ruby_versions.sh +0 -0
- data/bundle/ruby/2.5.0/gems/{safe_yaml-1.0.4 → safe_yaml-1.0.5}/safe_yaml.gemspec +0 -0
- data/bundle/ruby/2.5.0/gems/{sexp_processor-4.11.0 → sexp_processor-4.12.0}/History.rdoc +8 -0
- data/bundle/ruby/2.5.0/gems/{sexp_processor-4.11.0 → sexp_processor-4.12.0}/Manifest.txt +0 -0
- data/bundle/ruby/2.5.0/gems/{sexp_processor-4.11.0 → sexp_processor-4.12.0}/README.rdoc +0 -0
- data/bundle/ruby/2.5.0/gems/{sexp_processor-4.11.0 → sexp_processor-4.12.0}/lib/composite_sexp_processor.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{sexp_processor-4.11.0 → sexp_processor-4.12.0}/lib/pt_testcase.rb +2 -2
- data/bundle/ruby/2.5.0/gems/{sexp_processor-4.11.0 → sexp_processor-4.12.0}/lib/sexp.rb +4 -4
- data/bundle/ruby/2.5.0/gems/{sexp_processor-4.11.0 → sexp_processor-4.12.0}/lib/sexp_processor.rb +1 -1
- data/bundle/ruby/2.5.0/gems/{sexp_processor-4.11.0 → sexp_processor-4.12.0}/lib/strict_sexp.rb +3 -3
- data/bundle/ruby/2.5.0/gems/{sexp_processor-4.11.0 → sexp_processor-4.12.0}/lib/unique.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/CHANGES +6 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/EXPRESSIONS.md +1 -1
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/Gemfile +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/LICENSE +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/README.md +1 -1
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/engine.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/erb/engine.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/erb/parser.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/erb/template.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/erb/trimming.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/exceptions.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/filter.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/filters/code_merger.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/filters/control_flow.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/filters/dynamic_inliner.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/filters/encoding.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/filters/eraser.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/filters/escapable.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/filters/multi_flattener.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/filters/remove_bom.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/filters/static_analyzer.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/filters/static_merger.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/filters/string_splitter.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/filters/validator.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/generator.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/generators/array.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/generators/array_buffer.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/generators/erb.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/generators/rails_output_buffer.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/generators/string_buffer.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/grammar.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/html/attribute_merger.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/html/attribute_remover.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/html/attribute_sorter.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/html/dispatcher.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/html/fast.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/html/filter.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/html/pretty.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/html/safe.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/map.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/mixins/dispatcher.rb +2 -1
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/mixins/engine_dsl.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/mixins/grammar_dsl.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/mixins/options.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/mixins/template.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/parser.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/static_analyzer.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/templates.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/templates/rails.rb +2 -2
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/templates/tilt.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/lib/temple/utils.rb +0 -0
- data/bundle/ruby/2.5.0/gems/temple-0.8.1/lib/temple/version.rb +3 -0
- data/bundle/ruby/2.5.0/gems/{temple-0.8.0 → temple-0.8.1}/temple.gemspec +0 -0
- data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.4.1 → unicode-display_width-1.5.0}/CHANGELOG.md +4 -0
- data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.4.1 → unicode-display_width-1.5.0}/MIT-LICENSE.txt +1 -1
- data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.4.1 → unicode-display_width-1.5.0}/README.md +10 -10
- data/bundle/ruby/2.5.0/gems/unicode-display_width-1.5.0/data/display_width.marshal.gz +0 -0
- data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.4.1 → unicode-display_width-1.5.0}/lib/unicode/display_width.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.4.1 → unicode-display_width-1.5.0}/lib/unicode/display_width/constants.rb +2 -2
- data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.4.1 → unicode-display_width-1.5.0}/lib/unicode/display_width/index.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.4.1 → unicode-display_width-1.5.0}/lib/unicode/display_width/no_string_ext.rb +0 -0
- data/bundle/ruby/2.5.0/gems/{unicode-display_width-1.4.1 → unicode-display_width-1.5.0}/lib/unicode/display_width/string_ext.rb +0 -0
- data/lib/brakeman/checks/base_check.rb +16 -0
- data/lib/brakeman/checks/check_content_tag.rb +12 -0
- data/lib/brakeman/checks/check_cross_site_scripting.rb +6 -6
- data/lib/brakeman/checks/check_evaluation.rb +0 -1
- data/lib/brakeman/checks/check_execute.rb +18 -0
- data/lib/brakeman/checks/check_send.rb +0 -1
- data/lib/brakeman/checks/check_session_manipulation.rb +0 -1
- data/lib/brakeman/checks/check_sql.rb +12 -3
- data/lib/brakeman/file_parser.rb +8 -4
- data/lib/brakeman/parsers/haml_embedded.rb +44 -0
- data/lib/brakeman/parsers/slim_embedded.rb +44 -0
- data/lib/brakeman/parsers/template_parser.rb +2 -4
- data/lib/brakeman/processors/alias_processor.rb +23 -1
- data/lib/brakeman/processors/lib/call_conversion_helper.rb +4 -0
- data/lib/brakeman/processors/slim_template_processor.rb +16 -0
- data/lib/brakeman/processors/template_alias_processor.rb +2 -2
- data/lib/brakeman/scanner.rb +11 -10
- data/lib/brakeman/tracker.rb +5 -1
- data/lib/brakeman/tracker/config.rb +32 -7
- data/lib/brakeman/util.rb +17 -0
- data/lib/brakeman/version.rb +1 -1
- metadata +157 -320
- data/bundle/ruby/2.5.0/gems/ruby_parser-3.12.0/lib/ruby20_parser.rb +0 -6687
- data/bundle/ruby/2.5.0/gems/ruby_parser-3.12.0/lib/ruby21_parser.rb +0 -6767
- data/bundle/ruby/2.5.0/gems/ruby_parser-3.12.0/lib/ruby22_parser.rb +0 -6803
- data/bundle/ruby/2.5.0/gems/ruby_parser-3.12.0/lib/ruby22_parser.y +0 -2376
- data/bundle/ruby/2.5.0/gems/ruby_parser-3.12.0/lib/ruby23_parser.rb +0 -6818
- data/bundle/ruby/2.5.0/gems/ruby_parser-3.12.0/lib/ruby24_parser.rb +0 -6818
- data/bundle/ruby/2.5.0/gems/ruby_parser-3.12.0/lib/ruby25_parser.rb +0 -6818
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/CODE_OF_CONDUCT.md +0 -10
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/CONTRIBUTING.md +0 -148
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/MIT-LICENSE +0 -20
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/README.md +0 -227
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/REVISION +0 -1
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/VERSION +0 -1
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/VERSION_DATE +0 -1
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/VERSION_NAME +0 -1
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/extra/sass-spec-ref.sh +0 -32
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/extra/update_watch.rb +0 -13
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/init.rb +0 -18
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass.rb +0 -109
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/cache_stores.rb +0 -15
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/cache_stores/base.rb +0 -88
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/cache_stores/chain.rb +0 -34
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/cache_stores/filesystem.rb +0 -60
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/cache_stores/memory.rb +0 -46
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/cache_stores/null.rb +0 -25
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/callbacks.rb +0 -67
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/css.rb +0 -408
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/deprecation.rb +0 -55
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/engine.rb +0 -1226
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/environment.rb +0 -215
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/error.rb +0 -198
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/exec.rb +0 -9
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/exec/base.rb +0 -199
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/exec/sass_convert.rb +0 -283
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/exec/sass_scss.rb +0 -440
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/features.rb +0 -47
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/importers.rb +0 -23
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/importers/base.rb +0 -182
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/importers/deprecated_path.rb +0 -51
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/importers/filesystem.rb +0 -219
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/logger.rb +0 -17
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/logger/base.rb +0 -36
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/logger/delayed.rb +0 -50
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/logger/log_level.rb +0 -45
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/media.rb +0 -210
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/plugin.rb +0 -134
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/plugin/compiler.rb +0 -582
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/plugin/configuration.rb +0 -134
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/plugin/generic.rb +0 -15
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/plugin/merb.rb +0 -48
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/plugin/rack.rb +0 -60
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/plugin/rails.rb +0 -47
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/plugin/staleness_checker.rb +0 -199
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/railtie.rb +0 -10
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/repl.rb +0 -57
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/root.rb +0 -7
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/script.rb +0 -66
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/script/css_lexer.rb +0 -33
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/script/css_parser.rb +0 -33
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/script/css_variable_warning.rb +0 -52
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/script/functions.rb +0 -2693
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/script/lexer.rb +0 -464
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/script/parser.rb +0 -832
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/script/tree.rb +0 -16
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/script/tree/funcall.rb +0 -313
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/script/tree/interpolation.rb +0 -223
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/script/tree/list_literal.rb +0 -104
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/script/tree/literal.rb +0 -49
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/script/tree/map_literal.rb +0 -64
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/script/tree/node.rb +0 -127
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/script/tree/operation.rb +0 -156
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/script/tree/selector.rb +0 -26
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/script/tree/string_interpolation.rb +0 -125
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/script/tree/unary_operation.rb +0 -69
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/script/tree/variable.rb +0 -57
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/script/value.rb +0 -11
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/script/value/arg_list.rb +0 -36
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/script/value/base.rb +0 -241
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/script/value/bool.rb +0 -35
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/script/value/color.rb +0 -698
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/script/value/helpers.rb +0 -272
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/script/value/list.rb +0 -113
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/script/value/map.rb +0 -70
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/script/value/null.rb +0 -44
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/script/value/number.rb +0 -563
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/script/value/string.rb +0 -138
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/scss.rb +0 -14
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/scss/css_parser.rb +0 -56
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/scss/parser.rb +0 -1254
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/scss/rx.rb +0 -140
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/scss/static_parser.rb +0 -373
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/selector.rb +0 -323
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/selector/abstract_sequence.rb +0 -111
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/selector/comma_sequence.rb +0 -191
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/selector/pseudo.rb +0 -266
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/selector/sequence.rb +0 -636
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/selector/simple.rb +0 -117
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/selector/simple_sequence.rb +0 -344
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/shared.rb +0 -76
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/source/map.rb +0 -213
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/source/position.rb +0 -39
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/source/range.rb +0 -41
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/stack.rb +0 -120
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/supports.rb +0 -225
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/at_root_node.rb +0 -83
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/charset_node.rb +0 -22
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/comment_node.rb +0 -82
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/content_node.rb +0 -9
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/css_import_node.rb +0 -68
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/debug_node.rb +0 -18
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/directive_node.rb +0 -59
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/each_node.rb +0 -24
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/error_node.rb +0 -18
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/extend_node.rb +0 -43
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/for_node.rb +0 -36
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/function_node.rb +0 -44
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/if_node.rb +0 -52
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/import_node.rb +0 -75
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/keyframe_rule_node.rb +0 -15
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/media_node.rb +0 -48
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/mixin_def_node.rb +0 -38
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/mixin_node.rb +0 -52
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/node.rb +0 -240
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/prop_node.rb +0 -170
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/return_node.rb +0 -19
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/root_node.rb +0 -44
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/rule_node.rb +0 -155
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/supports_node.rb +0 -38
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/trace_node.rb +0 -33
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/variable_node.rb +0 -36
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/visitors/base.rb +0 -72
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/visitors/check_nesting.rb +0 -173
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/visitors/convert.rb +0 -351
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/visitors/cssize.rb +0 -373
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/visitors/deep_copy.rb +0 -107
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/visitors/extend.rb +0 -70
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/visitors/perform.rb +0 -564
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/visitors/set_options.rb +0 -139
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/visitors/to_css.rb +0 -409
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/warn_node.rb +0 -18
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/tree/while_node.rb +0 -18
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/util.rb +0 -1375
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/util/cross_platform_random.rb +0 -19
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/util/multibyte_string_scanner.rb +0 -155
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/util/normalized_map.rb +0 -129
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/util/ordered_hash.rb +0 -192
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/util/subset_map.rb +0 -109
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/util/test.rb +0 -9
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/lib/sass/version.rb +0 -124
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/rails/init.rb +0 -1
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/CHANGELOG.md +0 -1
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/CONTRIBUTING.md +0 -38
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/Gemfile +0 -20
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/Guardfile +0 -8
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/LICENSE +0 -20
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/README.md +0 -349
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/Rakefile +0 -5
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/Vagrantfile +0 -96
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/lib/listen.rb +0 -54
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/lib/listen/adapter.rb +0 -327
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/lib/listen/adapters/bsd.rb +0 -75
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/lib/listen/adapters/darwin.rb +0 -48
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/lib/listen/adapters/linux.rb +0 -81
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/lib/listen/adapters/polling.rb +0 -58
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/lib/listen/adapters/windows.rb +0 -91
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/lib/listen/directory_record.rb +0 -406
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/lib/listen/listener.rb +0 -323
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/lib/listen/turnstile.rb +0 -32
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/lib/listen/version.rb +0 -3
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/listen.gemspec +0 -28
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/spec/listen/adapter_spec.rb +0 -149
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/spec/listen/adapters/bsd_spec.rb +0 -36
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/spec/listen/adapters/darwin_spec.rb +0 -37
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/spec/listen/adapters/linux_spec.rb +0 -47
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/spec/listen/adapters/polling_spec.rb +0 -68
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/spec/listen/adapters/windows_spec.rb +0 -30
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/spec/listen/directory_record_spec.rb +0 -1250
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/spec/listen/listener_spec.rb +0 -258
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/spec/listen/turnstile_spec.rb +0 -56
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/spec/listen_spec.rb +0 -67
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/spec/spec_helper.rb +0 -25
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/spec/support/adapter_helper.rb +0 -666
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/spec/support/directory_record_helper.rb +0 -57
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/spec/support/fixtures_helper.rb +0 -29
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/spec/support/listeners_helper.rb +0 -179
- data/bundle/ruby/2.5.0/gems/sass-3.4.25/vendor/listen/spec/support/platform_helper.rb +0 -15
- data/bundle/ruby/2.5.0/gems/temple-0.8.0/lib/temple/version.rb +0 -3
- data/bundle/ruby/2.5.0/gems/unicode-display_width-1.4.1/data/display_width.marshal.gz +0 -0
@@ -1,1226 +0,0 @@
|
|
1
|
-
require 'set'
|
2
|
-
require 'digest/sha1'
|
3
|
-
require 'sass/cache_stores'
|
4
|
-
require 'sass/deprecation'
|
5
|
-
require 'sass/source/position'
|
6
|
-
require 'sass/source/range'
|
7
|
-
require 'sass/source/map'
|
8
|
-
require 'sass/tree/node'
|
9
|
-
require 'sass/tree/root_node'
|
10
|
-
require 'sass/tree/rule_node'
|
11
|
-
require 'sass/tree/comment_node'
|
12
|
-
require 'sass/tree/prop_node'
|
13
|
-
require 'sass/tree/directive_node'
|
14
|
-
require 'sass/tree/media_node'
|
15
|
-
require 'sass/tree/supports_node'
|
16
|
-
require 'sass/tree/css_import_node'
|
17
|
-
require 'sass/tree/variable_node'
|
18
|
-
require 'sass/tree/mixin_def_node'
|
19
|
-
require 'sass/tree/mixin_node'
|
20
|
-
require 'sass/tree/trace_node'
|
21
|
-
require 'sass/tree/content_node'
|
22
|
-
require 'sass/tree/function_node'
|
23
|
-
require 'sass/tree/return_node'
|
24
|
-
require 'sass/tree/extend_node'
|
25
|
-
require 'sass/tree/if_node'
|
26
|
-
require 'sass/tree/while_node'
|
27
|
-
require 'sass/tree/for_node'
|
28
|
-
require 'sass/tree/each_node'
|
29
|
-
require 'sass/tree/debug_node'
|
30
|
-
require 'sass/tree/warn_node'
|
31
|
-
require 'sass/tree/import_node'
|
32
|
-
require 'sass/tree/charset_node'
|
33
|
-
require 'sass/tree/at_root_node'
|
34
|
-
require 'sass/tree/keyframe_rule_node'
|
35
|
-
require 'sass/tree/error_node'
|
36
|
-
require 'sass/tree/visitors/base'
|
37
|
-
require 'sass/tree/visitors/perform'
|
38
|
-
require 'sass/tree/visitors/cssize'
|
39
|
-
require 'sass/tree/visitors/extend'
|
40
|
-
require 'sass/tree/visitors/convert'
|
41
|
-
require 'sass/tree/visitors/to_css'
|
42
|
-
require 'sass/tree/visitors/deep_copy'
|
43
|
-
require 'sass/tree/visitors/set_options'
|
44
|
-
require 'sass/tree/visitors/check_nesting'
|
45
|
-
require 'sass/selector'
|
46
|
-
require 'sass/environment'
|
47
|
-
require 'sass/script'
|
48
|
-
require 'sass/scss'
|
49
|
-
require 'sass/stack'
|
50
|
-
require 'sass/error'
|
51
|
-
require 'sass/importers'
|
52
|
-
require 'sass/shared'
|
53
|
-
require 'sass/media'
|
54
|
-
require 'sass/supports'
|
55
|
-
|
56
|
-
module Sass
|
57
|
-
# A Sass mixin or function.
|
58
|
-
#
|
59
|
-
# `name`: `String`
|
60
|
-
# : The name of the mixin/function.
|
61
|
-
#
|
62
|
-
# `args`: `Array<(Script::Tree::Node, Script::Tree::Node)>`
|
63
|
-
# : The arguments for the mixin/function.
|
64
|
-
# Each element is a tuple containing the variable node of the argument
|
65
|
-
# and the parse tree for the default value of the argument.
|
66
|
-
#
|
67
|
-
# `splat`: `Script::Tree::Node?`
|
68
|
-
# : The variable node of the splat argument for this callable, or null.
|
69
|
-
#
|
70
|
-
# `environment`: {Sass::Environment}
|
71
|
-
# : The environment in which the mixin/function was defined.
|
72
|
-
# This is captured so that the mixin/function can have access
|
73
|
-
# to local variables defined in its scope.
|
74
|
-
#
|
75
|
-
# `tree`: `Array<Tree::Node>`
|
76
|
-
# : The parse tree for the mixin/function.
|
77
|
-
#
|
78
|
-
# `has_content`: `Boolean`
|
79
|
-
# : Whether the callable accepts a content block.
|
80
|
-
#
|
81
|
-
# `type`: `String`
|
82
|
-
# : The user-friendly name of the type of the callable.
|
83
|
-
Callable = Struct.new(:name, :args, :splat, :environment, :tree, :has_content, :type)
|
84
|
-
|
85
|
-
# This class handles the parsing and compilation of the Sass template.
|
86
|
-
# Example usage:
|
87
|
-
#
|
88
|
-
# template = File.read('stylesheets/sassy.sass')
|
89
|
-
# sass_engine = Sass::Engine.new(template)
|
90
|
-
# output = sass_engine.render
|
91
|
-
# puts output
|
92
|
-
class Engine
|
93
|
-
@@old_property_deprecation = Deprecation.new
|
94
|
-
|
95
|
-
# A line of Sass code.
|
96
|
-
#
|
97
|
-
# `text`: `String`
|
98
|
-
# : The text in the line, without any whitespace at the beginning or end.
|
99
|
-
#
|
100
|
-
# `tabs`: `Integer`
|
101
|
-
# : The level of indentation of the line.
|
102
|
-
#
|
103
|
-
# `index`: `Integer`
|
104
|
-
# : The line number in the original document.
|
105
|
-
#
|
106
|
-
# `offset`: `Integer`
|
107
|
-
# : The number of bytes in on the line that the text begins.
|
108
|
-
# This ends up being the number of bytes of leading whitespace.
|
109
|
-
#
|
110
|
-
# `filename`: `String`
|
111
|
-
# : The name of the file in which this line appeared.
|
112
|
-
#
|
113
|
-
# `children`: `Array<Line>`
|
114
|
-
# : The lines nested below this one.
|
115
|
-
#
|
116
|
-
# `comment_tab_str`: `String?`
|
117
|
-
# : The prefix indentation for this comment, if it is a comment.
|
118
|
-
class Line < Struct.new(:text, :tabs, :index, :offset, :filename, :children, :comment_tab_str)
|
119
|
-
def comment?
|
120
|
-
text[0] == COMMENT_CHAR && (text[1] == SASS_COMMENT_CHAR || text[1] == CSS_COMMENT_CHAR)
|
121
|
-
end
|
122
|
-
end
|
123
|
-
|
124
|
-
# The character that begins a CSS property.
|
125
|
-
PROPERTY_CHAR = ?:
|
126
|
-
|
127
|
-
# The character that designates the beginning of a comment,
|
128
|
-
# either Sass or CSS.
|
129
|
-
COMMENT_CHAR = ?/
|
130
|
-
|
131
|
-
# The character that follows the general COMMENT_CHAR and designates a Sass comment,
|
132
|
-
# which is not output as a CSS comment.
|
133
|
-
SASS_COMMENT_CHAR = ?/
|
134
|
-
|
135
|
-
# The character that indicates that a comment allows interpolation
|
136
|
-
# and should be preserved even in `:compressed` mode.
|
137
|
-
SASS_LOUD_COMMENT_CHAR = ?!
|
138
|
-
|
139
|
-
# The character that follows the general COMMENT_CHAR and designates a CSS comment,
|
140
|
-
# which is embedded in the CSS document.
|
141
|
-
CSS_COMMENT_CHAR = ?*
|
142
|
-
|
143
|
-
# The character used to denote a compiler directive.
|
144
|
-
DIRECTIVE_CHAR = ?@
|
145
|
-
|
146
|
-
# Designates a non-parsed rule.
|
147
|
-
ESCAPE_CHAR = ?\\
|
148
|
-
|
149
|
-
# Designates block as mixin definition rather than CSS rules to output
|
150
|
-
MIXIN_DEFINITION_CHAR = ?=
|
151
|
-
|
152
|
-
# Includes named mixin declared using MIXIN_DEFINITION_CHAR
|
153
|
-
MIXIN_INCLUDE_CHAR = ?+
|
154
|
-
|
155
|
-
# The regex that matches and extracts data from
|
156
|
-
# properties of the form `:name prop`.
|
157
|
-
PROPERTY_OLD = /^:([^\s=:"]+)\s*(?:\s+|$)(.*)/
|
158
|
-
|
159
|
-
# The default options for Sass::Engine.
|
160
|
-
# @api public
|
161
|
-
DEFAULT_OPTIONS = {
|
162
|
-
:style => :nested,
|
163
|
-
:load_paths => [],
|
164
|
-
:cache => true,
|
165
|
-
:cache_location => './.sass-cache',
|
166
|
-
:syntax => :sass,
|
167
|
-
:filesystem_importer => Sass::Importers::Filesystem
|
168
|
-
}.freeze
|
169
|
-
|
170
|
-
# Converts a Sass options hash into a standard form, filling in
|
171
|
-
# default values and resolving aliases.
|
172
|
-
#
|
173
|
-
# @param options [{Symbol => Object}] The options hash;
|
174
|
-
# see {file:SASS_REFERENCE.md#Options the Sass options documentation}
|
175
|
-
# @return [{Symbol => Object}] The normalized options hash.
|
176
|
-
# @private
|
177
|
-
def self.normalize_options(options)
|
178
|
-
options = DEFAULT_OPTIONS.merge(options.reject {|_k, v| v.nil?})
|
179
|
-
|
180
|
-
# If the `:filename` option is passed in without an importer,
|
181
|
-
# assume it's using the default filesystem importer.
|
182
|
-
options[:importer] ||= options[:filesystem_importer].new(".") if options[:filename]
|
183
|
-
|
184
|
-
# Tracks the original filename of the top-level Sass file
|
185
|
-
options[:original_filename] ||= options[:filename]
|
186
|
-
|
187
|
-
options[:cache_store] ||= Sass::CacheStores::Chain.new(
|
188
|
-
Sass::CacheStores::Memory.new, Sass::CacheStores::Filesystem.new(options[:cache_location]))
|
189
|
-
# Support both, because the docs said one and the other actually worked
|
190
|
-
# for quite a long time.
|
191
|
-
options[:line_comments] ||= options[:line_numbers]
|
192
|
-
|
193
|
-
options[:load_paths] = (options[:load_paths] + Sass.load_paths).map do |p|
|
194
|
-
next p unless p.is_a?(String) || (defined?(Pathname) && p.is_a?(Pathname))
|
195
|
-
options[:filesystem_importer].new(p.to_s)
|
196
|
-
end
|
197
|
-
|
198
|
-
# Remove any deprecated importers if the location is imported explicitly
|
199
|
-
options[:load_paths].reject! do |importer|
|
200
|
-
importer.is_a?(Sass::Importers::DeprecatedPath) &&
|
201
|
-
options[:load_paths].find do |other_importer|
|
202
|
-
other_importer.is_a?(Sass::Importers::Filesystem) &&
|
203
|
-
other_importer != importer &&
|
204
|
-
other_importer.root == importer.root
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
|
-
# Backwards compatibility
|
209
|
-
options[:property_syntax] ||= options[:attribute_syntax]
|
210
|
-
case options[:property_syntax]
|
211
|
-
when :alternate; options[:property_syntax] = :new
|
212
|
-
when :normal; options[:property_syntax] = :old
|
213
|
-
end
|
214
|
-
options[:sourcemap] = :auto if options[:sourcemap] == true
|
215
|
-
options[:sourcemap] = :none if options[:sourcemap] == false
|
216
|
-
|
217
|
-
options
|
218
|
-
end
|
219
|
-
|
220
|
-
# Returns the {Sass::Engine} for the given file.
|
221
|
-
# This is preferable to Sass::Engine.new when reading from a file
|
222
|
-
# because it properly sets up the Engine's metadata,
|
223
|
-
# enables parse-tree caching,
|
224
|
-
# and infers the syntax from the filename.
|
225
|
-
#
|
226
|
-
# @param filename [String] The path to the Sass or SCSS file
|
227
|
-
# @param options [{Symbol => Object}] The options hash;
|
228
|
-
# See {file:SASS_REFERENCE.md#Options the Sass options documentation}.
|
229
|
-
# @return [Sass::Engine] The Engine for the given Sass or SCSS file.
|
230
|
-
# @raise [Sass::SyntaxError] if there's an error in the document.
|
231
|
-
def self.for_file(filename, options)
|
232
|
-
had_syntax = options[:syntax]
|
233
|
-
|
234
|
-
if had_syntax
|
235
|
-
# Use what was explicitly specified
|
236
|
-
elsif filename =~ /\.scss$/
|
237
|
-
options.merge!(:syntax => :scss)
|
238
|
-
elsif filename =~ /\.sass$/
|
239
|
-
options.merge!(:syntax => :sass)
|
240
|
-
end
|
241
|
-
|
242
|
-
Sass::Engine.new(File.read(filename), options.merge(:filename => filename))
|
243
|
-
end
|
244
|
-
|
245
|
-
# The options for the Sass engine.
|
246
|
-
# See {file:SASS_REFERENCE.md#Options the Sass options documentation}.
|
247
|
-
#
|
248
|
-
# @return [{Symbol => Object}]
|
249
|
-
attr_reader :options
|
250
|
-
|
251
|
-
# Creates a new Engine. Note that Engine should only be used directly
|
252
|
-
# when compiling in-memory Sass code.
|
253
|
-
# If you're compiling a single Sass file from the filesystem,
|
254
|
-
# use \{Sass::Engine.for\_file}.
|
255
|
-
# If you're compiling multiple files from the filesystem,
|
256
|
-
# use {Sass::Plugin}.
|
257
|
-
#
|
258
|
-
# @param template [String] The Sass template.
|
259
|
-
# This template can be encoded using any encoding
|
260
|
-
# that can be converted to Unicode.
|
261
|
-
# If the template contains an `@charset` declaration,
|
262
|
-
# that overrides the Ruby encoding
|
263
|
-
# (see {file:SASS_REFERENCE.md#Encodings the encoding documentation})
|
264
|
-
# @param options [{Symbol => Object}] An options hash.
|
265
|
-
# See {file:SASS_REFERENCE.md#Options the Sass options documentation}.
|
266
|
-
# @see {Sass::Engine.for_file}
|
267
|
-
# @see {Sass::Plugin}
|
268
|
-
def initialize(template, options = {})
|
269
|
-
@options = self.class.normalize_options(options)
|
270
|
-
@template = template
|
271
|
-
@checked_encoding = false
|
272
|
-
@filename = nil
|
273
|
-
@line = nil
|
274
|
-
end
|
275
|
-
|
276
|
-
# Render the template to CSS.
|
277
|
-
#
|
278
|
-
# @return [String] The CSS
|
279
|
-
# @raise [Sass::SyntaxError] if there's an error in the document
|
280
|
-
# @raise [Encoding::UndefinedConversionError] if the source encoding
|
281
|
-
# cannot be converted to UTF-8
|
282
|
-
# @raise [ArgumentError] if the document uses an unknown encoding with `@charset`
|
283
|
-
def render
|
284
|
-
return _to_tree.render unless @options[:quiet]
|
285
|
-
Sass::Util.silence_sass_warnings {_to_tree.render}
|
286
|
-
end
|
287
|
-
|
288
|
-
# Render the template to CSS and return the source map.
|
289
|
-
#
|
290
|
-
# @param sourcemap_uri [String] The sourcemap URI to use in the
|
291
|
-
# `@sourceMappingURL` comment. If this is relative, it should be relative
|
292
|
-
# to the location of the CSS file.
|
293
|
-
# @return [(String, Sass::Source::Map)] The rendered CSS and the associated
|
294
|
-
# source map
|
295
|
-
# @raise [Sass::SyntaxError] if there's an error in the document, or if the
|
296
|
-
# public URL for this document couldn't be determined.
|
297
|
-
# @raise [Encoding::UndefinedConversionError] if the source encoding
|
298
|
-
# cannot be converted to UTF-8
|
299
|
-
# @raise [ArgumentError] if the document uses an unknown encoding with `@charset`
|
300
|
-
def render_with_sourcemap(sourcemap_uri)
|
301
|
-
return _render_with_sourcemap(sourcemap_uri) unless @options[:quiet]
|
302
|
-
Sass::Util.silence_sass_warnings {_render_with_sourcemap(sourcemap_uri)}
|
303
|
-
end
|
304
|
-
|
305
|
-
alias_method :to_css, :render
|
306
|
-
|
307
|
-
# Parses the document into its parse tree. Memoized.
|
308
|
-
#
|
309
|
-
# @return [Sass::Tree::Node] The root of the parse tree.
|
310
|
-
# @raise [Sass::SyntaxError] if there's an error in the document
|
311
|
-
def to_tree
|
312
|
-
@tree ||= if @options[:quiet]
|
313
|
-
Sass::Util.silence_sass_warnings {_to_tree}
|
314
|
-
else
|
315
|
-
_to_tree
|
316
|
-
end
|
317
|
-
end
|
318
|
-
|
319
|
-
# Returns the original encoding of the document,
|
320
|
-
# or `nil` under Ruby 1.8.
|
321
|
-
#
|
322
|
-
# @return [Encoding, nil]
|
323
|
-
# @raise [Encoding::UndefinedConversionError] if the source encoding
|
324
|
-
# cannot be converted to UTF-8
|
325
|
-
# @raise [ArgumentError] if the document uses an unknown encoding with `@charset`
|
326
|
-
def source_encoding
|
327
|
-
check_encoding!
|
328
|
-
@source_encoding
|
329
|
-
end
|
330
|
-
|
331
|
-
# Gets a set of all the documents
|
332
|
-
# that are (transitive) dependencies of this document,
|
333
|
-
# not including the document itself.
|
334
|
-
#
|
335
|
-
# @return [[Sass::Engine]] The dependency documents.
|
336
|
-
def dependencies
|
337
|
-
_dependencies(Set.new, engines = Set.new)
|
338
|
-
Sass::Util.array_minus(engines, [self])
|
339
|
-
end
|
340
|
-
|
341
|
-
# Helper for \{#dependencies}.
|
342
|
-
#
|
343
|
-
# @private
|
344
|
-
def _dependencies(seen, engines)
|
345
|
-
key = [@options[:filename], @options[:importer]]
|
346
|
-
return if seen.include?(key)
|
347
|
-
seen << key
|
348
|
-
engines << self
|
349
|
-
to_tree.grep(Tree::ImportNode) do |n|
|
350
|
-
next if n.css_import?
|
351
|
-
n.imported_file._dependencies(seen, engines)
|
352
|
-
end
|
353
|
-
end
|
354
|
-
|
355
|
-
private
|
356
|
-
|
357
|
-
def _render_with_sourcemap(sourcemap_uri)
|
358
|
-
filename = @options[:filename]
|
359
|
-
importer = @options[:importer]
|
360
|
-
sourcemap_dir = @options[:sourcemap_filename] &&
|
361
|
-
File.dirname(File.expand_path(@options[:sourcemap_filename]))
|
362
|
-
if filename.nil?
|
363
|
-
raise Sass::SyntaxError.new(<<ERR)
|
364
|
-
Error generating source map: couldn't determine public URL for the source stylesheet.
|
365
|
-
No filename is available so there's nothing for the source map to link to.
|
366
|
-
ERR
|
367
|
-
elsif importer.nil?
|
368
|
-
raise Sass::SyntaxError.new(<<ERR)
|
369
|
-
Error generating source map: couldn't determine public URL for "#{filename}".
|
370
|
-
Without a public URL, there's nothing for the source map to link to.
|
371
|
-
An importer was not set for this file.
|
372
|
-
ERR
|
373
|
-
elsif Sass::Util.silence_warnings do
|
374
|
-
sourcemap_dir = nil if @options[:sourcemap] == :file
|
375
|
-
importer.public_url(filename, sourcemap_dir).nil?
|
376
|
-
end
|
377
|
-
raise Sass::SyntaxError.new(<<ERR)
|
378
|
-
Error generating source map: couldn't determine public URL for "#{filename}".
|
379
|
-
Without a public URL, there's nothing for the source map to link to.
|
380
|
-
Custom importers should define the #public_url method.
|
381
|
-
ERR
|
382
|
-
end
|
383
|
-
|
384
|
-
rendered, sourcemap = _to_tree.render_with_sourcemap
|
385
|
-
compressed = @options[:style] == :compressed
|
386
|
-
rendered << "\n" if rendered[-1] != ?\n
|
387
|
-
rendered << "\n" unless compressed
|
388
|
-
rendered << "/*# sourceMappingURL="
|
389
|
-
rendered << Sass::Util.escape_uri(sourcemap_uri)
|
390
|
-
rendered << " */\n"
|
391
|
-
return rendered, sourcemap
|
392
|
-
end
|
393
|
-
|
394
|
-
def _to_tree
|
395
|
-
check_encoding!
|
396
|
-
|
397
|
-
if (@options[:cache] || @options[:read_cache]) &&
|
398
|
-
@options[:filename] && @options[:importer]
|
399
|
-
key = sassc_key
|
400
|
-
sha = Digest::SHA1.hexdigest(@template)
|
401
|
-
|
402
|
-
if (root = @options[:cache_store].retrieve(key, sha))
|
403
|
-
root.options = @options
|
404
|
-
return root
|
405
|
-
end
|
406
|
-
end
|
407
|
-
|
408
|
-
if @options[:syntax] == :scss
|
409
|
-
root = Sass::SCSS::Parser.new(@template, @options[:filename], @options[:importer]).parse
|
410
|
-
else
|
411
|
-
root = Tree::RootNode.new(@template)
|
412
|
-
append_children(root, tree(tabulate(@template)).first, true)
|
413
|
-
end
|
414
|
-
|
415
|
-
root.options = @options
|
416
|
-
if @options[:cache] && key && sha
|
417
|
-
begin
|
418
|
-
old_options = root.options
|
419
|
-
root.options = {}
|
420
|
-
@options[:cache_store].store(key, sha, root)
|
421
|
-
ensure
|
422
|
-
root.options = old_options
|
423
|
-
end
|
424
|
-
end
|
425
|
-
root
|
426
|
-
rescue SyntaxError => e
|
427
|
-
e.modify_backtrace(:filename => @options[:filename], :line => @line)
|
428
|
-
e.sass_template = @template
|
429
|
-
raise e
|
430
|
-
end
|
431
|
-
|
432
|
-
def sassc_key
|
433
|
-
@options[:cache_store].key(*@options[:importer].key(@options[:filename], @options))
|
434
|
-
end
|
435
|
-
|
436
|
-
def check_encoding!
|
437
|
-
return if @checked_encoding
|
438
|
-
@checked_encoding = true
|
439
|
-
@template, @source_encoding = Sass::Util.check_sass_encoding(@template)
|
440
|
-
end
|
441
|
-
|
442
|
-
def tabulate(string)
|
443
|
-
tab_str = nil
|
444
|
-
comment_tab_str = nil
|
445
|
-
first = true
|
446
|
-
lines = []
|
447
|
-
string.scan(/^[^\n]*?$/).each_with_index do |line, index|
|
448
|
-
index += (@options[:line] || 1)
|
449
|
-
if line.strip.empty?
|
450
|
-
lines.last.text << "\n" if lines.last && lines.last.comment?
|
451
|
-
next
|
452
|
-
end
|
453
|
-
|
454
|
-
line_tab_str = line[/^\s*/]
|
455
|
-
unless line_tab_str.empty?
|
456
|
-
if tab_str.nil?
|
457
|
-
comment_tab_str ||= line_tab_str
|
458
|
-
next if try_comment(line, lines.last, "", comment_tab_str, index)
|
459
|
-
comment_tab_str = nil
|
460
|
-
end
|
461
|
-
|
462
|
-
tab_str ||= line_tab_str
|
463
|
-
|
464
|
-
raise SyntaxError.new("Indenting at the beginning of the document is illegal.",
|
465
|
-
:line => index) if first
|
466
|
-
|
467
|
-
raise SyntaxError.new("Indentation can't use both tabs and spaces.",
|
468
|
-
:line => index) if tab_str.include?(?\s) && tab_str.include?(?\t)
|
469
|
-
end
|
470
|
-
first &&= !tab_str.nil?
|
471
|
-
if tab_str.nil?
|
472
|
-
lines << Line.new(line.strip, 0, index, 0, @options[:filename], [])
|
473
|
-
next
|
474
|
-
end
|
475
|
-
|
476
|
-
comment_tab_str ||= line_tab_str
|
477
|
-
if try_comment(line, lines.last, tab_str * lines.last.tabs, comment_tab_str, index)
|
478
|
-
next
|
479
|
-
else
|
480
|
-
comment_tab_str = nil
|
481
|
-
end
|
482
|
-
|
483
|
-
line_tabs = line_tab_str.scan(tab_str).size
|
484
|
-
if tab_str * line_tabs != line_tab_str
|
485
|
-
message = <<END.strip.tr("\n", ' ')
|
486
|
-
Inconsistent indentation: #{Sass::Shared.human_indentation line_tab_str, true} used for indentation,
|
487
|
-
but the rest of the document was indented using #{Sass::Shared.human_indentation tab_str}.
|
488
|
-
END
|
489
|
-
raise SyntaxError.new(message, :line => index)
|
490
|
-
end
|
491
|
-
|
492
|
-
lines << Line.new(line.strip, line_tabs, index, line_tab_str.size, @options[:filename], [])
|
493
|
-
end
|
494
|
-
lines
|
495
|
-
end
|
496
|
-
|
497
|
-
# @comment
|
498
|
-
def try_comment(line, last, tab_str, comment_tab_str, index)
|
499
|
-
return unless last && last.comment?
|
500
|
-
# Nested comment stuff must be at least one whitespace char deeper
|
501
|
-
# than the normal indentation
|
502
|
-
return unless line =~ /^#{tab_str}\s/
|
503
|
-
unless line =~ /^(?:#{comment_tab_str})(.*)$/
|
504
|
-
raise SyntaxError.new(<<MSG.strip.tr("\n", " "), :line => index)
|
505
|
-
Inconsistent indentation:
|
506
|
-
previous line was indented by #{Sass::Shared.human_indentation comment_tab_str},
|
507
|
-
but this line was indented by #{Sass::Shared.human_indentation line[/^\s*/]}.
|
508
|
-
MSG
|
509
|
-
end
|
510
|
-
|
511
|
-
last.comment_tab_str ||= comment_tab_str
|
512
|
-
last.text << "\n" << line
|
513
|
-
true
|
514
|
-
end
|
515
|
-
|
516
|
-
def tree(arr, i = 0)
|
517
|
-
return [], i if arr[i].nil?
|
518
|
-
|
519
|
-
base = arr[i].tabs
|
520
|
-
nodes = []
|
521
|
-
while (line = arr[i]) && line.tabs >= base
|
522
|
-
if line.tabs > base
|
523
|
-
raise SyntaxError.new(
|
524
|
-
"The line was indented #{line.tabs - base} levels deeper than the previous line.",
|
525
|
-
:line => line.index) if line.tabs > base + 1
|
526
|
-
|
527
|
-
nodes.last.children, i = tree(arr, i)
|
528
|
-
else
|
529
|
-
nodes << line
|
530
|
-
i += 1
|
531
|
-
end
|
532
|
-
end
|
533
|
-
return nodes, i
|
534
|
-
end
|
535
|
-
|
536
|
-
def build_tree(parent, line, root = false)
|
537
|
-
@line = line.index
|
538
|
-
@offset = line.offset
|
539
|
-
node_or_nodes = parse_line(parent, line, root)
|
540
|
-
|
541
|
-
Array(node_or_nodes).each do |node|
|
542
|
-
# Node is a symbol if it's non-outputting, like a variable assignment
|
543
|
-
next unless node.is_a? Tree::Node
|
544
|
-
|
545
|
-
node.line = line.index
|
546
|
-
node.filename = line.filename
|
547
|
-
|
548
|
-
append_children(node, line.children, false)
|
549
|
-
end
|
550
|
-
|
551
|
-
node_or_nodes
|
552
|
-
end
|
553
|
-
|
554
|
-
def append_children(parent, children, root)
|
555
|
-
continued_rule = nil
|
556
|
-
continued_comment = nil
|
557
|
-
children.each do |line|
|
558
|
-
child = build_tree(parent, line, root)
|
559
|
-
|
560
|
-
if child.is_a?(Tree::RuleNode)
|
561
|
-
if child.continued? && child.children.empty?
|
562
|
-
if continued_rule
|
563
|
-
continued_rule.add_rules child
|
564
|
-
else
|
565
|
-
continued_rule = child
|
566
|
-
end
|
567
|
-
next
|
568
|
-
elsif continued_rule
|
569
|
-
continued_rule.add_rules child
|
570
|
-
continued_rule.children = child.children
|
571
|
-
continued_rule, child = nil, continued_rule
|
572
|
-
end
|
573
|
-
elsif continued_rule
|
574
|
-
continued_rule = nil
|
575
|
-
end
|
576
|
-
|
577
|
-
if child.is_a?(Tree::CommentNode) && child.type == :silent
|
578
|
-
if continued_comment &&
|
579
|
-
child.line == continued_comment.line +
|
580
|
-
continued_comment.lines + 1
|
581
|
-
continued_comment.value.last.sub!(%r{ \*/\Z}, '')
|
582
|
-
child.value.first.gsub!(%r{\A/\*}, ' *')
|
583
|
-
continued_comment.value += ["\n"] + child.value
|
584
|
-
next
|
585
|
-
end
|
586
|
-
|
587
|
-
continued_comment = child
|
588
|
-
end
|
589
|
-
|
590
|
-
check_for_no_children(child)
|
591
|
-
validate_and_append_child(parent, child, line, root)
|
592
|
-
end
|
593
|
-
|
594
|
-
parent
|
595
|
-
end
|
596
|
-
|
597
|
-
def validate_and_append_child(parent, child, line, root)
|
598
|
-
case child
|
599
|
-
when Array
|
600
|
-
child.each {|c| validate_and_append_child(parent, c, line, root)}
|
601
|
-
when Tree::Node
|
602
|
-
parent << child
|
603
|
-
end
|
604
|
-
end
|
605
|
-
|
606
|
-
def check_for_no_children(node)
|
607
|
-
return unless node.is_a?(Tree::RuleNode) && node.children.empty?
|
608
|
-
Sass::Util.sass_warn(<<WARNING.strip)
|
609
|
-
WARNING on line #{node.line}#{" of #{node.filename}" if node.filename}:
|
610
|
-
This selector doesn't have any properties and will not be rendered.
|
611
|
-
WARNING
|
612
|
-
end
|
613
|
-
|
614
|
-
def parse_line(parent, line, root)
|
615
|
-
case line.text[0]
|
616
|
-
when PROPERTY_CHAR
|
617
|
-
if line.text[1] == PROPERTY_CHAR ||
|
618
|
-
(@options[:property_syntax] == :new &&
|
619
|
-
line.text =~ PROPERTY_OLD && $2.empty?)
|
620
|
-
# Support CSS3-style pseudo-elements,
|
621
|
-
# which begin with ::,
|
622
|
-
# as well as pseudo-classes
|
623
|
-
# if we're using the new property syntax
|
624
|
-
Tree::RuleNode.new(parse_interp(line.text), full_line_range(line))
|
625
|
-
else
|
626
|
-
name_start_offset = line.offset + 1 # +1 for the leading ':'
|
627
|
-
name, value = line.text.scan(PROPERTY_OLD)[0]
|
628
|
-
raise SyntaxError.new("Invalid property: \"#{line.text}\".",
|
629
|
-
:line => @line) if name.nil? || value.nil?
|
630
|
-
|
631
|
-
@@old_property_deprecation.warn(@options[:filename], @line, <<WARNING)
|
632
|
-
Old-style properties like "#{line.text}" are deprecated and will be an error in future versions of Sass.
|
633
|
-
Use "#{name}: #{value}" instead.
|
634
|
-
WARNING
|
635
|
-
|
636
|
-
value_start_offset = name_end_offset = name_start_offset + name.length
|
637
|
-
unless value.empty?
|
638
|
-
# +1 and -1 both compensate for the leading ':', which is part of line.text
|
639
|
-
value_start_offset = name_start_offset + line.text.index(value, name.length + 1) - 1
|
640
|
-
end
|
641
|
-
|
642
|
-
property = parse_property(name, parse_interp(name), value, :old, line, value_start_offset)
|
643
|
-
property.name_source_range = Sass::Source::Range.new(
|
644
|
-
Sass::Source::Position.new(@line, to_parser_offset(name_start_offset)),
|
645
|
-
Sass::Source::Position.new(@line, to_parser_offset(name_end_offset)),
|
646
|
-
@options[:filename], @options[:importer])
|
647
|
-
property
|
648
|
-
end
|
649
|
-
when ?$
|
650
|
-
parse_variable(line)
|
651
|
-
when COMMENT_CHAR
|
652
|
-
parse_comment(line)
|
653
|
-
when DIRECTIVE_CHAR
|
654
|
-
parse_directive(parent, line, root)
|
655
|
-
when ESCAPE_CHAR
|
656
|
-
Tree::RuleNode.new(parse_interp(line.text[1..-1]), full_line_range(line))
|
657
|
-
when MIXIN_DEFINITION_CHAR
|
658
|
-
parse_mixin_definition(line)
|
659
|
-
when MIXIN_INCLUDE_CHAR
|
660
|
-
if line.text[1].nil? || line.text[1] == ?\s
|
661
|
-
Tree::RuleNode.new(parse_interp(line.text), full_line_range(line))
|
662
|
-
else
|
663
|
-
parse_mixin_include(line, root)
|
664
|
-
end
|
665
|
-
else
|
666
|
-
parse_property_or_rule(line)
|
667
|
-
end
|
668
|
-
end
|
669
|
-
|
670
|
-
def parse_property_or_rule(line)
|
671
|
-
scanner = Sass::Util::MultibyteStringScanner.new(line.text)
|
672
|
-
hack_char = scanner.scan(/[:\*\.]|\#(?!\{)/)
|
673
|
-
offset = line.offset
|
674
|
-
offset += hack_char.length if hack_char
|
675
|
-
parser = Sass::SCSS::Parser.new(scanner,
|
676
|
-
@options[:filename], @options[:importer],
|
677
|
-
@line, to_parser_offset(offset))
|
678
|
-
|
679
|
-
unless (res = parser.parse_interp_ident)
|
680
|
-
parsed = parse_interp(line.text, line.offset)
|
681
|
-
return Tree::RuleNode.new(parsed, full_line_range(line))
|
682
|
-
end
|
683
|
-
|
684
|
-
ident_range = Sass::Source::Range.new(
|
685
|
-
Sass::Source::Position.new(@line, to_parser_offset(line.offset)),
|
686
|
-
Sass::Source::Position.new(@line, parser.offset),
|
687
|
-
@options[:filename], @options[:importer])
|
688
|
-
offset = parser.offset - 1
|
689
|
-
res.unshift(hack_char) if hack_char
|
690
|
-
|
691
|
-
# Handle comments after a property name but before the colon.
|
692
|
-
if (comment = scanner.scan(Sass::SCSS::RX::COMMENT))
|
693
|
-
res << comment
|
694
|
-
offset += comment.length
|
695
|
-
end
|
696
|
-
|
697
|
-
name = line.text[0...scanner.pos]
|
698
|
-
if (scanned = scanner.scan(/\s*:(?:\s+|$)/)) # test for a property
|
699
|
-
offset += scanned.length
|
700
|
-
property = parse_property(name, res, scanner.rest, :new, line, offset)
|
701
|
-
property.name_source_range = ident_range
|
702
|
-
property
|
703
|
-
else
|
704
|
-
res.pop if comment
|
705
|
-
|
706
|
-
if (trailing = (scanner.scan(/\s*#{Sass::SCSS::RX::COMMENT}/) ||
|
707
|
-
scanner.scan(/\s*#{Sass::SCSS::RX::SINGLE_LINE_COMMENT}/)))
|
708
|
-
trailing.strip!
|
709
|
-
end
|
710
|
-
interp_parsed = parse_interp(scanner.rest)
|
711
|
-
selector_range = Sass::Source::Range.new(
|
712
|
-
ident_range.start_pos,
|
713
|
-
Sass::Source::Position.new(@line, to_parser_offset(line.offset) + line.text.length),
|
714
|
-
@options[:filename], @options[:importer])
|
715
|
-
rule = Tree::RuleNode.new(res + interp_parsed, selector_range)
|
716
|
-
rule << Tree::CommentNode.new([trailing], :silent) if trailing
|
717
|
-
rule
|
718
|
-
end
|
719
|
-
end
|
720
|
-
|
721
|
-
# @comment
|
722
|
-
# rubocop:disable ParameterLists
|
723
|
-
def parse_property(name, parsed_name, value, prop, line, start_offset)
|
724
|
-
# rubocop:enable ParameterLists
|
725
|
-
if value.strip.empty?
|
726
|
-
expr = Sass::Script::Tree::Literal.new(Sass::Script::Value::String.new(""))
|
727
|
-
end_offset = start_offset
|
728
|
-
else
|
729
|
-
expr = parse_script(value,
|
730
|
-
:offset => to_parser_offset(start_offset),
|
731
|
-
:css_variable => name.start_with?("--"))
|
732
|
-
end_offset = expr.source_range.end_pos.offset - 1
|
733
|
-
end
|
734
|
-
|
735
|
-
node = Tree::PropNode.new(parse_interp(name), expr, prop)
|
736
|
-
node.value_source_range = Sass::Source::Range.new(
|
737
|
-
Sass::Source::Position.new(line.index, to_parser_offset(start_offset)),
|
738
|
-
Sass::Source::Position.new(line.index, to_parser_offset(end_offset)),
|
739
|
-
@options[:filename], @options[:importer])
|
740
|
-
if value.strip.empty? && line.children.empty?
|
741
|
-
raise SyntaxError.new(
|
742
|
-
"Invalid property: \"#{node.declaration}\" (no value)." +
|
743
|
-
node.pseudo_class_selector_message)
|
744
|
-
end
|
745
|
-
|
746
|
-
node
|
747
|
-
end
|
748
|
-
|
749
|
-
def parse_variable(line)
|
750
|
-
name, value, flags = line.text.scan(Script::MATCH)[0]
|
751
|
-
raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath variable declarations.",
|
752
|
-
:line => @line + 1) unless line.children.empty?
|
753
|
-
raise SyntaxError.new("Invalid variable: \"#{line.text}\".",
|
754
|
-
:line => @line) unless name && value
|
755
|
-
flags = flags ? flags.split(/\s+/) : []
|
756
|
-
if (invalid_flag = flags.find {|f| f != '!default' && f != '!global'})
|
757
|
-
raise SyntaxError.new("Invalid flag \"#{invalid_flag}\".", :line => @line)
|
758
|
-
end
|
759
|
-
|
760
|
-
# This workaround is needed for the case when the variable value is part of the identifier,
|
761
|
-
# otherwise we end up with the offset equal to the value index inside the name:
|
762
|
-
# $red_color: red;
|
763
|
-
var_lhs_length = 1 + name.length # 1 stands for '$'
|
764
|
-
index = line.text.index(value, line.offset + var_lhs_length) || 0
|
765
|
-
expr = parse_script(value, :offset => to_parser_offset(line.offset + index))
|
766
|
-
|
767
|
-
Tree::VariableNode.new(name, expr, flags.include?('!default'), flags.include?('!global'))
|
768
|
-
end
|
769
|
-
|
770
|
-
def parse_comment(line)
|
771
|
-
if line.text[1] == CSS_COMMENT_CHAR || line.text[1] == SASS_COMMENT_CHAR
|
772
|
-
silent = line.text[1] == SASS_COMMENT_CHAR
|
773
|
-
loud = !silent && line.text[2] == SASS_LOUD_COMMENT_CHAR
|
774
|
-
if silent
|
775
|
-
value = [line.text]
|
776
|
-
else
|
777
|
-
value = self.class.parse_interp(
|
778
|
-
line.text, line.index, to_parser_offset(line.offset), :filename => @filename)
|
779
|
-
end
|
780
|
-
value = Sass::Util.with_extracted_values(value) do |str|
|
781
|
-
str = str.gsub(/^#{line.comment_tab_str}/m, '')[2..-1] # get rid of // or /*
|
782
|
-
format_comment_text(str, silent)
|
783
|
-
end
|
784
|
-
type = if silent
|
785
|
-
:silent
|
786
|
-
elsif loud
|
787
|
-
:loud
|
788
|
-
else
|
789
|
-
:normal
|
790
|
-
end
|
791
|
-
comment = Tree::CommentNode.new(value, type)
|
792
|
-
comment.line = line.index
|
793
|
-
text = line.text.rstrip
|
794
|
-
if text.include?("\n")
|
795
|
-
end_offset = text.length - text.rindex("\n")
|
796
|
-
else
|
797
|
-
end_offset = to_parser_offset(line.offset + text.length)
|
798
|
-
end
|
799
|
-
comment.source_range = Sass::Source::Range.new(
|
800
|
-
Sass::Source::Position.new(@line, to_parser_offset(line.offset)),
|
801
|
-
Sass::Source::Position.new(@line + text.count("\n"), end_offset),
|
802
|
-
@options[:filename])
|
803
|
-
comment
|
804
|
-
else
|
805
|
-
Tree::RuleNode.new(parse_interp(line.text), full_line_range(line))
|
806
|
-
end
|
807
|
-
end
|
808
|
-
|
809
|
-
DIRECTIVES = Set[:mixin, :include, :function, :return, :debug, :warn, :for,
|
810
|
-
:each, :while, :if, :else, :extend, :import, :media, :charset, :content,
|
811
|
-
:at_root, :error]
|
812
|
-
|
813
|
-
def parse_directive(parent, line, root)
|
814
|
-
directive, whitespace, value = line.text[1..-1].split(/(\s+)/, 2)
|
815
|
-
raise SyntaxError.new("Invalid directive: '@'.") unless directive
|
816
|
-
offset = directive.size + whitespace.size + 1 if whitespace
|
817
|
-
|
818
|
-
directive_name = directive.tr('-', '_').to_sym
|
819
|
-
if DIRECTIVES.include?(directive_name)
|
820
|
-
return send("parse_#{directive_name}_directive", parent, line, root, value, offset)
|
821
|
-
end
|
822
|
-
|
823
|
-
unprefixed_directive = directive.gsub(/^-[a-z0-9]+-/i, '')
|
824
|
-
if unprefixed_directive == 'supports'
|
825
|
-
parser = Sass::SCSS::Parser.new(value, @options[:filename], @line)
|
826
|
-
return Tree::SupportsNode.new(directive, parser.parse_supports_condition)
|
827
|
-
end
|
828
|
-
|
829
|
-
Tree::DirectiveNode.new(
|
830
|
-
value.nil? ? ["@#{directive}"] : ["@#{directive} "] + parse_interp(value, offset))
|
831
|
-
end
|
832
|
-
|
833
|
-
def parse_while_directive(parent, line, root, value, offset)
|
834
|
-
raise SyntaxError.new("Invalid while directive '@while': expected expression.") unless value
|
835
|
-
Tree::WhileNode.new(parse_script(value, :offset => offset))
|
836
|
-
end
|
837
|
-
|
838
|
-
def parse_if_directive(parent, line, root, value, offset)
|
839
|
-
raise SyntaxError.new("Invalid if directive '@if': expected expression.") unless value
|
840
|
-
Tree::IfNode.new(parse_script(value, :offset => offset))
|
841
|
-
end
|
842
|
-
|
843
|
-
def parse_debug_directive(parent, line, root, value, offset)
|
844
|
-
raise SyntaxError.new("Invalid debug directive '@debug': expected expression.") unless value
|
845
|
-
raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath debug directives.",
|
846
|
-
:line => @line + 1) unless line.children.empty?
|
847
|
-
offset = line.offset + line.text.index(value).to_i
|
848
|
-
Tree::DebugNode.new(parse_script(value, :offset => offset))
|
849
|
-
end
|
850
|
-
|
851
|
-
def parse_error_directive(parent, line, root, value, offset)
|
852
|
-
raise SyntaxError.new("Invalid error directive '@error': expected expression.") unless value
|
853
|
-
raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath error directives.",
|
854
|
-
:line => @line + 1) unless line.children.empty?
|
855
|
-
offset = line.offset + line.text.index(value).to_i
|
856
|
-
Tree::ErrorNode.new(parse_script(value, :offset => offset))
|
857
|
-
end
|
858
|
-
|
859
|
-
def parse_extend_directive(parent, line, root, value, offset)
|
860
|
-
raise SyntaxError.new("Invalid extend directive '@extend': expected expression.") unless value
|
861
|
-
raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath extend directives.",
|
862
|
-
:line => @line + 1) unless line.children.empty?
|
863
|
-
optional = !!value.gsub!(/\s+#{Sass::SCSS::RX::OPTIONAL}$/, '')
|
864
|
-
offset = line.offset + line.text.index(value).to_i
|
865
|
-
interp_parsed = parse_interp(value, offset)
|
866
|
-
selector_range = Sass::Source::Range.new(
|
867
|
-
Sass::Source::Position.new(@line, to_parser_offset(offset)),
|
868
|
-
Sass::Source::Position.new(@line, to_parser_offset(line.offset) + line.text.length),
|
869
|
-
@options[:filename], @options[:importer]
|
870
|
-
)
|
871
|
-
Tree::ExtendNode.new(interp_parsed, optional, selector_range)
|
872
|
-
end
|
873
|
-
|
874
|
-
def parse_warn_directive(parent, line, root, value, offset)
|
875
|
-
raise SyntaxError.new("Invalid warn directive '@warn': expected expression.") unless value
|
876
|
-
raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath warn directives.",
|
877
|
-
:line => @line + 1) unless line.children.empty?
|
878
|
-
offset = line.offset + line.text.index(value).to_i
|
879
|
-
Tree::WarnNode.new(parse_script(value, :offset => offset))
|
880
|
-
end
|
881
|
-
|
882
|
-
def parse_return_directive(parent, line, root, value, offset)
|
883
|
-
raise SyntaxError.new("Invalid @return: expected expression.") unless value
|
884
|
-
raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath return directives.",
|
885
|
-
:line => @line + 1) unless line.children.empty?
|
886
|
-
offset = line.offset + line.text.index(value).to_i
|
887
|
-
Tree::ReturnNode.new(parse_script(value, :offset => offset))
|
888
|
-
end
|
889
|
-
|
890
|
-
def parse_charset_directive(parent, line, root, value, offset)
|
891
|
-
name = value && value[/\A(["'])(.*)\1\Z/, 2] # "
|
892
|
-
raise SyntaxError.new("Invalid charset directive '@charset': expected string.") unless name
|
893
|
-
raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath charset directives.",
|
894
|
-
:line => @line + 1) unless line.children.empty?
|
895
|
-
Tree::CharsetNode.new(name)
|
896
|
-
end
|
897
|
-
|
898
|
-
def parse_media_directive(parent, line, root, value, offset)
|
899
|
-
parser = Sass::SCSS::Parser.new(value,
|
900
|
-
@options[:filename], @options[:importer],
|
901
|
-
@line, to_parser_offset(@offset))
|
902
|
-
offset = line.offset + line.text.index('media').to_i - 1
|
903
|
-
parsed_media_query_list = parser.parse_media_query_list.to_a
|
904
|
-
node = Tree::MediaNode.new(parsed_media_query_list)
|
905
|
-
node.source_range = Sass::Source::Range.new(
|
906
|
-
Sass::Source::Position.new(@line, to_parser_offset(offset)),
|
907
|
-
Sass::Source::Position.new(@line, to_parser_offset(line.offset) + line.text.length),
|
908
|
-
@options[:filename], @options[:importer])
|
909
|
-
node
|
910
|
-
end
|
911
|
-
|
912
|
-
def parse_at_root_directive(parent, line, root, value, offset)
|
913
|
-
return Sass::Tree::AtRootNode.new unless value
|
914
|
-
|
915
|
-
if value.start_with?('(')
|
916
|
-
parser = Sass::SCSS::Parser.new(value,
|
917
|
-
@options[:filename], @options[:importer],
|
918
|
-
@line, to_parser_offset(@offset))
|
919
|
-
offset = line.offset + line.text.index('at-root').to_i - 1
|
920
|
-
return Tree::AtRootNode.new(parser.parse_at_root_query)
|
921
|
-
end
|
922
|
-
|
923
|
-
at_root_node = Tree::AtRootNode.new
|
924
|
-
parsed = parse_interp(value, offset)
|
925
|
-
rule_node = Tree::RuleNode.new(parsed, full_line_range(line))
|
926
|
-
|
927
|
-
# The caller expects to automatically add children to the returned node
|
928
|
-
# and we want it to add children to the rule node instead, so we
|
929
|
-
# manually handle the wiring here and return nil so the caller doesn't
|
930
|
-
# duplicate our efforts.
|
931
|
-
append_children(rule_node, line.children, false)
|
932
|
-
at_root_node << rule_node
|
933
|
-
parent << at_root_node
|
934
|
-
nil
|
935
|
-
end
|
936
|
-
|
937
|
-
def parse_for_directive(parent, line, root, value, offset)
|
938
|
-
var, from_expr, to_name, to_expr =
|
939
|
-
value.scan(/^([^\s]+)\s+from\s+(.+)\s+(to|through)\s+(.+)$/).first
|
940
|
-
|
941
|
-
if var.nil? # scan failed, try to figure out why for error message
|
942
|
-
if value !~ /^[^\s]+/
|
943
|
-
expected = "variable name"
|
944
|
-
elsif value !~ /^[^\s]+\s+from\s+.+/
|
945
|
-
expected = "'from <expr>'"
|
946
|
-
else
|
947
|
-
expected = "'to <expr>' or 'through <expr>'"
|
948
|
-
end
|
949
|
-
raise SyntaxError.new("Invalid for directive '@for #{value}': expected #{expected}.")
|
950
|
-
end
|
951
|
-
raise SyntaxError.new("Invalid variable \"#{var}\".") unless var =~ Script::VALIDATE
|
952
|
-
|
953
|
-
var = var[1..-1]
|
954
|
-
parsed_from = parse_script(from_expr, :offset => line.offset + line.text.index(from_expr))
|
955
|
-
parsed_to = parse_script(to_expr, :offset => line.offset + line.text.index(to_expr))
|
956
|
-
Tree::ForNode.new(var, parsed_from, parsed_to, to_name == 'to')
|
957
|
-
end
|
958
|
-
|
959
|
-
def parse_each_directive(parent, line, root, value, offset)
|
960
|
-
vars, list_expr = value.scan(/^([^\s]+(?:\s*,\s*[^\s]+)*)\s+in\s+(.+)$/).first
|
961
|
-
|
962
|
-
if vars.nil? # scan failed, try to figure out why for error message
|
963
|
-
if value !~ /^[^\s]+/
|
964
|
-
expected = "variable name"
|
965
|
-
elsif value !~ /^[^\s]+(?:\s*,\s*[^\s]+)*[^\s]+\s+from\s+.+/
|
966
|
-
expected = "'in <expr>'"
|
967
|
-
end
|
968
|
-
raise SyntaxError.new("Invalid each directive '@each #{value}': expected #{expected}.")
|
969
|
-
end
|
970
|
-
|
971
|
-
vars = vars.split(',').map do |var|
|
972
|
-
var.strip!
|
973
|
-
raise SyntaxError.new("Invalid variable \"#{var}\".") unless var =~ Script::VALIDATE
|
974
|
-
var[1..-1]
|
975
|
-
end
|
976
|
-
|
977
|
-
parsed_list = parse_script(list_expr, :offset => line.offset + line.text.index(list_expr))
|
978
|
-
Tree::EachNode.new(vars, parsed_list)
|
979
|
-
end
|
980
|
-
|
981
|
-
def parse_else_directive(parent, line, root, value, offset)
|
982
|
-
previous = parent.children.last
|
983
|
-
raise SyntaxError.new("@else must come after @if.") unless previous.is_a?(Tree::IfNode)
|
984
|
-
|
985
|
-
if value
|
986
|
-
if value !~ /^if\s+(.+)/
|
987
|
-
raise SyntaxError.new("Invalid else directive '@else #{value}': expected 'if <expr>'.")
|
988
|
-
end
|
989
|
-
expr = parse_script($1, :offset => line.offset + line.text.index($1))
|
990
|
-
end
|
991
|
-
|
992
|
-
node = Tree::IfNode.new(expr)
|
993
|
-
append_children(node, line.children, false)
|
994
|
-
previous.add_else node
|
995
|
-
nil
|
996
|
-
end
|
997
|
-
|
998
|
-
def parse_import_directive(parent, line, root, value, offset)
|
999
|
-
raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath import directives.",
|
1000
|
-
:line => @line + 1) unless line.children.empty?
|
1001
|
-
|
1002
|
-
scanner = Sass::Util::MultibyteStringScanner.new(value)
|
1003
|
-
values = []
|
1004
|
-
|
1005
|
-
loop do
|
1006
|
-
unless (node = parse_import_arg(scanner, offset + scanner.pos))
|
1007
|
-
raise SyntaxError.new(
|
1008
|
-
"Invalid @import: expected file to import, was #{scanner.rest.inspect}",
|
1009
|
-
:line => @line)
|
1010
|
-
end
|
1011
|
-
values << node
|
1012
|
-
break unless scanner.scan(/,\s*/)
|
1013
|
-
end
|
1014
|
-
|
1015
|
-
if scanner.scan(/;/)
|
1016
|
-
raise SyntaxError.new("Invalid @import: expected end of line, was \";\".",
|
1017
|
-
:line => @line)
|
1018
|
-
end
|
1019
|
-
|
1020
|
-
values
|
1021
|
-
end
|
1022
|
-
|
1023
|
-
# @comment
|
1024
|
-
# rubocop:disable MethodLength
|
1025
|
-
def parse_import_arg(scanner, offset)
|
1026
|
-
return if scanner.eos?
|
1027
|
-
|
1028
|
-
if scanner.match?(/url\(/i)
|
1029
|
-
script_parser = Sass::Script::Parser.new(scanner, @line, to_parser_offset(offset), @options)
|
1030
|
-
str = script_parser.parse_string
|
1031
|
-
|
1032
|
-
if scanner.eos?
|
1033
|
-
end_pos = str.source_range.end_pos
|
1034
|
-
node = Tree::CssImportNode.new(str)
|
1035
|
-
else
|
1036
|
-
supports_parser = Sass::SCSS::Parser.new(scanner,
|
1037
|
-
@options[:filename], @options[:importer],
|
1038
|
-
@line, str.source_range.end_pos.offset)
|
1039
|
-
supports_condition = supports_parser.parse_supports_clause
|
1040
|
-
|
1041
|
-
if scanner.eos?
|
1042
|
-
node = Tree::CssImportNode.new(str, [], supports_condition)
|
1043
|
-
else
|
1044
|
-
media_parser = Sass::SCSS::Parser.new(scanner,
|
1045
|
-
@options[:filename], @options[:importer],
|
1046
|
-
@line, str.source_range.end_pos.offset)
|
1047
|
-
media = media_parser.parse_media_query_list
|
1048
|
-
end_pos = Sass::Source::Position.new(@line, media_parser.offset + 1)
|
1049
|
-
node = Tree::CssImportNode.new(str, media.to_a, supports_condition)
|
1050
|
-
end
|
1051
|
-
end
|
1052
|
-
|
1053
|
-
node.source_range = Sass::Source::Range.new(
|
1054
|
-
str.source_range.start_pos, end_pos,
|
1055
|
-
@options[:filename], @options[:importer])
|
1056
|
-
return node
|
1057
|
-
end
|
1058
|
-
|
1059
|
-
unless (quoted_val = scanner.scan(Sass::SCSS::RX::STRING))
|
1060
|
-
scanned = scanner.scan(/[^,;]+/)
|
1061
|
-
node = Tree::ImportNode.new(scanned)
|
1062
|
-
start_parser_offset = to_parser_offset(offset)
|
1063
|
-
node.source_range = Sass::Source::Range.new(
|
1064
|
-
Sass::Source::Position.new(@line, start_parser_offset),
|
1065
|
-
Sass::Source::Position.new(@line, start_parser_offset + scanned.length),
|
1066
|
-
@options[:filename], @options[:importer])
|
1067
|
-
return node
|
1068
|
-
end
|
1069
|
-
|
1070
|
-
start_offset = offset
|
1071
|
-
offset += scanner.matched.length
|
1072
|
-
val = Sass::Script::Value::String.value(scanner[1] || scanner[2])
|
1073
|
-
scanned = scanner.scan(/\s*/)
|
1074
|
-
if !scanner.match?(/[,;]|$/)
|
1075
|
-
offset += scanned.length if scanned
|
1076
|
-
media_parser = Sass::SCSS::Parser.new(scanner,
|
1077
|
-
@options[:filename], @options[:importer], @line, offset)
|
1078
|
-
media = media_parser.parse_media_query_list
|
1079
|
-
node = Tree::CssImportNode.new(quoted_val, media.to_a)
|
1080
|
-
node.source_range = Sass::Source::Range.new(
|
1081
|
-
Sass::Source::Position.new(@line, to_parser_offset(start_offset)),
|
1082
|
-
Sass::Source::Position.new(@line, media_parser.offset),
|
1083
|
-
@options[:filename], @options[:importer])
|
1084
|
-
elsif val =~ %r{^(https?:)?//}
|
1085
|
-
node = Tree::CssImportNode.new(quoted_val)
|
1086
|
-
node.source_range = Sass::Source::Range.new(
|
1087
|
-
Sass::Source::Position.new(@line, to_parser_offset(start_offset)),
|
1088
|
-
Sass::Source::Position.new(@line, to_parser_offset(offset)),
|
1089
|
-
@options[:filename], @options[:importer])
|
1090
|
-
else
|
1091
|
-
node = Tree::ImportNode.new(val)
|
1092
|
-
node.source_range = Sass::Source::Range.new(
|
1093
|
-
Sass::Source::Position.new(@line, to_parser_offset(start_offset)),
|
1094
|
-
Sass::Source::Position.new(@line, to_parser_offset(offset)),
|
1095
|
-
@options[:filename], @options[:importer])
|
1096
|
-
end
|
1097
|
-
node
|
1098
|
-
end
|
1099
|
-
# @comment
|
1100
|
-
# rubocop:enable MethodLength
|
1101
|
-
|
1102
|
-
def parse_mixin_directive(parent, line, root, value, offset)
|
1103
|
-
parse_mixin_definition(line)
|
1104
|
-
end
|
1105
|
-
|
1106
|
-
MIXIN_DEF_RE = /^(?:=|@mixin)\s*(#{Sass::SCSS::RX::IDENT})(.*)$/
|
1107
|
-
def parse_mixin_definition(line)
|
1108
|
-
name, arg_string = line.text.scan(MIXIN_DEF_RE).first
|
1109
|
-
raise SyntaxError.new("Invalid mixin \"#{line.text[1..-1]}\".") if name.nil?
|
1110
|
-
|
1111
|
-
offset = line.offset + line.text.size - arg_string.size
|
1112
|
-
args, splat = Script::Parser.new(arg_string.strip, @line, to_parser_offset(offset), @options).
|
1113
|
-
parse_mixin_definition_arglist
|
1114
|
-
Tree::MixinDefNode.new(name, args, splat)
|
1115
|
-
end
|
1116
|
-
|
1117
|
-
CONTENT_RE = /^@content\s*(.+)?$/
|
1118
|
-
def parse_content_directive(parent, line, root, value, offset)
|
1119
|
-
trailing = line.text.scan(CONTENT_RE).first.first
|
1120
|
-
unless trailing.nil?
|
1121
|
-
raise SyntaxError.new(
|
1122
|
-
"Invalid content directive. Trailing characters found: \"#{trailing}\".")
|
1123
|
-
end
|
1124
|
-
raise SyntaxError.new("Illegal nesting: Nothing may be nested beneath @content directives.",
|
1125
|
-
:line => line.index + 1) unless line.children.empty?
|
1126
|
-
Tree::ContentNode.new
|
1127
|
-
end
|
1128
|
-
|
1129
|
-
def parse_include_directive(parent, line, root, value, offset)
|
1130
|
-
parse_mixin_include(line, root)
|
1131
|
-
end
|
1132
|
-
|
1133
|
-
MIXIN_INCLUDE_RE = /^(?:\+|@include)\s*(#{Sass::SCSS::RX::IDENT})(.*)$/
|
1134
|
-
def parse_mixin_include(line, root)
|
1135
|
-
name, arg_string = line.text.scan(MIXIN_INCLUDE_RE).first
|
1136
|
-
raise SyntaxError.new("Invalid mixin include \"#{line.text}\".") if name.nil?
|
1137
|
-
|
1138
|
-
offset = line.offset + line.text.size - arg_string.size
|
1139
|
-
args, keywords, splat, kwarg_splat =
|
1140
|
-
Script::Parser.new(arg_string.strip, @line, to_parser_offset(offset), @options).
|
1141
|
-
parse_mixin_include_arglist
|
1142
|
-
Tree::MixinNode.new(name, args, keywords, splat, kwarg_splat)
|
1143
|
-
end
|
1144
|
-
|
1145
|
-
FUNCTION_RE = /^@function\s*(#{Sass::SCSS::RX::IDENT})(.*)$/
|
1146
|
-
def parse_function_directive(parent, line, root, value, offset)
|
1147
|
-
name, arg_string = line.text.scan(FUNCTION_RE).first
|
1148
|
-
raise SyntaxError.new("Invalid function definition \"#{line.text}\".") if name.nil?
|
1149
|
-
|
1150
|
-
offset = line.offset + line.text.size - arg_string.size
|
1151
|
-
args, splat = Script::Parser.new(arg_string.strip, @line, to_parser_offset(offset), @options).
|
1152
|
-
parse_function_definition_arglist
|
1153
|
-
Tree::FunctionNode.new(name, args, splat)
|
1154
|
-
end
|
1155
|
-
|
1156
|
-
def parse_script(script, options = {})
|
1157
|
-
line = options.delete(:line) || @line
|
1158
|
-
offset = options.delete(:offset) || @offset + 1
|
1159
|
-
Script.parse(script, line, offset, @options.merge(options))
|
1160
|
-
end
|
1161
|
-
|
1162
|
-
def format_comment_text(text, silent)
|
1163
|
-
content = text.split("\n")
|
1164
|
-
|
1165
|
-
if content.first && content.first.strip.empty?
|
1166
|
-
removed_first = true
|
1167
|
-
content.shift
|
1168
|
-
end
|
1169
|
-
|
1170
|
-
return "/* */" if content.empty?
|
1171
|
-
content.last.gsub!(%r{ ?\*/ *$}, '')
|
1172
|
-
first = content.shift unless removed_first
|
1173
|
-
content.map! {|l| l.gsub!(/^\*( ?)/, '\1') || (l.empty? ? "" : " ") + l}
|
1174
|
-
content.unshift first unless removed_first
|
1175
|
-
if silent
|
1176
|
-
"/*" + content.join("\n *") + " */"
|
1177
|
-
else
|
1178
|
-
# The #gsub fixes the case of a trailing */
|
1179
|
-
"/*" + content.join("\n *").gsub(/ \*\Z/, '') + " */"
|
1180
|
-
end
|
1181
|
-
end
|
1182
|
-
|
1183
|
-
def parse_interp(text, offset = 0)
|
1184
|
-
self.class.parse_interp(text, @line, offset, :filename => @filename)
|
1185
|
-
end
|
1186
|
-
|
1187
|
-
# Parser tracks 1-based line and offset, so our offset should be converted.
|
1188
|
-
def to_parser_offset(offset)
|
1189
|
-
offset + 1
|
1190
|
-
end
|
1191
|
-
|
1192
|
-
def full_line_range(line)
|
1193
|
-
Sass::Source::Range.new(
|
1194
|
-
Sass::Source::Position.new(@line, to_parser_offset(line.offset)),
|
1195
|
-
Sass::Source::Position.new(@line, to_parser_offset(line.offset) + line.text.length),
|
1196
|
-
@options[:filename], @options[:importer])
|
1197
|
-
end
|
1198
|
-
|
1199
|
-
# It's important that this have strings (at least)
|
1200
|
-
# at the beginning, the end, and between each Script::Tree::Node.
|
1201
|
-
#
|
1202
|
-
# @private
|
1203
|
-
def self.parse_interp(text, line, offset, options)
|
1204
|
-
res = []
|
1205
|
-
rest = Sass::Shared.handle_interpolation text do |scan|
|
1206
|
-
escapes = scan[2].size
|
1207
|
-
res << scan.matched[0...-2 - escapes]
|
1208
|
-
if escapes.odd?
|
1209
|
-
res << "\\" * (escapes - 1) << '#{'
|
1210
|
-
else
|
1211
|
-
res << "\\" * [0, escapes - 1].max
|
1212
|
-
if scan[1].include?("\n")
|
1213
|
-
line += scan[1].count("\n")
|
1214
|
-
offset = scan.matched_size - scan[1].rindex("\n")
|
1215
|
-
else
|
1216
|
-
offset += scan.matched_size
|
1217
|
-
end
|
1218
|
-
node = Script::Parser.new(scan, line, offset, options).parse_interpolated
|
1219
|
-
offset = node.source_range.end_pos.offset
|
1220
|
-
res << node
|
1221
|
-
end
|
1222
|
-
end
|
1223
|
-
res << rest
|
1224
|
-
end
|
1225
|
-
end
|
1226
|
-
end
|