rbs 0.2.0 → 0.6.0

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