Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

- Parser#parse returns nil instead of false if error is thrown #722

Merged
merged 1 commit into from Jul 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 6 additions & 5 deletions lib/parser/base.rb
Expand Up @@ -177,16 +177,16 @@ def reset
end

##
# Parses a source buffer and returns the AST.
# Parses a source buffer and returns the AST, or `nil` in case of a non fatal error.
#
# @param [Parser::Source::Buffer] source_buffer The source buffer to parse.
# @return [Parser::AST::Node]
# @return [Parser::AST::Node, nil]
#
def parse(source_buffer)
@lexer.source_buffer = source_buffer
@source_buffer = source_buffer

do_parse
do_parse || nil # Force `false` to `nil`, see https://github.com/ruby/racc/pull/136
ensure
# Don't keep references to the source file.
@source_buffer = nil
Expand All @@ -210,8 +210,9 @@ def parse_with_comments(source_buffer)

##
# Parses a source buffer and returns the AST, the source code comments,
# and the tokens emitted by the lexer. If `recover` is true and a fatal
# {SyntaxError} is encountered, `nil` is returned instead of the AST, and
# and the tokens emitted by the lexer. In case of a fatal error, a {SyntaxError}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ha, it took me a while to understand that recover here is responsible for "swallowing the error", but not "error recovery". Not sure if it's worth renaming it, current name sounds good as a part of the public API (you "recover" from VM error, not from the parsing error). Thanks for changing this doc too 👍

# is raised, unless `recover` is true. In case of an error
# (non-fatal or recovered), `nil` is returned instead of the AST, and
# comments as well as tokens are only returned up to the location of
# the error.
#
Expand Down
10 changes: 10 additions & 0 deletions test/test_parser.rb
Expand Up @@ -9796,4 +9796,14 @@ def test_find_pattern
%q{ ~~~~~~~~ expression (in_pattern.find_pattern)},
SINCE_2_8)
end

def test_invalid_source
with_versions(ALL_VERSIONS) do |_ver, parser|
source_file = Parser::Source::Buffer.new('(comments)', source: "def foo; en")

parser.diagnostics.all_errors_are_fatal = false
ast = parser.parse(source_file)
assert_nil(ast)
end
end
end