Skip to content

Commit 088d66a

Browse files
authored
Merge pull request #2828 from Earlopain/no-ripper
Use prism to parse comments
2 parents bb75928 + 79ac260 commit 088d66a

File tree

7 files changed

+63
-49
lines changed

7 files changed

+63
-49
lines changed

Gemfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ PATH
33
specs:
44
rbs (4.0.0.dev.5)
55
logger
6-
prism (>= 1.3.0)
6+
prism (>= 1.6.0)
77
tsort
88

99
PATH

lib/rbs.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
require "json"
77
require "pathname" unless defined?(Pathname)
88
require "pp"
9-
require "ripper"
109
require "logger"
1110
require "tsort"
1211
require "strscan"

lib/rbs/prototype/helpers.rb

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,63 @@ module Prototype
55
module Helpers
66
private
77

8+
# Prism can't parse Ruby 3.2 code
9+
if RUBY_VERSION >= "3.3"
10+
def parse_comments(string, include_trailing:)
11+
Prism.parse_comments(string, version: "current").yield_self do |prism_comments| # steep:ignore UnexpectedKeywordArgument
12+
prism_comments.each_with_object({}) do |comment, hash| #$ Hash[Integer, AST::Comment]
13+
# Skip EmbDoc comments
14+
next unless comment.is_a?(Prism::InlineComment)
15+
# skip like `module Foo # :nodoc:`
16+
next if comment.trailing? && !include_trailing
17+
18+
line = comment.location.start_line
19+
body = "#{comment.location.slice}\n"
20+
body = body[2..-1] or raise
21+
body = "\n" if body.empty?
22+
23+
comment = AST::Comment.new(string: body, location: nil)
24+
if prev_comment = hash.delete(line - 1)
25+
hash[line] = AST::Comment.new(string: prev_comment.string + comment.string,
26+
location: nil)
27+
else
28+
hash[line] = comment
29+
end
30+
end
31+
end
32+
end
33+
else
34+
require "ripper"
35+
def parse_comments(string, include_trailing:)
36+
Ripper.lex(string).yield_self do |tokens|
37+
code_lines = {} #: Hash[Integer, bool]
38+
tokens.each.with_object({}) do |token, hash| #$ Hash[Integer, AST::Comment]
39+
case token[1]
40+
when :on_sp, :on_ignored_nl
41+
# skip
42+
when :on_comment
43+
line = token[0][0]
44+
# skip like `module Foo # :nodoc:`
45+
next if code_lines[line] && !include_trailing
46+
body = token[2][2..-1] or raise
47+
48+
body = "\n" if body.empty?
49+
50+
comment = AST::Comment.new(string: body, location: nil)
51+
if prev_comment = hash.delete(line - 1)
52+
hash[line] = AST::Comment.new(string: prev_comment.string + comment.string,
53+
location: nil)
54+
else
55+
hash[line] = comment
56+
end
57+
else
58+
code_lines[token[0][0]] = true
59+
end
60+
end
61+
end
62+
end
63+
end
64+
865
def block_from_body(node)
966
_, args_node, body_node = node.children
1067
_pre_num, _pre_init, _opt, _first_post, _post_num, _post_init, _rest, _kw, _kwrest, block_var = args_from_node(args_node)

lib/rbs/prototype/rb.rb

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -74,32 +74,7 @@ def decls
7474

7575
def parse(string)
7676
# @type var comments: Hash[Integer, AST::Comment]
77-
comments = Ripper.lex(string).yield_self do |tokens|
78-
code_lines = {} #: Hash[Integer, bool]
79-
tokens.each.with_object({}) do |token, hash| #$ Hash[Integer, AST::Comment]
80-
case token[1]
81-
when :on_sp, :on_ignored_nl
82-
# skip
83-
when :on_comment
84-
line = token[0][0]
85-
# skip like `module Foo # :nodoc:`
86-
next if code_lines[line]
87-
body = token[2][2..-1] or raise
88-
89-
body = "\n" if body.empty?
90-
91-
comment = AST::Comment.new(string: body, location: nil)
92-
if prev_comment = hash.delete(line - 1)
93-
hash[line] = AST::Comment.new(string: prev_comment.string + comment.string,
94-
location: nil)
95-
else
96-
hash[line] = comment
97-
end
98-
else
99-
code_lines[token[0][0]] = true
100-
end
101-
end
102-
end
77+
comments = parse_comments(string, include_trailing: false)
10378

10479
process RubyVM::AbstractSyntaxTree.parse(string), decls: source_decls, comments: comments, context: Context.initial
10580
end

lib/rbs/prototype/rbi.rb

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,26 +16,7 @@ def initialize
1616
end
1717

1818
def parse(string)
19-
comments = Ripper.lex(string).yield_self do |tokens|
20-
tokens.each.with_object({}) do |token, hash| #$ Hash[Integer, AST::Comment]
21-
if token[1] == :on_comment
22-
line = token[0][0]
23-
body = token[2][2..-1] or raise
24-
25-
body = "\n" if body.empty?
26-
27-
comment = AST::Comment.new(string: body, location: nil)
28-
if (prev_comment = hash.delete(line - 1))
29-
hash[line] = AST::Comment.new(
30-
string: prev_comment.string + comment.string,
31-
location: nil
32-
)
33-
else
34-
hash[line] = comment
35-
end
36-
end
37-
end
38-
end
19+
comments = parse_comments(string, include_trailing: true)
3920
process RubyVM::AbstractSyntaxTree.parse(string), comments: comments
4021
end
4122

rbs.gemspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,6 @@ Gem::Specification.new do |spec|
4646
spec.require_paths = ["lib"]
4747
spec.required_ruby_version = ">= 3.2"
4848
spec.add_dependency "logger"
49-
spec.add_dependency "prism", ">= 1.3.0"
49+
spec.add_dependency "prism", ">= 1.6.0"
5050
spec.add_dependency "tsort"
5151
end

sig/prototype/helpers.rbs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ module RBS
33
module Helpers
44
type node = RubyVM::AbstractSyntaxTree::Node
55

6+
def parse_comments: (String, include_trailing: bool) -> Hash[Integer, AST::Comment]
7+
68
def block_from_body: (node) -> Types::Block?
79

810
def each_node: (Array[untyped] nodes) { (node) -> void } -> void

0 commit comments

Comments
 (0)