[ruby/prism] Small fixes for the parser translator

https://github.com/ruby/prism/commit/4327051c86
This commit is contained in:
Kevin Newton 2024-02-02 12:37:32 -05:00
Родитель 8f9d999d59
Коммит 420a6349ec
2 изменённых файлов: 96 добавлений и 93 удалений

Просмотреть файл

@ -26,7 +26,7 @@ module Prism
Racc_debug_parser = false # :nodoc:
def version # :nodoc:
33
34
end
# The default encoding for Ruby files is UTF-8.
@ -42,9 +42,10 @@ module Prism
@source_buffer = source_buffer
source = source_buffer.source
result = unwrap(Prism.parse(source, filepath: source_buffer.name))
offset_cache = build_offset_cache(source)
result = unwrap(Prism.parse(source, filepath: source_buffer.name), offset_cache)
build_ast(result.value, build_offset_cache(source))
build_ast(result.value, offset_cache)
ensure
@source_buffer = nil
end
@ -55,7 +56,7 @@ module Prism
source = source_buffer.source
offset_cache = build_offset_cache(source)
result = unwrap(Prism.parse(source, filepath: source_buffer.name))
result = unwrap(Prism.parse(source, filepath: source_buffer.name), offset_cache)
[
build_ast(result.value, offset_cache),
@ -72,7 +73,7 @@ module Prism
source = source_buffer.source
offset_cache = build_offset_cache(source)
result = unwrap(Prism.parse_lex(source, filepath: source_buffer.name))
result = unwrap(Prism.parse_lex(source, filepath: source_buffer.name), offset_cache)
program, tokens = result.value
@ -93,16 +94,23 @@ module Prism
private
# This is a hook to allow consumers to disable some errors if they don't
# want them to block creating the syntax tree.
def valid_error?(error)
true
end
# If there was a error generated during the parse, then raise an
# appropriate syntax error. Otherwise return the result.
def unwrap(result)
return result if result.success?
def unwrap(result, offset_cache)
result.errors.each do |error|
next unless valid_error?(error)
error = result.errors.first
offset_cache = build_offset_cache(source_buffer.source)
location = build_range(error.location, offset_cache)
diagnostics.process(Diagnostic.new(error.message, location))
end
diagnostic = Diagnostic.new(error.message, build_range(error.location, offset_cache))
raise ::Parser::SyntaxError, diagnostic
result
end
# Prism deals with offsets in bytes, while the parser gem deals with

Просмотреть файл

@ -241,53 +241,51 @@ module Prism
block = nil
end
if node.call_operator_loc.nil?
case name
when :!
return visit_block(builder.not_op(token(node.message_loc), token(node.opening_loc), visit(node.receiver), token(node.closing_loc)), block)
when :[]
return visit_block(builder.index(visit(node.receiver), token(node.opening_loc), visit_all(arguments), token(node.closing_loc)), block)
when :[]=
if node.message != "[]=" && node.arguments && block.nil? && !node.safe_navigation?
return visit_block(
builder.assign(
builder.index_asgn(
visit(node.receiver),
token(node.opening_loc),
visit_all(node.arguments.arguments[...-1]),
token(node.closing_loc),
),
srange_find(node.message_loc.end_offset, node.arguments.arguments.last.location.start_offset, ["="]),
visit(node.arguments.arguments.last)
),
block
)
end
end
end
message_loc = node.message_loc
call_operator_loc = node.call_operator_loc
call_operator = [{ "." => :dot, "&." => :anddot, "::" => "::" }.fetch(call_operator_loc.slice), srange(call_operator_loc)] if call_operator_loc
visit_block(
if name == :!
builder.not_op(
token(node.message_loc),
token(node.opening_loc),
visit(node.receiver),
token(node.closing_loc)
if name.end_with?("=") && !message_loc.slice.end_with?("=") && node.arguments && block.nil?
builder.assign(
builder.attr_asgn(visit(node.receiver), call_operator, token(message_loc)),
srange_find(message_loc.end_offset, node.arguments.location.start_offset, ["="]),
visit(node.arguments.arguments.last)
)
elsif name == :[]
builder.index(
else
builder.call_method(
visit(node.receiver),
call_operator,
message_loc ? [node.name, srange(message_loc)] : nil,
token(node.opening_loc),
visit_all(arguments),
token(node.closing_loc)
)
elsif name == :[]= && node.message != "[]=" && node.arguments && block.nil?
builder.assign(
builder.index_asgn(
visit(node.receiver),
token(node.opening_loc),
visit_all(node.arguments.arguments[...-1]),
token(node.closing_loc),
),
srange_find(node.message_loc.end_offset, node.arguments.arguments.last.location.start_offset, ["="]),
visit(node.arguments.arguments.last)
)
else
message_loc = node.message_loc
call_operator_loc = node.call_operator_loc
call_operator = [{ "." => :dot, "&." => :anddot, "::" => "::" }.fetch(call_operator_loc.slice), srange(call_operator_loc)] if call_operator_loc
if name.end_with?("=") && !message_loc.slice.end_with?("=") && node.arguments && block.nil?
builder.assign(
builder.attr_asgn(visit(node.receiver), call_operator, token(message_loc)),
srange_find(message_loc.end_offset, node.arguments.location.start_offset, ["="]),
visit(node.arguments.arguments.last)
)
else
builder.call_method(
visit(node.receiver),
call_operator,
message_loc ? [node.name, srange(message_loc)] : nil,
token(node.opening_loc),
visit_all(arguments),
token(node.closing_loc)
)
end
end,
block
)
@ -519,8 +517,6 @@ module Prism
# def self.foo; end
# ^^^^^^^^^^^^^^^^^
def visit_def_node(node)
forwarding = find_forwarding(node.parameters)
if node.equal_loc
if node.receiver
builder.def_endless_singleton(
@ -530,7 +526,7 @@ module Prism
token(node.name_loc),
builder.args(token(node.lparen_loc), visit(node.parameters) || [], token(node.rparen_loc), false),
token(node.equal_loc),
node.body&.accept(copy_compiler(forwarding: forwarding))
node.body&.accept(copy_compiler(forwarding: find_forwarding(node.parameters)))
)
else
builder.def_endless_method(
@ -538,7 +534,7 @@ module Prism
token(node.name_loc),
builder.args(token(node.lparen_loc), visit(node.parameters) || [], token(node.rparen_loc), false),
token(node.equal_loc),
node.body&.accept(copy_compiler(forwarding: forwarding))
node.body&.accept(copy_compiler(forwarding: find_forwarding(node.parameters)))
)
end
elsif node.receiver
@ -548,7 +544,7 @@ module Prism
token(node.operator_loc),
token(node.name_loc),
builder.args(token(node.lparen_loc), visit(node.parameters) || [], token(node.rparen_loc), false),
node.body&.accept(copy_compiler(forwarding: forwarding)),
node.body&.accept(copy_compiler(forwarding: find_forwarding(node.parameters))),
token(node.end_keyword_loc)
)
else
@ -556,7 +552,7 @@ module Prism
token(node.def_keyword_loc),
token(node.name_loc),
builder.args(token(node.lparen_loc), visit(node.parameters) || [], token(node.rparen_loc), false),
node.body&.accept(copy_compiler(forwarding: forwarding)),
node.body&.accept(copy_compiler(forwarding: find_forwarding(node.parameters))),
token(node.end_keyword_loc)
)
end
@ -993,24 +989,24 @@ module Prism
# -> {}
def visit_lambda_node(node)
parameters = node.parameters
builder.block(
builder.call_lambda(token(node.operator_loc)),
[node.opening, srange(node.opening_loc)],
if node.parameters
if node.parameters.is_a?(NumberedParametersNode)
visit(node.parameters)
else
builder.args(
token(node.parameters.opening_loc),
visit(node.parameters),
token(node.parameters.closing_loc),
false
)
end
else
if parameters.nil?
builder.args(nil, [], nil, false)
elsif node.parameters.is_a?(NumberedParametersNode)
visit(node.parameters)
else
builder.args(
token(node.parameters.opening_loc),
visit(node.parameters),
token(node.parameters.closing_loc),
false
)
end,
node.body&.accept(copy_compiler(forwarding: find_forwarding(node.parameters&.parameters))),
node.body&.accept(copy_compiler(forwarding: parameters.is_a?(NumberedParametersNode) ? [] : find_forwarding(parameters&.parameters))),
[node.closing, srange(node.closing_loc)]
)
end
@ -1096,7 +1092,7 @@ module Prism
# case of a syntax error. The parser gem doesn't have such a concept, so
# we invent our own here.
def visit_missing_node(node)
raise CompilationError, "Cannot compile missing nodes"
::AST::Node.new(:missing, [], location: ::Parser::Source::Map.new(srange(node.location)))
end
# module Foo; end
@ -1727,29 +1723,29 @@ module Prism
# Visit a block node on a call.
def visit_block(call, block)
if block
parameters = block.parameters
builder.block(
call,
token(block.opening_loc),
if (parameters = block.parameters)
if parameters.is_a?(NumberedParametersNode)
visit(parameters)
else
builder.args(
token(parameters.opening_loc),
if procarg0?(parameters.parameters)
parameter = parameters.parameters.requireds.first
[builder.procarg0(visit(parameter))].concat(visit_all(parameters.locals))
else
visit(parameters)
end,
token(parameters.closing_loc),
false
)
end
else
if parameters.nil?
builder.args(nil, [], nil, false)
elsif parameters.is_a?(NumberedParametersNode)
visit(parameters)
else
builder.args(
token(parameters.opening_loc),
if procarg0?(parameters.parameters)
parameter = parameters.parameters.requireds.first
[builder.procarg0(visit(parameter))].concat(visit_all(parameters.locals))
else
visit(parameters)
end,
token(parameters.closing_loc),
false
)
end,
block.body&.accept(copy_compiler(forwarding: find_forwarding(block.parameters&.parameters))),
block.body&.accept(copy_compiler(forwarding: parameters.is_a?(NumberedParametersNode) ? [] : find_forwarding(parameters&.parameters))),
token(block.closing_loc)
)
else
@ -1762,9 +1758,9 @@ module Prism
children = []
node.parts.each do |part|
pushing =
if part.is_a?(StringNode) && part.unescaped.count("\n") > 1
unescaped = part.unescaped.split("\n")
escaped = part.content.split("\n")
if part.is_a?(StringNode) && part.unescaped.include?("\n")
unescaped = part.unescaped.lines(chomp: true)
escaped = part.content.lines(chomp: true)
escaped_lengths =
if node.opening.end_with?("'")
@ -1779,7 +1775,6 @@ module Prism
unescaped.zip(escaped_lengths).map do |unescaped_line, escaped_length|
end_offset = start_offset + (escaped_length || 0)
inner_part = builder.string_internal(["#{unescaped_line}\n", srange_offsets(start_offset, end_offset)])
start_offset = end_offset
inner_part
end