rbs-inline 0.2.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/lib/rbs/inline/ast/annotations.rb +21 -0
- data/lib/rbs/inline/ast/comment_lines.rb +19 -2
- data/lib/rbs/inline/ast/declarations.rb +6 -13
- data/lib/rbs/inline/ast/members.rb +9 -26
- data/lib/rbs/inline/ast/tree.rb +88 -4
- data/lib/rbs/inline/cli.rb +17 -4
- data/lib/rbs/inline/node_utils.rb +4 -0
- data/lib/rbs/inline/parser.rb +26 -8
- data/lib/rbs/inline/version.rb +1 -1
- data/lib/rbs/inline/writer.rb +81 -9
- data/lib/rbs/inline.rb +3 -0
- data/rbs_collection.lock.yaml +3 -7
- data/rbs_collection.yaml +2 -0
- data/sig/generated/rbs/inline/ast/annotations.rbs +2 -0
- data/sig/{rbs → generated/rbs}/inline/ast/comment_lines.rbs +8 -4
- data/sig/generated/rbs/inline/ast/declarations.rbs +4 -1
- data/sig/generated/rbs/inline/ast/members.rbs +8 -10
- data/sig/{rbs → generated/rbs}/inline/ast/tree.rbs +49 -21
- data/sig/generated/rbs/inline/node_utils.rbs +11 -0
- data/sig/generated/rbs/inline/parser.rbs +8 -4
- data/sig/generated/rbs/inline/version.rbs +7 -0
- data/sig/generated/rbs/inline/writer.rbs +72 -0
- data/sig/generated/rbs/inline.rbs +7 -0
- metadata +20 -16
- data/sig/rbs/inline/annotation_parser.rbs +0 -0
- data/sig/rbs/inline/node_utils.rbs +0 -7
- data/sig/rbs/inline/writer.rbs +0 -27
- data/sig/rbs/inline.rbs +0 -41
- data/yard-samples/hello.rb +0 -6
- data/yard-samples/sample1.rb +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 713b2bd4c5ddd833fa1bd1a71505924081013101a8a41200a88fed55751146ba
|
4
|
+
data.tar.gz: 44ffe7a91c0c0afeb7e163a02de508c50f96a609ae7c64593a6b739109ac11b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6507f727be79bcae3890c8b8c3c3865544022058e44d5bfd060efb5df0c91e50f2b5e43a11f284c7ea3de1066bdd0ed7e269a14c20b45cc05cafa7ad60ecffb7
|
7
|
+
data.tar.gz: aad87cafa19657b4d4b055527924146cb232cd96c56081bcbb24c1e1b0ff2fc24a449bdfe2132a43c2e5f5ac2affca8d615d0946b135676979556eaca4887aec
|
data/README.md
CHANGED
@@ -80,12 +80,12 @@ The gem works as a transpiler from annotated Ruby code to RBS files. Run `rbs-in
|
|
80
80
|
$ bundle exec rbs-inline lib
|
81
81
|
|
82
82
|
# Save generated RBS files under sig/generated
|
83
|
-
$ bundle exec rbs-inline --output
|
83
|
+
$ bundle exec rbs-inline --output lib
|
84
84
|
```
|
85
85
|
|
86
86
|
You may want to use `fswatch` or likes to automatically generate RBS files when you edit the Ruby code.
|
87
87
|
|
88
|
-
$ fswatch -0 lib | xargs -0 -n1 bundle exec rbs-inline --output
|
88
|
+
$ fswatch -0 lib | xargs -0 -n1 bundle exec rbs-inline --output
|
89
89
|
|
90
90
|
## More materials
|
91
91
|
|
@@ -4,6 +4,27 @@ module RBS
|
|
4
4
|
module Inline
|
5
5
|
module AST
|
6
6
|
module Annotations
|
7
|
+
# @rbs!
|
8
|
+
# type t = VarType
|
9
|
+
# | ReturnType
|
10
|
+
# | Use
|
11
|
+
# | Inherits
|
12
|
+
# | Generic
|
13
|
+
# | ModuleSelf
|
14
|
+
# | Skip
|
15
|
+
# | Assertion
|
16
|
+
# | Application
|
17
|
+
# | RBSAnnotation
|
18
|
+
# | Override
|
19
|
+
# | IvarType
|
20
|
+
# | Yields
|
21
|
+
# | Embedded
|
22
|
+
# # | Def
|
23
|
+
# # | AttrReader | AttrWriter | AttrAccessor
|
24
|
+
# # | Include | Extend | Prepend
|
25
|
+
# # | Alias
|
26
|
+
|
27
|
+
|
7
28
|
class Base
|
8
29
|
attr_reader :source #:: CommentLines
|
9
30
|
attr_reader :tree #:: Tree
|
@@ -1,9 +1,24 @@
|
|
1
|
+
# rbs_inline: enabled
|
2
|
+
|
1
3
|
module RBS
|
2
4
|
module Inline
|
3
5
|
module AST
|
6
|
+
# CommentLines represents consecutive comments
|
7
|
+
#
|
8
|
+
# The comments construct one String.
|
9
|
+
#
|
10
|
+
# ```ruby
|
11
|
+
# # Hello <-- Comment1
|
12
|
+
# # World <-- Comment2
|
13
|
+
# ```
|
14
|
+
#
|
15
|
+
# We want to get a String of comment1 and comment2, `"Hello\nWorld".
|
16
|
+
# And want to translate a location in the string into the location in comment1 and comment2.
|
17
|
+
#
|
4
18
|
class CommentLines
|
5
|
-
attr_reader :comments
|
19
|
+
attr_reader :comments #:: Array[[Prism::Comment, Integer]]
|
6
20
|
|
21
|
+
# @rbs comments: Array[Prism::Comment]
|
7
22
|
def initialize(comments)
|
8
23
|
offsets = comments.map do |comment|
|
9
24
|
comment.location.slice.index(/[^#\s]/) || 1
|
@@ -18,10 +33,12 @@ module RBS
|
|
18
33
|
end
|
19
34
|
end
|
20
35
|
|
21
|
-
def string
|
36
|
+
def string #:: String
|
22
37
|
comments.map {|comment, offset| comment.location.slice[offset..] }.join("\n")
|
23
38
|
end
|
24
39
|
|
40
|
+
# @rbs index: Integer
|
41
|
+
# @rbs returns [Prism::Comment, Integer]?
|
25
42
|
def comment_location(index)
|
26
43
|
comments.each do |comment, offset|
|
27
44
|
comment_length = comment.location.length
|
@@ -9,23 +9,13 @@ module RBS
|
|
9
9
|
# @rbs returns TypeName?
|
10
10
|
def type_name(node)
|
11
11
|
case node
|
12
|
-
when Prism::ConstantReadNode
|
13
|
-
TypeName(node.
|
14
|
-
when Prism::ConstantPathNode
|
15
|
-
if node.parent
|
16
|
-
if parent = type_name(node.parent)
|
17
|
-
if child = type_name(node.child)
|
18
|
-
return parent + child
|
19
|
-
end
|
20
|
-
end
|
21
|
-
else
|
22
|
-
type_name(node.child)&.absolute!
|
23
|
-
end
|
12
|
+
when Prism::ConstantReadNode, Prism::ConstantPathNode
|
13
|
+
TypeName(node.full_name)
|
24
14
|
end
|
25
15
|
end
|
26
16
|
end
|
27
17
|
|
28
|
-
# @rbs! type t = ClassDecl | ModuleDecl | ConstantDecl
|
18
|
+
# @rbs! type t = ClassDecl | ModuleDecl | ConstantDecl | SingletonClassDecl
|
29
19
|
|
30
20
|
# @rbs!
|
31
21
|
# interface _WithComments
|
@@ -237,6 +227,9 @@ module RBS
|
|
237
227
|
node.location.start_line
|
238
228
|
end
|
239
229
|
end
|
230
|
+
|
231
|
+
class SingletonClassDecl < ModuleOrClass #[Prism::SingletonClassNode]
|
232
|
+
end
|
240
233
|
end
|
241
234
|
end
|
242
235
|
end
|
@@ -4,6 +4,11 @@ module RBS
|
|
4
4
|
module Inline
|
5
5
|
module AST
|
6
6
|
module Members
|
7
|
+
# @rbs!
|
8
|
+
# type ruby = RubyDef | RubyAlias | RubyMixin | RubyAttr | RubyPublic | RubyPrivate
|
9
|
+
# type rbs = RBSIvar | RBSEmbedded
|
10
|
+
# type t = ruby | rbs
|
11
|
+
|
7
12
|
class Base
|
8
13
|
attr_reader :location #:: Prism::Location
|
9
14
|
|
@@ -64,27 +69,6 @@ module RBS
|
|
64
69
|
end
|
65
70
|
end
|
66
71
|
|
67
|
-
# Returns the `kind` of the method definition
|
68
|
-
#
|
69
|
-
# [FIXME] It only supports `self` receiver.
|
70
|
-
#
|
71
|
-
# ```rb
|
72
|
-
# def self.foo = () # :singleton
|
73
|
-
# def object.foo = () # Not supported (returns :instance)
|
74
|
-
# ```
|
75
|
-
#
|
76
|
-
def method_kind #:: RBS::AST::Members::MethodDefinition::kind
|
77
|
-
# FIXME: really hacky implementation
|
78
|
-
case node.receiver
|
79
|
-
when Prism::SelfNode
|
80
|
-
:singleton
|
81
|
-
when nil
|
82
|
-
:instance
|
83
|
-
else
|
84
|
-
:instance
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
72
|
def return_type #:: Types::t?
|
89
73
|
if assertion
|
90
74
|
if assertion.type?
|
@@ -341,6 +325,8 @@ module RBS
|
|
341
325
|
end
|
342
326
|
|
343
327
|
class RubyMixin < RubyBase
|
328
|
+
include Declarations::ConstantUtil
|
329
|
+
|
344
330
|
# CallNode that calls `include`, `prepend`, and `extend` method
|
345
331
|
attr_reader :node #:: Prism::CallNode
|
346
332
|
|
@@ -371,11 +357,8 @@ module RBS
|
|
371
357
|
return unless node.arguments.arguments.size == 1
|
372
358
|
|
373
359
|
arg = node.arguments.arguments[0] || raise
|
374
|
-
|
375
|
-
|
376
|
-
else
|
377
|
-
raise
|
378
|
-
end
|
360
|
+
type_name = type_name(arg)
|
361
|
+
return unless type_name
|
379
362
|
|
380
363
|
args = [] #: Array[Types::t]
|
381
364
|
if application
|
data/lib/rbs/inline/ast/tree.rb
CHANGED
@@ -1,17 +1,28 @@
|
|
1
|
+
# rbs_inline: enabled
|
2
|
+
|
1
3
|
module RBS
|
2
4
|
module Inline
|
3
5
|
module AST
|
4
6
|
class Tree
|
5
|
-
|
6
|
-
|
7
|
-
|
7
|
+
# @rbs!
|
8
|
+
# type token = [Symbol, String]
|
9
|
+
# type tree = token | Tree | Types::t | MethodType | nil
|
10
|
+
|
11
|
+
attr_reader :trees #:: Array[tree]
|
12
|
+
attr_reader :type #:: Symbol
|
13
|
+
|
14
|
+
# Children but without `tWHITESPACE` tokens
|
15
|
+
attr_reader :non_trivia_trees #:: Array[tree]
|
8
16
|
|
17
|
+
# @rbs type: Symbol
|
9
18
|
def initialize(type)
|
10
19
|
@type = type
|
11
20
|
@trees = []
|
12
21
|
@non_trivia_trees = []
|
13
22
|
end
|
14
23
|
|
24
|
+
# @rbs tok: tree
|
25
|
+
# @rbs returns self
|
15
26
|
def <<(tok)
|
16
27
|
trees << tok
|
17
28
|
unless tok.is_a?(Array) && tok[0] == :tWHITESPACE
|
@@ -20,7 +31,8 @@ module RBS
|
|
20
31
|
self
|
21
32
|
end
|
22
33
|
|
23
|
-
|
34
|
+
# Returns the source code associated to the tree
|
35
|
+
def to_s #:: String
|
24
36
|
buf = +""
|
25
37
|
|
26
38
|
trees.each do |tree|
|
@@ -39,6 +51,12 @@ module RBS
|
|
39
51
|
buf
|
40
52
|
end
|
41
53
|
|
54
|
+
# Returns n-th token from the children
|
55
|
+
#
|
56
|
+
# Raises if the value is not a token or nil.
|
57
|
+
#
|
58
|
+
# @rbs index: Integer
|
59
|
+
# @rbs returns token?
|
42
60
|
def nth_token(index)
|
43
61
|
tok = non_trivia_trees[index]
|
44
62
|
case tok
|
@@ -49,6 +67,12 @@ module RBS
|
|
49
67
|
end
|
50
68
|
end
|
51
69
|
|
70
|
+
# Returns n-th token from the children
|
71
|
+
#
|
72
|
+
# Returns `nil` if the value is not a token.
|
73
|
+
#
|
74
|
+
# @rbs index: Integer
|
75
|
+
# @rbs returns token?
|
52
76
|
def nth_token?(index)
|
53
77
|
tok = non_trivia_trees[index]
|
54
78
|
case tok
|
@@ -59,10 +83,22 @@ module RBS
|
|
59
83
|
end
|
60
84
|
end
|
61
85
|
|
86
|
+
# Returns n-th token from the children
|
87
|
+
#
|
88
|
+
# Raises if the value is not token.
|
89
|
+
#
|
90
|
+
# @rbs index: Integer
|
91
|
+
# @rbs returns token
|
62
92
|
def nth_token!(index)
|
63
93
|
nth_token(index) || raise
|
64
94
|
end
|
65
95
|
|
96
|
+
# Returns n-th tree from the children
|
97
|
+
#
|
98
|
+
# Raises if the value is not a tree or nil.
|
99
|
+
#
|
100
|
+
# @rbs index: Integer
|
101
|
+
# @rbs returns Tree?
|
66
102
|
def nth_tree(index)
|
67
103
|
tok = non_trivia_trees[index]
|
68
104
|
case tok
|
@@ -73,6 +109,12 @@ module RBS
|
|
73
109
|
end
|
74
110
|
end
|
75
111
|
|
112
|
+
# Returns n-th tree from the children
|
113
|
+
#
|
114
|
+
# Returns `nil` if the value is not a tree or nil.
|
115
|
+
#
|
116
|
+
# @rbs index: Integer
|
117
|
+
# @rbs returns Tree?
|
76
118
|
def nth_tree?(index)
|
77
119
|
tok = non_trivia_trees[index]
|
78
120
|
case tok
|
@@ -83,11 +125,23 @@ module RBS
|
|
83
125
|
end
|
84
126
|
end
|
85
127
|
|
128
|
+
# Returns n-th tree from the children
|
129
|
+
#
|
130
|
+
# Raises if the value is not a tree.
|
131
|
+
#
|
132
|
+
# @rbs index: Integer
|
133
|
+
# @rbs returns Tree
|
86
134
|
def nth_tree!(index)
|
87
135
|
nth_tree(index) || raise
|
88
136
|
end
|
89
137
|
|
90
138
|
|
139
|
+
# Returns n-th type from the children
|
140
|
+
#
|
141
|
+
# Raises if the value is not a type or nil.
|
142
|
+
#
|
143
|
+
# @rbs index: Integer
|
144
|
+
# @rbs returns Types::t?
|
91
145
|
def nth_type(index)
|
92
146
|
tok = non_trivia_trees[index]
|
93
147
|
case tok
|
@@ -98,6 +152,12 @@ module RBS
|
|
98
152
|
end
|
99
153
|
end
|
100
154
|
|
155
|
+
# Returns n-th type from the children
|
156
|
+
#
|
157
|
+
# Returns `nil` if the value is not a type.
|
158
|
+
#
|
159
|
+
# @rbs index: Integer
|
160
|
+
# @rbs returns Types::t?
|
101
161
|
def nth_type?(index)
|
102
162
|
tok = non_trivia_trees[index]
|
103
163
|
case tok
|
@@ -108,10 +168,22 @@ module RBS
|
|
108
168
|
end
|
109
169
|
end
|
110
170
|
|
171
|
+
# Returns n-th type from the children
|
172
|
+
#
|
173
|
+
# Raises if the value is not a type.
|
174
|
+
#
|
175
|
+
# @rbs index: Integer
|
176
|
+
# @rbs returns Types::t
|
111
177
|
def nth_type!(index)
|
112
178
|
nth_type(index) || raise
|
113
179
|
end
|
114
180
|
|
181
|
+
# Returns n-th method type from the children
|
182
|
+
#
|
183
|
+
# Raises if the value is not a method type or `nil`.
|
184
|
+
#
|
185
|
+
# @rbs index: Integer
|
186
|
+
# @rbs returns MethodType?
|
115
187
|
def nth_method_type(index)
|
116
188
|
tok = non_trivia_trees[index]
|
117
189
|
case tok
|
@@ -122,6 +194,12 @@ module RBS
|
|
122
194
|
end
|
123
195
|
end
|
124
196
|
|
197
|
+
# Returns n-th method type from the children
|
198
|
+
#
|
199
|
+
# Returns `nil` if the value is not a method type.
|
200
|
+
#
|
201
|
+
# @rbs index: Integer
|
202
|
+
# @rbs returns MethodType?
|
125
203
|
def nth_method_type?(index)
|
126
204
|
tok = non_trivia_trees[index]
|
127
205
|
case tok
|
@@ -132,6 +210,12 @@ module RBS
|
|
132
210
|
end
|
133
211
|
end
|
134
212
|
|
213
|
+
# Returns n-th method tree from the children
|
214
|
+
#
|
215
|
+
# Raises if the value is not a method tree.
|
216
|
+
#
|
217
|
+
# @rbs index: Integer
|
218
|
+
# @rbs returns MethodType
|
135
219
|
def nth_method_type!(index)
|
136
220
|
nth_method_type(index) || raise
|
137
221
|
end
|
data/lib/rbs/inline/cli.rb
CHANGED
@@ -72,15 +72,28 @@ module RBS
|
|
72
72
|
def run(args)
|
73
73
|
base_paths = [Pathname("lib"), Pathname("app")]
|
74
74
|
output_path = nil #: Pathname?
|
75
|
+
opt_in = true
|
75
76
|
|
76
77
|
OptionParser.new do |opts|
|
77
|
-
opts.on("--base=
|
78
|
+
opts.on("--base=BASE", "The path to calculate relative path of files (defaults to #{base_paths.join(File::PATH_SEPARATOR)})") do |str|
|
78
79
|
# @type var str: String
|
79
80
|
base_paths = str.split(File::PATH_SEPARATOR).map {|path| Pathname(path) }
|
80
81
|
end
|
81
82
|
|
82
|
-
opts.on("--output=
|
83
|
-
|
83
|
+
opts.on("--output[=DEST]", "Save the generated RBS files under `sig/generated` or DEST if specified (defaults to output to STDOUT)") do
|
84
|
+
if _1
|
85
|
+
output_path = Pathname(_1)
|
86
|
+
else
|
87
|
+
output_path = Pathname("sig/generated")
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
opts.on("--opt-out", "Generates RBS files by default. Opt-out with `# rbs_inline: disabled` comment") do
|
92
|
+
opt_in = false
|
93
|
+
end
|
94
|
+
|
95
|
+
opts.on("--opt-in", "Generates RBS files only for files with `# rbs_inline: enabled` comment (default)") do
|
96
|
+
opt_in = true
|
84
97
|
end
|
85
98
|
|
86
99
|
opts.on("--verbose") do
|
@@ -126,7 +139,7 @@ module RBS
|
|
126
139
|
|
127
140
|
logger.debug { "Parsing ruby file #{target}..." }
|
128
141
|
|
129
|
-
if (uses, decls = Parser.parse(Prism.parse_file(target.to_s)))
|
142
|
+
if (uses, decls = Parser.parse(Prism.parse_file(target.to_s), opt_in: opt_in))
|
130
143
|
writer = Writer.new()
|
131
144
|
writer.header("Generated from #{target.relative? ? target : target.relative_path_from(Pathname.pwd)} with RBS::Inline")
|
132
145
|
writer.write(uses, decls)
|
data/lib/rbs/inline/parser.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# rbs_inline: enabled
|
2
|
+
|
1
3
|
# @rbs use Prism::*
|
2
4
|
|
3
5
|
module RBS
|
@@ -36,22 +38,26 @@ module RBS
|
|
36
38
|
@comments = {}
|
37
39
|
end
|
38
40
|
|
39
|
-
# @rbs result: ParseResult
|
41
|
+
# @rbs result: ParseResult
|
42
|
+
# @rbs opt_in: bool -- `true` for *opt-out* mode, `false` for *opt-in* mode.
|
40
43
|
# @rbs returns [Array[AST::Annotations::Use], Array[AST::Declarations::t]]?
|
41
|
-
def self.parse(result)
|
44
|
+
def self.parse(result, opt_in:)
|
42
45
|
instance = Parser.new()
|
43
46
|
|
44
|
-
# pp result
|
45
|
-
|
46
47
|
annots = AnnotationParser.parse(result.comments)
|
47
48
|
annots.each do |result|
|
48
49
|
instance.comments[result.line_range.end] = result
|
49
50
|
end
|
50
51
|
|
51
|
-
|
52
|
-
|
52
|
+
with_enable_magic_comment = result.comments.any? {|comment| comment.location.slice =~ /\A# rbs_inline: enabled\Z/}
|
53
|
+
with_disable_magic_comment = result.comments.any? {|comment| comment.location.slice =~ /\A# rbs_inline: disabled\Z/}
|
53
54
|
|
54
|
-
return
|
55
|
+
return if with_disable_magic_comment # Skips if `rbs_inline: disabled`
|
56
|
+
|
57
|
+
if opt_in
|
58
|
+
# opt-in means the `rbs_inline: enable` is required.
|
59
|
+
return unless with_enable_magic_comment
|
60
|
+
end
|
55
61
|
|
56
62
|
uses = [] #: Array[AST::Annotations::Use]
|
57
63
|
annots.each do |annot|
|
@@ -80,7 +86,7 @@ module RBS
|
|
80
86
|
current_class_module_decl or raise
|
81
87
|
end
|
82
88
|
|
83
|
-
#:: (AST::Declarations::ModuleDecl | AST::Declarations::ClassDecl) { () -> void } -> void
|
89
|
+
#:: (AST::Declarations::ModuleDecl | AST::Declarations::ClassDecl | AST::Declarations::SingletonClassDecl) { () -> void } -> void
|
84
90
|
#:: (AST::Declarations::ConstantDecl) -> void
|
85
91
|
def push_class_module_decl(decl)
|
86
92
|
if current = current_class_module_decl
|
@@ -146,6 +152,18 @@ module RBS
|
|
146
152
|
load_inner_annotations(node.location.start_line, node.location.end_line, class_decl.members)
|
147
153
|
end
|
148
154
|
|
155
|
+
# @rbs override
|
156
|
+
def visit_singleton_class_node(node)
|
157
|
+
return if ignored_node?(node)
|
158
|
+
|
159
|
+
associated_comment = comments.delete(node.location.start_line - 1)
|
160
|
+
singleton_decl = AST::Declarations::SingletonClassDecl.new(node, associated_comment)
|
161
|
+
|
162
|
+
push_class_module_decl(singleton_decl) do
|
163
|
+
visit node.body
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
149
167
|
# @rbs override
|
150
168
|
def visit_module_node(node)
|
151
169
|
return if ignored_node?(node)
|