rbs 0.3.1 → 0.8.0

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.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +7 -1
  3. data/.gitignore +1 -1
  4. data/CHANGELOG.md +39 -0
  5. data/COPYING +1 -1
  6. data/Gemfile +16 -2
  7. data/README.md +87 -48
  8. data/Rakefile +54 -22
  9. data/bin/rbs-prof +9 -0
  10. data/bin/run_in_md.rb +49 -0
  11. data/bin/test_runner.rb +0 -2
  12. data/docs/sigs.md +6 -6
  13. data/docs/stdlib.md +3 -5
  14. data/docs/syntax.md +6 -3
  15. data/goodcheck.yml +65 -0
  16. data/lib/rbs.rb +3 -0
  17. data/lib/rbs/ast/declarations.rb +115 -14
  18. data/lib/rbs/ast/members.rb +41 -17
  19. data/lib/rbs/cli.rb +315 -122
  20. data/lib/rbs/constant.rb +4 -4
  21. data/lib/rbs/constant_table.rb +51 -45
  22. data/lib/rbs/definition.rb +175 -59
  23. data/lib/rbs/definition_builder.rb +802 -604
  24. data/lib/rbs/environment.rb +352 -210
  25. data/lib/rbs/environment_walker.rb +14 -23
  26. data/lib/rbs/errors.rb +184 -3
  27. data/lib/rbs/factory.rb +14 -0
  28. data/lib/rbs/parser.y +95 -27
  29. data/lib/rbs/prototype/rb.rb +119 -117
  30. data/lib/rbs/prototype/rbi.rb +5 -3
  31. data/lib/rbs/prototype/runtime.rb +34 -7
  32. data/lib/rbs/substitution.rb +12 -1
  33. data/lib/rbs/test.rb +82 -3
  34. data/lib/rbs/test/errors.rb +5 -1
  35. data/lib/rbs/test/hook.rb +133 -259
  36. data/lib/rbs/test/observer.rb +17 -0
  37. data/lib/rbs/test/setup.rb +35 -19
  38. data/lib/rbs/test/setup_helper.rb +29 -0
  39. data/lib/rbs/test/spy.rb +0 -321
  40. data/lib/rbs/test/tester.rb +116 -0
  41. data/lib/rbs/test/type_check.rb +43 -7
  42. data/lib/rbs/type_name_resolver.rb +58 -0
  43. data/lib/rbs/types.rb +94 -2
  44. data/lib/rbs/validator.rb +51 -0
  45. data/lib/rbs/variance_calculator.rb +12 -2
  46. data/lib/rbs/version.rb +1 -1
  47. data/lib/rbs/writer.rb +127 -91
  48. data/rbs.gemspec +0 -9
  49. data/schema/annotation.json +14 -0
  50. data/schema/comment.json +26 -0
  51. data/schema/decls.json +353 -0
  52. data/schema/function.json +87 -0
  53. data/schema/location.json +56 -0
  54. data/schema/members.json +248 -0
  55. data/schema/methodType.json +44 -0
  56. data/schema/types.json +299 -0
  57. data/stdlib/benchmark/benchmark.rbs +151 -151
  58. data/stdlib/builtin/encoding.rbs +2 -0
  59. data/stdlib/builtin/enumerable.rbs +4 -4
  60. data/stdlib/builtin/enumerator.rbs +3 -1
  61. data/stdlib/builtin/fiber.rbs +5 -1
  62. data/stdlib/builtin/file.rbs +0 -3
  63. data/stdlib/builtin/io.rbs +4 -4
  64. data/stdlib/builtin/proc.rbs +1 -2
  65. data/stdlib/builtin/symbol.rbs +1 -1
  66. data/stdlib/builtin/thread.rbs +2 -2
  67. data/stdlib/csv/csv.rbs +4 -6
  68. data/stdlib/fiber/fiber.rbs +117 -0
  69. data/stdlib/json/json.rbs +1 -1
  70. data/stdlib/logger/formatter.rbs +23 -0
  71. data/stdlib/logger/log_device.rbs +39 -0
  72. data/stdlib/logger/logger.rbs +507 -0
  73. data/stdlib/logger/period.rbs +7 -0
  74. data/stdlib/logger/severity.rbs +8 -0
  75. data/stdlib/mutex_m/mutex_m.rbs +77 -0
  76. data/stdlib/pathname/pathname.rbs +6 -6
  77. data/stdlib/prime/integer-extension.rbs +1 -1
  78. data/stdlib/prime/prime.rbs +44 -44
  79. data/stdlib/pty/pty.rbs +159 -0
  80. data/stdlib/tmpdir/tmpdir.rbs +1 -1
  81. metadata +28 -116
  82. data/lib/rbs/test/test_helper.rb +0 -183
@@ -0,0 +1,51 @@
1
+ module RBS
2
+ class Validator
3
+ attr_reader :env
4
+ attr_reader :resolver
5
+
6
+ def initialize(env:, resolver:)
7
+ @env = env
8
+ @resolver = resolver
9
+ end
10
+
11
+ def absolute_type(type, context:)
12
+ type.map_type_name do |type_name, _, type|
13
+ resolver.resolve(type_name, context: context) || yield(type)
14
+ end
15
+ end
16
+
17
+ # Validates presence of the relative type, and application arity match.
18
+ def validate_type(type, context:)
19
+ case type
20
+ when Types::ClassInstance, Types::Interface
21
+ if type.name.namespace.relative?
22
+ type = absolute_type(type, context: context) do |type|
23
+ NoTypeFoundError.check!(type.name.absolute!, env: env, location: type.location)
24
+ end
25
+ end
26
+
27
+ type_params = case type
28
+ when Types::ClassInstance
29
+ env.class_decls[type.name]&.type_params
30
+ when Types::Interface
31
+ env.interface_decls[type.name]&.decl&.type_params
32
+ end
33
+
34
+ unless type_params
35
+ raise NoTypeFoundError.new(type_name: type.name, location: type.location)
36
+ end
37
+
38
+ InvalidTypeApplicationError.check!(
39
+ type_name: type.name,
40
+ args: type.args,
41
+ params: type_params.each.map(&:name),
42
+ location: type.location
43
+ )
44
+ end
45
+
46
+ type.each_type do |type|
47
+ validate_type(type, context: context)
48
+ end
49
+ end
50
+ end
51
+ end
@@ -107,9 +107,19 @@ module RBS
107
107
  end
108
108
  end
109
109
  when Types::ClassInstance, Types::Interface
110
- decl = env.find_class(type.name)
110
+ NoTypeFoundError.check!(type.name,
111
+ env: env,
112
+ location: type.location)
113
+
114
+ type_params = case type
115
+ when Types::ClassInstance
116
+ env.class_decls[type.name]&.type_params
117
+ when Types::Interface
118
+ env.interface_decls[type.name]&.decl&.type_params
119
+ end
120
+
111
121
  type.args.each.with_index do |ty, i|
112
- var = decl.type_params.params[i]
122
+ var = type_params.params[i]
113
123
  case var.variance
114
124
  when :invariant
115
125
  type(ty, result: result, context: :invariant)
@@ -1,3 +1,3 @@
1
1
  module RBS
2
- VERSION = "0.3.1"
2
+ VERSION = "0.8.0"
3
3
  end
@@ -1,37 +1,59 @@
1
1
  module RBS
2
2
  class Writer
3
3
  attr_reader :out
4
+ attr_reader :indentation
4
5
 
5
6
  def initialize(out:)
6
7
  @out = out
8
+ @indentation = []
7
9
  end
8
10
 
9
- def write_annotation(annotations, level:)
10
- prefix = " " * level
11
+ def indent(size = 2)
12
+ indentation.push(" " * size)
13
+ yield
14
+ ensure
15
+ indentation.pop
16
+ end
17
+
18
+ def prefix
19
+ indentation.join()
20
+ end
21
+
22
+ def puts(string = "")
23
+ if string.size > 0
24
+ @out.puts("#{prefix}#{string}")
25
+ else
26
+ @out.puts
27
+ end
28
+ end
11
29
 
30
+ def write_annotation(annotations)
12
31
  annotations.each do |annotation|
13
32
  string = annotation.string
14
33
  case
15
34
  when string !~ /\}/
16
- out.puts "#{prefix}%a{#{string}}"
35
+ puts "%a{#{string}}"
17
36
  when string !~ /\)/
18
- out.puts "#{prefix}%a(#{string})"
37
+ puts "%a(#{string})"
19
38
  when string !~ /\]/
20
- out.puts "#{prefix}%a[#{string}]"
39
+ puts "%a[#{string}]"
21
40
  when string !~ /\>/
22
- out.puts "#{prefix}%a<#{string}>"
41
+ puts "%a<#{string}>"
23
42
  when string !~ /\|/
24
- out.puts "#{prefix}%a|#{string}|"
43
+ puts "%a|#{string}|"
25
44
  end
26
45
  end
27
46
  end
28
47
 
29
- def write_comment(comment, level:)
48
+ def write_comment(comment)
30
49
  if comment
31
- prefix = " " * level
32
50
  comment.string.lines.each do |line|
33
- line = " #{line}" unless line.chomp.empty?
34
- out.puts "#{prefix}##{line}"
51
+ line = line.chomp
52
+ unless line.empty?
53
+ puts "# #{line}"
54
+ else
55
+ puts "#"
56
+ end
35
57
  end
36
58
  end
37
59
  end
@@ -49,68 +71,72 @@ module RBS
49
71
  super_class = if decl.super_class
50
72
  " < #{name_and_args(decl.super_class.name, decl.super_class.args)}"
51
73
  end
52
- write_comment decl.comment, level: 0
53
- write_annotation decl.annotations, level: 0
54
- out.puts "class #{name_and_params(decl.name, decl.type_params)}#{super_class}"
74
+ write_comment decl.comment
75
+ write_annotation decl.annotations
76
+ puts "class #{name_and_params(decl.name, decl.type_params)}#{super_class}"
55
77
 
56
- [nil, *decl.members].each_cons(2) do |prev, member|
57
- preserve_empty_line prev, member
58
- write_member member
78
+ indent do
79
+ [nil, *decl.members].each_cons(2) do |prev, member|
80
+ preserve_empty_line prev, member
81
+ write_member member
82
+ end
59
83
  end
60
84
 
61
- out.puts "end"
85
+ puts "end"
62
86
 
63
87
  when AST::Declarations::Module
64
- self_type = if decl.self_type
65
- " : #{decl.self_type}"
88
+ self_type = unless decl.self_types.empty?
89
+ " : #{decl.self_types.join(", ")}"
66
90
  end
67
91
 
68
- write_comment decl.comment, level: 0
69
- write_annotation decl.annotations, level: 0
70
- out.puts "module #{name_and_params(decl.name, decl.type_params)}#{self_type}"
71
- decl.members.each.with_index do |member, index|
72
- if index > 0
73
- out.puts
92
+ write_comment decl.comment
93
+ write_annotation decl.annotations
94
+
95
+ puts "module #{name_and_params(decl.name, decl.type_params)}#{self_type}"
96
+
97
+ indent do
98
+ decl.members.each.with_index do |member, index|
99
+ if index > 0
100
+ puts
101
+ end
102
+ write_member member
74
103
  end
75
- write_member member
76
104
  end
77
- out.puts "end"
105
+
106
+ puts "end"
78
107
  when AST::Declarations::Constant
79
- write_comment decl.comment, level: 0
80
- out.puts "#{decl.name}: #{decl.type}"
108
+ write_comment decl.comment
109
+ puts "#{decl.name}: #{decl.type}"
81
110
 
82
111
  when AST::Declarations::Global
83
- write_comment decl.comment, level: 0
84
- out.puts "#{decl.name}: #{decl.type}"
112
+ write_comment decl.comment
113
+ puts "#{decl.name}: #{decl.type}"
85
114
 
86
115
  when AST::Declarations::Alias
87
- write_comment decl.comment, level: 0
88
- write_annotation decl.annotations, level: 0
89
- out.puts "type #{decl.name} = #{decl.type}"
116
+ write_comment decl.comment
117
+ write_annotation decl.annotations
118
+ puts "type #{decl.name} = #{decl.type}"
90
119
 
91
120
  when AST::Declarations::Interface
92
- write_comment decl.comment, level: 0
93
- write_annotation decl.annotations, level: 0
94
- out.puts "interface #{name_and_params(decl.name, decl.type_params)}"
95
- decl.members.each.with_index do |member, index|
96
- if index > 0
97
- out.puts
121
+ write_comment decl.comment
122
+ write_annotation decl.annotations
123
+
124
+ puts "interface #{name_and_params(decl.name, decl.type_params)}"
125
+
126
+ indent do
127
+ decl.members.each.with_index do |member, index|
128
+ if index > 0
129
+ puts
130
+ end
131
+ write_member member
98
132
  end
99
- write_member member
100
133
  end
101
- out.puts "end"
134
+
135
+ puts "end"
102
136
 
103
137
  when AST::Declarations::Extension
104
- write_comment decl.comment, level: 0
105
- write_annotation decl.annotations, level: 0
106
- out.puts "extension #{name_and_args(decl.name, decl.type_params)} (#{decl.extension_name})"
107
- decl.members.each.with_index do |member, index|
108
- if index > 0
109
- out.puts
110
- end
111
- write_member member
112
- end
113
- out.puts "end"
138
+ RBS.logger.warn "Extension is ignored: #{decl.name}"
139
+
114
140
  end
115
141
  end
116
142
 
@@ -151,52 +177,54 @@ module RBS
151
177
  def write_member(member)
152
178
  case member
153
179
  when AST::Members::Include
154
- write_comment member.comment, level: 2
155
- write_annotation member.annotations, level: 2
156
- out.puts " include #{name_and_args(member.name, member.args)}"
180
+ write_comment member.comment
181
+ write_annotation member.annotations
182
+ puts "include #{name_and_args(member.name, member.args)}"
157
183
  when AST::Members::Extend
158
- write_comment member.comment, level: 2
159
- write_annotation member.annotations, level: 2
160
- out.puts " extend #{name_and_args(member.name, member.args)}"
184
+ write_comment member.comment
185
+ write_annotation member.annotations
186
+ puts "extend #{name_and_args(member.name, member.args)}"
161
187
  when AST::Members::Prepend
162
- write_comment member.comment, level: 2
163
- write_annotation member.annotations, level: 2
164
- out.puts " prepend #{name_and_args(member.name, member.args)}"
188
+ write_comment member.comment
189
+ write_annotation member.annotations
190
+ puts "prepend #{name_and_args(member.name, member.args)}"
165
191
  when AST::Members::AttrAccessor
166
- write_comment member.comment, level: 2
167
- write_annotation member.annotations, level: 2
168
- out.puts " #{attribute(:accessor, member)}"
192
+ write_comment member.comment
193
+ write_annotation member.annotations
194
+ puts "#{attribute(:accessor, member)}"
169
195
  when AST::Members::AttrReader
170
- write_comment member.comment, level: 2
171
- write_annotation member.annotations, level: 2
172
- out.puts " #{attribute(:reader, member)}"
196
+ write_comment member.comment
197
+ write_annotation member.annotations
198
+ puts "#{attribute(:reader, member)}"
173
199
  when AST::Members::AttrWriter
174
- write_comment member.comment, level: 2
175
- write_annotation member.annotations, level: 2
176
- out.puts " #{attribute(:writer, member)}"
200
+ write_comment member.comment
201
+ write_annotation member.annotations
202
+ puts "#{attribute(:writer, member)}"
177
203
  when AST::Members::Public
178
- out.puts " public"
204
+ puts "public"
179
205
  when AST::Members::Private
180
- out.puts " private"
206
+ puts "private"
181
207
  when AST::Members::Alias
182
- write_comment member.comment, level: 2
183
- write_annotation member.annotations, level: 2
208
+ write_comment member.comment
209
+ write_annotation member.annotations
184
210
  new_name = member.singleton? ? "self.#{member.new_name}" : member.new_name
185
211
  old_name = member.singleton? ? "self.#{member.old_name}" : member.old_name
186
- out.puts " alias #{new_name} #{old_name}"
212
+ puts "alias #{new_name} #{old_name}"
187
213
  when AST::Members::InstanceVariable
188
- write_comment member.comment, level: 2
189
- out.puts " #{member.name}: #{member.type}"
214
+ write_comment member.comment
215
+ puts "#{member.name}: #{member.type}"
190
216
  when AST::Members::ClassInstanceVariable
191
- write_comment member.comment, level: 2
192
- out.puts " self.#{member.name}: #{member.type}"
217
+ write_comment member.comment
218
+ puts "self.#{member.name}: #{member.type}"
193
219
  when AST::Members::ClassVariable
194
- write_comment member.comment, level: 2
195
- out.puts " #{member.name}: #{member.type}"
220
+ write_comment member.comment
221
+ puts "#{member.name}: #{member.type}"
196
222
  when AST::Members::MethodDefinition
197
- write_comment member.comment, level: 2
198
- write_annotation member.annotations, level: 2
223
+ write_comment member.comment
224
+ write_annotation member.annotations
199
225
  write_def member
226
+ else
227
+ write_decl member
200
228
  end
201
229
  end
202
230
 
@@ -220,18 +248,26 @@ module RBS
220
248
  "self.#{method_name(member.name)}"
221
249
  end
222
250
 
251
+ string = ""
252
+
223
253
  attrs = member.attributes.empty? ? "" : member.attributes.join(" ") + " "
224
- prefix = " #{attrs}def #{name}:"
254
+ overload = member.overload? ? "overload " : ""
255
+ prefix = "#{overload}#{attrs}def #{name}:"
225
256
  padding = " " * (prefix.size-1)
226
257
 
227
- out.print prefix
258
+ string << prefix
228
259
 
229
260
  member.types.each.with_index do |type, index|
230
261
  if index > 0
231
- out.print padding
232
- out.print "|"
262
+ string << padding
263
+ string << "|"
233
264
  end
234
- out.puts " #{type}"
265
+
266
+ string << " #{type}\n"
267
+ end
268
+
269
+ string.each_line do |line|
270
+ puts line.chomp
235
271
  end
236
272
  end
237
273
 
@@ -255,14 +291,14 @@ module RBS
255
291
  # When the signature is not constructed by the parser,
256
292
  # it always inserts an empty line.
257
293
  if !prev.location || !decl.location
258
- out.puts
294
+ puts
259
295
  return
260
296
  end
261
297
 
262
298
  prev_end_line = prev.location.end_line
263
299
  start_line = decl.location.start_line
264
300
  if start_line - prev_end_line > 1
265
- out.puts
301
+ puts
266
302
  end
267
303
  end
268
304
  end
@@ -34,13 +34,4 @@ Gem::Specification.new do |spec|
34
34
  spec.bindir = "exe"
35
35
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
36
36
  spec.require_paths = ["lib"]
37
-
38
- spec.add_development_dependency "bundler"
39
- spec.add_development_dependency "rake", "~> 13.0"
40
- spec.add_development_dependency "minitest", "~> 5.0"
41
- spec.add_development_dependency "racc", "~> 1.4.16"
42
- spec.add_development_dependency "rubocop"
43
- spec.add_development_dependency "rubocop-rubycw"
44
- spec.add_development_dependency "minitest-reporters", "~> 1.3.6"
45
- spec.add_development_dependency "json", "~> 2.3.0"
46
37
  end
@@ -0,0 +1,14 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-04/schema#",
3
+ "title": "Annotation associated to a declaration or a member: `%a{rbs:test}`, `%a{steep:deprecated}`, ...",
4
+ "type": "object",
5
+ "properties": {
6
+ "string": {
7
+ "type": "string"
8
+ },
9
+ "location": {
10
+ "$ref": "location.json"
11
+ }
12
+ },
13
+ "required": ["string", "location"]
14
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-04/schema#",
3
+ "definitions": {
4
+ "comment": {
5
+ "type": "object",
6
+ "properties": {
7
+ "string": {
8
+ "type": "string"
9
+ },
10
+ "location": {
11
+ "$ref": "location.json"
12
+ }
13
+ },
14
+ "required": ["string", "location"]
15
+ }
16
+ },
17
+ "title": "Comment associated with a declaration or a member",
18
+ "oneOf": [
19
+ {
20
+ "$ref": "#/definitions/comment"
21
+ },
22
+ {
23
+ "type": "null"
24
+ }
25
+ ]
26
+ }