зеркало из https://github.com/github/ruby.git
[ruby/prism] Small fixes for the parser translator
https://github.com/ruby/prism/commit/4327051c86
This commit is contained in:
Родитель
8f9d999d59
Коммит
420a6349ec
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче