rbs 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +7 -1
  3. data/.gitignore +1 -1
  4. data/CHANGELOG.md +7 -0
  5. data/Gemfile +12 -0
  6. data/README.md +86 -47
  7. data/Rakefile +54 -21
  8. data/bin/rbs-prof +9 -0
  9. data/bin/run_in_md.rb +49 -0
  10. data/lib/rbs.rb +2 -0
  11. data/lib/rbs/ast/declarations.rb +62 -7
  12. data/lib/rbs/ast/members.rb +41 -17
  13. data/lib/rbs/cli.rb +299 -121
  14. data/lib/rbs/constant.rb +4 -4
  15. data/lib/rbs/constant_table.rb +50 -44
  16. data/lib/rbs/definition.rb +175 -59
  17. data/lib/rbs/definition_builder.rb +647 -603
  18. data/lib/rbs/environment.rb +338 -209
  19. data/lib/rbs/environment_walker.rb +14 -23
  20. data/lib/rbs/errors.rb +141 -3
  21. data/lib/rbs/parser.y +14 -9
  22. data/lib/rbs/prototype/rb.rb +100 -112
  23. data/lib/rbs/prototype/rbi.rb +4 -2
  24. data/lib/rbs/prototype/runtime.rb +10 -6
  25. data/lib/rbs/substitution.rb +8 -1
  26. data/lib/rbs/test/hook.rb +2 -2
  27. data/lib/rbs/test/setup.rb +3 -1
  28. data/lib/rbs/test/test_helper.rb +2 -5
  29. data/lib/rbs/test/type_check.rb +1 -2
  30. data/lib/rbs/type_name_resolver.rb +58 -0
  31. data/lib/rbs/types.rb +94 -2
  32. data/lib/rbs/validator.rb +51 -0
  33. data/lib/rbs/variance_calculator.rb +12 -2
  34. data/lib/rbs/version.rb +1 -1
  35. data/lib/rbs/writer.rb +125 -89
  36. data/rbs.gemspec +0 -10
  37. data/schema/decls.json +15 -0
  38. data/schema/members.json +3 -0
  39. data/stdlib/benchmark/benchmark.rbs +151 -151
  40. data/stdlib/builtin/enumerable.rbs +1 -1
  41. data/stdlib/builtin/file.rbs +0 -3
  42. data/stdlib/builtin/io.rbs +4 -4
  43. data/stdlib/builtin/thread.rbs +2 -2
  44. data/stdlib/csv/csv.rbs +4 -6
  45. data/stdlib/fiber/fiber.rbs +1 -1
  46. data/stdlib/json/json.rbs +1 -1
  47. data/stdlib/mutex_m/mutex_m.rbs +77 -0
  48. data/stdlib/pathname/pathname.rbs +6 -6
  49. data/stdlib/prime/integer-extension.rbs +1 -1
  50. data/stdlib/prime/prime.rbs +44 -44
  51. data/stdlib/tmpdir/tmpdir.rbs +1 -1
  52. metadata +8 -129
@@ -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
 
@@ -88,14 +101,18 @@ module RBS
88
101
  end
89
102
 
90
103
  def constant_scopes_module(name, scopes:)
91
- decl = env.find_class(name)
104
+ entry = env.class_decls[name]
92
105
  namespace = name.to_namespace
93
106
 
94
- decl.members.each do |member|
95
- case member
96
- when AST::Members::Include
97
- constant_scopes_module absolute_type_name(member.name, namespace: namespace),
98
- 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
99
116
  end
100
117
  end
101
118
 
@@ -103,53 +120,42 @@ module RBS
103
120
  end
104
121
 
105
122
  def constant_scopes0(name, scopes: [])
106
- decl = env.find_class(name)
123
+ entry = env.class_decls[name]
107
124
  namespace = name.to_namespace
108
125
 
109
- case decl
110
- when AST::Declarations::Module
111
- constant_scopes0 BuiltinNames::Module.name, scopes: scopes
112
- constant_scopes_module name, scopes: scopes
113
-
114
- when AST::Declarations::Class
126
+ case entry
127
+ when Environment::ClassEntry
115
128
  unless name == BuiltinNames::BasicObject.name
116
- super_name = decl.super_class&.yield_self {|super_class|
117
- absolute_type_name(super_class.name, namespace: namespace)
118
- } || 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
119
132
 
120
133
  constant_scopes0 super_name, scopes: scopes
121
134
  end
122
135
 
123
- decl.members.each do |member|
124
- case member
125
- when AST::Members::Include
126
- constant_scopes_module absolute_type_name(member.name, namespace: namespace),
127
- 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
128
145
  end
129
146
  end
130
147
 
131
148
  scopes.unshift namespace
149
+
150
+ when Environment::ModuleEntry
151
+ constant_scopes0 BuiltinNames::Module.name, scopes: scopes
152
+ constant_scopes_module name, scopes: scopes
153
+
132
154
  else
133
155
  raise "Unexpected declaration: #{name} (#{decl.class})"
134
156
  end
135
157
 
136
- env.each_extension(name).sort_by {|e| e.extension_name.to_s }.each do |extension|
137
- extension.members.each do |member|
138
- case member
139
- when AST::Members::Include
140
- constant_scopes_module absolute_type_name(member.name, namespace: namespace),
141
- scopes: []
142
- end
143
- end
144
- end
145
-
146
158
  scopes
147
159
  end
148
-
149
- def absolute_type_name(name, namespace:)
150
- env.absolute_type_name(name, namespace: namespace) do
151
- raise
152
- end
153
- end
154
160
  end
155
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