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