lib/sass/script/parser.rb in sass-3.3.14 vs lib/sass/script/parser.rb in sass-3.4.0.rc.1

- old
+ new

@@ -34,17 +34,23 @@ # Parses a SassScript expression within an interpolated segment (`#{}`). # This means that it stops when it comes across an unmatched `}`, # which signals the end of an interpolated segment, # it returns rather than throwing an error. # + # @param warn_for_color [Boolean] Whether raw color values passed to + # interoplation should cause a warning. # @return [Script::Tree::Node] The root node of the parse tree # @raise [Sass::SyntaxError] if the expression isn't valid SassScript - def parse_interpolated + def parse_interpolated(warn_for_color = false) + # Start two characters back to compensate for #{ + start_pos = Sass::Source::Position.new(line, offset - 2) expr = assert_expr :expr assert_tok :end_interpolation + expr = Sass::Script::Tree::Interpolation.new( + nil, expr, nil, !:wb, !:wa, !:originally_text, warn_for_color) expr.options = @options - expr + node(expr, start_pos) rescue Sass::SyntaxError => e e.modify_backtrace :line => @lexer.line, :filename => @options[:filename] raise e end @@ -338,11 +344,12 @@ def interpolation(first = space) e = first while (interp = try_tok(:begin_interpolation)) wb = @lexer.whitespace?(interp) - mid = parse_interpolated + mid = assert_expr :expr + assert_tok :end_interpolation wa = @lexer.whitespace? e = node( Script::Tree::Interpolation.new(e, mid, space, wb, wa), (e || mid).source_range.start_pos) end @@ -380,11 +387,11 @@ return funcall unless @lexer.peek && @lexer.peek.type == :ident return if @stop_at && @stop_at.include?(@lexer.peek.value) name = @lexer.next if (color = Sass::Script::Value::Color::COLOR_NAMES[name.value.downcase]) - literal_node(Sass::Script::Value::Color.new(color), name.source_range) + literal_node(Sass::Script::Value::Color.new(color, name.value), name.source_range) elsif name.value == "true" literal_node(Sass::Script::Value::Bool.new(true), name.source_range) elsif name.value == "false" literal_node(Sass::Script::Value::Bool.new(false), name.source_range) elsif name.value == "null" @@ -485,18 +492,26 @@ return special_fun unless tok literal_node(Script::Value::String.new(tok.value), tok.source_range) end def special_fun - first = try_tok(:special_fun) - return paren unless first - str = literal_node(first.value, first.source_range) - return str unless try_tok(:begin_interpolation) - mid = parse_interpolated - last = assert_expr(:special_fun) - node(Tree::Interpolation.new(str, mid, last, false, false), - first.source_range.start_pos) + start_pos = source_position + tok = try_tok(:special_fun) + return paren unless tok + first = literal_node(Script::Value::String.new(tok.value.first), + start_pos, start_pos.after(tok.value.first)) + Sass::Util.enum_slice(tok.value[1..-1], 2).inject(first) do |l, (i, r)| + end_pos = i.source_range.end_pos + end_pos = end_pos.after(r) if r + node( + Script::Tree::Interpolation.new( + l, i, + r && literal_node(Script::Value::String.new(r), + i.source_range.end_pos, end_pos), + false, false), + start_pos, end_pos) + end end def paren return variable unless try_tok(:lparen) was_in_parens = @in_parens @@ -520,11 +535,12 @@ def string first = try_tok(:string) return number unless first str = literal_node(first.value, first.source_range) return str unless try_tok(:begin_interpolation) - mid = parse_interpolated + mid = assert_expr :expr + assert_tok :end_interpolation last = assert_expr(:string) node(Tree::StringInterpolation.new(str, mid, last), first.source_range.start_pos) end def number @@ -553,10 +569,9 @@ :string => "string", :default => "expression (e.g. 1px, bold)", :mixin_arglist => "mixin argument", :fn_arglist => "function argument", :splat => "...", - :special_fun => '")"', } def assert_expr(name, expected = nil) e = send(name) return e if e