Line numbers for all parse errors

This commit is contained in:
Florian Weingarten
2014-10-03 21:00:31 +00:00
parent b79c9cb9bf
commit 584b492e70
3 changed files with 84 additions and 29 deletions
+34 -29
View File
@@ -15,42 +15,47 @@ module Liquid
@nodelist.clear @nodelist.clear
while token = tokens.shift while token = tokens.shift
unless token.empty? begin
case unless token.empty?
when token.start_with?(TAGSTART) case
if token =~ FullToken when token.start_with?(TAGSTART)
if token =~ FullToken
# if we found the proper block delimiter just end parsing here and let the outer block # if we found the proper block delimiter just end parsing here and let the outer block
# proceed # proceed
if block_delimiter == $1 if block_delimiter == $1
end_tag end_tag
return return
end end
# fetch the tag from registered blocks # fetch the tag from registered blocks
if tag = Template.tags[$1] if tag = Template.tags[$1]
markup = token.is_a?(Token) ? token.child($2) : $2 markup = token.is_a?(Token) ? token.child($2) : $2
new_tag = tag.parse($1, markup, tokens, @options) new_tag = tag.parse($1, markup, tokens, @options)
new_tag.line_number = token.line_number if token.is_a?(Token) new_tag.line_number = token.line_number if token.is_a?(Token)
@blank &&= new_tag.blank? @blank &&= new_tag.blank?
@nodelist << new_tag @nodelist << new_tag
else
# this tag is not registered with the system
# pass it to the current block for special handling or error reporting
unknown_tag($1, $2, tokens)
end
else else
# this tag is not registered with the system raise SyntaxError.new(options[:locale].t("errors.syntax.tag_termination".freeze, :token => token, :tag_end => TagEnd.inspect))
# pass it to the current block for special handling or error reporting
unknown_tag($1, $2, tokens)
end end
when token.start_with?(VARSTART)
new_var = create_variable(token)
new_var.line_number = token.line_number if token.is_a?(Token)
@nodelist << new_var
@blank = false
else else
raise SyntaxError.new(options[:locale].t("errors.syntax.tag_termination".freeze, :token => token, :tag_end => TagEnd.inspect)) @nodelist << token
@blank &&= (token =~ /\A\s*\z/)
end end
when token.start_with?(VARSTART)
new_var = create_variable(token)
new_var.line_number = token.line_number if token.is_a?(Token)
@nodelist << new_var
@blank = false
else
@nodelist << token
@blank &&= (token =~ /\A\s*\z/)
end end
rescue SyntaxError => e
e.set_line_number_from_token(token)
raise
end end
end end
+1
View File
@@ -18,6 +18,7 @@ module Liquid
def set_line_number_from_token(token) def set_line_number_from_token(token)
return unless token.respond_to?(:line_number) return unless token.respond_to?(:line_number)
return if self.line_number
self.line_number = token.line_number self.line_number = token.line_number
end end
+49
View File
@@ -100,6 +100,55 @@ class ErrorHandlingTest < Minitest::Test
assert_equal Liquid::ArgumentError, template.errors.first.class assert_equal Liquid::ArgumentError, template.errors.first.class
end end
def test_with_line_numbers_adds_numbers_to_parser_errors
err = assert_raises(SyntaxError) do
template = Liquid::Template.parse(%q{
foobar
{% "cat" | foobar %}
bla
},
:line_numbers => true
)
end
assert_match /Liquid syntax error \(line 4\)/, err.message
end
def test_parsing_warn_with_line_numbers_adds_numbers_to_lexer_errors
template = Liquid::Template.parse(%q{
foobar
{% if 1 =! 2 %}ok{% endif %}
bla
},
:error_mode => :warn,
:line_numbers => true
)
assert_equal ['Liquid syntax error (line 4): Unexpected character = in "1 =! 2"'],
template.warnings.map(&:message)
end
def test_parsing_strict_with_line_numbers_adds_numbers_to_lexer_errors
err = assert_raises(SyntaxError) do
Liquid::Template.parse(%q{
foobar
{% if 1 =! 2 %}ok{% endif %}
bla
},
:error_mode => :strict,
:line_numbers => true
)
end
assert_equal 'Liquid syntax error (line 4): Unexpected character = in "1 =! 2"', err.message
end
def test_strict_error_messages def test_strict_error_messages
err = assert_raises(SyntaxError) do err = assert_raises(SyntaxError) do
Liquid::Template.parse(' {% if 1 =! 2 %}ok{% endif %} ', :error_mode => :strict) Liquid::Template.parse(' {% if 1 =! 2 %}ok{% endif %} ', :error_mode => :strict)