yard2rbs 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/yard2rbs/converter.rb +44 -42
- data/lib/yard2rbs/version.rb +1 -1
- data/lib/yard2rbs/yard_parser.rb +95 -0
- data/lib/yard2rbs.rb +2 -5
- data/sig/lib/yard2rbs/converter.rbs +1 -1
- data/sig/lib/yard2rbs/yard_parser.rbs +6 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 89cede55d743ff594a63059976abb91340df2296817864612b5414ac7d2202ed
|
4
|
+
data.tar.gz: 340ea58b5d5425d9257fc43589534f7097e78ae5bad5040695b532eb88365603
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 06d23c6bf1c51b606a39071c2cdd7b9ee4b72043e2f2b7f36d9b71b27b66e7e9c371b213b0e70bac65c3fb8c1bd9877b8f7175aaac17dcab5cf9b967f9cf80f6
|
7
|
+
data.tar.gz: df576094cc163320c461cd04cf3007b480e372b70f5d19353b5c04e7d192bf9c96a215d3129e1cf3e845e5106ed2f44bb21e0c2029eb389093748c444000ff56
|
data/lib/yard2rbs/converter.rb
CHANGED
@@ -1,13 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "prism"
|
4
|
+
require "rbs"
|
4
5
|
|
5
6
|
# https://ruby.github.io/prism/rb/index.html
|
6
7
|
# https://github.com/ruby/rbs/blob/master/docs/syntax.md
|
7
8
|
# https://github.com/ruby/rbs/blob/master/lib/rbs/prototype/rb.rb
|
9
|
+
# https://rubydoc.info/gems/yard/file/docs/GettingStarted.md
|
8
10
|
|
9
11
|
module Yard2rbs
|
10
12
|
class Converter
|
13
|
+
class << self
|
14
|
+
# @param input_path [String]
|
15
|
+
# @return [String]
|
16
|
+
def convert(input_path)
|
17
|
+
new(input_path).convert
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
11
21
|
# @param input_path [String]
|
12
22
|
# @return [void]
|
13
23
|
def initialize(input_path)
|
@@ -19,6 +29,7 @@ module Yard2rbs
|
|
19
29
|
# @return [String]
|
20
30
|
def convert
|
21
31
|
@_indent_level = 0
|
32
|
+
@_superclasses = []
|
22
33
|
# puts @parse_result.value.inspect
|
23
34
|
process(@parse_result.value)
|
24
35
|
output = @output.join("\n")
|
@@ -39,12 +50,20 @@ module Yard2rbs
|
|
39
50
|
|
40
51
|
when Prism::ClassNode
|
41
52
|
if node.superclass
|
42
|
-
|
53
|
+
case node.superclass
|
54
|
+
when Prism::SelfNode
|
55
|
+
output("class #{node.constant_path.name} < ::#{@_superclasses.join("::")}")
|
56
|
+
else
|
57
|
+
output("class #{node.constant_path.name} < #{node.superclass.name}")
|
58
|
+
end
|
43
59
|
else
|
44
60
|
output("class #{node.constant_path.name}")
|
45
61
|
end
|
62
|
+
|
46
63
|
@_indent_level += 1
|
64
|
+
@_superclasses << node.constant_path.name
|
47
65
|
process(node.compact_child_nodes)
|
66
|
+
@_superclasses.pop
|
48
67
|
@_indent_level -= 1
|
49
68
|
output("end")
|
50
69
|
|
@@ -56,7 +75,9 @@ module Yard2rbs
|
|
56
75
|
when Prism::ModuleNode
|
57
76
|
output("module #{node.constant_path.name}")
|
58
77
|
@_indent_level += 1
|
78
|
+
@_superclasses << node.constant_path.name
|
59
79
|
process(node.compact_child_nodes)
|
80
|
+
@_superclasses.pop
|
60
81
|
@_indent_level -= 1
|
61
82
|
output("end")
|
62
83
|
|
@@ -66,10 +87,14 @@ module Yard2rbs
|
|
66
87
|
output("#{node.name}: #{type}")
|
67
88
|
|
68
89
|
when Prism::ClassVariableWriteNode
|
69
|
-
|
90
|
+
types = parse_comments(node)
|
91
|
+
type = format_types(types[:returns])
|
92
|
+
output("#{node.name}: #{type}")
|
70
93
|
|
71
94
|
when Prism::InstanceVariableWriteNode
|
72
|
-
|
95
|
+
types = parse_comments(node)
|
96
|
+
type = format_types(types[:returns])
|
97
|
+
output("self.#{node.name}: #{type}")
|
73
98
|
|
74
99
|
when Prism::DefNode
|
75
100
|
visibility = @_visibility_node&.name
|
@@ -96,7 +121,7 @@ module Yard2rbs
|
|
96
121
|
|
97
122
|
if arg = node.parameters.rest
|
98
123
|
type = format_types(types[:params][arg.name.to_s])
|
99
|
-
params << "*#{type}
|
124
|
+
params << "*#{type}"
|
100
125
|
end
|
101
126
|
|
102
127
|
if node.parameters.keywords
|
@@ -112,11 +137,19 @@ module Yard2rbs
|
|
112
137
|
|
113
138
|
if arg = node.parameters.keyword_rest
|
114
139
|
type = format_types(types[:params][arg.name.to_s])
|
115
|
-
params << "**#{type}
|
140
|
+
params << "**#{type}"
|
116
141
|
end
|
117
142
|
|
118
143
|
if arg = node.parameters.block
|
119
|
-
|
144
|
+
yieldparams =
|
145
|
+
types[:yieldparams].map do |name, types|
|
146
|
+
type = format_types(types)
|
147
|
+
"#{type} #{name}"
|
148
|
+
end
|
149
|
+
|
150
|
+
return_type = format_types(types[:yieldreturns])
|
151
|
+
|
152
|
+
block = "{ (#{yieldparams.join(", ")}) -> #{return_type} }"
|
120
153
|
end
|
121
154
|
end
|
122
155
|
|
@@ -148,10 +181,12 @@ module Yard2rbs
|
|
148
181
|
when :attr_accessor, :attr_reader, :attr_writer
|
149
182
|
if node.arguments
|
150
183
|
receiver = "self." if self?(node)
|
184
|
+
types = parse_comments(node)
|
185
|
+
type = format_types(types[:returns])
|
151
186
|
node.arguments.arguments.each do |arg|
|
152
187
|
output([
|
153
188
|
"#{receiver}#{node.name}",
|
154
|
-
"#{arg.unescaped}:
|
189
|
+
"#{arg.unescaped}: #{type}"
|
155
190
|
].compact.join(' '))
|
156
191
|
end
|
157
192
|
end
|
@@ -211,41 +246,8 @@ module Yard2rbs
|
|
211
246
|
# @param node [Prism::Node]
|
212
247
|
# @return [Hash]
|
213
248
|
def parse_comments(node)
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
comments = node.location.comments
|
218
|
-
comments&.each do |comment|
|
219
|
-
line = comment.slice
|
220
|
-
|
221
|
-
case line
|
222
|
-
when /@param/
|
223
|
-
if matches = line.match(/# @param ([^\s]+) \[([^\]]+)\].*/)
|
224
|
-
types = matches[2].split(',').map(&:strip)
|
225
|
-
params[matches[1]] = convert_types(types)
|
226
|
-
end
|
227
|
-
when /@return/
|
228
|
-
if matches = line.match(/# @return \[([^\]]+)\].*/)
|
229
|
-
types = matches[1].split(',').map(&:strip)
|
230
|
-
returns += convert_types(types)
|
231
|
-
end
|
232
|
-
end
|
233
|
-
end
|
234
|
-
|
235
|
-
{
|
236
|
-
params: params,
|
237
|
-
returns: returns,
|
238
|
-
}
|
239
|
-
end
|
240
|
-
|
241
|
-
# @param types [String]
|
242
|
-
# @return [Array<String>]
|
243
|
-
def convert_types(types)
|
244
|
-
types.map do |type|
|
245
|
-
type.
|
246
|
-
gsub(/Array\<([^>]+)\>/, 'Array[\1]').
|
247
|
-
gsub(/Hash\<([^>]+),\s*([^>]+)\>/, 'Hash[\1,\2]')
|
248
|
-
end
|
249
|
+
comments = node.location.comments.map(&:slice)
|
250
|
+
YardParser.parse(comments)
|
249
251
|
end
|
250
252
|
|
251
253
|
# @param types [Array<String>]
|
data/lib/yard2rbs/version.rb
CHANGED
@@ -0,0 +1,95 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# TODO:
|
4
|
+
# * Convert YARD "Boolean" to RBS "bool"
|
5
|
+
# * Make some classes top level via :: (e.g. String -> ::String)
|
6
|
+
|
7
|
+
module Yard2rbs
|
8
|
+
class YardParser
|
9
|
+
class << self
|
10
|
+
# @param comments [Array<String>]
|
11
|
+
# @return [Hash<Symbol, Array<String> | Hash<String, String>>]
|
12
|
+
def parse(comments)
|
13
|
+
params = {}
|
14
|
+
returns = []
|
15
|
+
|
16
|
+
yieldparams = {}
|
17
|
+
yieldreturns = []
|
18
|
+
|
19
|
+
comments&.each do |comment|
|
20
|
+
case comment
|
21
|
+
when /@param/
|
22
|
+
if matches = comment.match(/# @param ([^\s]+) \[([^\]]+)\].*/)
|
23
|
+
params[matches[1]] = convert(matches[2])
|
24
|
+
end
|
25
|
+
|
26
|
+
when /@return/
|
27
|
+
if matches = comment.match(/# @return \[([^\]]+)\].*/)
|
28
|
+
returns += convert(matches[1])
|
29
|
+
end
|
30
|
+
|
31
|
+
when /@yieldparam/
|
32
|
+
if matches = comment.match(/# @yieldparam ([^\s]+) \[([^\]]+)\].*/)
|
33
|
+
yieldparams[matches[1]] = convert(matches[2])
|
34
|
+
end
|
35
|
+
|
36
|
+
when /@yieldreturn/
|
37
|
+
if matches = comment.match(/# @yieldreturn \[([^\]]+)\].*/)
|
38
|
+
yieldreturns += convert(matches[1])
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
{
|
44
|
+
params:,
|
45
|
+
returns:,
|
46
|
+
|
47
|
+
yieldparams:,
|
48
|
+
yieldreturns:,
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
# Converts YARD type string into RBS type array
|
53
|
+
# e.g. Input: "String, Array<String>, Hash<String, String>"
|
54
|
+
# Output: ["String", "Array[String]", "Hash[String, String]"]
|
55
|
+
#
|
56
|
+
# @param types_str [String]
|
57
|
+
# @return [Array<String>]
|
58
|
+
def convert(types_str)
|
59
|
+
types = []
|
60
|
+
|
61
|
+
nested_level = 0
|
62
|
+
current_type = []
|
63
|
+
types_str.each_char.with_index(1) do |char, index|
|
64
|
+
case char
|
65
|
+
when ','
|
66
|
+
if nested_level > 0
|
67
|
+
current_type << char
|
68
|
+
else
|
69
|
+
types << current_type.join
|
70
|
+
current_type = []
|
71
|
+
end
|
72
|
+
when '<'
|
73
|
+
nested_level += 1
|
74
|
+
current_type << "["
|
75
|
+
when '>'
|
76
|
+
nested_level -= 1
|
77
|
+
current_type << "]"
|
78
|
+
when ' '
|
79
|
+
if current_type.any?
|
80
|
+
current_type << " "
|
81
|
+
end
|
82
|
+
else
|
83
|
+
current_type << char
|
84
|
+
end
|
85
|
+
|
86
|
+
if index == types_str.size
|
87
|
+
types << current_type.join
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
types
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
data/lib/yard2rbs.rb
CHANGED
@@ -1,19 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require_relative "yard2rbs/converter"
|
4
|
+
require_relative "yard2rbs/yard_parser"
|
4
5
|
require_relative "yard2rbs/version"
|
5
6
|
|
6
|
-
require "rbs"
|
7
|
-
|
8
7
|
module Yard2rbs
|
9
8
|
class << self
|
10
9
|
# @param file_paths [Array<String>]
|
11
10
|
# @return [Boolean]
|
12
11
|
def convert(file_paths)
|
13
|
-
# TODO: Clear out rbs/ directory
|
14
|
-
|
15
12
|
file_paths.each do |file_path|
|
16
|
-
output = Converter.
|
13
|
+
output = Converter.convert(file_path)
|
17
14
|
next if output.empty?
|
18
15
|
|
19
16
|
input_dirname = File.dirname(file_path)
|
@@ -1,5 +1,6 @@
|
|
1
1
|
module Yard2rbs
|
2
2
|
class Converter
|
3
|
+
def self.convert: (String input_path) -> String
|
3
4
|
def initialize: (String input_path) -> void
|
4
5
|
def convert: () -> String
|
5
6
|
private
|
@@ -8,7 +9,6 @@ module Yard2rbs
|
|
8
9
|
def output: (String str) -> String
|
9
10
|
def self?: (Prism::Node node) -> Boolean
|
10
11
|
def parse_comments: (Prism::Node node) -> Hash
|
11
|
-
def convert_types: (String types) -> Array[String]
|
12
12
|
def format_types: (Array[String] types) -> String
|
13
13
|
end
|
14
14
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: yard2rbs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kieran Pilkington
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-06-
|
11
|
+
date: 2024-06-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: prism
|
@@ -54,9 +54,11 @@ files:
|
|
54
54
|
- lib/yard2rbs.rb
|
55
55
|
- lib/yard2rbs/converter.rb
|
56
56
|
- lib/yard2rbs/version.rb
|
57
|
+
- lib/yard2rbs/yard_parser.rb
|
57
58
|
- sig/lib/yard2rbs.rbs
|
58
59
|
- sig/lib/yard2rbs/converter.rbs
|
59
60
|
- sig/lib/yard2rbs/version.rbs
|
61
|
+
- sig/lib/yard2rbs/yard_parser.rbs
|
60
62
|
homepage:
|
61
63
|
licenses:
|
62
64
|
- MIT
|