rbs 0.2.0 → 0.6.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 (81) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +7 -1
  3. data/.gitignore +1 -1
  4. data/CHANGELOG.md +35 -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 +301 -123
  20. data/lib/rbs/constant.rb +4 -4
  21. data/lib/rbs/constant_table.rb +64 -53
  22. data/lib/rbs/definition.rb +175 -59
  23. data/lib/rbs/definition_builder.rb +646 -603
  24. data/lib/rbs/environment.rb +352 -210
  25. data/lib/rbs/environment_walker.rb +14 -23
  26. data/lib/rbs/errors.rb +159 -3
  27. data/lib/rbs/factory.rb +14 -0
  28. data/lib/rbs/namespace.rb +18 -0
  29. data/lib/rbs/parser.y +75 -21
  30. data/lib/rbs/prototype/rb.rb +119 -117
  31. data/lib/rbs/prototype/rbi.rb +5 -3
  32. data/lib/rbs/prototype/runtime.rb +34 -7
  33. data/lib/rbs/substitution.rb +8 -1
  34. data/lib/rbs/test.rb +81 -3
  35. data/lib/rbs/test/errors.rb +1 -1
  36. data/lib/rbs/test/hook.rb +133 -259
  37. data/lib/rbs/test/observer.rb +17 -0
  38. data/lib/rbs/test/setup.rb +13 -14
  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 +44 -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 +2 -2
  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/tmpdir/tmpdir.rbs +1 -1
  80. metadata +26 -116
  81. data/lib/rbs/test/test_helper.rb +0 -183
@@ -4,23 +4,23 @@ module RBS
4
4
  attr_reader :type
5
5
  attr_reader :declaration
6
6
 
7
- def initialize(name:, type:, declaration:)
7
+ def initialize(name:, type:, entry:)
8
8
  @name = name
9
9
  @type = type
10
- @declaration = declaration
10
+ @entry = entry
11
11
  end
12
12
 
13
13
  def ==(other)
14
14
  other.is_a?(Constant) &&
15
15
  other.name == name &&
16
16
  other.type == type &&
17
- other.declaration == declaration
17
+ other.entry == entry
18
18
  end
19
19
 
20
20
  alias eql? ==
21
21
 
22
22
  def hash
23
- self.class.hash ^ name.hash ^ type.hash ^ declaration.hash
23
+ self.class.hash ^ name.hash ^ type.hash ^ entry.hash
24
24
  end
25
25
  end
26
26
  end
@@ -7,21 +7,34 @@ module RBS
7
7
  definition_builder.env
8
8
  end
9
9
 
10
+ def resolver
11
+ @resolver ||= TypeNameResolver.from_env(env)
12
+ end
13
+
10
14
  def initialize(builder:)
11
15
  @definition_builder = builder
12
16
  @constant_scopes_cache = {}
13
17
  end
14
18
 
19
+ def absolute_type(type, context:)
20
+ type.map_type_name do |type_name, location|
21
+ absolute_type_name(type_name, context: context, location: location)
22
+ end
23
+ end
24
+
25
+ def absolute_type_name(type_name, context:, location:)
26
+ resolver.resolve(type_name, context: context) or
27
+ raise NoTypeFoundError.new(type_name: type_name, location: location)
28
+ end
29
+
15
30
  def name_to_constant(name)
16
31
  case
17
- when env.name_to_constant.key?(name)
18
- decl = env.name_to_constant[name]
19
- type = env.absolute_type(decl.type, namespace: name.namespace) {|type| type.name.absolute! }
20
- Constant.new(name: name, type: type, declaration: decl)
21
- when env.class?(name)
22
- decl = env.name_to_decl[name]
32
+ when entry = env.constant_decls[name]
33
+ type = absolute_type(entry.decl.type, context: entry.context)
34
+ Constant.new(name: name, type: type, entry: entry)
35
+ when entry = env.class_decls[name]
23
36
  type = Types::ClassSingleton.new(name: name, location: nil)
24
- Constant.new(name: name, type: type, declaration: decl)
37
+ Constant.new(name: name, type: type, entry: entry)
25
38
  end
26
39
  end
27
40
 
@@ -30,17 +43,18 @@ module RBS
30
43
  end
31
44
 
32
45
  def resolve_constant_reference(name, context:)
46
+ raise "Context cannot be empty: Specify `[Namespace.root]`" if context.empty?
47
+
33
48
  head, *tail = split_name(name)
34
49
 
35
50
  head_constant = case
36
51
  when name.absolute?
37
52
  name_to_constant(TypeName.new(name: head, namespace: Namespace.root))
38
- when !context || context.empty?
53
+ when context == [Namespace.root]
39
54
  name_to_constant(TypeName.new(name: head, namespace: Namespace.root))
40
55
  else
41
56
  resolve_constant_reference_context(head, context: context) ||
42
- resolve_constant_reference_inherit(head,
43
- scopes: constant_scopes(context.to_type_name))
57
+ resolve_constant_reference_inherit(head, scopes: constant_scopes(context.first.to_type_name))
44
58
  end
45
59
 
46
60
  if head_constant
@@ -53,11 +67,15 @@ module RBS
53
67
  end
54
68
 
55
69
  def resolve_constant_reference_context(name, context:)
56
- if context.empty?
57
- nil
58
- else
59
- name_to_constant(TypeName.new(name: name, namespace: context)) ||
60
- resolve_constant_reference_context(name, context: context.parent)
70
+ head, *tail = context
71
+
72
+ if head
73
+ if head.path.last == name
74
+ name_to_constant(head.to_type_name)
75
+ else
76
+ name_to_constant(TypeName.new(name: name, namespace: head)) ||
77
+ resolve_constant_reference_context(name, context: tail)
78
+ end
61
79
  end
62
80
  end
63
81
 
@@ -83,14 +101,18 @@ module RBS
83
101
  end
84
102
 
85
103
  def constant_scopes_module(name, scopes:)
86
- decl = env.find_class(name)
104
+ entry = env.class_decls[name]
87
105
  namespace = name.to_namespace
88
106
 
89
- decl.members.each do |member|
90
- case member
91
- when AST::Members::Include
92
- constant_scopes_module absolute_type_name(member.name, namespace: namespace),
93
- scopes: scopes
107
+ entry.decls.each do |d|
108
+ d.decl.members.each do |member|
109
+ case member
110
+ when AST::Members::Include
111
+ if member.name.class?
112
+ constant_scopes_module absolute_type_name(member.name, context: d.context, location: member.location),
113
+ scopes: scopes
114
+ end
115
+ end
94
116
  end
95
117
  end
96
118
 
@@ -98,53 +120,42 @@ module RBS
98
120
  end
99
121
 
100
122
  def constant_scopes0(name, scopes: [])
101
- decl = env.find_class(name)
123
+ entry = env.class_decls[name]
102
124
  namespace = name.to_namespace
103
125
 
104
- case decl
105
- when AST::Declarations::Module
106
- constant_scopes0 BuiltinNames::Module.name, scopes: scopes
107
- constant_scopes_module name, scopes: scopes
108
-
109
- when AST::Declarations::Class
126
+ case entry
127
+ when Environment::ClassEntry
110
128
  unless name == BuiltinNames::BasicObject.name
111
- super_name = decl.super_class&.yield_self {|super_class|
112
- absolute_type_name(super_class.name, namespace: namespace)
113
- } || BuiltinNames::Object.name
129
+ super_name = entry.primary.decl.super_class&.yield_self do |super_class|
130
+ absolute_type_name(super_class.name, context: entry.primary.context, location: entry.primary.decl.location)
131
+ end || BuiltinNames::Object.name
114
132
 
115
133
  constant_scopes0 super_name, scopes: scopes
116
134
  end
117
135
 
118
- decl.members.each do |member|
119
- case member
120
- when AST::Members::Include
121
- constant_scopes_module absolute_type_name(member.name, namespace: namespace),
122
- scopes: scopes
136
+ entry.decls.each do |d|
137
+ d.decl.members.each do |member|
138
+ case member
139
+ when AST::Members::Include
140
+ if member.name.class?
141
+ constant_scopes_module absolute_type_name(member.name, context: d.context, location: member.location),
142
+ scopes: scopes
143
+ end
144
+ end
123
145
  end
124
146
  end
125
147
 
126
148
  scopes.unshift namespace
127
- else
128
- raise "Unexpected declaration: #{name}"
129
- end
130
149
 
131
- env.each_extension(name).sort_by {|e| e.extension_name.to_s }.each do |extension|
132
- extension.members.each do |member|
133
- case member
134
- when AST::Members::Include
135
- constant_scopes_module absolute_type_name(member.name, namespace: namespace),
136
- scopes: []
137
- end
138
- end
150
+ when Environment::ModuleEntry
151
+ constant_scopes0 BuiltinNames::Module.name, scopes: scopes
152
+ constant_scopes_module name, scopes: scopes
153
+
154
+ else
155
+ raise "Unexpected declaration: #{name} (#{decl.class})"
139
156
  end
140
157
 
141
158
  scopes
142
159
  end
143
-
144
- def absolute_type_name(name, namespace:)
145
- env.absolute_type_name(name, namespace: namespace) do
146
- raise
147
- end
148
- end
149
160
  end
150
161
  end
@@ -10,27 +10,76 @@ module RBS
10
10
  @type = type
11
11
  @declared_in = declared_in
12
12
  end
13
+
14
+ def sub(s)
15
+ self.class.new(
16
+ parent_variable: parent_variable,
17
+ type: type.sub(s),
18
+ declared_in: declared_in
19
+ )
20
+ end
13
21
  end
14
22
 
15
23
  class Method
24
+ class TypeDef
25
+ attr_reader :type
26
+ attr_reader :member
27
+ attr_reader :defined_in
28
+ attr_reader :implemented_in
29
+
30
+ def initialize(type:, member:, defined_in:, implemented_in:)
31
+ @type = type
32
+ @member = member
33
+ @defined_in = defined_in
34
+ @implemented_in = implemented_in
35
+ end
36
+
37
+ def comment
38
+ member.comment
39
+ end
40
+
41
+ def annotations
42
+ member.annotations
43
+ end
44
+
45
+ def update(type: self.type, member: self.member, defined_in: self.defined_in, implemented_in: self.implemented_in)
46
+ TypeDef.new(type: type, member: member, defined_in: defined_in, implemented_in: implemented_in)
47
+ end
48
+ end
49
+
16
50
  attr_reader :super_method
17
- attr_reader :method_types
18
- attr_reader :defined_in
19
- attr_reader :implemented_in
51
+ attr_reader :defs
20
52
  attr_reader :accessibility
21
- attr_reader :attributes
22
- attr_reader :annotations
23
- attr_reader :comment
24
53
 
25
- def initialize(super_method:, method_types:, defined_in:, implemented_in:, accessibility:, attributes:, annotations:, comment:)
54
+ def initialize(super_method:, defs:, accessibility:)
26
55
  @super_method = super_method
27
- @method_types = method_types
28
- @defined_in = defined_in
29
- @implemented_in = implemented_in
56
+ @defs = defs
30
57
  @accessibility = accessibility
31
- @attributes = attributes
32
- @annotations = annotations
33
- @comment = comment
58
+ end
59
+
60
+ def defined_in
61
+ @defined_in ||= defs.last.defined_in
62
+ end
63
+
64
+ def implemented_in
65
+ @implemented_in ||= defs.last.implemented_in
66
+ end
67
+
68
+ def method_types
69
+ @method_types ||= defs.map(&:type)
70
+ end
71
+
72
+ def comments
73
+ @comments ||= defs.map(&:comment).compact
74
+ end
75
+
76
+ def annotations
77
+ @annotations ||= defs.flat_map(&:annotations)
78
+ end
79
+
80
+ # @deprecated
81
+ def attributes
82
+ []
34
83
  end
35
84
 
36
85
  def public?
@@ -44,28 +93,24 @@ module RBS
44
93
  def sub(s)
45
94
  self.class.new(
46
95
  super_method: super_method&.sub(s),
47
- method_types: method_types.map {|ty| ty.sub(s) },
48
- defined_in: defined_in,
49
- implemented_in: implemented_in,
50
- accessibility: @accessibility,
51
- attributes: attributes,
52
- annotations: annotations,
53
- comment: comment
96
+ defs: defs.map {|defn| defn.update(type: defn.type.sub(s)) },
97
+ accessibility: @accessibility
54
98
  )
55
99
  end
56
100
 
57
101
  def map_type(&block)
58
102
  self.class.new(
59
103
  super_method: super_method&.map_type(&block),
60
- method_types: method_types.map do |ty|
61
- ty.map_type(&block)
62
- end,
63
- defined_in: defined_in,
64
- implemented_in: implemented_in,
65
- accessibility: @accessibility,
66
- attributes: attributes,
67
- annotations: annotations,
68
- comment: comment
104
+ defs: defs.map {|defn| defn.update(type: defn.type.map_type(&block)) },
105
+ accessibility: @accessibility
106
+ )
107
+ end
108
+
109
+ def map_method_type(&block)
110
+ self.class.new(
111
+ super_method: super_method,
112
+ defs: defs.map {|defn| defn.update(type: yield(defn.type)) },
113
+ accessibility: @accessibility
69
114
  )
70
115
  end
71
116
  end
@@ -73,78 +118,149 @@ module RBS
73
118
  module Ancestor
74
119
  Instance = Struct.new(:name, :args, keyword_init: true)
75
120
  Singleton = Struct.new(:name, keyword_init: true)
76
- ExtensionInstance = Struct.new(:name, :extension_name, :args, keyword_init: true)
77
- ExtensionSingleton = Struct.new(:name, :extension_name, keyword_init: true)
78
121
  end
79
122
 
80
- attr_reader :declaration
123
+ class InstanceAncestors
124
+ attr_reader :type_name
125
+ attr_reader :params
126
+ attr_reader :ancestors
127
+
128
+ def initialize(type_name:, params:, ancestors:)
129
+ @type_name = type_name
130
+ @params = params
131
+ @ancestors = ancestors
132
+ end
133
+
134
+ def apply(args, location:)
135
+ InvalidTypeApplicationError.check!(
136
+ type_name: type_name,
137
+ args: args,
138
+ params: params,
139
+ location: location
140
+ )
141
+
142
+ subst = Substitution.build(params, args)
143
+
144
+ ancestors.map do |ancestor|
145
+ case ancestor
146
+ when Ancestor::Instance
147
+ if ancestor.args.empty?
148
+ ancestor
149
+ else
150
+ Ancestor::Instance.new(
151
+ name: ancestor.name,
152
+ args: ancestor.args.map {|type| type.sub(subst) }
153
+ )
154
+ end
155
+ when Ancestor::Singleton
156
+ ancestor
157
+ end
158
+ end
159
+ end
160
+ end
161
+
162
+ class SingletonAncestors
163
+ attr_reader :type_name
164
+ attr_reader :ancestors
165
+
166
+ def initialize(type_name:, ancestors:)
167
+ @type_name = type_name
168
+ @ancestors = ancestors
169
+ end
170
+ end
171
+
172
+ attr_reader :type_name
173
+ attr_reader :entry
174
+ attr_reader :ancestors
81
175
  attr_reader :self_type
82
176
  attr_reader :methods
83
177
  attr_reader :instance_variables
84
178
  attr_reader :class_variables
85
- attr_reader :ancestors
86
179
 
87
- def initialize(declaration:, self_type:, ancestors:)
88
- unless declaration.is_a?(AST::Declarations::Class) ||
89
- declaration.is_a?(AST::Declarations::Module) ||
90
- declaration.is_a?(AST::Declarations::Interface) ||
91
- declaration.is_a?(AST::Declarations::Extension)
92
- raise "Declaration should be a class, module, or interface: #{declaration.name}"
180
+ def initialize(type_name:, entry:, self_type:, ancestors:)
181
+ case entry
182
+ when Environment::ClassEntry, Environment::ModuleEntry
183
+ # ok
184
+ else
185
+ unless entry.decl.is_a?(AST::Declarations::Interface)
186
+ raise "Declaration should be a class, module, or interface: #{type_name}"
187
+ end
93
188
  end
94
189
 
95
- unless (self_type.is_a?(Types::ClassSingleton) || self_type.is_a?(Types::Interface) || self_type.is_a?(Types::ClassInstance)) && self_type.name == declaration.name.absolute!
190
+ unless self_type.is_a?(Types::ClassSingleton) || self_type.is_a?(Types::Interface) || self_type.is_a?(Types::ClassInstance)
96
191
  raise "self_type should be the type of declaration: #{self_type}"
97
192
  end
98
193
 
194
+ @type_name = type_name
99
195
  @self_type = self_type
100
- @declaration = declaration
196
+ @entry = entry
101
197
  @methods = {}
102
198
  @instance_variables = {}
103
199
  @class_variables = {}
104
200
  @ancestors = ancestors
105
201
  end
106
202
 
107
- def name
108
- declaration.name
109
- end
110
-
111
203
  def class?
112
- declaration.is_a?(AST::Declarations::Class)
204
+ entry.is_a?(Environment::ClassEntry)
113
205
  end
114
206
 
115
207
  def module?
116
- declaration.is_a?(AST::Declarations::Module)
208
+ entry.is_a?(Environment::ModuleEntry)
209
+ end
210
+
211
+ def interface?
212
+ entry.is_a?(Environment::SingleEntry) && entry.decl.is_a?(AST::Declarations::Interface)
117
213
  end
118
214
 
119
215
  def class_type?
120
- @self_type.is_a?(Types::ClassSingleton)
216
+ self_type.is_a?(Types::ClassSingleton)
121
217
  end
122
218
 
123
219
  def instance_type?
124
- @self_type.is_a?(Types::ClassInstance)
220
+ self_type.is_a?(Types::ClassInstance)
125
221
  end
126
222
 
127
223
  def interface_type?
128
- @self_type.is_a?(Types::Interface)
224
+ self_type.is_a?(Types::Interface)
129
225
  end
130
226
 
131
227
  def type_params
132
- @self_type.args.map(&:name)
228
+ type_params_decl.each.map(&:name)
133
229
  end
134
230
 
135
231
  def type_params_decl
136
- case declaration
137
- when AST::Declarations::Extension
138
- nil
139
- else
140
- declaration.type_params
232
+ case entry
233
+ when Environment::ClassEntry, Environment::ModuleEntry
234
+ entry.type_params
235
+ when Environment::SingleEntry
236
+ entry.decl.type_params
141
237
  end
142
238
  end
143
239
 
240
+ def sub(s)
241
+ definition = self.class.new(type_name: type_name, self_type: self_type.sub(s), ancestors: ancestors, entry: entry)
242
+
243
+ definition.methods.merge!(methods.transform_values {|method| method.sub(s) })
244
+ definition.instance_variables.merge!(instance_variables.transform_values {|v| v.sub(s) })
245
+ definition.class_variables.merge!(class_variables.transform_values {|v| v.sub(s) })
246
+
247
+ definition
248
+ end
249
+
250
+ def map_method_type(&block)
251
+ definition = self.class.new(type_name: type_name, self_type: self_type, ancestors: ancestors, entry: entry)
252
+
253
+ definition.methods.merge!(methods.transform_values {|method| method.map_method_type(&block) })
254
+ definition.instance_variables.merge!(instance_variables)
255
+ definition.class_variables.merge!(class_variables)
256
+
257
+ definition
258
+ end
259
+
144
260
  def each_type(&block)
145
261
  if block_given?
146
262
  methods.each_value do |method|
147
- if method.defined_in == self.declaration
263
+ if method.defined_in == type_name
148
264
  method.method_types.each do |method_type|
149
265
  method_type.each_type(&block)
150
266
  end
@@ -152,13 +268,13 @@ module RBS
152
268
  end
153
269
 
154
270
  instance_variables.each_value do |var|
155
- if var.declared_in == self.declaration
271
+ if var.declared_in == type_name
156
272
  yield var.type
157
273
  end
158
274
  end
159
275
 
160
276
  class_variables.each_value do |var|
161
- if var.declared_in == self.declaration
277
+ if var.declared_in == type_name
162
278
  yield var.type
163
279
  end
164
280
  end