rbs 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +7 -1
- data/.gitignore +1 -1
- data/CHANGELOG.md +7 -0
- data/Gemfile +12 -0
- data/README.md +86 -47
- data/Rakefile +54 -21
- data/bin/rbs-prof +9 -0
- data/bin/run_in_md.rb +49 -0
- data/lib/rbs.rb +2 -0
- data/lib/rbs/ast/declarations.rb +62 -7
- data/lib/rbs/ast/members.rb +41 -17
- data/lib/rbs/cli.rb +299 -121
- data/lib/rbs/constant.rb +4 -4
- data/lib/rbs/constant_table.rb +50 -44
- data/lib/rbs/definition.rb +175 -59
- data/lib/rbs/definition_builder.rb +647 -603
- data/lib/rbs/environment.rb +338 -209
- data/lib/rbs/environment_walker.rb +14 -23
- data/lib/rbs/errors.rb +141 -3
- data/lib/rbs/parser.y +14 -9
- data/lib/rbs/prototype/rb.rb +100 -112
- data/lib/rbs/prototype/rbi.rb +4 -2
- data/lib/rbs/prototype/runtime.rb +10 -6
- data/lib/rbs/substitution.rb +8 -1
- data/lib/rbs/test/hook.rb +2 -2
- data/lib/rbs/test/setup.rb +3 -1
- data/lib/rbs/test/test_helper.rb +2 -5
- data/lib/rbs/test/type_check.rb +1 -2
- data/lib/rbs/type_name_resolver.rb +58 -0
- data/lib/rbs/types.rb +94 -2
- data/lib/rbs/validator.rb +51 -0
- data/lib/rbs/variance_calculator.rb +12 -2
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs/writer.rb +125 -89
- data/rbs.gemspec +0 -10
- data/schema/decls.json +15 -0
- data/schema/members.json +3 -0
- data/stdlib/benchmark/benchmark.rbs +151 -151
- data/stdlib/builtin/enumerable.rbs +1 -1
- data/stdlib/builtin/file.rbs +0 -3
- data/stdlib/builtin/io.rbs +4 -4
- data/stdlib/builtin/thread.rbs +2 -2
- data/stdlib/csv/csv.rbs +4 -6
- data/stdlib/fiber/fiber.rbs +1 -1
- data/stdlib/json/json.rbs +1 -1
- data/stdlib/mutex_m/mutex_m.rbs +77 -0
- data/stdlib/pathname/pathname.rbs +6 -6
- data/stdlib/prime/integer-extension.rbs +1 -1
- data/stdlib/prime/prime.rbs +44 -44
- data/stdlib/tmpdir/tmpdir.rbs +1 -1
- metadata +8 -129
data/lib/rbs/ast/members.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
module RBS
|
2
2
|
module AST
|
3
3
|
module Members
|
4
|
-
class
|
4
|
+
class Base
|
5
|
+
end
|
6
|
+
|
7
|
+
class MethodDefinition < Base
|
5
8
|
attr_reader :name
|
6
9
|
attr_reader :kind
|
7
10
|
attr_reader :types
|
@@ -9,8 +12,9 @@ module RBS
|
|
9
12
|
attr_reader :location
|
10
13
|
attr_reader :comment
|
11
14
|
attr_reader :attributes
|
15
|
+
attr_reader :overload
|
12
16
|
|
13
|
-
def initialize(name:, kind:, types:, annotations:, location:, comment:, attributes:)
|
17
|
+
def initialize(name:, kind:, types:, annotations:, location:, comment:, attributes:, overload:)
|
14
18
|
@name = name
|
15
19
|
@kind = kind
|
16
20
|
@types = types
|
@@ -18,6 +22,7 @@ module RBS
|
|
18
22
|
@location = location
|
19
23
|
@comment = comment
|
20
24
|
@attributes = attributes
|
25
|
+
@overload = overload
|
21
26
|
end
|
22
27
|
|
23
28
|
def ==(other)
|
@@ -25,13 +30,14 @@ module RBS
|
|
25
30
|
other.name == name &&
|
26
31
|
other.kind == kind &&
|
27
32
|
other.types == types &&
|
28
|
-
other.attributes == attributes
|
33
|
+
other.attributes == attributes &&
|
34
|
+
other.overload == overload
|
29
35
|
end
|
30
36
|
|
31
37
|
alias eql? ==
|
32
38
|
|
33
39
|
def hash
|
34
|
-
self.class.hash ^ name.hash ^ kind.hash ^ types.hash ^ attributes.hash
|
40
|
+
self.class.hash ^ name.hash ^ kind.hash ^ types.hash ^ attributes.hash ^ overload.hash
|
35
41
|
end
|
36
42
|
|
37
43
|
def instance?
|
@@ -42,6 +48,23 @@ module RBS
|
|
42
48
|
kind == :singleton || kind == :singleton_instance
|
43
49
|
end
|
44
50
|
|
51
|
+
def overload?
|
52
|
+
overload
|
53
|
+
end
|
54
|
+
|
55
|
+
def update(name: self.name, kind: self.kind, types: self.types, annotations: self.annotations, location: self.location, comment: self.comment, attributes: self.attributes, overload: self.overload)
|
56
|
+
self.class.new(
|
57
|
+
name: name,
|
58
|
+
kind: kind,
|
59
|
+
types: types,
|
60
|
+
annotations: annotations,
|
61
|
+
location: location,
|
62
|
+
comment: comment,
|
63
|
+
attributes: attributes,
|
64
|
+
overload: overload
|
65
|
+
)
|
66
|
+
end
|
67
|
+
|
45
68
|
def to_json(*a)
|
46
69
|
{
|
47
70
|
member: :method_definition,
|
@@ -50,7 +73,8 @@ module RBS
|
|
50
73
|
annotations: annotations,
|
51
74
|
location: location,
|
52
75
|
comment: comment,
|
53
|
-
attributes: attributes
|
76
|
+
attributes: attributes,
|
77
|
+
overload: overload
|
54
78
|
}.to_json(*a)
|
55
79
|
end
|
56
80
|
end
|
@@ -79,7 +103,7 @@ module RBS
|
|
79
103
|
end
|
80
104
|
end
|
81
105
|
|
82
|
-
class InstanceVariable
|
106
|
+
class InstanceVariable < Base
|
83
107
|
include Var
|
84
108
|
|
85
109
|
def to_json(*a)
|
@@ -93,7 +117,7 @@ module RBS
|
|
93
117
|
end
|
94
118
|
end
|
95
119
|
|
96
|
-
class ClassInstanceVariable
|
120
|
+
class ClassInstanceVariable < Base
|
97
121
|
include Var
|
98
122
|
|
99
123
|
def to_json(*a)
|
@@ -107,7 +131,7 @@ module RBS
|
|
107
131
|
end
|
108
132
|
end
|
109
133
|
|
110
|
-
class ClassVariable
|
134
|
+
class ClassVariable < Base
|
111
135
|
include Var
|
112
136
|
|
113
137
|
def to_json(*a)
|
@@ -149,7 +173,7 @@ module RBS
|
|
149
173
|
end
|
150
174
|
end
|
151
175
|
|
152
|
-
class Include
|
176
|
+
class Include < Base
|
153
177
|
include Mixin
|
154
178
|
|
155
179
|
def to_json(*a)
|
@@ -164,7 +188,7 @@ module RBS
|
|
164
188
|
end
|
165
189
|
end
|
166
190
|
|
167
|
-
class Extend
|
191
|
+
class Extend < Base
|
168
192
|
include Mixin
|
169
193
|
|
170
194
|
def to_json(*a)
|
@@ -179,7 +203,7 @@ module RBS
|
|
179
203
|
end
|
180
204
|
end
|
181
205
|
|
182
|
-
class Prepend
|
206
|
+
class Prepend < Base
|
183
207
|
include Mixin
|
184
208
|
|
185
209
|
def to_json(*a)
|
@@ -225,7 +249,7 @@ module RBS
|
|
225
249
|
end
|
226
250
|
end
|
227
251
|
|
228
|
-
class AttrReader
|
252
|
+
class AttrReader < Base
|
229
253
|
include Attribute
|
230
254
|
|
231
255
|
def to_json(*a)
|
@@ -241,7 +265,7 @@ module RBS
|
|
241
265
|
end
|
242
266
|
end
|
243
267
|
|
244
|
-
class AttrAccessor
|
268
|
+
class AttrAccessor < Base
|
245
269
|
include Attribute
|
246
270
|
|
247
271
|
def to_json(*a)
|
@@ -257,7 +281,7 @@ module RBS
|
|
257
281
|
end
|
258
282
|
end
|
259
283
|
|
260
|
-
class AttrWriter
|
284
|
+
class AttrWriter < Base
|
261
285
|
include Attribute
|
262
286
|
|
263
287
|
def to_json(*a)
|
@@ -291,7 +315,7 @@ module RBS
|
|
291
315
|
end
|
292
316
|
end
|
293
317
|
|
294
|
-
class Public
|
318
|
+
class Public < Base
|
295
319
|
include LocationOnly
|
296
320
|
|
297
321
|
def to_json(*a)
|
@@ -299,7 +323,7 @@ module RBS
|
|
299
323
|
end
|
300
324
|
end
|
301
325
|
|
302
|
-
class Private
|
326
|
+
class Private < Base
|
303
327
|
include LocationOnly
|
304
328
|
|
305
329
|
def to_json(*a)
|
@@ -307,7 +331,7 @@ module RBS
|
|
307
331
|
end
|
308
332
|
end
|
309
333
|
|
310
|
-
class Alias
|
334
|
+
class Alias < Base
|
311
335
|
attr_reader :new_name
|
312
336
|
attr_reader :old_name
|
313
337
|
attr_reader :kind
|
data/lib/rbs/cli.rb
CHANGED
@@ -36,18 +36,18 @@ module RBS
|
|
36
36
|
@stderr = stderr
|
37
37
|
end
|
38
38
|
|
39
|
-
COMMANDS = [:ast, :list, :ancestors, :methods, :method, :validate, :constant, :paths, :prototype, :vendor, :
|
39
|
+
COMMANDS = [:ast, :list, :ancestors, :methods, :method, :validate, :constant, :paths, :prototype, :vendor, :parse]
|
40
40
|
|
41
41
|
def library_parse(opts, options:)
|
42
|
-
opts.on("-r LIBRARY") do |lib|
|
42
|
+
opts.on("-r LIBRARY", "Load RBS files of the library") do |lib|
|
43
43
|
options.libs << lib
|
44
44
|
end
|
45
45
|
|
46
|
-
opts.on("-I DIR") do |dir|
|
46
|
+
opts.on("-I DIR", "Load RBS files from the directory") do |dir|
|
47
47
|
options.dirs << dir
|
48
48
|
end
|
49
49
|
|
50
|
-
opts.on("--no-stdlib") do
|
50
|
+
opts.on("--no-stdlib", "Skip loading standard library signatures") do
|
51
51
|
options.no_stdlib = true
|
52
52
|
end
|
53
53
|
|
@@ -55,11 +55,11 @@ module RBS
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def parse_logging_options(opts)
|
58
|
-
opts.on("--log-level
|
58
|
+
opts.on("--log-level LEVEL", "Specify log level (defaults to `warn`)") do |level|
|
59
59
|
RBS.logger_level = level
|
60
60
|
end
|
61
61
|
|
62
|
-
opts.on("--log-output
|
62
|
+
opts.on("--log-output OUTPUT", "Specify the file to output log (defaults to stderr)") do |output|
|
63
63
|
RBS.logger_output = File.open(output, "a")
|
64
64
|
end
|
65
65
|
|
@@ -71,17 +71,24 @@ module RBS
|
|
71
71
|
|
72
72
|
opts = OptionParser.new
|
73
73
|
opts.banner = <<~USAGE
|
74
|
-
Usage: rbs [options]
|
75
|
-
|
74
|
+
Usage: rbs [options...] [command...]
|
75
|
+
|
76
|
+
Available commands: #{COMMANDS.join(", ")}, version, help.
|
77
|
+
|
78
|
+
Options:
|
76
79
|
USAGE
|
77
80
|
library_parse(opts, options: options)
|
78
81
|
parse_logging_options(opts)
|
82
|
+
opts.version = RBS::VERSION
|
79
83
|
|
80
84
|
opts.order!(args)
|
81
85
|
|
82
86
|
command = args.shift&.to_sym
|
83
87
|
|
84
|
-
|
88
|
+
case command
|
89
|
+
when :version
|
90
|
+
stdout.puts opts.ver
|
91
|
+
when *COMMANDS
|
85
92
|
__send__ :"run_#{command}", args, options
|
86
93
|
else
|
87
94
|
stdout.puts opts.help
|
@@ -89,101 +96,151 @@ module RBS
|
|
89
96
|
end
|
90
97
|
|
91
98
|
def run_ast(args, options)
|
92
|
-
|
99
|
+
OptionParser.new do |opts|
|
100
|
+
opts.banner = <<EOB
|
101
|
+
Usage: rbs ast [patterns...]
|
102
|
+
|
103
|
+
Print JSON AST of loaded environment.
|
104
|
+
You can specify patterns to filter declarations with the file names.
|
105
|
+
|
106
|
+
Examples:
|
107
|
+
|
108
|
+
$ rbs ast
|
109
|
+
$ rbs ast 'basic_object.rbs'
|
110
|
+
$ rbs -I ./sig ast ./sig
|
111
|
+
$ rbs -I ./sig ast '*/models/*.rbs'
|
112
|
+
EOB
|
113
|
+
end.order!(args)
|
93
114
|
|
115
|
+
patterns = args.map do |arg|
|
116
|
+
path = Pathname(arg)
|
117
|
+
if path.exist?
|
118
|
+
# Pathname means a directory or a file
|
119
|
+
path
|
120
|
+
else
|
121
|
+
# String means a `fnmatch` pattern
|
122
|
+
arg
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
loader = EnvironmentLoader.new()
|
94
127
|
options.setup(loader)
|
95
128
|
|
96
|
-
env = Environment.
|
97
|
-
|
129
|
+
env = Environment.from_loader(loader).resolve_type_names
|
130
|
+
|
131
|
+
decls = env.declarations.select do |decl|
|
132
|
+
name = decl.location.buffer.name
|
98
133
|
|
99
|
-
|
134
|
+
patterns.empty? || patterns.any? do |pat|
|
135
|
+
case pat
|
136
|
+
when Pathname
|
137
|
+
Pathname(name).ascend.any? {|p| p == pat }
|
138
|
+
when String
|
139
|
+
name.end_with?(pat) || File.fnmatch(pat, name, File::FNM_EXTGLOB)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
stdout.print JSON.generate(decls)
|
100
145
|
stdout.flush
|
101
146
|
end
|
102
147
|
|
103
148
|
def run_list(args, options)
|
104
|
-
list = []
|
149
|
+
list = Set[]
|
105
150
|
|
106
151
|
OptionParser.new do |opts|
|
107
|
-
opts.
|
108
|
-
|
109
|
-
|
152
|
+
opts.banner = <<EOB
|
153
|
+
Usage: rbs list [options...]
|
154
|
+
|
155
|
+
List classes, modules, and interfaces.
|
156
|
+
|
157
|
+
Examples:
|
158
|
+
|
159
|
+
$ rbs list
|
160
|
+
$ rbs list --class --module --interface
|
161
|
+
|
162
|
+
Options:
|
163
|
+
EOB
|
164
|
+
opts.on("--class", "List classes") { list << :class }
|
165
|
+
opts.on("--module", "List modules") { list << :module }
|
166
|
+
opts.on("--interface", "List interfaces") { list << :interface }
|
110
167
|
end.order!(args)
|
111
168
|
|
112
|
-
list.
|
169
|
+
list.merge([:class, :module, :interface]) if list.empty?
|
113
170
|
|
114
171
|
loader = EnvironmentLoader.new()
|
115
|
-
|
116
172
|
options.setup(loader)
|
117
173
|
|
118
|
-
env = Environment.
|
119
|
-
loader.load(env: env)
|
174
|
+
env = Environment.from_loader(loader).resolve_type_names
|
120
175
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
if list.include?(:interface)
|
133
|
-
stdout.puts "#{type_name} (interface)"
|
176
|
+
if list.include?(:class) || list.include?(:module)
|
177
|
+
env.class_decls.each do |name, entry|
|
178
|
+
case entry
|
179
|
+
when Environment::ModuleEntry
|
180
|
+
if list.include?(:module)
|
181
|
+
stdout.puts "#{name} (module)"
|
182
|
+
end
|
183
|
+
when Environment::ClassEntry
|
184
|
+
if list.include?(:class)
|
185
|
+
stdout.puts "#{name} (class)"
|
186
|
+
end
|
134
187
|
end
|
135
188
|
end
|
136
189
|
end
|
190
|
+
|
191
|
+
if list.include?(:interface)
|
192
|
+
env.interface_decls.each do |name, entry|
|
193
|
+
stdout.puts "#{name} (interface)"
|
194
|
+
end
|
195
|
+
end
|
137
196
|
end
|
138
197
|
|
139
198
|
def run_ancestors(args, options)
|
140
199
|
kind = :instance
|
141
200
|
|
142
201
|
OptionParser.new do |opts|
|
143
|
-
opts.
|
144
|
-
|
202
|
+
opts.banner = <<EOU
|
203
|
+
Usage: rbs ancestors [options...] [type_name]
|
204
|
+
|
205
|
+
Show ancestors of the given class or module.
|
206
|
+
|
207
|
+
Examples:
|
208
|
+
|
209
|
+
$ rbs ancestors --instance String
|
210
|
+
$ rbs ancestors --singleton Array
|
211
|
+
|
212
|
+
Options:
|
213
|
+
EOU
|
214
|
+
opts.on("--instance", "Ancestors of instance of the given type_name (default)") { kind = :instance }
|
215
|
+
opts.on("--singleton", "Ancestors of singleton of the given type_name") { kind = :singleton }
|
145
216
|
end.order!(args)
|
146
217
|
|
147
218
|
loader = EnvironmentLoader.new()
|
148
|
-
|
149
219
|
options.setup(loader)
|
150
220
|
|
151
|
-
env = Environment.
|
152
|
-
loader.load(env: env)
|
221
|
+
env = Environment.from_loader(loader).resolve_type_names
|
153
222
|
|
154
223
|
builder = DefinitionBuilder.new(env: env)
|
155
224
|
type_name = parse_type_name(args[0]).absolute!
|
156
225
|
|
157
|
-
if env.
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
Definition::Ancestor::Singleton.new(name: type_name)
|
165
|
-
end
|
166
|
-
|
167
|
-
ancestors = builder.build_ancestors(ancestor)
|
226
|
+
if env.class_decls.key?(type_name)
|
227
|
+
ancestors = case kind
|
228
|
+
when :instance
|
229
|
+
builder.instance_ancestors(type_name)
|
230
|
+
when :singleton
|
231
|
+
builder.singleton_ancestors(type_name)
|
232
|
+
end
|
168
233
|
|
169
|
-
ancestors.each do |ancestor|
|
234
|
+
ancestors.ancestors.each do |ancestor|
|
170
235
|
case ancestor
|
171
236
|
when Definition::Ancestor::Singleton
|
172
237
|
stdout.puts "singleton(#{ancestor.name})"
|
173
|
-
when Definition::Ancestor::ExtensionSingleton
|
174
|
-
stdout.puts "singleton(#{ancestor.name} (#{ancestor.extension_name}))"
|
175
238
|
when Definition::Ancestor::Instance
|
176
239
|
if ancestor.args.empty?
|
177
240
|
stdout.puts ancestor.name.to_s
|
178
241
|
else
|
179
242
|
stdout.puts "#{ancestor.name}[#{ancestor.args.join(", ")}]"
|
180
243
|
end
|
181
|
-
when Definition::Ancestor::ExtensionInstance
|
182
|
-
if ancestor.args.empty?
|
183
|
-
stdout.puts "#{ancestor.name} (#{ancestor.extension_name})"
|
184
|
-
else
|
185
|
-
stdout.puts "#{ancestor.name}[#{ancestor.args.join(", ")}] (#{ancestor.extension_name})"
|
186
|
-
end
|
187
244
|
end
|
188
245
|
end
|
189
246
|
else
|
@@ -196,10 +253,21 @@ module RBS
|
|
196
253
|
inherit = true
|
197
254
|
|
198
255
|
OptionParser.new do |opts|
|
199
|
-
opts.
|
200
|
-
|
201
|
-
|
202
|
-
|
256
|
+
opts.banner = <<EOU
|
257
|
+
Usage: rbs methods [options...] [type_name]
|
258
|
+
|
259
|
+
Show methods defined in the class or module.
|
260
|
+
|
261
|
+
Examples:
|
262
|
+
|
263
|
+
$ rbs methods --instance Kernel
|
264
|
+
$ rbs methods --singleton --no-inherit String
|
265
|
+
|
266
|
+
Options:
|
267
|
+
EOU
|
268
|
+
opts.on("--instance", "Show instance methods (default)") { kind = :instance }
|
269
|
+
opts.on("--singleton", "Show singleton methods") { kind = :singleton }
|
270
|
+
opts.on("--[no-]inherit", "Show methods defined in super class and mixed modules too") {|v| inherit = v }
|
203
271
|
end.order!(args)
|
204
272
|
|
205
273
|
unless args.size == 1
|
@@ -208,16 +276,14 @@ module RBS
|
|
208
276
|
end
|
209
277
|
|
210
278
|
loader = EnvironmentLoader.new()
|
211
|
-
|
212
279
|
options.setup(loader)
|
213
280
|
|
214
|
-
env = Environment.
|
215
|
-
loader.load(env: env)
|
281
|
+
env = Environment.from_loader(loader).resolve_type_names
|
216
282
|
|
217
283
|
builder = DefinitionBuilder.new(env: env)
|
218
284
|
type_name = parse_type_name(args[0]).absolute!
|
219
285
|
|
220
|
-
if env.
|
286
|
+
if env.class_decls.key?(type_name)
|
221
287
|
definition = case kind
|
222
288
|
when :instance
|
223
289
|
builder.build_instance(type_name)
|
@@ -227,7 +293,7 @@ module RBS
|
|
227
293
|
|
228
294
|
definition.methods.keys.sort.each do |name|
|
229
295
|
method = definition.methods[name]
|
230
|
-
if inherit || method.implemented_in ==
|
296
|
+
if inherit || method.implemented_in == type_name
|
231
297
|
stdout.puts "#{name} (#{method.accessibility})"
|
232
298
|
end
|
233
299
|
end
|
@@ -240,8 +306,20 @@ module RBS
|
|
240
306
|
kind = :instance
|
241
307
|
|
242
308
|
OptionParser.new do |opts|
|
243
|
-
opts.
|
244
|
-
|
309
|
+
opts.banner = <<EOU
|
310
|
+
Usage: rbs method [options...] [type_name] [method_name]
|
311
|
+
|
312
|
+
Show the information of the method specified by type_name and method_name.
|
313
|
+
|
314
|
+
Examples:
|
315
|
+
|
316
|
+
$ rbs method --instance Kernel puts
|
317
|
+
$ rbs method --singleton String try_convert
|
318
|
+
|
319
|
+
Options:
|
320
|
+
EOU
|
321
|
+
opts.on("--instance", "Show an instance method (default)") { kind = :instance }
|
322
|
+
opts.on("--singleton", "Show a singleton method") { kind = :singleton }
|
245
323
|
end.order!(args)
|
246
324
|
|
247
325
|
unless args.size == 2
|
@@ -250,17 +328,15 @@ module RBS
|
|
250
328
|
end
|
251
329
|
|
252
330
|
loader = EnvironmentLoader.new()
|
253
|
-
|
254
331
|
options.setup(loader)
|
255
332
|
|
256
|
-
env = Environment.
|
257
|
-
loader.load(env: env)
|
333
|
+
env = Environment.from_loader(loader).resolve_type_names
|
258
334
|
|
259
335
|
builder = DefinitionBuilder.new(env: env)
|
260
336
|
type_name = parse_type_name(args[0]).absolute!
|
261
337
|
method_name = args[1].to_sym
|
262
338
|
|
263
|
-
unless env.
|
339
|
+
unless env.class_decls.key?(type_name)
|
264
340
|
stdout.puts "Cannot find class: #{type_name}"
|
265
341
|
return
|
266
342
|
end
|
@@ -280,8 +356,8 @@ module RBS
|
|
280
356
|
end
|
281
357
|
|
282
358
|
stdout.puts "#{type_name}#{kind == :instance ? "#" : "."}#{method_name}"
|
283
|
-
stdout.puts " defined_in: #{method.defined_in
|
284
|
-
stdout.puts " implementation: #{method.implemented_in
|
359
|
+
stdout.puts " defined_in: #{method.defined_in}"
|
360
|
+
stdout.puts " implementation: #{method.implemented_in}"
|
285
361
|
stdout.puts " accessibility: #{method.accessibility}"
|
286
362
|
stdout.puts " types:"
|
287
363
|
separator = " "
|
@@ -292,46 +368,57 @@ module RBS
|
|
292
368
|
end
|
293
369
|
|
294
370
|
def run_validate(args, options)
|
371
|
+
OptionParser.new do |opts|
|
372
|
+
opts.banner = <<EOU
|
373
|
+
Usage: rbs validate
|
374
|
+
|
375
|
+
Validate RBS files. It ensures the type names in RBS files are present and the type applications have correct arity.
|
376
|
+
|
377
|
+
Examples:
|
378
|
+
|
379
|
+
$ rbs validate
|
380
|
+
EOU
|
381
|
+
end.parse!(args)
|
382
|
+
|
295
383
|
loader = EnvironmentLoader.new()
|
296
384
|
|
297
385
|
options.setup(loader)
|
298
386
|
|
299
|
-
env = Environment.
|
300
|
-
loader.load(env: env)
|
387
|
+
env = Environment.from_loader(loader).resolve_type_names
|
301
388
|
|
302
389
|
builder = DefinitionBuilder.new(env: env)
|
390
|
+
validator = Validator.new(env: env, resolver: TypeNameResolver.from_env(env))
|
303
391
|
|
304
|
-
env.
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
builder.build_singleton(decl.name.absolute!).each_type do |type|
|
312
|
-
env.validate type, namespace: Namespace.root
|
313
|
-
end
|
314
|
-
when AST::Declarations::Interface
|
315
|
-
stdout.puts "#{Location.to_string decl.location}:\tValidating interface: `#{name}`..."
|
316
|
-
builder.build_interface(decl.name.absolute!, decl).each_type do |type|
|
317
|
-
env.validate type, namespace: Namespace.root
|
318
|
-
end
|
392
|
+
env.class_decls.each_key do |name|
|
393
|
+
stdout.puts "Validating class/module definition: `#{name}`..."
|
394
|
+
builder.build_instance(name).each_type do |type|
|
395
|
+
validator.validate_type type, context: [Namespace.root]
|
396
|
+
end
|
397
|
+
builder.build_singleton(name).each_type do |type|
|
398
|
+
validator.validate_type type, context: [Namespace.root]
|
319
399
|
end
|
320
400
|
end
|
321
401
|
|
322
|
-
env.
|
323
|
-
stdout.puts "
|
324
|
-
|
402
|
+
env.interface_decls.each_key do |name|
|
403
|
+
stdout.puts "Validating interface: `#{name}`..."
|
404
|
+
builder.build_interface(name).each_type do |type|
|
405
|
+
validator.validate_type type, context: [Namespace.root]
|
406
|
+
end
|
325
407
|
end
|
326
408
|
|
327
|
-
env.
|
328
|
-
stdout.puts "
|
329
|
-
|
409
|
+
env.constant_decls.each do |name, const|
|
410
|
+
stdout.puts "Validating constant: `#{name}`..."
|
411
|
+
validator.validate_type const.decl.type, context: const.context
|
330
412
|
end
|
331
413
|
|
332
|
-
env.
|
333
|
-
stdout.puts "
|
334
|
-
|
414
|
+
env.global_decls.each do |name, global|
|
415
|
+
stdout.puts "Validating global: `#{name}`..."
|
416
|
+
validator.validate_type global.decl.type, context: [Namespace.root]
|
417
|
+
end
|
418
|
+
|
419
|
+
env.alias_decls.each do |name, decl|
|
420
|
+
stdout.puts "Validating alias: `#{name}`..."
|
421
|
+
validator.validate_type decl.decl.type, context: decl.context
|
335
422
|
end
|
336
423
|
end
|
337
424
|
|
@@ -339,7 +426,20 @@ module RBS
|
|
339
426
|
context = nil
|
340
427
|
|
341
428
|
OptionParser.new do |opts|
|
342
|
-
opts.
|
429
|
+
opts.banner = <<EOU
|
430
|
+
Usage: rbs constant [options...] [name]
|
431
|
+
|
432
|
+
Resolve constant based on RBS.
|
433
|
+
|
434
|
+
Examples:
|
435
|
+
|
436
|
+
$ rbs constant ::Object
|
437
|
+
$ rbs constant UTF_8
|
438
|
+
$ rbs constant --context=::Encoding UTF_8
|
439
|
+
|
440
|
+
Options:
|
441
|
+
EOU
|
442
|
+
opts.on("--context CONTEXT", "Name of the module where the constant resolution starts") {|c| context = c }
|
343
443
|
end.order!(args)
|
344
444
|
|
345
445
|
unless args.size == 1
|
@@ -351,8 +451,7 @@ module RBS
|
|
351
451
|
|
352
452
|
options.setup(loader)
|
353
453
|
|
354
|
-
env = Environment.
|
355
|
-
loader.load(env: env)
|
454
|
+
env = Environment.from_loader(loader).resolve_type_names
|
356
455
|
|
357
456
|
builder = DefinitionBuilder.new(env: env)
|
358
457
|
table = ConstantTable.new(builder: builder)
|
@@ -371,11 +470,20 @@ module RBS
|
|
371
470
|
end
|
372
471
|
end
|
373
472
|
|
374
|
-
def run_version(args, options)
|
375
|
-
stdout.puts "rbs #{VERSION}"
|
376
|
-
end
|
377
|
-
|
378
473
|
def run_paths(args, options)
|
474
|
+
OptionParser.new do |opts|
|
475
|
+
opts.banner = <<EOU
|
476
|
+
Usage: rbs paths
|
477
|
+
|
478
|
+
Show paths to directories where the RBS files are loaded from.
|
479
|
+
|
480
|
+
Examples:
|
481
|
+
|
482
|
+
$ rbs paths
|
483
|
+
$ tbs -r set paths
|
484
|
+
EOU
|
485
|
+
end.parse!(args)
|
486
|
+
|
379
487
|
loader = EnvironmentLoader.new()
|
380
488
|
|
381
489
|
options.setup(loader)
|
@@ -423,16 +531,30 @@ module RBS
|
|
423
531
|
owners_included = []
|
424
532
|
|
425
533
|
OptionParser.new do |opts|
|
426
|
-
opts.
|
534
|
+
opts.banner = <<EOU
|
535
|
+
Usage: rbs prototype runtime [options...] [pattern...]
|
536
|
+
|
537
|
+
Generate RBS prototype based on runtime introspection.
|
538
|
+
It loads Ruby code specified in [options] and generates RBS prototypes for classes matches to [pattern].
|
539
|
+
|
540
|
+
Examples:
|
541
|
+
|
542
|
+
$ rbs prototype runtime String
|
543
|
+
$ rbs prototype runtime --require set Set
|
544
|
+
$ rbs prototype runtime -R lib/rbs RBS::*
|
545
|
+
|
546
|
+
Options:
|
547
|
+
EOU
|
548
|
+
opts.on("-r", "--require LIB", "Load library using `require`") do |lib|
|
427
549
|
require_libs << lib
|
428
550
|
end
|
429
|
-
opts.on("--require-relative LIB") do |lib|
|
551
|
+
opts.on("-R", "--require-relative LIB", "Load library using `require_relative`") do |lib|
|
430
552
|
relative_libs << lib
|
431
553
|
end
|
432
|
-
opts.on("--merge") do
|
554
|
+
opts.on("--merge", "Merge generated prototype RBS with existing RBS") do
|
433
555
|
merge = true
|
434
556
|
end
|
435
|
-
opts.on("--method-owner CLASS") do |klass|
|
557
|
+
opts.on("--method-owner CLASS", "Generate method prototypes if the owner of the method is [CLASS]") do |klass|
|
436
558
|
owners_included << klass
|
437
559
|
end
|
438
560
|
end.parse!(args)
|
@@ -441,8 +563,7 @@ module RBS
|
|
441
563
|
|
442
564
|
options.setup(loader)
|
443
565
|
|
444
|
-
env = Environment.
|
445
|
-
loader.load(env: env)
|
566
|
+
env = Environment.from_loader(loader).resolve_type_names
|
446
567
|
|
447
568
|
require_libs.each do |lib|
|
448
569
|
require(lib)
|
@@ -454,15 +575,49 @@ module RBS
|
|
454
575
|
|
455
576
|
decls = Prototype::Runtime.new(patterns: args, env: env, merge: merge, owners_included: owners_included).decls
|
456
577
|
else
|
457
|
-
stdout.puts
|
578
|
+
stdout.puts <<EOU
|
579
|
+
Usage: rbs prototype [generator...] [args...]
|
580
|
+
|
581
|
+
Generate prototype of RBS files.
|
582
|
+
Supported generators are rb, rbi, runtime.
|
583
|
+
|
584
|
+
Examples:
|
585
|
+
|
586
|
+
$ rbs prototype rb foo.rb
|
587
|
+
$ rbs prototype rbi foo.rbi
|
588
|
+
$ rbs prototype runtime String
|
589
|
+
EOU
|
458
590
|
exit 1
|
459
591
|
end
|
460
592
|
|
461
|
-
|
462
|
-
|
593
|
+
if decls
|
594
|
+
writer = Writer.new(out: stdout)
|
595
|
+
writer.write decls
|
596
|
+
else
|
597
|
+
exit 1
|
598
|
+
end
|
463
599
|
end
|
464
600
|
|
465
601
|
def run_prototype_file(format, args)
|
602
|
+
opts = OptionParser.new
|
603
|
+
opts.banner = <<EOU
|
604
|
+
Usage: rbs prototype #{format} [options...] [files...]
|
605
|
+
|
606
|
+
Generate RBS prototype from source code.
|
607
|
+
It parses specified Ruby code and and generates RBS prototypes.
|
608
|
+
|
609
|
+
Examples:
|
610
|
+
|
611
|
+
$ rbs prototype rb lib/foo.rb
|
612
|
+
$ rbs prototype rbi sorbet/rbi/foo.rbi
|
613
|
+
EOU
|
614
|
+
opts.parse!(args)
|
615
|
+
|
616
|
+
if args.empty?
|
617
|
+
stdout.puts opts
|
618
|
+
return nil
|
619
|
+
end
|
620
|
+
|
466
621
|
parser = case format
|
467
622
|
when "rbi"
|
468
623
|
Prototype::RBI.new()
|
@@ -483,9 +638,19 @@ module RBS
|
|
483
638
|
vendor_dir = Pathname("vendor/sigs")
|
484
639
|
|
485
640
|
OptionParser.new do |opts|
|
486
|
-
opts.banner =
|
487
|
-
|
488
|
-
|
641
|
+
opts.banner = <<-EOB
|
642
|
+
Usage: rbs vendor [options...] [gems...]
|
643
|
+
|
644
|
+
Vendor signatures in the project directory.
|
645
|
+
This command ignores the RBS loading global options, `-r` and `-I`.
|
646
|
+
|
647
|
+
Examples:
|
648
|
+
|
649
|
+
$ rbs vendor
|
650
|
+
$ rbs vendor --vendor-dir=sig
|
651
|
+
$ rbs vendor --no-stdlib
|
652
|
+
|
653
|
+
Options:
|
489
654
|
EOB
|
490
655
|
|
491
656
|
opts.on("--[no-]clean", "Clean vendor directory (default: no)") do |v|
|
@@ -528,6 +693,18 @@ module RBS
|
|
528
693
|
end
|
529
694
|
|
530
695
|
def run_parse(args, options)
|
696
|
+
OptionParser.new do |opts|
|
697
|
+
opts.banner = <<-EOB
|
698
|
+
Usage: rbs parse [files...]
|
699
|
+
|
700
|
+
Parse given RBS files and print syntax errors.
|
701
|
+
|
702
|
+
Examples:
|
703
|
+
|
704
|
+
$ rbs parse sig/app/models.rbs sig/app/controllers.rbs
|
705
|
+
EOB
|
706
|
+
end.parse!(args)
|
707
|
+
|
531
708
|
loader = EnvironmentLoader.new()
|
532
709
|
|
533
710
|
syntax_error = false
|
@@ -545,6 +722,7 @@ module RBS
|
|
545
722
|
syntax_error = true
|
546
723
|
end
|
547
724
|
end
|
725
|
+
|
548
726
|
exit 1 if syntax_error
|
549
727
|
end
|
550
728
|
|