rbs 0.5.0 → 0.9.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +33 -0
- data/Gemfile +2 -0
- data/Rakefile +2 -3
- data/docs/stdlib.md +0 -2
- data/docs/syntax.md +6 -3
- data/goodcheck.yml +65 -0
- data/lib/rbs.rb +1 -0
- data/lib/rbs/ast/comment.rb +6 -0
- data/lib/rbs/ast/declarations.rb +44 -6
- data/lib/rbs/cli.rb +21 -3
- data/lib/rbs/constant_table.rb +1 -1
- data/lib/rbs/definition_builder.rb +290 -124
- data/lib/rbs/environment.rb +50 -37
- data/lib/rbs/errors.rb +68 -25
- data/lib/rbs/factory.rb +14 -0
- data/lib/rbs/location.rb +15 -0
- data/lib/rbs/parser.y +89 -28
- data/lib/rbs/prototype/rb.rb +2 -2
- data/lib/rbs/prototype/rbi.rb +1 -1
- data/lib/rbs/prototype/runtime.rb +1 -1
- data/lib/rbs/substitution.rb +6 -2
- data/lib/rbs/test.rb +82 -3
- data/lib/rbs/test/errors.rb +5 -1
- data/lib/rbs/test/hook.rb +133 -259
- data/lib/rbs/test/observer.rb +17 -0
- data/lib/rbs/test/setup.rb +37 -20
- data/lib/rbs/test/setup_helper.rb +29 -0
- data/lib/rbs/test/spy.rb +0 -321
- data/lib/rbs/test/tester.rb +118 -0
- data/lib/rbs/test/type_check.rb +42 -5
- data/lib/rbs/validator.rb +4 -0
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs/writer.rb +2 -2
- data/schema/decls.json +21 -10
- data/stdlib/builtin/enumerable.rbs +2 -2
- data/stdlib/builtin/proc.rbs +1 -2
- data/stdlib/json/json.rbs +6 -0
- data/stdlib/logger/formatter.rbs +23 -0
- data/stdlib/logger/log_device.rbs +39 -0
- data/stdlib/logger/logger.rbs +507 -0
- data/stdlib/logger/period.rbs +7 -0
- data/stdlib/logger/severity.rbs +8 -0
- data/stdlib/pty/pty.rbs +159 -0
- metadata +13 -3
- data/lib/rbs/test/test_helper.rb +0 -180
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '094182e5d2602ec5ba9244068f67f854dfd5aa9c804fe48f2e943934da3e806b'
|
4
|
+
data.tar.gz: bbd2a02e2c79a092f3e3555337aebdb557301fd2dd712bc46bcfaaa3ae4f3ed5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8de689c6af71a94ef511cd5efc9b64d1277f99256e759ec58ad4185505831e3ca041a8555f454ea6700713a4f03a88caeed2104009b8915b9acf5c8b4e5ba53b
|
7
|
+
data.tar.gz: dec9ab30d0d1261897103b71c7203d3857c2cd4150ef145f3b8f3d005b7ba3f9daa947033a1db37c7f7aaf7530725f9129707d29def747fe9334a75acbcc9a16
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,39 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 0.9.1 (2020-08-04)
|
6
|
+
|
7
|
+
* Ensure using Module#name [#354](https://github.com/ruby/rbs/pull/354)
|
8
|
+
* Fix runtime test setup [#353](https://github.com/ruby/rbs/pull/353)
|
9
|
+
|
10
|
+
## 0.9.0 (2020-08-03)
|
11
|
+
|
12
|
+
* Fix signature validation [#351](https://github.com/ruby/rbs/pull/351), [#352](https://github.com/ruby/rbs/pull/352)
|
13
|
+
* Parsing performance improvement [#350](https://github.com/ruby/rbs/pull/350)
|
14
|
+
|
15
|
+
## 0.8.0 (2020-08-01)
|
16
|
+
|
17
|
+
* Signature updates for `Enumerator` and `PTY`
|
18
|
+
* Fix prototype rb/rbi error handling [#349](https://github.com/ruby/rbs/pull/349)
|
19
|
+
* Runtime test improvements [#344](https://github.com/ruby/rbs/pull/344), [#343](https://github.com/ruby/rbs/pull/343)
|
20
|
+
* Add `...` syntax [#342](https://github.com/ruby/rbs/pull/342)
|
21
|
+
|
22
|
+
## 0.7.0 (2020-07-20)
|
23
|
+
|
24
|
+
* Add `DefinitionBuilder#one_instance_ancestors` and `DefinitionBuilder#one_singleton_ancestors` [#341](https://github.com/ruby/rbs/pull/341)
|
25
|
+
* Bug fix in ConstantTable [#340](https://github.com/ruby/rbs/pull/340)
|
26
|
+
* Make `rbs validate` faster [#338](https://github.com/ruby/rbs/pull/338)
|
27
|
+
* Dedup methods generated by `rbs prototype rb` [#334](https://github.com/ruby/rbs/pull/334)
|
28
|
+
|
29
|
+
## 0.6.0 (2020-07-12)
|
30
|
+
|
31
|
+
* Signature update for `Logger`.
|
32
|
+
* Clean `Environment#inspect`. [#331](https://github.com/ruby/rbs/pull/331)
|
33
|
+
* Module self type syntax update. [#329](https://github.com/ruby/rbs/pull/329)
|
34
|
+
* Better validation. [#328](https://github.com/ruby/rbs/pull/328)
|
35
|
+
* Parser performance improvement. [#327](https://github.com/ruby/rbs/pull/327)
|
36
|
+
* Runtime type checking performance improvements with sampling [#323](https://github.com/ruby/rbs/pull/323)
|
37
|
+
|
5
38
|
## 0.5.0 (2020-07-04)
|
6
39
|
|
7
40
|
* Signature updates for `Mutex_m`, `IO`, and `Enumerable`.
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -78,11 +78,10 @@ namespace :generate do
|
|
78
78
|
def call
|
79
79
|
ERB.new(<<~ERB, trim_mode: "-").result(binding)
|
80
80
|
require_relative "test_helper"
|
81
|
-
require 'rbs/test/test_helper'
|
82
81
|
|
83
82
|
<%- unless class_methods.empty? -%>
|
84
83
|
class <%= klass %>SingletonTest < Minitest::Test
|
85
|
-
include
|
84
|
+
include TypeAssertions
|
86
85
|
|
87
86
|
# library "pathname", "set", "securerandom" # Declare library signatures to load
|
88
87
|
testing "singleton(::<%= klass %>)"
|
@@ -100,7 +99,7 @@ namespace :generate do
|
|
100
99
|
|
101
100
|
<%- unless instance_methods.empty? -%>
|
102
101
|
class <%= klass %>Test < Minitest::Test
|
103
|
-
include
|
102
|
+
include TypeAssertions
|
104
103
|
|
105
104
|
# library "pathname", "set", "securerandom" # Declare library signatures to load
|
106
105
|
testing "::<%= klass %>"
|
data/docs/stdlib.md
CHANGED
@@ -120,7 +120,6 @@ The test scripts would look like the following:
|
|
120
120
|
```rb
|
121
121
|
class StringTest < StdlibTest
|
122
122
|
target String
|
123
|
-
using hook.refinement
|
124
123
|
|
125
124
|
def test_gsub
|
126
125
|
s = "string"
|
@@ -136,7 +135,6 @@ end
|
|
136
135
|
|
137
136
|
You need two method calls, `target` and `using`.
|
138
137
|
`target` method call tells which class is the subject of the class.
|
139
|
-
`using hook.refinement` installs a special instrumentation for stdlib, based on refinements.
|
140
138
|
And you write the sample programs which calls all of the patterns of overloads.
|
141
139
|
|
142
140
|
Note that the instrumentation is based on refinements and you need to write all method calls in the unit class definitions.
|
data/docs/syntax.md
CHANGED
@@ -166,7 +166,7 @@ end
|
|
166
166
|
|
167
167
|
### Proc type
|
168
168
|
|
169
|
-
Proc type
|
169
|
+
Proc type denotes type of procedures, `Proc` instances.
|
170
170
|
|
171
171
|
```
|
172
172
|
^(Integer) -> String # A procedure with an `Integer` parameter and returns `String`
|
@@ -348,7 +348,7 @@ attr_reader id: Integer
|
|
348
348
|
# @id: Integer
|
349
349
|
# def id: () -> Integer
|
350
350
|
|
351
|
-
# Defines `name=` method and
|
351
|
+
# Defines `name=` method and `@raw_name` instance variable.
|
352
352
|
attr_writer name (@raw_name) : String
|
353
353
|
# @raw_name: String
|
354
354
|
# def name=: (String) -> String
|
@@ -408,7 +408,10 @@ _class-decl_ ::= `class` _class-name_ _module-type-parameters_ _members_ `end`
|
|
408
408
|
| `class` _class-name_ _module-type-parameters_ `<` _class-name_ _type-arguments_ _members_ `end`
|
409
409
|
|
410
410
|
_module-decl_ ::= `module` _module-name_ _module-type-parameters_ _members_ `end`
|
411
|
-
| `module` _module-name_ _module-type-parameters_ `:`
|
411
|
+
| `module` _module-name_ _module-type-parameters_ `:` _module-self-types_ _members_ `end`
|
412
|
+
|
413
|
+
_module-self-types_ ::= _class-name_ _type-arguments_ `,` _module-self-types_ (Class instance)
|
414
|
+
| _interface-name_ _type-arguments_ `,` _module-self-types_ (Interface)
|
412
415
|
|
413
416
|
_interface-decl_ ::= `interface` _interface-name_ _module-type-parameters_ _interface-members_ `end`
|
414
417
|
|
data/goodcheck.yml
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
rules:
|
2
|
+
- id: rbs.no_mark
|
3
|
+
pattern: 💪👽🚨
|
4
|
+
message: Do you forget to delete `arglists` section?
|
5
|
+
glob:
|
6
|
+
- "stdlib/**/*.rbs"
|
7
|
+
fail:
|
8
|
+
- |
|
9
|
+
# arglists 💪👽🚨 << Delete this section
|
10
|
+
# File.absolute_path?(file_name) -> true or false
|
11
|
+
#
|
12
|
+
|
13
|
+
- id: rbs.no_arg
|
14
|
+
pattern:
|
15
|
+
regexp: arg\d+
|
16
|
+
message: |
|
17
|
+
Stop using parameter names like `arg0` or `arg1`
|
18
|
+
|
19
|
+
The parameter names like `arg0` or `arg1` is not informative enough.
|
20
|
+
Try finding good parameter names from documents or arglists.
|
21
|
+
If you cannot find a good name, just delete the name of the parameters.
|
22
|
+
justification:
|
23
|
+
- Documents (comments) may contain that pattern.
|
24
|
+
glob:
|
25
|
+
- "stdlib/**/*.rbs"
|
26
|
+
fail:
|
27
|
+
- "def `send`: (String | Symbol arg0, *untyped arg1) -> untyped"
|
28
|
+
pass:
|
29
|
+
- "def `send`: (String | Symbol, *untyped) -> untyped"
|
30
|
+
|
31
|
+
- id: deprecate_stdlib_test
|
32
|
+
pattern:
|
33
|
+
token: < StdlibTest
|
34
|
+
message: |
|
35
|
+
StdlibTest is deprecated
|
36
|
+
|
37
|
+
We recommend writing tests based on `TypeAssertions` and `#assert_send_type`.
|
38
|
+
justification:
|
39
|
+
- When you are updating existing tests.
|
40
|
+
- When you are writing tests for callback, which cannot be done with `#assert_send_type`.
|
41
|
+
glob:
|
42
|
+
- "test/stdlib/**/*_test.rb"
|
43
|
+
fail:
|
44
|
+
- |
|
45
|
+
class IntegerTest < StdlibTest
|
46
|
+
target Integer
|
47
|
+
|
48
|
+
def test_plus
|
49
|
+
1 + 2
|
50
|
+
end
|
51
|
+
end
|
52
|
+
pass:
|
53
|
+
- |
|
54
|
+
class IntegerTest < Minitest::Test
|
55
|
+
include TypeAssertions
|
56
|
+
|
57
|
+
testing "Integer"
|
58
|
+
|
59
|
+
def test_plus
|
60
|
+
assert_send_type "(::Integer) -> ::Integer",
|
61
|
+
1, :+, 2
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
|
data/lib/rbs.rb
CHANGED
data/lib/rbs/ast/comment.rb
CHANGED
data/lib/rbs/ast/declarations.rb
CHANGED
@@ -204,6 +204,44 @@ module RBS
|
|
204
204
|
end
|
205
205
|
|
206
206
|
class Module < Base
|
207
|
+
class Self
|
208
|
+
attr_reader :name
|
209
|
+
attr_reader :args
|
210
|
+
attr_reader :location
|
211
|
+
|
212
|
+
def initialize(name:, args:, location:)
|
213
|
+
@name = name
|
214
|
+
@args = args
|
215
|
+
@location = location
|
216
|
+
end
|
217
|
+
|
218
|
+
def ==(other)
|
219
|
+
other.is_a?(Self) && other.name == name && other.args == args
|
220
|
+
end
|
221
|
+
|
222
|
+
alias eql? ==
|
223
|
+
|
224
|
+
def hash
|
225
|
+
self.class.hash ^ name.hash ^ args.hash ^ location.hash
|
226
|
+
end
|
227
|
+
|
228
|
+
def to_json(*a)
|
229
|
+
{
|
230
|
+
name: name,
|
231
|
+
args: args,
|
232
|
+
location: location
|
233
|
+
}.to_json(*a)
|
234
|
+
end
|
235
|
+
|
236
|
+
def to_s
|
237
|
+
if args.empty?
|
238
|
+
name.to_s
|
239
|
+
else
|
240
|
+
"#{name}[#{args.join(", ")}]"
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
207
245
|
include NestedDeclarationHelper
|
208
246
|
include MixinHelper
|
209
247
|
|
@@ -212,13 +250,13 @@ module RBS
|
|
212
250
|
attr_reader :members
|
213
251
|
attr_reader :location
|
214
252
|
attr_reader :annotations
|
215
|
-
attr_reader :
|
253
|
+
attr_reader :self_types
|
216
254
|
attr_reader :comment
|
217
255
|
|
218
|
-
def initialize(name:, type_params:, members:,
|
256
|
+
def initialize(name:, type_params:, members:, self_types:, annotations:, location:, comment:)
|
219
257
|
@name = name
|
220
258
|
@type_params = type_params
|
221
|
-
@
|
259
|
+
@self_types = self_types
|
222
260
|
@members = members
|
223
261
|
@annotations = annotations
|
224
262
|
@location = location
|
@@ -229,14 +267,14 @@ module RBS
|
|
229
267
|
other.is_a?(Module) &&
|
230
268
|
other.name == name &&
|
231
269
|
other.type_params == type_params &&
|
232
|
-
other.
|
270
|
+
other.self_types == self_types &&
|
233
271
|
other.members == members
|
234
272
|
end
|
235
273
|
|
236
274
|
alias eql? ==
|
237
275
|
|
238
276
|
def hash
|
239
|
-
self.class.hash ^ name.hash ^ type_params.hash ^
|
277
|
+
self.class.hash ^ name.hash ^ type_params.hash ^ self_types.hash ^ members.hash
|
240
278
|
end
|
241
279
|
|
242
280
|
def to_json(*a)
|
@@ -245,7 +283,7 @@ module RBS
|
|
245
283
|
name: name,
|
246
284
|
type_params: type_params,
|
247
285
|
members: members,
|
248
|
-
|
286
|
+
self_types: self_types,
|
249
287
|
annotations: annotations,
|
250
288
|
location: location,
|
251
289
|
comment: comment
|
data/lib/rbs/cli.rb
CHANGED
@@ -66,6 +66,10 @@ module RBS
|
|
66
66
|
opts
|
67
67
|
end
|
68
68
|
|
69
|
+
def has_parser?
|
70
|
+
defined?(RubyVM::AbstractSyntaxTree)
|
71
|
+
end
|
72
|
+
|
69
73
|
def run(args)
|
70
74
|
options = LibraryOptions.new
|
71
75
|
|
@@ -409,6 +413,7 @@ EOU
|
|
409
413
|
env.constant_decls.each do |name, const|
|
410
414
|
stdout.puts "Validating constant: `#{name}`..."
|
411
415
|
validator.validate_type const.decl.type, context: const.context
|
416
|
+
builder.ensure_namespace!(name.namespace, location: const.decl.location)
|
412
417
|
end
|
413
418
|
|
414
419
|
env.global_decls.each do |name, global|
|
@@ -418,7 +423,9 @@ EOU
|
|
418
423
|
|
419
424
|
env.alias_decls.each do |name, decl|
|
420
425
|
stdout.puts "Validating alias: `#{name}`..."
|
421
|
-
|
426
|
+
builder.expand_alias(name).tap do |type|
|
427
|
+
validator.validate_type type, context: [Namespace.root]
|
428
|
+
end
|
422
429
|
end
|
423
430
|
end
|
424
431
|
|
@@ -599,12 +606,18 @@ EOU
|
|
599
606
|
end
|
600
607
|
|
601
608
|
def run_prototype_file(format, args)
|
609
|
+
availability = unless has_parser?
|
610
|
+
"\n** This command does not work on this interpreter (#{RUBY_ENGINE}) **\n"
|
611
|
+
end
|
612
|
+
|
602
613
|
opts = OptionParser.new
|
603
614
|
opts.banner = <<EOU
|
604
615
|
Usage: rbs prototype #{format} [options...] [files...]
|
605
|
-
|
616
|
+
#{availability}
|
606
617
|
Generate RBS prototype from source code.
|
607
|
-
It parses specified Ruby code and and generates RBS prototypes.
|
618
|
+
It parses specified Ruby code and and generates RBS prototypes.
|
619
|
+
|
620
|
+
It only works on MRI because it parses Ruby code with `RubyVM::AbstractSyntaxTree`.
|
608
621
|
|
609
622
|
Examples:
|
610
623
|
|
@@ -613,6 +626,11 @@ Examples:
|
|
613
626
|
EOU
|
614
627
|
opts.parse!(args)
|
615
628
|
|
629
|
+
unless has_parser?
|
630
|
+
stdout.puts "Not supported on this interpreter (#{RUBY_ENGINE})."
|
631
|
+
exit 1
|
632
|
+
end
|
633
|
+
|
616
634
|
if args.empty?
|
617
635
|
stdout.puts opts
|
618
636
|
return nil
|
data/lib/rbs/constant_table.rb
CHANGED
@@ -13,6 +13,77 @@ module RBS
|
|
13
13
|
attr_reader :instance_ancestors_cache
|
14
14
|
attr_reader :singleton_ancestor_cache
|
15
15
|
|
16
|
+
attr_reader :one_instance_ancestors_cache
|
17
|
+
attr_reader :one_singleton_ancestors_cache
|
18
|
+
|
19
|
+
class OneAncestors
|
20
|
+
attr_reader :type_name
|
21
|
+
attr_reader :params
|
22
|
+
attr_reader :super_class
|
23
|
+
attr_reader :self_types
|
24
|
+
attr_reader :included_modules
|
25
|
+
attr_reader :prepended_modules
|
26
|
+
attr_reader :extended_modules
|
27
|
+
|
28
|
+
def initialize(type_name:, params:, super_class:, self_types:, included_modules:, prepended_modules:, extended_modules:)
|
29
|
+
@type_name = type_name
|
30
|
+
@params = params
|
31
|
+
@super_class = super_class
|
32
|
+
@self_types = self_types
|
33
|
+
@included_modules = included_modules
|
34
|
+
@prepended_modules = prepended_modules
|
35
|
+
@extended_modules = extended_modules
|
36
|
+
end
|
37
|
+
|
38
|
+
def each_ancestor(&block)
|
39
|
+
if block_given?
|
40
|
+
yield super_class if super_class
|
41
|
+
self_types&.each(&block)
|
42
|
+
included_modules&.each(&block)
|
43
|
+
prepended_modules&.each(&block)
|
44
|
+
extended_modules&.each(&block)
|
45
|
+
else
|
46
|
+
enum_for :each_ancestor
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.class_instance(type_name:, params:, super_class:)
|
51
|
+
new(
|
52
|
+
type_name: type_name,
|
53
|
+
params: params,
|
54
|
+
super_class: super_class,
|
55
|
+
self_types: nil,
|
56
|
+
included_modules: [],
|
57
|
+
prepended_modules: [],
|
58
|
+
extended_modules: nil
|
59
|
+
)
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.singleton(type_name:, super_class:)
|
63
|
+
new(
|
64
|
+
type_name: type_name,
|
65
|
+
params: nil,
|
66
|
+
super_class: super_class,
|
67
|
+
self_types: nil,
|
68
|
+
included_modules: nil,
|
69
|
+
prepended_modules: nil,
|
70
|
+
extended_modules: []
|
71
|
+
)
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.module_instance(type_name:, params:)
|
75
|
+
new(
|
76
|
+
type_name: type_name,
|
77
|
+
params: params,
|
78
|
+
self_types: [],
|
79
|
+
included_modules: [],
|
80
|
+
prepended_modules: [],
|
81
|
+
super_class: nil,
|
82
|
+
extended_modules: nil
|
83
|
+
)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
16
87
|
def initialize(env:)
|
17
88
|
@env = env
|
18
89
|
@type_name_resolver = TypeNameResolver.from_env(env)
|
@@ -26,6 +97,9 @@ module RBS
|
|
26
97
|
|
27
98
|
@instance_ancestors_cache = {}
|
28
99
|
@singleton_ancestor_cache = {}
|
100
|
+
|
101
|
+
@one_instance_ancestors_cache = {}
|
102
|
+
@one_singleton_ancestors_cache = {}
|
29
103
|
end
|
30
104
|
|
31
105
|
def validate_super_class!(type_name, entry)
|
@@ -45,30 +119,19 @@ module RBS
|
|
45
119
|
raise SuperclassMismatchError.new(name: type_name, super_classes: super_types, entry: entry)
|
46
120
|
end
|
47
121
|
|
48
|
-
def
|
49
|
-
as =
|
122
|
+
def one_instance_ancestors(type_name)
|
123
|
+
as = one_instance_ancestors_cache[type_name] and return as
|
50
124
|
|
51
|
-
entry = env.class_decls[type_name]
|
125
|
+
entry = env.class_decls[type_name] or raise "Unknown name for one_instance_ancestors: #{type_name}"
|
52
126
|
params = entry.type_params.each.map(&:name)
|
53
|
-
args = Types::Variable.build(params)
|
54
|
-
self_ancestor = Definition::Ancestor::Instance.new(name: type_name, args: args)
|
55
|
-
|
56
|
-
RecursiveAncestorError.check!(self_ancestor,
|
57
|
-
ancestors: building_ancestors,
|
58
|
-
location: entry.primary.decl.location)
|
59
|
-
building_ancestors.push self_ancestor
|
60
|
-
|
61
|
-
ancestors = []
|
62
127
|
|
63
128
|
case entry
|
64
129
|
when Environment::ClassEntry
|
65
130
|
validate_super_class!(type_name, entry)
|
131
|
+
primary = entry.primary
|
132
|
+
super_class = primary.decl.super_class
|
66
133
|
|
67
|
-
|
68
|
-
if self_ancestor.name != BuiltinNames::BasicObject.name
|
69
|
-
primary = entry.primary
|
70
|
-
super_class = primary.decl.super_class
|
71
|
-
|
134
|
+
if type_name != BuiltinNames::BasicObject.name
|
72
135
|
if super_class
|
73
136
|
super_name = super_class.name
|
74
137
|
super_args = super_class.args
|
@@ -77,91 +140,88 @@ module RBS
|
|
77
140
|
super_args = []
|
78
141
|
end
|
79
142
|
|
80
|
-
|
81
|
-
ancestors.unshift(*super_ancestors.apply(super_args, location: primary.decl.location))
|
82
|
-
end
|
83
|
-
|
84
|
-
build_ancestors_mixin_self(self_ancestor, entry, ancestors: ancestors, building_ancestors: building_ancestors)
|
143
|
+
NoSuperclassFoundError.check!(super_name, env: env, location: primary.decl.location)
|
85
144
|
|
145
|
+
ancestors = OneAncestors.class_instance(
|
146
|
+
type_name: type_name,
|
147
|
+
params: params,
|
148
|
+
super_class: Definition::Ancestor::Instance.new(name: super_name, args: super_args)
|
149
|
+
)
|
150
|
+
else
|
151
|
+
ancestors = OneAncestors.class_instance(
|
152
|
+
type_name: type_name,
|
153
|
+
params: params,
|
154
|
+
super_class: nil
|
155
|
+
)
|
156
|
+
end
|
86
157
|
when Environment::ModuleEntry
|
87
|
-
|
158
|
+
ancestors = OneAncestors.module_instance(type_name: type_name, params: params)
|
88
159
|
|
160
|
+
entry.self_types.each do |module_self|
|
161
|
+
NoSelfTypeFoundError.check!(module_self, env: env)
|
162
|
+
ancestors.self_types.push Definition::Ancestor::Instance.new(name: module_self.name, args: module_self.args)
|
163
|
+
end
|
164
|
+
else
|
165
|
+
raise "Unexpected entry for: #{type_name}"
|
89
166
|
end
|
90
167
|
|
91
|
-
|
168
|
+
mixin_ancestors(entry,
|
169
|
+
included_modules: ancestors.included_modules,
|
170
|
+
prepended_modules: ancestors.prepended_modules,
|
171
|
+
extended_modules: nil)
|
92
172
|
|
93
|
-
|
94
|
-
type_name: type_name,
|
95
|
-
params: params,
|
96
|
-
ancestors: ancestors
|
97
|
-
)
|
173
|
+
one_instance_ancestors_cache[type_name] = ancestors
|
98
174
|
end
|
99
175
|
|
100
|
-
def
|
101
|
-
as =
|
176
|
+
def one_singleton_ancestors(type_name)
|
177
|
+
as = one_singleton_ancestors_cache[type_name] and return as
|
102
178
|
|
103
|
-
entry = env.class_decls[type_name]
|
104
|
-
self_ancestor = Definition::Ancestor::Singleton.new(name: type_name)
|
105
|
-
|
106
|
-
RecursiveAncestorError.check!(self_ancestor,
|
107
|
-
ancestors: building_ancestors,
|
108
|
-
location: entry.primary.decl.location)
|
109
|
-
building_ancestors.push self_ancestor
|
110
|
-
|
111
|
-
ancestors = []
|
179
|
+
entry = env.class_decls[type_name] or raise "Unknown name for one_singleton_ancestors: #{type_name}"
|
112
180
|
|
113
181
|
case entry
|
114
182
|
when Environment::ClassEntry
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
super_class = primary.decl.super_class
|
183
|
+
validate_super_class!(type_name, entry)
|
184
|
+
primary = entry.primary
|
185
|
+
super_class = primary.decl.super_class
|
119
186
|
|
187
|
+
if type_name != BuiltinNames::BasicObject.name
|
120
188
|
if super_class
|
121
189
|
super_name = super_class.name
|
122
190
|
else
|
123
191
|
super_name = BuiltinNames::Object.name
|
124
192
|
end
|
125
193
|
|
126
|
-
|
127
|
-
|
194
|
+
NoSuperclassFoundError.check!(super_name, env: env, location: primary.decl.location)
|
195
|
+
|
196
|
+
ancestors = OneAncestors.singleton(
|
197
|
+
type_name: type_name,
|
198
|
+
super_class: Definition::Ancestor::Singleton.new(name: super_name)
|
199
|
+
)
|
128
200
|
else
|
129
|
-
|
130
|
-
|
201
|
+
ancestors = OneAncestors.singleton(
|
202
|
+
type_name: type_name,
|
203
|
+
super_class: Definition::Ancestor::Instance.new(name: BuiltinNames::Class.name, args: [])
|
204
|
+
)
|
131
205
|
end
|
132
|
-
|
133
206
|
when Environment::ModuleEntry
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
# Extend comes next
|
139
|
-
entry.decls.each do |d|
|
140
|
-
decl = d.decl
|
207
|
+
ancestors = OneAncestors.singleton(
|
208
|
+
type_name: type_name,
|
209
|
+
super_class: Definition::Ancestor::Instance.new(name: BuiltinNames::Module.name, args: [])
|
210
|
+
)
|
141
211
|
|
142
|
-
|
143
|
-
|
144
|
-
when AST::Members::Extend
|
145
|
-
if member.name.class?
|
146
|
-
module_ancestors = instance_ancestors(member.name, building_ancestors: building_ancestors)
|
147
|
-
ancestors.unshift(*module_ancestors.apply(member.args, location: member.location))
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
212
|
+
else
|
213
|
+
raise "Unexpected entry for: #{type_name}"
|
151
214
|
end
|
152
215
|
|
153
|
-
|
154
|
-
|
155
|
-
|
216
|
+
mixin_ancestors(entry,
|
217
|
+
included_modules: nil,
|
218
|
+
prepended_modules: nil,
|
219
|
+
extended_modules: ancestors.extended_modules)
|
156
220
|
|
157
|
-
|
158
|
-
type_name: type_name,
|
159
|
-
ancestors: ancestors
|
160
|
-
)
|
221
|
+
one_singleton_ancestors_cache[type_name] = ancestors
|
161
222
|
end
|
162
223
|
|
163
|
-
def
|
164
|
-
# Include comes next
|
224
|
+
def mixin_ancestors(entry, included_modules:, extended_modules:, prepended_modules:)
|
165
225
|
entry.decls.each do |d|
|
166
226
|
decl = d.decl
|
167
227
|
|
@@ -173,38 +233,143 @@ module RBS
|
|
173
233
|
decl.each_mixin do |member|
|
174
234
|
case member
|
175
235
|
when AST::Members::Include
|
176
|
-
if
|
236
|
+
if included_modules
|
237
|
+
NoMixinFoundError.check!(member.name, env: env, member: member)
|
238
|
+
|
239
|
+
module_name = member.name
|
240
|
+
module_args = member.args.map {|type| type.sub(align_params) }
|
241
|
+
|
242
|
+
included_modules << Definition::Ancestor::Instance.new(name: module_name, args: module_args)
|
243
|
+
end
|
244
|
+
|
245
|
+
when AST::Members::Prepend
|
246
|
+
if prepended_modules
|
247
|
+
NoMixinFoundError.check!(member.name, env: env, member: member)
|
248
|
+
|
177
249
|
module_name = member.name
|
178
250
|
module_args = member.args.map {|type| type.sub(align_params) }
|
179
251
|
|
180
|
-
|
181
|
-
|
252
|
+
prepended_modules << Definition::Ancestor::Instance.new(name: module_name, args: module_args)
|
253
|
+
end
|
254
|
+
|
255
|
+
when AST::Members::Extend
|
256
|
+
if extended_modules
|
257
|
+
NoMixinFoundError.check!(member.name, env: env, member: member)
|
258
|
+
|
259
|
+
module_name = member.name
|
260
|
+
module_args = member.args
|
261
|
+
|
262
|
+
extended_modules << Definition::Ancestor::Instance.new(name: module_name, args: module_args)
|
182
263
|
end
|
183
264
|
end
|
184
265
|
end
|
185
266
|
end
|
267
|
+
end
|
268
|
+
|
269
|
+
def instance_ancestors(type_name, building_ancestors: [])
|
270
|
+
as = instance_ancestors_cache[type_name] and return as
|
271
|
+
|
272
|
+
entry = env.class_decls[type_name] or raise "Unknown name for instance_ancestors: #{type_name}"
|
273
|
+
params = entry.type_params.each.map(&:name)
|
274
|
+
args = Types::Variable.build(params)
|
275
|
+
self_ancestor = Definition::Ancestor::Instance.new(name: type_name, args: args)
|
276
|
+
|
277
|
+
RecursiveAncestorError.check!(self_ancestor,
|
278
|
+
ancestors: building_ancestors,
|
279
|
+
location: entry.primary.decl.location)
|
280
|
+
building_ancestors.push self_ancestor
|
281
|
+
|
282
|
+
one_ancestors = one_instance_ancestors(type_name)
|
283
|
+
|
284
|
+
ancestors = []
|
285
|
+
|
286
|
+
case entry
|
287
|
+
when Environment::ClassEntry
|
288
|
+
if one_ancestors.super_class
|
289
|
+
super_name = one_ancestors.super_class.name
|
290
|
+
super_args = one_ancestors.super_class.args
|
291
|
+
|
292
|
+
super_ancestors = instance_ancestors(super_name, building_ancestors: building_ancestors)
|
293
|
+
ancestors.unshift(*super_ancestors.apply(super_args, location: entry.primary.decl.location))
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
one_ancestors.included_modules.each do |mod|
|
298
|
+
if mod.name.class?
|
299
|
+
name = mod.name
|
300
|
+
args = mod.args
|
301
|
+
mod_ancestors = instance_ancestors(name, building_ancestors: building_ancestors)
|
302
|
+
ancestors.unshift(*mod_ancestors.apply(args, location: entry.primary.decl.location))
|
303
|
+
end
|
304
|
+
end
|
186
305
|
|
187
|
-
# Self
|
188
306
|
ancestors.unshift(self_ancestor)
|
189
307
|
|
190
|
-
|
191
|
-
|
192
|
-
|
308
|
+
one_ancestors.prepended_modules.each do |mod|
|
309
|
+
if mod.name.class?
|
310
|
+
name = mod.name
|
311
|
+
args = mod.args
|
312
|
+
mod_ancestors = instance_ancestors(name, building_ancestors: building_ancestors)
|
313
|
+
ancestors.unshift(*mod_ancestors.apply(args, location: entry.primary.decl.location))
|
314
|
+
end
|
315
|
+
end
|
193
316
|
|
194
|
-
|
195
|
-
Types::Variable.build(entry.type_params.each.map(&:name)))
|
317
|
+
building_ancestors.pop
|
196
318
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
319
|
+
instance_ancestors_cache[type_name] = Definition::InstanceAncestors.new(
|
320
|
+
type_name: type_name,
|
321
|
+
params: params,
|
322
|
+
ancestors: ancestors
|
323
|
+
)
|
324
|
+
end
|
202
325
|
|
203
|
-
|
204
|
-
|
205
|
-
|
326
|
+
def singleton_ancestors(type_name, building_ancestors: [])
|
327
|
+
as = singleton_ancestor_cache[type_name] and return as
|
328
|
+
|
329
|
+
entry = env.class_decls[type_name] or raise "Unknown name for singleton_ancestors: #{type_name}"
|
330
|
+
self_ancestor = Definition::Ancestor::Singleton.new(name: type_name)
|
331
|
+
|
332
|
+
RecursiveAncestorError.check!(self_ancestor,
|
333
|
+
ancestors: building_ancestors,
|
334
|
+
location: entry.primary.decl.location)
|
335
|
+
building_ancestors.push self_ancestor
|
336
|
+
|
337
|
+
one_ancestors = one_singleton_ancestors(type_name)
|
338
|
+
|
339
|
+
ancestors = []
|
340
|
+
|
341
|
+
case one_ancestors.super_class
|
342
|
+
when Definition::Ancestor::Instance
|
343
|
+
super_name = one_ancestors.super_class.name
|
344
|
+
super_args = one_ancestors.super_class.args
|
345
|
+
|
346
|
+
super_ancestors = instance_ancestors(super_name, building_ancestors: building_ancestors)
|
347
|
+
ancestors.unshift(*super_ancestors.apply(super_args, location: entry.primary.decl.location))
|
348
|
+
|
349
|
+
when Definition::Ancestor::Singleton
|
350
|
+
super_name = one_ancestors.super_class.name
|
351
|
+
|
352
|
+
super_ancestors = singleton_ancestors(super_name, building_ancestors: [])
|
353
|
+
ancestors.unshift(*super_ancestors.ancestors)
|
354
|
+
end
|
355
|
+
|
356
|
+
one_ancestors.extended_modules.each do |mod|
|
357
|
+
if mod.name.class?
|
358
|
+
name = mod.name
|
359
|
+
args = mod.args
|
360
|
+
mod_ancestors = instance_ancestors(name, building_ancestors: building_ancestors)
|
361
|
+
ancestors.unshift(*mod_ancestors.apply(args, location: entry.primary.decl.location))
|
206
362
|
end
|
207
363
|
end
|
364
|
+
|
365
|
+
ancestors.unshift(self_ancestor)
|
366
|
+
|
367
|
+
building_ancestors.pop
|
368
|
+
|
369
|
+
singleton_ancestor_cache[type_name] = Definition::SingletonAncestors.new(
|
370
|
+
type_name: type_name,
|
371
|
+
ancestors: ancestors
|
372
|
+
)
|
208
373
|
end
|
209
374
|
|
210
375
|
def each_member_with_accessibility(members, accessibility: :public)
|
@@ -220,9 +385,18 @@ module RBS
|
|
220
385
|
end
|
221
386
|
end
|
222
387
|
|
388
|
+
def ensure_namespace!(namespace, location:)
|
389
|
+
namespace.ascend do |ns|
|
390
|
+
unless ns.empty?
|
391
|
+
NoTypeFoundError.check!(ns.to_type_name, env: env, location: location)
|
392
|
+
end
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
223
396
|
def build_instance(type_name)
|
224
397
|
try_cache type_name, cache: instance_cache do
|
225
|
-
entry = env.class_decls[type_name]
|
398
|
+
entry = env.class_decls[type_name] or raise "Unknown name for build_instance: #{type_name}"
|
399
|
+
ensure_namespace!(type_name.namespace, location: entry.decls[0].decl.location)
|
226
400
|
|
227
401
|
case entry
|
228
402
|
when Environment::ClassEntry, Environment::ModuleEntry
|
@@ -243,11 +417,18 @@ module RBS
|
|
243
417
|
end
|
244
418
|
|
245
419
|
if entry.is_a?(Environment::ModuleEntry)
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
420
|
+
entry.self_types.each do |module_self|
|
421
|
+
ancestor = Definition::Ancestor::Instance.new(name: module_self.name, args: module_self.args)
|
422
|
+
definition_pairs.push(
|
423
|
+
[
|
424
|
+
ancestor,
|
425
|
+
if module_self.name.interface?
|
426
|
+
build_interface(module_self.name)
|
427
|
+
else
|
428
|
+
build_instance(module_self.name)
|
429
|
+
end
|
430
|
+
]
|
431
|
+
)
|
251
432
|
end
|
252
433
|
end
|
253
434
|
|
@@ -259,32 +440,10 @@ module RBS
|
|
259
440
|
end
|
260
441
|
end
|
261
442
|
|
262
|
-
def module_self_ancestor(type_name, entry)
|
263
|
-
self_decls = entry.decls.select {|d| d.decl.self_type }
|
264
|
-
|
265
|
-
return if self_decls.empty?
|
266
|
-
|
267
|
-
selfs = self_decls.map do |d|
|
268
|
-
Definition::Ancestor::Instance.new(
|
269
|
-
name: d.decl.self_type.name,
|
270
|
-
args: d.decl.self_type.args
|
271
|
-
)
|
272
|
-
end
|
273
|
-
|
274
|
-
selfs.uniq!
|
275
|
-
|
276
|
-
return selfs[0] if selfs.size == 1
|
277
|
-
|
278
|
-
raise ModuleSelfTypeMismatchError.new(
|
279
|
-
name: type_name,
|
280
|
-
entry: entry,
|
281
|
-
location: self_decls[0].decl.location
|
282
|
-
)
|
283
|
-
end
|
284
|
-
|
285
443
|
def build_singleton(type_name)
|
286
444
|
try_cache type_name, cache: singleton_cache do
|
287
|
-
entry = env.class_decls[type_name]
|
445
|
+
entry = env.class_decls[type_name] or raise "Unknown name for build_singleton: #{type_name}"
|
446
|
+
ensure_namespace!(type_name.namespace, location: entry.decls[0].decl.location)
|
288
447
|
|
289
448
|
case entry
|
290
449
|
when Environment::ClassEntry, Environment::ModuleEntry
|
@@ -350,6 +509,8 @@ module RBS
|
|
350
509
|
when AST::Members::Include, AST::Members::Extend
|
351
510
|
if member.name.interface?
|
352
511
|
if (kind == :instance && member.is_a?(AST::Members::Include)) || (kind == :singleton && member.is_a?(AST::Members::Extend))
|
512
|
+
NoMixinFoundError.check!(member.name, env: env, member: member)
|
513
|
+
|
353
514
|
interface_name = member.name
|
354
515
|
interface_args = member.args
|
355
516
|
|
@@ -842,7 +1003,7 @@ module RBS
|
|
842
1003
|
methods[name] = Definition::Method.new(
|
843
1004
|
super_method: super_method,
|
844
1005
|
accessibility: method.accessibility,
|
845
|
-
defs: method.defs.map {|defn| defn.update(type: defn.type.sub(sub)) }
|
1006
|
+
defs: sub.mapping.empty? ? method.defs : method.defs.map {|defn| defn.update(type: defn.type.sub(sub)) }
|
846
1007
|
)
|
847
1008
|
end
|
848
1009
|
|
@@ -867,8 +1028,9 @@ module RBS
|
|
867
1028
|
|
868
1029
|
def build_interface(type_name)
|
869
1030
|
try_cache(type_name, cache: interface_cache) do
|
870
|
-
entry = env.interface_decls[type_name]
|
1031
|
+
entry = env.interface_decls[type_name] or raise "Unknown name for build_interface: #{type_name}"
|
871
1032
|
declaration = entry.decl
|
1033
|
+
ensure_namespace!(type_name.namespace, location: declaration.location)
|
872
1034
|
|
873
1035
|
self_type = Types::Interface.new(
|
874
1036
|
name: type_name,
|
@@ -893,6 +1055,8 @@ module RBS
|
|
893
1055
|
end
|
894
1056
|
|
895
1057
|
include_members.each do |member|
|
1058
|
+
NoMixinFoundError.check!(member.name, env: env, member: member)
|
1059
|
+
|
896
1060
|
mixin = build_interface(member.name)
|
897
1061
|
|
898
1062
|
args = member.args
|
@@ -957,7 +1121,9 @@ module RBS
|
|
957
1121
|
end
|
958
1122
|
|
959
1123
|
def expand_alias(type_name)
|
960
|
-
env.alias_decls[type_name]
|
1124
|
+
entry = env.alias_decls[type_name] or raise "Unknown name for expand_alias: #{type_name}"
|
1125
|
+
ensure_namespace!(type_name.namespace, location: entry.decl.location)
|
1126
|
+
entry.decl.type
|
961
1127
|
end
|
962
1128
|
end
|
963
1129
|
end
|