rbs 0.3.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }