зеркало из 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:
|
Racc_debug_parser = false # :nodoc:
|
||||||
|
|
||||||
def version # :nodoc:
|
def version # :nodoc:
|
||||||
33
|
34
|
||||||
end
|
end
|
||||||
|
|
||||||
# The default encoding for Ruby files is UTF-8.
|
# The default encoding for Ruby files is UTF-8.
|
||||||
|
@ -42,9 +42,10 @@ module Prism
|
||||||
@source_buffer = source_buffer
|
@source_buffer = source_buffer
|
||||||
source = source_buffer.source
|
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
|
ensure
|
||||||
@source_buffer = nil
|
@source_buffer = nil
|
||||||
end
|
end
|
||||||
|
@ -55,7 +56,7 @@ module Prism
|
||||||
source = source_buffer.source
|
source = source_buffer.source
|
||||||
|
|
||||||
offset_cache = build_offset_cache(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),
|
build_ast(result.value, offset_cache),
|
||||||
|
@ -72,7 +73,7 @@ module Prism
|
||||||
source = source_buffer.source
|
source = source_buffer.source
|
||||||
|
|
||||||
offset_cache = build_offset_cache(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
|
program, tokens = result.value
|
||||||
|
|
||||||
|
@ -93,16 +94,23 @@ module Prism
|
||||||
|
|
||||||
private
|
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
|
# If there was a error generated during the parse, then raise an
|
||||||
# appropriate syntax error. Otherwise return the result.
|
# appropriate syntax error. Otherwise return the result.
|
||||||
def unwrap(result)
|
def unwrap(result, offset_cache)
|
||||||
return result if result.success?
|
result.errors.each do |error|
|
||||||
|
next unless valid_error?(error)
|
||||||
|
|
||||||
error = result.errors.first
|
location = build_range(error.location, offset_cache)
|
||||||
offset_cache = build_offset_cache(source_buffer.source)
|
diagnostics.process(Diagnostic.new(error.message, location))
|
||||||
|
end
|
||||||
|
|
||||||
diagnostic = Diagnostic.new(error.message, build_range(error.location, offset_cache))
|
result
|
||||||
raise ::Parser::SyntaxError, diagnostic
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Prism deals with offsets in bytes, while the parser gem deals with
|
# Prism deals with offsets in bytes, while the parser gem deals with
|
||||||
|
|
|
@ -241,53 +241,51 @@ module Prism
|
||||||
block = nil
|
block = nil
|
||||||
end
|
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(
|
visit_block(
|
||||||
if name == :!
|
if name.end_with?("=") && !message_loc.slice.end_with?("=") && node.arguments && block.nil?
|
||||||
builder.not_op(
|
builder.assign(
|
||||||
token(node.message_loc),
|
builder.attr_asgn(visit(node.receiver), call_operator, token(message_loc)),
|
||||||
token(node.opening_loc),
|
srange_find(message_loc.end_offset, node.arguments.location.start_offset, ["="]),
|
||||||
visit(node.receiver),
|
visit(node.arguments.arguments.last)
|
||||||
token(node.closing_loc)
|
|
||||||
)
|
)
|
||||||
elsif name == :[]
|
else
|
||||||
builder.index(
|
builder.call_method(
|
||||||
visit(node.receiver),
|
visit(node.receiver),
|
||||||
|
call_operator,
|
||||||
|
message_loc ? [node.name, srange(message_loc)] : nil,
|
||||||
token(node.opening_loc),
|
token(node.opening_loc),
|
||||||
visit_all(arguments),
|
visit_all(arguments),
|
||||||
token(node.closing_loc)
|
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,
|
end,
|
||||||
block
|
block
|
||||||
)
|
)
|
||||||
|
@ -519,8 +517,6 @@ module Prism
|
||||||
# def self.foo; end
|
# def self.foo; end
|
||||||
# ^^^^^^^^^^^^^^^^^
|
# ^^^^^^^^^^^^^^^^^
|
||||||
def visit_def_node(node)
|
def visit_def_node(node)
|
||||||
forwarding = find_forwarding(node.parameters)
|
|
||||||
|
|
||||||
if node.equal_loc
|
if node.equal_loc
|
||||||
if node.receiver
|
if node.receiver
|
||||||
builder.def_endless_singleton(
|
builder.def_endless_singleton(
|
||||||
|
@ -530,7 +526,7 @@ module Prism
|
||||||
token(node.name_loc),
|
token(node.name_loc),
|
||||||
builder.args(token(node.lparen_loc), visit(node.parameters) || [], token(node.rparen_loc), false),
|
builder.args(token(node.lparen_loc), visit(node.parameters) || [], token(node.rparen_loc), false),
|
||||||
token(node.equal_loc),
|
token(node.equal_loc),
|
||||||
node.body&.accept(copy_compiler(forwarding: forwarding))
|
node.body&.accept(copy_compiler(forwarding: find_forwarding(node.parameters)))
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
builder.def_endless_method(
|
builder.def_endless_method(
|
||||||
|
@ -538,7 +534,7 @@ module Prism
|
||||||
token(node.name_loc),
|
token(node.name_loc),
|
||||||
builder.args(token(node.lparen_loc), visit(node.parameters) || [], token(node.rparen_loc), false),
|
builder.args(token(node.lparen_loc), visit(node.parameters) || [], token(node.rparen_loc), false),
|
||||||
token(node.equal_loc),
|
token(node.equal_loc),
|
||||||
node.body&.accept(copy_compiler(forwarding: forwarding))
|
node.body&.accept(copy_compiler(forwarding: find_forwarding(node.parameters)))
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
elsif node.receiver
|
elsif node.receiver
|
||||||
|
@ -548,7 +544,7 @@ module Prism
|
||||||
token(node.operator_loc),
|
token(node.operator_loc),
|
||||||
token(node.name_loc),
|
token(node.name_loc),
|
||||||
builder.args(token(node.lparen_loc), visit(node.parameters) || [], token(node.rparen_loc), false),
|
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)
|
token(node.end_keyword_loc)
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
|
@ -556,7 +552,7 @@ module Prism
|
||||||
token(node.def_keyword_loc),
|
token(node.def_keyword_loc),
|
||||||
token(node.name_loc),
|
token(node.name_loc),
|
||||||
builder.args(token(node.lparen_loc), visit(node.parameters) || [], token(node.rparen_loc), false),
|
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)
|
token(node.end_keyword_loc)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -993,24 +989,24 @@ module Prism
|
||||||
|
|
||||||
# -> {}
|
# -> {}
|
||||||
def visit_lambda_node(node)
|
def visit_lambda_node(node)
|
||||||
|
parameters = node.parameters
|
||||||
|
|
||||||
builder.block(
|
builder.block(
|
||||||
builder.call_lambda(token(node.operator_loc)),
|
builder.call_lambda(token(node.operator_loc)),
|
||||||
[node.opening, srange(node.opening_loc)],
|
[node.opening, srange(node.opening_loc)],
|
||||||
if node.parameters
|
if parameters.nil?
|
||||||
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
|
|
||||||
builder.args(nil, [], nil, false)
|
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,
|
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)]
|
[node.closing, srange(node.closing_loc)]
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -1096,7 +1092,7 @@ module Prism
|
||||||
# case of a syntax error. The parser gem doesn't have such a concept, so
|
# case of a syntax error. The parser gem doesn't have such a concept, so
|
||||||
# we invent our own here.
|
# we invent our own here.
|
||||||
def visit_missing_node(node)
|
def visit_missing_node(node)
|
||||||
raise CompilationError, "Cannot compile missing nodes"
|
::AST::Node.new(:missing, [], location: ::Parser::Source::Map.new(srange(node.location)))
|
||||||
end
|
end
|
||||||
|
|
||||||
# module Foo; end
|
# module Foo; end
|
||||||
|
@ -1727,29 +1723,29 @@ module Prism
|
||||||
# Visit a block node on a call.
|
# Visit a block node on a call.
|
||||||
def visit_block(call, block)
|
def visit_block(call, block)
|
||||||
if block
|
if block
|
||||||
|
parameters = block.parameters
|
||||||
|
|
||||||
builder.block(
|
builder.block(
|
||||||
call,
|
call,
|
||||||
token(block.opening_loc),
|
token(block.opening_loc),
|
||||||
if (parameters = block.parameters)
|
if parameters.nil?
|
||||||
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
|
|
||||||
builder.args(nil, [], nil, false)
|
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,
|
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)
|
token(block.closing_loc)
|
||||||
)
|
)
|
||||||
else
|
else
|
||||||
|
@ -1762,9 +1758,9 @@ module Prism
|
||||||
children = []
|
children = []
|
||||||
node.parts.each do |part|
|
node.parts.each do |part|
|
||||||
pushing =
|
pushing =
|
||||||
if part.is_a?(StringNode) && part.unescaped.count("\n") > 1
|
if part.is_a?(StringNode) && part.unescaped.include?("\n")
|
||||||
unescaped = part.unescaped.split("\n")
|
unescaped = part.unescaped.lines(chomp: true)
|
||||||
escaped = part.content.split("\n")
|
escaped = part.content.lines(chomp: true)
|
||||||
|
|
||||||
escaped_lengths =
|
escaped_lengths =
|
||||||
if node.opening.end_with?("'")
|
if node.opening.end_with?("'")
|
||||||
|
@ -1779,7 +1775,6 @@ module Prism
|
||||||
unescaped.zip(escaped_lengths).map do |unescaped_line, escaped_length|
|
unescaped.zip(escaped_lengths).map do |unescaped_line, escaped_length|
|
||||||
end_offset = start_offset + (escaped_length || 0)
|
end_offset = start_offset + (escaped_length || 0)
|
||||||
inner_part = builder.string_internal(["#{unescaped_line}\n", srange_offsets(start_offset, end_offset)])
|
inner_part = builder.string_internal(["#{unescaped_line}\n", srange_offsets(start_offset, end_offset)])
|
||||||
|
|
||||||
start_offset = end_offset
|
start_offset = end_offset
|
||||||
inner_part
|
inner_part
|
||||||
end
|
end
|
||||||
|
|
Загрузка…
Ссылка в новой задаче