rbs 0.4.0 → 0.9.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 +35 -0
- data/Gemfile +14 -0
- data/README.md +86 -47
- data/Rakefile +53 -21
- data/bin/rbs-prof +9 -0
- data/bin/run_in_md.rb +49 -0
- data/docs/stdlib.md +0 -2
- data/docs/syntax.md +6 -3
- data/goodcheck.yml +65 -0
- data/lib/rbs.rb +3 -0
- data/lib/rbs/ast/comment.rb +6 -0
- data/lib/rbs/ast/declarations.rb +106 -13
- data/lib/rbs/ast/members.rb +41 -17
- data/lib/rbs/cli.rb +317 -121
- data/lib/rbs/constant.rb +4 -4
- data/lib/rbs/constant_table.rb +51 -45
- data/lib/rbs/definition.rb +175 -59
- data/lib/rbs/definition_builder.rb +814 -604
- data/lib/rbs/environment.rb +352 -210
- data/lib/rbs/environment_walker.rb +14 -23
- data/lib/rbs/errors.rb +184 -3
- data/lib/rbs/factory.rb +14 -0
- data/lib/rbs/location.rb +15 -0
- data/lib/rbs/parser.y +100 -34
- data/lib/rbs/prototype/rb.rb +101 -113
- data/lib/rbs/prototype/rbi.rb +5 -3
- data/lib/rbs/prototype/runtime.rb +11 -7
- data/lib/rbs/substitution.rb +12 -1
- data/lib/rbs/test.rb +82 -3
- data/lib/rbs/test/errors.rb +5 -1
- data/lib/rbs/test/hook.rb +133 -259
- data/lib/rbs/test/observer.rb +17 -0
- data/lib/rbs/test/setup.rb +35 -19
- data/lib/rbs/test/setup_helper.rb +29 -0
- data/lib/rbs/test/spy.rb +0 -321
- data/lib/rbs/test/tester.rb +116 -0
- data/lib/rbs/test/type_check.rb +43 -7
- data/lib/rbs/type_name_resolver.rb +58 -0
- data/lib/rbs/types.rb +94 -2
- data/lib/rbs/validator.rb +55 -0
- data/lib/rbs/variance_calculator.rb +12 -2
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs/writer.rb +127 -91
- data/rbs.gemspec +0 -10
- data/schema/decls.json +36 -10
- data/schema/members.json +3 -0
- data/stdlib/benchmark/benchmark.rbs +151 -151
- data/stdlib/builtin/enumerable.rbs +3 -3
- data/stdlib/builtin/file.rbs +0 -3
- data/stdlib/builtin/io.rbs +4 -4
- data/stdlib/builtin/proc.rbs +1 -2
- 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 +7 -1
- data/stdlib/logger/formatter.rbs +23 -0
- data/stdlib/logger/log_device.rbs +39 -0
- data/stdlib/logger/logger.rbs +507 -0
- data/stdlib/logger/period.rbs +7 -0
- data/stdlib/logger/severity.rbs +8 -0
- 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/pty/pty.rbs +159 -0
- data/stdlib/tmpdir/tmpdir.rbs +1 -1
- metadata +19 -130
- data/lib/rbs/test/test_helper.rb +0 -183
data/docs/stdlib.md
CHANGED
@@ -120,7 +120,6 @@ The test scripts would look like the following:
|
|
120
120
|
```rb
|
121
121
|
class StringTest < StdlibTest
|
122
122
|
target String
|
123
|
-
using hook.refinement
|
124
123
|
|
125
124
|
def test_gsub
|
126
125
|
s = "string"
|
@@ -136,7 +135,6 @@ end
|
|
136
135
|
|
137
136
|
You need two method calls, `target` and `using`.
|
138
137
|
`target` method call tells which class is the subject of the class.
|
139
|
-
`using hook.refinement` installs a special instrumentation for stdlib, based on refinements.
|
140
138
|
And you write the sample programs which calls all of the patterns of overloads.
|
141
139
|
|
142
140
|
Note that the instrumentation is based on refinements and you need to write all method calls in the unit class definitions.
|
data/docs/syntax.md
CHANGED
@@ -166,7 +166,7 @@ end
|
|
166
166
|
|
167
167
|
### Proc type
|
168
168
|
|
169
|
-
Proc type
|
169
|
+
Proc type denotes type of procedures, `Proc` instances.
|
170
170
|
|
171
171
|
```
|
172
172
|
^(Integer) -> String # A procedure with an `Integer` parameter and returns `String`
|
@@ -348,7 +348,7 @@ attr_reader id: Integer
|
|
348
348
|
# @id: Integer
|
349
349
|
# def id: () -> Integer
|
350
350
|
|
351
|
-
# Defines `name=` method and
|
351
|
+
# Defines `name=` method and `@raw_name` instance variable.
|
352
352
|
attr_writer name (@raw_name) : String
|
353
353
|
# @raw_name: String
|
354
354
|
# def name=: (String) -> String
|
@@ -408,7 +408,10 @@ _class-decl_ ::= `class` _class-name_ _module-type-parameters_ _members_ `end`
|
|
408
408
|
| `class` _class-name_ _module-type-parameters_ `<` _class-name_ _type-arguments_ _members_ `end`
|
409
409
|
|
410
410
|
_module-decl_ ::= `module` _module-name_ _module-type-parameters_ _members_ `end`
|
411
|
-
| `module` _module-name_ _module-type-parameters_ `:`
|
411
|
+
| `module` _module-name_ _module-type-parameters_ `:` _module-self-types_ _members_ `end`
|
412
|
+
|
413
|
+
_module-self-types_ ::= _class-name_ _type-arguments_ `,` _module-self-types_ (Class instance)
|
414
|
+
| _interface-name_ _type-arguments_ `,` _module-self-types_ (Interface)
|
412
415
|
|
413
416
|
_interface-decl_ ::= `interface` _interface-name_ _module-type-parameters_ _interface-members_ `end`
|
414
417
|
|
data/goodcheck.yml
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
rules:
|
2
|
+
- id: rbs.no_mark
|
3
|
+
pattern: 💪👽🚨
|
4
|
+
message: Do you forget to delete `arglists` section?
|
5
|
+
glob:
|
6
|
+
- "stdlib/**/*.rbs"
|
7
|
+
fail:
|
8
|
+
- |
|
9
|
+
# arglists 💪👽🚨 << Delete this section
|
10
|
+
# File.absolute_path?(file_name) -> true or false
|
11
|
+
#
|
12
|
+
|
13
|
+
- id: rbs.no_arg
|
14
|
+
pattern:
|
15
|
+
regexp: arg\d+
|
16
|
+
message: |
|
17
|
+
Stop using parameter names like `arg0` or `arg1`
|
18
|
+
|
19
|
+
The parameter names like `arg0` or `arg1` is not informative enough.
|
20
|
+
Try finding good parameter names from documents or arglists.
|
21
|
+
If you cannot find a good name, just delete the name of the parameters.
|
22
|
+
justification:
|
23
|
+
- Documents (comments) may contain that pattern.
|
24
|
+
glob:
|
25
|
+
- "stdlib/**/*.rbs"
|
26
|
+
fail:
|
27
|
+
- "def `send`: (String | Symbol arg0, *untyped arg1) -> untyped"
|
28
|
+
pass:
|
29
|
+
- "def `send`: (String | Symbol, *untyped) -> untyped"
|
30
|
+
|
31
|
+
- id: deprecate_stdlib_test
|
32
|
+
pattern:
|
33
|
+
token: < StdlibTest
|
34
|
+
message: |
|
35
|
+
StdlibTest is deprecated
|
36
|
+
|
37
|
+
We recommend writing tests based on `TypeAssertions` and `#assert_send_type`.
|
38
|
+
justification:
|
39
|
+
- When you are updating existing tests.
|
40
|
+
- When you are writing tests for callback, which cannot be done with `#assert_send_type`.
|
41
|
+
glob:
|
42
|
+
- "test/stdlib/**/*_test.rb"
|
43
|
+
fail:
|
44
|
+
- |
|
45
|
+
class IntegerTest < StdlibTest
|
46
|
+
target Integer
|
47
|
+
|
48
|
+
def test_plus
|
49
|
+
1 + 2
|
50
|
+
end
|
51
|
+
end
|
52
|
+
pass:
|
53
|
+
- |
|
54
|
+
class IntegerTest < Minitest::Test
|
55
|
+
include TypeAssertions
|
56
|
+
|
57
|
+
testing "Integer"
|
58
|
+
|
59
|
+
def test_plus
|
60
|
+
assert_send_type "(::Integer) -> ::Integer",
|
61
|
+
1, :+, 2
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
|
data/lib/rbs.rb
CHANGED
@@ -32,8 +32,11 @@ require "rbs/writer"
|
|
32
32
|
require "rbs/prototype/rbi"
|
33
33
|
require "rbs/prototype/rb"
|
34
34
|
require "rbs/prototype/runtime"
|
35
|
+
require "rbs/type_name_resolver"
|
35
36
|
require "rbs/environment_walker"
|
36
37
|
require "rbs/vendorer"
|
38
|
+
require "rbs/validator"
|
39
|
+
require "rbs/factory"
|
37
40
|
|
38
41
|
begin
|
39
42
|
require "rbs/parser"
|
data/lib/rbs/ast/comment.rb
CHANGED
data/lib/rbs/ast/declarations.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
module RBS
|
2
2
|
module AST
|
3
3
|
module Declarations
|
4
|
+
class Base
|
5
|
+
end
|
6
|
+
|
4
7
|
class ModuleTypeParams
|
5
8
|
attr_reader :params
|
6
9
|
|
@@ -77,7 +80,53 @@ module RBS
|
|
77
80
|
end
|
78
81
|
end
|
79
82
|
|
80
|
-
|
83
|
+
module NestedDeclarationHelper
|
84
|
+
def each_member
|
85
|
+
if block_given?
|
86
|
+
members.each do |member|
|
87
|
+
if member.is_a?(Members::Base)
|
88
|
+
yield member
|
89
|
+
end
|
90
|
+
end
|
91
|
+
else
|
92
|
+
enum_for :each_member
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def each_decl
|
97
|
+
if block_given?
|
98
|
+
members.each do |member|
|
99
|
+
if member.is_a?(Declarations::Base)
|
100
|
+
yield member
|
101
|
+
end
|
102
|
+
end
|
103
|
+
else
|
104
|
+
enum_for :each_decl
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
module MixinHelper
|
110
|
+
def each_mixin(&block)
|
111
|
+
if block_given?
|
112
|
+
@mixins ||= begin
|
113
|
+
members.select do |member|
|
114
|
+
case member
|
115
|
+
when Members::Include, Members::Extend, Members::Prepend
|
116
|
+
true
|
117
|
+
else
|
118
|
+
false
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
@mixins.each(&block)
|
123
|
+
else
|
124
|
+
enum_for :each_mixin
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
class Class < Base
|
81
130
|
class Super
|
82
131
|
attr_reader :name
|
83
132
|
attr_reader :args
|
@@ -105,6 +154,9 @@ module RBS
|
|
105
154
|
end
|
106
155
|
end
|
107
156
|
|
157
|
+
include NestedDeclarationHelper
|
158
|
+
include MixinHelper
|
159
|
+
|
108
160
|
attr_reader :name
|
109
161
|
attr_reader :type_params
|
110
162
|
attr_reader :members
|
@@ -151,19 +203,60 @@ module RBS
|
|
151
203
|
end
|
152
204
|
end
|
153
205
|
|
154
|
-
class Module
|
206
|
+
class Module < Base
|
207
|
+
class Self
|
208
|
+
attr_reader :name
|
209
|
+
attr_reader :args
|
210
|
+
attr_reader :location
|
211
|
+
|
212
|
+
def initialize(name:, args:, location:)
|
213
|
+
@name = name
|
214
|
+
@args = args
|
215
|
+
@location = location
|
216
|
+
end
|
217
|
+
|
218
|
+
def ==(other)
|
219
|
+
other.is_a?(Self) && other.name == name && other.args == args
|
220
|
+
end
|
221
|
+
|
222
|
+
alias eql? ==
|
223
|
+
|
224
|
+
def hash
|
225
|
+
self.class.hash ^ name.hash ^ args.hash ^ location.hash
|
226
|
+
end
|
227
|
+
|
228
|
+
def to_json(*a)
|
229
|
+
{
|
230
|
+
name: name,
|
231
|
+
args: args,
|
232
|
+
location: location
|
233
|
+
}.to_json(*a)
|
234
|
+
end
|
235
|
+
|
236
|
+
def to_s
|
237
|
+
if args.empty?
|
238
|
+
name.to_s
|
239
|
+
else
|
240
|
+
"#{name}[#{args.join(", ")}]"
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
include NestedDeclarationHelper
|
246
|
+
include MixinHelper
|
247
|
+
|
155
248
|
attr_reader :name
|
156
249
|
attr_reader :type_params
|
157
250
|
attr_reader :members
|
158
251
|
attr_reader :location
|
159
252
|
attr_reader :annotations
|
160
|
-
attr_reader :
|
253
|
+
attr_reader :self_types
|
161
254
|
attr_reader :comment
|
162
255
|
|
163
|
-
def initialize(name:, type_params:, members:,
|
256
|
+
def initialize(name:, type_params:, members:, self_types:, annotations:, location:, comment:)
|
164
257
|
@name = name
|
165
258
|
@type_params = type_params
|
166
|
-
@
|
259
|
+
@self_types = self_types
|
167
260
|
@members = members
|
168
261
|
@annotations = annotations
|
169
262
|
@location = location
|
@@ -174,14 +267,14 @@ module RBS
|
|
174
267
|
other.is_a?(Module) &&
|
175
268
|
other.name == name &&
|
176
269
|
other.type_params == type_params &&
|
177
|
-
other.
|
270
|
+
other.self_types == self_types &&
|
178
271
|
other.members == members
|
179
272
|
end
|
180
273
|
|
181
274
|
alias eql? ==
|
182
275
|
|
183
276
|
def hash
|
184
|
-
self.class.hash ^ name.hash ^ type_params.hash ^
|
277
|
+
self.class.hash ^ name.hash ^ type_params.hash ^ self_types.hash ^ members.hash
|
185
278
|
end
|
186
279
|
|
187
280
|
def to_json(*a)
|
@@ -190,7 +283,7 @@ module RBS
|
|
190
283
|
name: name,
|
191
284
|
type_params: type_params,
|
192
285
|
members: members,
|
193
|
-
|
286
|
+
self_types: self_types,
|
194
287
|
annotations: annotations,
|
195
288
|
location: location,
|
196
289
|
comment: comment
|
@@ -198,7 +291,7 @@ module RBS
|
|
198
291
|
end
|
199
292
|
end
|
200
293
|
|
201
|
-
class Extension
|
294
|
+
class Extension < Base
|
202
295
|
attr_reader :name
|
203
296
|
attr_reader :type_params
|
204
297
|
attr_reader :extension_name
|
@@ -245,7 +338,7 @@ module RBS
|
|
245
338
|
end
|
246
339
|
end
|
247
340
|
|
248
|
-
class Interface
|
341
|
+
class Interface < Base
|
249
342
|
attr_reader :name
|
250
343
|
attr_reader :type_params
|
251
344
|
attr_reader :members
|
@@ -288,7 +381,7 @@ module RBS
|
|
288
381
|
end
|
289
382
|
end
|
290
383
|
|
291
|
-
class Alias
|
384
|
+
class Alias < Base
|
292
385
|
attr_reader :name
|
293
386
|
attr_reader :type
|
294
387
|
attr_reader :annotations
|
@@ -327,7 +420,7 @@ module RBS
|
|
327
420
|
end
|
328
421
|
end
|
329
422
|
|
330
|
-
class Constant
|
423
|
+
class Constant < Base
|
331
424
|
attr_reader :name
|
332
425
|
attr_reader :type
|
333
426
|
attr_reader :location
|
@@ -363,7 +456,7 @@ module RBS
|
|
363
456
|
end
|
364
457
|
end
|
365
458
|
|
366
|
-
class Global
|
459
|
+
class Global < Base
|
367
460
|
attr_reader :name
|
368
461
|
attr_reader :type
|
369
462
|
attr_reader :location
|
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
|