Skip to content

Commit 47fcc42

Browse files
committed
Port prototype rbi generation to prism
Apart from porting to prism, this also does the following: 1. Remove `variable` tracking for `type_of0`. It contains `AST::TypeParam` but checked for inclusion of a Symbol. There's no difference in the output even when this is fixed, so I just removed it entirely 2. Have the parse method return declarations, make it a class method. Just more convenient with the new structure. Eventually `rb prototype` will do this as well 3. Allow to use it on jruby/truffleruby. 4. Split comment parsing from comment processing in the helper. In rbi the comments now come from a plain parse. When `prototype rb` uses prism as well, `parse_comments` can be removed (as well as most of the other helper methods there) I tested this against code samples from https://github.com/Shopify/tapioca/blob/d029cc9c3f76865f61fdbaff68d75e18a0014764/spec/tapioca/gem/pipeline_spec.rb The output is largely the same, and improved in some areas. For example, `type_member` with no paren is no longer considered an untyped constant. Previously that was only the case for `type_member()` or when an argument was passed like `type_member(:out)`.
1 parent 5de6ecd commit 47fcc42

11 files changed

Lines changed: 854 additions & 939 deletions

File tree

lib/rbs/cli.rb

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,8 @@ def parse_logging_options(opts)
108108
opts
109109
end
110110

111-
def has_parser?
111+
def has_parser?(format)
112+
return true if format == "rbi"
112113
defined?(RubyVM::AbstractSyntaxTree) ? true : false
113114
end
114115

@@ -683,7 +684,7 @@ def autoload(name, path)
683684
end
684685

685686
def run_prototype_file(format, args)
686-
availability = unless has_parser?
687+
availability = unless has_parser?(format)
687688
"\n** This command does not work on this interpreter (#{RUBY_ENGINE}) **\n"
688689
end
689690

@@ -728,7 +729,7 @@ def run_prototype_file(format, args)
728729

729730
opts.parse!(args)
730731

731-
unless has_parser?
732+
unless has_parser?(format)
732733
stdout.puts "Not supported on this interpreter (#{RUBY_ENGINE})."
733734
return 1
734735
end
@@ -741,7 +742,7 @@ def run_prototype_file(format, args)
741742
new_parser = -> do
742743
case format
743744
when "rbi"
744-
Prototype::RBI.new()
745+
Prototype::RBI
745746
when "rb"
746747
Prototype::RB.new()
747748
else
@@ -796,7 +797,7 @@ def run_prototype_file(format, args)
796797

797798
parser = new_parser[]
798799
begin
799-
parser.parse file_path.read()
800+
decls = parser.parse file_path.read()
800801
rescue SyntaxError
801802
stdout.puts " ⚠️ Unable to parse due to SyntaxError: `#{file_path}`"
802803
next
@@ -817,7 +818,7 @@ def run_prototype_file(format, args)
817818
(output_path.parent).mkpath
818819
output_path.open("w") do |io|
819820
writer = Writer.new(out: io)
820-
writer.write(parser.decls)
821+
writer.write(decls)
821822
end
822823
end
823824
end
@@ -837,13 +838,12 @@ def run_prototype_file(format, args)
837838
else
838839
# file mode
839840
parser = new_parser[]
841+
writer = Writer.new(out: stdout)
840842

841843
input_paths.each do |file|
842-
parser.parse file.read()
844+
writer.write parser.parse(file.read())
843845
end
844846

845-
writer = Writer.new(out: stdout)
846-
writer.write parser.decls
847847
end
848848

849849
0

lib/rbs/prototype/helpers.rb

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,28 @@ module Helpers
77

88
def parse_comments(string, include_trailing:)
99
Prism.parse_comments(string, version: "current").yield_self do |prism_comments| # steep:ignore UnexpectedKeywordArgument
10-
prism_comments.each_with_object({}) do |comment, hash| #$ Hash[Integer, AST::Comment]
11-
# Skip EmbDoc comments
12-
next unless comment.is_a?(Prism::InlineComment)
13-
# skip like `module Foo # :nodoc:`
14-
next if comment.trailing? && !include_trailing
15-
16-
line = comment.location.start_line
17-
body = "#{comment.location.slice}\n"
18-
body = body[2..-1] or raise
19-
body = "\n" if body.empty?
20-
21-
comment = AST::Comment.new(string: body, location: nil)
22-
if prev_comment = hash.delete(line - 1)
23-
hash[line] = AST::Comment.new(string: prev_comment.string + comment.string,
24-
location: nil)
25-
else
26-
hash[line] = comment
27-
end
10+
process_comments(prism_comments, include_trailing: include_trailing)
11+
end
12+
end
13+
14+
def process_comments(comments, include_trailing:)
15+
comments.each_with_object({}) do |comment, hash| #$ Hash[Integer, AST::Comment]
16+
# Skip EmbDoc comments
17+
next unless comment.is_a?(Prism::InlineComment)
18+
# skip like `module Foo # :nodoc:`
19+
next if comment.trailing? && !include_trailing
20+
21+
line = comment.location.start_line
22+
body = "#{comment.slice}\n"
23+
body = body[2..-1] or raise
24+
body = "\n" if body.empty?
25+
26+
comment = AST::Comment.new(string: body, location: nil)
27+
if prev_comment = hash.delete(line - 1)
28+
hash[line] = AST::Comment.new(string: prev_comment.string + comment.string,
29+
location: nil)
30+
else
31+
hash[line] = comment
2832
end
2933
end
3034
end

lib/rbs/prototype/rb.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ def parse(string)
7777
comments = parse_comments(string, include_trailing: false)
7878

7979
process RubyVM::AbstractSyntaxTree.parse(string), decls: source_decls, comments: comments, context: Context.initial
80+
decls
8081
end
8182

8283
def process(node, decls:, comments:, context:)

0 commit comments

Comments
 (0)