[ruby/prism] Various cleanup for initializers and typechecks

https://github.com/ruby/prism/commit/86cf82794a
This commit is contained in:
Kevin Newton 2024-07-03 11:23:17 -04:00
Родитель 2bf9ae3fa1
Коммит aa473489a2
8 изменённых файлов: 66 добавлений и 38 удалений

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

@ -588,6 +588,7 @@ module Prism
autoload :Newlines, "prism/parse_result/newlines"
private_constant :Comments
private_constant :Errors
private_constant :Newlines
# The syntax tree that was parsed from the source code.

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

@ -32,19 +32,19 @@ module Prism
io = StringIO.new
source_lines.each.with_index(1) do |line, line_number|
io.puts(line)
(error_lines.delete(line_number) || []).each do |error|
location = error.location
case line_number
when location.start_line
io.print(" " * location.start_column + "^")
if location.start_line == location.end_line
if location.start_column != location.end_column
io.print("~" * (location.end_column - location.start_column - 1))
end
io.puts(" " + error.message)
else
io.puts("~" * (line.bytesize - location.start_column))
@ -56,7 +56,7 @@ module Prism
end
end
end
io.puts
io.string
end

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

@ -104,6 +104,7 @@ Gem::Specification.new do |spec|
"prism.gemspec",
"rbi/prism.rbi",
"rbi/prism/compiler.rbi",
"rbi/prism/dsl.rbi",
"rbi/prism/inspect_visitor.rbi",
"rbi/prism/node_ext.rbi",
"rbi/prism/node.rbi",

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

@ -69,8 +69,15 @@ module Prism
# Create a new <%= node.name %> node.
def <%= node.human %>(<%= ["source: default_source", "node_id: 0", "location: default_location", "flags: 0", *node.fields.map { |field|
case field
when Prism::Template::NodeField, Prism::Template::ConstantField
"#{field.name}: default_node(source, location)"
when Prism::Template::NodeField
if !field.kind?
"#{field.name}: default_node(source, location)"
else
kind = field.specific_kind || field.union_kind.first
"#{field.name}: #{kind.gsub(/(?<=.)[A-Z]/, "_\\0").downcase}(source: source)"
end
when Prism::Template::ConstantField
"#{field.name}: :\"\""
when Prism::Template::OptionalNodeField, Prism::Template::OptionalConstantField, Prism::Template::OptionalLocationField
"#{field.name}: nil"
when Prism::Template::NodeListField, Prism::Template::ConstantListField
@ -79,8 +86,10 @@ module Prism
"#{field.name}: \"\""
when Prism::Template::LocationField
"#{field.name}: location"
when Prism::Template::UInt8Field, Prism::Template::UInt32Field, Prism::Template::IntegerField, Prism::Template::DoubleField
when Prism::Template::UInt8Field, Prism::Template::UInt32Field, Prism::Template::IntegerField
"#{field.name}: 0"
when Prism::Template::DoubleField
"#{field.name}: 0.0"
else
raise
end
@ -96,7 +105,7 @@ module Prism
<%- flag.values.each do |value| -%>
when :<%= value.name.downcase %> then <%= flag.name %>::<%= value.name %>
<%- end -%>
else raise ArgumentError, "invalid <%= flag.name %> flag: #{name.inspect}"
else Kernel.raise ArgumentError, "invalid <%= flag.name %> flag: #{name.inspect}"
end
end
<%- end -%>
@ -118,7 +127,7 @@ module Prism
# The default node that gets attached to nodes if no node is specified for a
# required node field.
def default_node(source, location)
MissingNode.new(source, location)
MissingNode.new(source, -1, location, 0)
end
end
end

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

@ -93,6 +93,10 @@ module Prism
# Some node fields can be specialized if they point to a specific kind of
# node and not just a generic node.
class NodeKindField < Field
def kind?
options.key?(:kind)
end
def c_type
if specific_kind
"pm_#{specific_kind.gsub(/(?<=.)[A-Z]/, "_\\0").downcase}"
@ -624,6 +628,7 @@ module Prism
"src/prettyprint.c",
"src/serialize.c",
"src/token_type.c",
"rbi/prism/dsl.rbi",
"rbi/prism/node.rbi",
"rbi/prism/visitor.rbi",
"sig/prism.rbs",

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

@ -18,6 +18,12 @@ module Prism
]
end
if RUBY_VERSION < "3.4"
filepaths -= [
"it_with_ordinary_parameter.txt"
]
end
filepaths.each do |filepath|
define_method(:"test_#{File.basename(filepath, ".txt")}") do
assert_errors(File.join(base, filepath))
@ -77,7 +83,7 @@ module Prism
private
def assert_errors(filepath)
expected = File.read(filepath)
expected = File.read(filepath, binmode: true, external_encoding: Encoding::UTF_8)
source = expected.lines.grep_v(/^\s*\^/).join.gsub(/\n*\z/, "")
refute_valid_syntax(source)

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

@ -76,33 +76,38 @@ module Prism
end
def test_literal_in_conditionals
source = <<~RUBY
if (a = 2); a; end
if ($a = 2); end
if (@a = 2); end
if (@@a = 2); end
if a; elsif b = 2; b end
unless (a = 2); a; end
unless ($a = 2); end
unless (@a = 2); end
unless (@@a = 2); end
while (a = 2); a; end
while ($a = 2); end
while (@a = 2); end
while (@@a = 2); end
until (a = 2); a; end
until ($a = 2); end
until (@a = 2); end
until (@@a = 2); end
foo if (a, b = 2); [a, b]
foo if a = 2 and a
(@foo = 1) ? a : b
!(a = 2) and a
not a = 2 and a
RUBY
sources = [
"if (a = 2); a; end",
"if ($a = 2); end",
"if (@a = 2); end",
"if a; elsif b = 2; b end",
"unless (a = 2); a; end",
"unless ($a = 2); end",
"unless (@a = 2); end",
"while (a = 2); a; end",
"while ($a = 2); end",
"while (@a = 2); end",
"until (a = 2); a; end",
"until ($a = 2); end",
"until (@a = 2); end",
"foo if (a, b = 2); [a, b]",
"foo if a = 2 and a",
"(@foo = 1) ? a : b",
"!(a = 2) and a",
"not a = 2 and a"
]
source.each_line(chomp: true) do |line|
assert_warning(line, "found '= literal' in conditional, should be ==")
if RUBY_VERSION >= "3.3"
sources.push(
"if (@@a = 2); end",
"unless (@@a = 2); end",
"while (@@a = 2); end",
"until (@@a = 2); end"
)
end
sources.each do |source|
assert_warning(source, "= literal' in conditional, should be ==")
end
end

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

@ -2,11 +2,12 @@
source "https://rubygems.org"
gem "rubocop", ">= 1.52.1", "< 2"
gemspec path: "../.."
gem "minitest"
gem "rake"
gem "rake-compiler"
gem "rspec"
gem "rubocop", ">= 1.52.1", "< 2"
gem "test-unit"
gem "rb_sys"