Permalink
Browse files

Fix an interpolation parsing bug.

This was reported in the comments of sass/sass#198.
  • Loading branch information...
1 parent d5ec058 commit 5ef3a3b5245be688f8807e6756f08f12d6be125d @nex3 nex3 committed Nov 23, 2011
Showing with 17 additions and 5 deletions.
  1. +1 −0 doc-src/SASS_CHANGELOG.md
  2. +12 −5 lib/sass/script/parser.rb
  3. +2 −0 test/sass/script_conversion_test.rb
  4. +2 −0 test/sass/script_test.rb
View
1 doc-src/SASS_CHANGELOG.md
@@ -7,6 +7,7 @@
* Allow control directives (such as `@if`) to be nested beneath properties.
* Allow property names to begin with a hyphen followed by interpolation (e.g. `-#{...}`).
+* Fix a parsing error with interpolation in comma-separated lists.
* Make `--cache-store` with with `--update`.
* Properly report `ArgumentError`s that occur within user-defined functions.
* Don't crash on JRuby if the underlying Java doesn't support every Unicode encoding.
View
17 lib/sass/script/parser.rb
@@ -182,7 +182,11 @@ def #{name}
interp = try_ops_after_interp(#{ops.inspect}, #{name.inspect}) and return interp
return unless e = #{sub}
while tok = try_tok(#{ops.map {|o| o.inspect}.join(', ')})
- interp = try_op_before_interp(tok, e) and return interp
+ if interp = try_op_before_interp(tok, e)
+ return interp unless other_interp = try_ops_after_interp(#{ops.inspect}, #{name.inspect}, interp)
+ return other_interp
+ end
+
line = @lexer.line
e = Operation.new(e, assert_expr(#{sub.inspect}), tok.type)
e.line = line
@@ -217,7 +221,10 @@ def expr
return unless e = interpolation
arr = [e]
while tok = try_tok(:comma)
- interp = try_op_before_interp(tok, e) and return interp
+ if interp = try_op_before_interp(tok, e)
+ return interp unless other_interp = try_ops_after_interp([:comma], :expr, interp)
+ return other_interp
+ end
arr << assert_expr(:interpolation)
end
arr.size == 1 ? arr.first : node(List.new(arr, :comma), line)
@@ -235,15 +242,15 @@ def try_op_before_interp(op, prev = nil)
interpolation(interp)
end
- def try_ops_after_interp(ops, name)
+ def try_ops_after_interp(ops, name, prev = nil)
return unless @lexer.after_interpolation?
return unless op = try_tok(*ops)
- interp = try_op_before_interp(op) and return interp
+ interp = try_op_before_interp(op, prev) and return interp
wa = @lexer.whitespace?
str = Script::String.new(Lexer::OPERATORS_REVERSE[op.type])
str.line = @lexer.line
- interp = Script::Interpolation.new(nil, str, assert_expr(name), !:wb, wa, :originally_text)
+ interp = Script::Interpolation.new(prev, str, assert_expr(name), !:wb, wa, :originally_text)
interp.line = @lexer.line
return interp
end
View
2 test/sass/script_conversion_test.rb
@@ -223,6 +223,8 @@ def test_interpolation_near_operators
assert_renders '#{1 + 2}, #{3 + 4}'
assert_renders '#{1 + 2} ,#{3 + 4}'
assert_renders '#{1 + 2},#{3 + 4}'
+ assert_renders '#{1 + 2}, #{3 + 4}, #{5 + 6}'
+ assert_renders '3, #{3 + 4}, 11'
assert_renders '3 / #{3 + 4}'
assert_renders '3 /#{3 + 4}'
View
2 test/sass/script_test.rb
@@ -138,6 +138,8 @@ def test_interpolation_near_operators
assert_equal '3, 7', resolve('#{1 + 2}, #{3 + 4}')
assert_equal '3 ,7', resolve('#{1 + 2} ,#{3 + 4}')
assert_equal '3,7', resolve('#{1 + 2},#{3 + 4}')
+ assert_equal '3, 7, 11', resolve('#{1 + 2}, #{3 + 4}, #{5 + 6}')
+ assert_equal '3, 7, 11', resolve('3, #{3 + 4}, 11')
assert_equal '3 / 7', resolve('3 / #{3 + 4}')
assert_equal '3 /7', resolve('3 /#{3 + 4}')

0 comments on commit 5ef3a3b

Please sign in to comment.