rbs 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -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/declarations.rb +44 -6
- data/lib/rbs/definition_builder.rb +33 -34
- data/lib/rbs/environment.rb +49 -36
- data/lib/rbs/errors.rb +43 -25
- data/lib/rbs/factory.rb +14 -0
- data/lib/rbs/parser.y +60 -11
- data/lib/rbs/prototype/rb.rb +1 -1
- data/lib/rbs/prototype/rbi.rb +1 -1
- data/lib/rbs/prototype/runtime.rb +1 -1
- data/lib/rbs/test.rb +81 -3
- data/lib/rbs/test/errors.rb +1 -1
- data/lib/rbs/test/hook.rb +133 -259
- data/lib/rbs/test/observer.rb +17 -0
- data/lib/rbs/test/setup.rb +12 -15
- data/lib/rbs/test/spy.rb +0 -321
- data/lib/rbs/test/tester.rb +116 -0
- data/lib/rbs/test/type_check.rb +43 -5
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs/writer.rb +2 -2
- data/schema/decls.json +21 -10
- data/stdlib/builtin/proc.rbs +1 -2
- 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
- metadata +11 -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: ce3b2807a94277727870ef841bdb1e3a96567098948930ab6885e9fba2fc3ccf
|
4
|
+
data.tar.gz: 5d4a01b26887124240ec757b8a0374c79d56c3daf8b32431a571a3ba401112cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7978edfd75f809eb604edb58e0c35ff9a1e85b0e34f7462399f76deb36c5a6a0c61030d1fc3a3bb42d689395a0372995e03e41dd47223063084703dc207294d6
|
7
|
+
data.tar.gz: e1216599f496cd883e8b301d1040f395984d3fc3029ba65fa6c2f63ab3e431a96bc8369ff06bd3f97390dd78e0a10279e1e556ba2c25ac4ef5af6dfaf9aafa77
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,15 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 0.6.0 (2020-07-12)
|
6
|
+
|
7
|
+
* Signature update for `Logger`.
|
8
|
+
* Clean `Environment#inspect`. [#331](https://github.com/ruby/rbs/pull/331)
|
9
|
+
* Module self type syntax update. [#329](https://github.com/ruby/rbs/pull/329)
|
10
|
+
* Better validation. [#328](https://github.com/ruby/rbs/pull/328)
|
11
|
+
* Parser performance improvement. [#327](https://github.com/ruby/rbs/pull/327)
|
12
|
+
* Runtime type checking performance improvements with sampling [#323](https://github.com/ruby/rbs/pull/323)
|
13
|
+
|
5
14
|
## 0.5.0 (2020-07-04)
|
6
15
|
|
7
16
|
* 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/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
|
@@ -48,7 +48,7 @@ module RBS
|
|
48
48
|
def instance_ancestors(type_name, building_ancestors: [])
|
49
49
|
as = instance_ancestors_cache[type_name] and return as
|
50
50
|
|
51
|
-
entry = env.class_decls[type_name]
|
51
|
+
entry = env.class_decls[type_name] or raise "Unknown name for instance_ancestors: #{type_name}"
|
52
52
|
params = entry.type_params.each.map(&:name)
|
53
53
|
args = Types::Variable.build(params)
|
54
54
|
self_ancestor = Definition::Ancestor::Instance.new(name: type_name, args: args)
|
@@ -77,6 +77,8 @@ module RBS
|
|
77
77
|
super_args = []
|
78
78
|
end
|
79
79
|
|
80
|
+
NoSuperclassFoundError.check!(super_name, env: env, location: primary.decl.location)
|
81
|
+
|
80
82
|
super_ancestors = instance_ancestors(super_name, building_ancestors: building_ancestors)
|
81
83
|
ancestors.unshift(*super_ancestors.apply(super_args, location: primary.decl.location))
|
82
84
|
end
|
@@ -100,7 +102,7 @@ module RBS
|
|
100
102
|
def singleton_ancestors(type_name, building_ancestors: [])
|
101
103
|
as = singleton_ancestor_cache[type_name] and return as
|
102
104
|
|
103
|
-
entry = env.class_decls[type_name]
|
105
|
+
entry = env.class_decls[type_name] or raise "Unknown name for singleton_ancestors: #{type_name}"
|
104
106
|
self_ancestor = Definition::Ancestor::Singleton.new(name: type_name)
|
105
107
|
|
106
108
|
RecursiveAncestorError.check!(self_ancestor,
|
@@ -123,6 +125,8 @@ module RBS
|
|
123
125
|
super_name = BuiltinNames::Object.name
|
124
126
|
end
|
125
127
|
|
128
|
+
NoSuperclassFoundError.check!(super_name, env: env, location: primary.decl.location)
|
129
|
+
|
126
130
|
super_ancestors = singleton_ancestors(super_name, building_ancestors: building_ancestors)
|
127
131
|
ancestors.unshift(*super_ancestors.ancestors)
|
128
132
|
else
|
@@ -143,6 +147,8 @@ module RBS
|
|
143
147
|
case member
|
144
148
|
when AST::Members::Extend
|
145
149
|
if member.name.class?
|
150
|
+
NoMixinFoundError.check!(member.name, env: env, member: member)
|
151
|
+
|
146
152
|
module_ancestors = instance_ancestors(member.name, building_ancestors: building_ancestors)
|
147
153
|
ancestors.unshift(*module_ancestors.apply(member.args, location: member.location))
|
148
154
|
end
|
@@ -174,6 +180,8 @@ module RBS
|
|
174
180
|
case member
|
175
181
|
when AST::Members::Include
|
176
182
|
if member.name.class?
|
183
|
+
NoMixinFoundError.check!(member.name, env: env, member: member)
|
184
|
+
|
177
185
|
module_name = member.name
|
178
186
|
module_args = member.args.map {|type| type.sub(align_params) }
|
179
187
|
|
@@ -197,6 +205,8 @@ module RBS
|
|
197
205
|
decl.each_mixin do |member|
|
198
206
|
case member
|
199
207
|
when AST::Members::Prepend
|
208
|
+
NoMixinFoundError.check!(member.name, env: env, member: member)
|
209
|
+
|
200
210
|
module_name = member.name
|
201
211
|
module_args = member.args.map {|type| type.sub(align_params) }
|
202
212
|
|
@@ -222,7 +232,7 @@ module RBS
|
|
222
232
|
|
223
233
|
def build_instance(type_name)
|
224
234
|
try_cache type_name, cache: instance_cache do
|
225
|
-
entry = env.class_decls[type_name]
|
235
|
+
entry = env.class_decls[type_name] or raise "Unknown name for build_instance: #{type_name}"
|
226
236
|
|
227
237
|
case entry
|
228
238
|
when Environment::ClassEntry, Environment::ModuleEntry
|
@@ -243,11 +253,18 @@ module RBS
|
|
243
253
|
end
|
244
254
|
|
245
255
|
if entry.is_a?(Environment::ModuleEntry)
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
256
|
+
entry.self_types.each do |module_self|
|
257
|
+
ancestor = Definition::Ancestor::Instance.new(name: module_self.name, args: module_self.args)
|
258
|
+
definition_pairs.push(
|
259
|
+
[
|
260
|
+
ancestor,
|
261
|
+
if module_self.name.interface?
|
262
|
+
build_interface(module_self.name)
|
263
|
+
else
|
264
|
+
build_instance(module_self.name)
|
265
|
+
end
|
266
|
+
]
|
267
|
+
)
|
251
268
|
end
|
252
269
|
end
|
253
270
|
|
@@ -259,32 +276,9 @@ module RBS
|
|
259
276
|
end
|
260
277
|
end
|
261
278
|
|
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
279
|
def build_singleton(type_name)
|
286
280
|
try_cache type_name, cache: singleton_cache do
|
287
|
-
entry = env.class_decls[type_name]
|
281
|
+
entry = env.class_decls[type_name] or raise "Unknown name for build_singleton: #{type_name}"
|
288
282
|
|
289
283
|
case entry
|
290
284
|
when Environment::ClassEntry, Environment::ModuleEntry
|
@@ -350,6 +344,8 @@ module RBS
|
|
350
344
|
when AST::Members::Include, AST::Members::Extend
|
351
345
|
if member.name.interface?
|
352
346
|
if (kind == :instance && member.is_a?(AST::Members::Include)) || (kind == :singleton && member.is_a?(AST::Members::Extend))
|
347
|
+
NoMixinFoundError.check!(member.name, env: env, member: member)
|
348
|
+
|
353
349
|
interface_name = member.name
|
354
350
|
interface_args = member.args
|
355
351
|
|
@@ -867,7 +863,7 @@ module RBS
|
|
867
863
|
|
868
864
|
def build_interface(type_name)
|
869
865
|
try_cache(type_name, cache: interface_cache) do
|
870
|
-
entry = env.interface_decls[type_name]
|
866
|
+
entry = env.interface_decls[type_name] or raise "Unknown name for build_interface: #{type_name}"
|
871
867
|
declaration = entry.decl
|
872
868
|
|
873
869
|
self_type = Types::Interface.new(
|
@@ -893,6 +889,8 @@ module RBS
|
|
893
889
|
end
|
894
890
|
|
895
891
|
include_members.each do |member|
|
892
|
+
NoMixinFoundError.check!(member.name, env: env, member: member)
|
893
|
+
|
896
894
|
mixin = build_interface(member.name)
|
897
895
|
|
898
896
|
args = member.args
|
@@ -957,7 +955,8 @@ module RBS
|
|
957
955
|
end
|
958
956
|
|
959
957
|
def expand_alias(type_name)
|
960
|
-
env.alias_decls[type_name]
|
958
|
+
entry = env.alias_decls[type_name] or raise "Unknown name for expand_alias: #{type_name}"
|
959
|
+
entry.decl.type
|
961
960
|
end
|
962
961
|
end
|
963
962
|
end
|
data/lib/rbs/environment.rb
CHANGED
@@ -34,56 +34,49 @@ module RBS
|
|
34
34
|
|
35
35
|
def insert(decl:, outer:)
|
36
36
|
decls << D.new(decl: decl, outer: outer)
|
37
|
+
@primary = nil
|
37
38
|
end
|
38
39
|
|
39
|
-
def
|
40
|
-
|
41
|
-
|
42
|
-
|
40
|
+
def validate_type_params
|
41
|
+
unless decls.empty?
|
42
|
+
hd_decl, *tl_decls = decls
|
43
|
+
hd_params = hd_decl.decl.type_params
|
44
|
+
hd_names = hd_params.params.map(&:name)
|
43
45
|
|
44
|
-
|
45
|
-
|
46
|
-
unless decl.is_a?(AST::Declarations::Module)
|
47
|
-
raise MixedClassModuleDeclarationError.new(name: name, decl: decl)
|
48
|
-
end
|
46
|
+
tl_decls.each do |tl_decl|
|
47
|
+
tl_params = tl_decl.decl.type_params
|
49
48
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
raise GenericParameterMismatchError.new(name: name, decl: decl)
|
49
|
+
unless hd_params.size == tl_params.size && hd_params == tl_params.rename_to(hd_names)
|
50
|
+
raise GenericParameterMismatchError.new(name: name, decl: tl_decl.decl)
|
51
|
+
end
|
54
52
|
end
|
55
53
|
end
|
54
|
+
end
|
56
55
|
|
57
|
-
|
56
|
+
def type_params
|
57
|
+
primary.decl.type_params
|
58
58
|
end
|
59
|
+
end
|
59
60
|
|
60
|
-
|
61
|
-
|
61
|
+
class ModuleEntry < MultiEntry
|
62
|
+
def self_types
|
63
|
+
decls.flat_map do |d|
|
64
|
+
d.decl.self_types
|
65
|
+
end.uniq
|
62
66
|
end
|
63
67
|
|
64
|
-
def
|
65
|
-
primary
|
68
|
+
def primary
|
69
|
+
@primary ||= begin
|
70
|
+
validate_type_params
|
71
|
+
decls.first
|
72
|
+
end
|
66
73
|
end
|
67
74
|
end
|
68
75
|
|
69
76
|
class ClassEntry < MultiEntry
|
70
|
-
def insert(decl:, outer:)
|
71
|
-
unless decl.is_a?(AST::Declarations::Class)
|
72
|
-
raise MixedClassModuleDeclarationError.new(name: name, decl: decl)
|
73
|
-
end
|
74
|
-
|
75
|
-
unless decls.empty?
|
76
|
-
names = decls[0].decl.type_params.each.map(&:name)
|
77
|
-
unless names.size == decl.type_params.each.size && decls[0].decl.type_params == decl.type_params.rename_to(names)
|
78
|
-
raise GenericParameterMismatchError.new(name: name, decl: decl)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
super(decl: decl, outer: outer)
|
83
|
-
end
|
84
|
-
|
85
77
|
def primary
|
86
78
|
@primary ||= begin
|
79
|
+
validate_type_params
|
87
80
|
decls.find {|d| d.decl.super_class } || decls.first
|
88
81
|
end
|
89
82
|
end
|
@@ -157,7 +150,18 @@ module RBS
|
|
157
150
|
end
|
158
151
|
end
|
159
152
|
|
160
|
-
class_decls[name]
|
153
|
+
existing_entry = class_decls[name]
|
154
|
+
|
155
|
+
case
|
156
|
+
when decl.is_a?(AST::Declarations::Module) && existing_entry.is_a?(ModuleEntry)
|
157
|
+
# OK
|
158
|
+
when decl.is_a?(AST::Declarations::Class) && existing_entry.is_a?(ClassEntry)
|
159
|
+
# OK
|
160
|
+
else
|
161
|
+
raise DuplicatedDeclarationError.new(name, decl, existing_entry.primary.decl)
|
162
|
+
end
|
163
|
+
|
164
|
+
existing_entry.insert(decl: decl, outer: outer)
|
161
165
|
|
162
166
|
prefix = outer + [decl]
|
163
167
|
ns = name.to_namespace
|
@@ -255,8 +259,12 @@ module RBS
|
|
255
259
|
AST::Declarations::Module.new(
|
256
260
|
name: decl.name.with_prefix(prefix),
|
257
261
|
type_params: decl.type_params,
|
258
|
-
|
259
|
-
|
262
|
+
self_types: decl.self_types.map do |module_self|
|
263
|
+
AST::Declarations::Module::Self.new(
|
264
|
+
name: absolute_type_name(resolver, module_self.name, context: context),
|
265
|
+
args: module_self.args.map {|type| absolute_type(resolver, type, context: context) },
|
266
|
+
location: module_self.location
|
267
|
+
)
|
260
268
|
end,
|
261
269
|
members: decl.members.map do |member|
|
262
270
|
case member
|
@@ -406,5 +414,10 @@ module RBS
|
|
406
414
|
absolute_type_name(resolver, name, context: context)
|
407
415
|
end
|
408
416
|
end
|
417
|
+
|
418
|
+
def inspect
|
419
|
+
ivars = %i[@buffers @declarations @class_decls @interface_decls @alias_decls @constant_decls @global_decls]
|
420
|
+
"\#<RBS::Environment #{ivars.map { |iv| "#{iv}=(#{instance_variable_get(iv).size} items)"}.join(' ')}>"
|
421
|
+
end
|
409
422
|
end
|
410
423
|
end
|