rbs 0.18.1 → 1.0.0.pre2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +31 -0
- data/Rakefile +12 -0
- data/Steepfile +2 -1
- data/bin/annotate-with-rdoc +0 -4
- data/core/builtin.rbs +4 -0
- data/core/file.rbs +3 -4
- data/core/hash.rbs +1 -3
- data/core/io.rbs +165 -7
- data/core/kernel.rbs +1 -1
- data/core/module.rbs +41 -0
- data/core/time.rbs +0 -12
- data/docs/syntax.md +0 -17
- data/goodcheck.yml +22 -2
- data/lib/rbs.rb +2 -0
- data/lib/rbs/ast/declarations.rb +7 -49
- data/lib/rbs/ast/members.rb +10 -4
- data/lib/rbs/cli.rb +10 -10
- data/lib/rbs/definition.rb +70 -3
- data/lib/rbs/definition_builder.rb +573 -984
- data/lib/rbs/definition_builder/ancestor_builder.rb +525 -0
- data/lib/rbs/definition_builder/method_builder.rb +217 -0
- data/lib/rbs/environment.rb +6 -8
- data/lib/rbs/environment_loader.rb +8 -4
- data/lib/rbs/errors.rb +88 -121
- data/lib/rbs/method_type.rb +1 -31
- data/lib/rbs/parser.rb +1082 -1014
- data/lib/rbs/parser.y +108 -76
- data/lib/rbs/prototype/rb.rb +18 -3
- data/lib/rbs/prototype/rbi.rb +6 -6
- data/lib/rbs/prototype/runtime.rb +71 -35
- data/lib/rbs/substitution.rb +4 -0
- data/lib/rbs/test.rb +3 -1
- data/lib/rbs/test/hook.rb +26 -8
- data/lib/rbs/types.rb +68 -7
- data/lib/rbs/validator.rb +4 -2
- data/lib/rbs/variance_calculator.rb +5 -1
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs/writer.rb +13 -4
- data/schema/members.json +5 -1
- data/sig/ancestor_builder.rbs +98 -0
- data/sig/declarations.rbs +4 -16
- data/sig/definition.rbs +6 -1
- data/sig/definition_builder.rbs +15 -67
- data/sig/errors.rbs +159 -0
- data/sig/members.rbs +4 -1
- data/sig/method_builder.rbs +71 -0
- data/sig/method_types.rbs +3 -16
- data/sig/substitution.rbs +3 -0
- data/sig/type_name_resolver.rbs +4 -2
- data/sig/types.rbs +17 -15
- data/sig/validator.rbs +12 -0
- data/stdlib/csv/0/csv.rbs +3 -0
- data/stdlib/dbm/0/dbm.rbs +0 -2
- data/stdlib/logger/0/log_device.rbs +1 -2
- data/stdlib/monitor/0/monitor.rbs +119 -0
- data/stdlib/pathname/0/pathname.rbs +1 -1
- data/stdlib/prime/0/prime.rbs +6 -0
- data/stdlib/securerandom/0/securerandom.rbs +2 -0
- data/stdlib/time/0/time.rbs +327 -0
- data/stdlib/tsort/0/tsort.rbs +8 -0
- data/stdlib/uri/0/common.rbs +401 -0
- data/stdlib/uri/0/rfc2396_parser.rbs +9 -0
- data/stdlib/uri/0/rfc3986_parser.rbs +2 -0
- data/steep/Gemfile.lock +13 -14
- metadata +16 -5
@@ -0,0 +1,217 @@
|
|
1
|
+
module RBS
|
2
|
+
class DefinitionBuilder
|
3
|
+
class MethodBuilder
|
4
|
+
class Methods
|
5
|
+
Definition = Struct.new(:name, :type, :originals, :overloads, :accessibilities, keyword_init: true) do
|
6
|
+
def original
|
7
|
+
originals[0]
|
8
|
+
end
|
9
|
+
|
10
|
+
def accessibility
|
11
|
+
accessibilities[0]
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.empty(name:, type:)
|
15
|
+
new(type: type, name: name, originals: [], overloads: [], accessibilities: [])
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_reader :type
|
20
|
+
attr_reader :methods
|
21
|
+
|
22
|
+
def initialize(type:)
|
23
|
+
@type = type
|
24
|
+
@methods = {}
|
25
|
+
end
|
26
|
+
|
27
|
+
def validate!
|
28
|
+
methods.each_value do |defn|
|
29
|
+
if defn.originals.size > 1
|
30
|
+
raise DuplicatedMethodDefinitionError.new(
|
31
|
+
type: type,
|
32
|
+
method_name: defn.name,
|
33
|
+
members: defn.originals
|
34
|
+
)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
self
|
39
|
+
end
|
40
|
+
|
41
|
+
def each
|
42
|
+
if block_given?
|
43
|
+
Sorter.new(methods).each_strongly_connected_component do |scc|
|
44
|
+
if scc.size > 1
|
45
|
+
raise RecursiveAliasDefinitionError.new(type: type, defs: scc)
|
46
|
+
end
|
47
|
+
|
48
|
+
yield scc[0]
|
49
|
+
end
|
50
|
+
else
|
51
|
+
enum_for :each
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
class Sorter
|
56
|
+
include TSort
|
57
|
+
|
58
|
+
attr_reader :methods
|
59
|
+
|
60
|
+
def initialize(methods)
|
61
|
+
@methods = methods
|
62
|
+
end
|
63
|
+
|
64
|
+
def tsort_each_node(&block)
|
65
|
+
methods.each_value(&block)
|
66
|
+
end
|
67
|
+
|
68
|
+
def tsort_each_child(defn)
|
69
|
+
if (member = defn.original).is_a?(AST::Members::Alias)
|
70
|
+
if old = methods[member.old_name]
|
71
|
+
yield old
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
attr_reader :env
|
79
|
+
attr_reader :instance_methods
|
80
|
+
attr_reader :singleton_methods
|
81
|
+
attr_reader :interface_methods
|
82
|
+
|
83
|
+
def initialize(env:)
|
84
|
+
@env = env
|
85
|
+
|
86
|
+
@instance_methods = {}
|
87
|
+
@singleton_methods = {}
|
88
|
+
@interface_methods = {}
|
89
|
+
end
|
90
|
+
|
91
|
+
def build_instance(type_name)
|
92
|
+
instance_methods[type_name] ||=
|
93
|
+
begin
|
94
|
+
entry = env.class_decls[type_name]
|
95
|
+
args = Types::Variable.build(entry.type_params.each.map(&:name))
|
96
|
+
type = Types::ClassInstance.new(name: type_name, args: args, location: nil)
|
97
|
+
Methods.new(type: type).tap do |methods|
|
98
|
+
entry.decls.each do |d|
|
99
|
+
each_member_with_accessibility(d.decl.members) do |member, accessibility|
|
100
|
+
case member
|
101
|
+
when AST::Members::MethodDefinition
|
102
|
+
if member.instance?
|
103
|
+
build_method(methods, type, member: member, accessibility: accessibility)
|
104
|
+
end
|
105
|
+
when AST::Members::AttrReader, AST::Members::AttrWriter, AST::Members::AttrAccessor
|
106
|
+
if member.kind == :instance
|
107
|
+
build_attribute(methods, type, member: member, accessibility: accessibility)
|
108
|
+
end
|
109
|
+
when AST::Members::Alias
|
110
|
+
if member.kind == :instance
|
111
|
+
build_alias(methods, type, member: member, accessibility: accessibility)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end.validate!
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def build_singleton(type_name)
|
121
|
+
singleton_methods[type_name] ||=
|
122
|
+
begin
|
123
|
+
entry = env.class_decls[type_name]
|
124
|
+
type = Types::ClassSingleton.new(name: type_name, location: nil)
|
125
|
+
|
126
|
+
Methods.new(type: type).tap do |methods|
|
127
|
+
entry.decls.each do |d|
|
128
|
+
each_member_with_accessibility(d.decl.members) do |member, accessibility|
|
129
|
+
case member
|
130
|
+
when AST::Members::MethodDefinition
|
131
|
+
if member.singleton?
|
132
|
+
build_method(methods, type, member: member, accessibility: accessibility)
|
133
|
+
end
|
134
|
+
when AST::Members::AttrReader, AST::Members::AttrWriter, AST::Members::AttrAccessor
|
135
|
+
if member.kind == :singleton
|
136
|
+
build_attribute(methods, type, member: member, accessibility: accessibility)
|
137
|
+
end
|
138
|
+
when AST::Members::Alias
|
139
|
+
if member.kind == :singleton
|
140
|
+
build_alias(methods, type, member: member, accessibility: accessibility)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end.validate!
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def build_interface(type_name)
|
150
|
+
interface_methods[type_name] ||=
|
151
|
+
begin
|
152
|
+
entry = env.interface_decls[type_name]
|
153
|
+
args = Types::Variable.build(entry.decl.type_params.each.map(&:name))
|
154
|
+
type = Types::Interface.new(name: type_name, args: args, location: nil)
|
155
|
+
|
156
|
+
Methods.new(type: type).tap do |methods|
|
157
|
+
entry.decl.members.each do |member|
|
158
|
+
case member
|
159
|
+
when AST::Members::MethodDefinition
|
160
|
+
build_method(methods, type, member: member, accessibility: :public)
|
161
|
+
when AST::Members::Alias
|
162
|
+
build_alias(methods, type, member: member, accessibility: :public)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end.validate!
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
def build_alias(methods, type, member:, accessibility:)
|
170
|
+
defn = methods.methods[member.new_name] ||= Methods::Definition.empty(type: type, name: member.new_name)
|
171
|
+
|
172
|
+
defn.originals << member
|
173
|
+
defn.accessibilities << accessibility
|
174
|
+
end
|
175
|
+
|
176
|
+
def build_attribute(methods, type, member:, accessibility:)
|
177
|
+
if member.is_a?(AST::Members::AttrReader) || member.is_a?(AST::Members::AttrAccessor)
|
178
|
+
defn = methods.methods[member.name] ||= Methods::Definition.empty(type: type, name: member.name)
|
179
|
+
|
180
|
+
defn.accessibilities << accessibility
|
181
|
+
defn.originals << member
|
182
|
+
end
|
183
|
+
|
184
|
+
if member.is_a?(AST::Members::AttrWriter) || member.is_a?(AST::Members::AttrAccessor)
|
185
|
+
defn = methods.methods[:"#{member.name}="] ||= Methods::Definition.empty(type: type, name: :"#{member.name}=")
|
186
|
+
|
187
|
+
defn.accessibilities << accessibility
|
188
|
+
defn.originals << member
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
def build_method(methods, type, member:, accessibility:)
|
193
|
+
defn = methods.methods[member.name] ||= Methods::Definition.empty(type: type, name: member.name)
|
194
|
+
|
195
|
+
if member.overload?
|
196
|
+
defn.overloads << member
|
197
|
+
else
|
198
|
+
defn.accessibilities << accessibility
|
199
|
+
defn.originals << member
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def each_member_with_accessibility(members, accessibility: :public)
|
204
|
+
members.each do |member|
|
205
|
+
case member
|
206
|
+
when AST::Members::Public
|
207
|
+
accessibility = :public
|
208
|
+
when AST::Members::Private
|
209
|
+
accessibility = :private
|
210
|
+
else
|
211
|
+
yield member, accessibility
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
data/lib/rbs/environment.rb
CHANGED
@@ -133,7 +133,7 @@ module RBS
|
|
133
133
|
|
134
134
|
def cache_name(cache, name:, decl:, outer:)
|
135
135
|
if cache.key?(name)
|
136
|
-
raise DuplicatedDeclarationError.new(name, decl, cache[name].decl)
|
136
|
+
raise DuplicatedDeclarationError.new(_ = name, _ = decl, _ = cache[name].decl)
|
137
137
|
end
|
138
138
|
|
139
139
|
cache[name] = SingleEntry.new(name: name, decl: decl, outer: outer)
|
@@ -195,9 +195,6 @@ module RBS
|
|
195
195
|
|
196
196
|
when AST::Declarations::Global
|
197
197
|
cache_name global_decls, name: decl.name, decl: decl, outer: outer
|
198
|
-
|
199
|
-
when AST::Declarations::Extension
|
200
|
-
RBS.logger.warn "#{Location.to_string decl.location} Extension construct is deprecated: use class/module syntax instead"
|
201
198
|
end
|
202
199
|
end
|
203
200
|
|
@@ -244,7 +241,8 @@ module RBS
|
|
244
241
|
super_class: decl.super_class&.yield_self do |super_class|
|
245
242
|
AST::Declarations::Class::Super.new(
|
246
243
|
name: absolute_type_name(resolver, super_class.name, context: context),
|
247
|
-
args: super_class.args.map {|type| absolute_type(resolver, type, context: context) }
|
244
|
+
args: super_class.args.map {|type| absolute_type(resolver, type, context: context) },
|
245
|
+
location: super_class.location
|
248
246
|
)
|
249
247
|
end,
|
250
248
|
members: decl.members.map do |member|
|
@@ -325,9 +323,6 @@ module RBS
|
|
325
323
|
location: decl.location,
|
326
324
|
comment: decl.comment
|
327
325
|
)
|
328
|
-
|
329
|
-
else
|
330
|
-
raise
|
331
326
|
end
|
332
327
|
end
|
333
328
|
|
@@ -349,6 +344,7 @@ module RBS
|
|
349
344
|
AST::Members::AttrAccessor.new(
|
350
345
|
name: member.name,
|
351
346
|
type: absolute_type(resolver, member.type, context: context),
|
347
|
+
kind: member.kind,
|
352
348
|
annotations: member.annotations,
|
353
349
|
comment: member.comment,
|
354
350
|
location: member.location,
|
@@ -358,6 +354,7 @@ module RBS
|
|
358
354
|
AST::Members::AttrReader.new(
|
359
355
|
name: member.name,
|
360
356
|
type: absolute_type(resolver, member.type, context: context),
|
357
|
+
kind: member.kind,
|
361
358
|
annotations: member.annotations,
|
362
359
|
comment: member.comment,
|
363
360
|
location: member.location,
|
@@ -367,6 +364,7 @@ module RBS
|
|
367
364
|
AST::Members::AttrWriter.new(
|
368
365
|
name: member.name,
|
369
366
|
type: absolute_type(resolver, member.type, context: context),
|
367
|
+
kind: member.kind,
|
370
368
|
annotations: member.annotations,
|
371
369
|
comment: member.comment,
|
372
370
|
location: member.location,
|
@@ -48,7 +48,11 @@ module RBS
|
|
48
48
|
end
|
49
49
|
|
50
50
|
def has_library?(library:, version:)
|
51
|
-
self.class.gem_sig_path(library, version) || repository.lookup(library, version)
|
51
|
+
if self.class.gem_sig_path(library, version) || repository.lookup(library, version)
|
52
|
+
true
|
53
|
+
else
|
54
|
+
false
|
55
|
+
end
|
52
56
|
end
|
53
57
|
|
54
58
|
def load(env:)
|
@@ -70,7 +74,7 @@ module RBS
|
|
70
74
|
|
71
75
|
libs.each do |lib|
|
72
76
|
unless has_library?(version: lib.version, library: lib.name)
|
73
|
-
raise UnknownLibraryError.new(lib: lib)
|
77
|
+
raise UnknownLibraryError.new(lib: lib)
|
74
78
|
end
|
75
79
|
|
76
80
|
case
|
@@ -97,12 +101,12 @@ module RBS
|
|
97
101
|
if path.basename.to_s.start_with?("_")
|
98
102
|
if skip_hidden
|
99
103
|
unless immediate
|
100
|
-
return
|
104
|
+
return
|
101
105
|
end
|
102
106
|
end
|
103
107
|
end
|
104
108
|
|
105
|
-
path.
|
109
|
+
path.children.sort.each do |child|
|
106
110
|
each_file(child, immediate: false, skip_hidden: skip_hidden, &block)
|
107
111
|
end
|
108
112
|
end
|
data/lib/rbs/errors.rb
CHANGED
@@ -35,51 +35,25 @@ module RBS
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
class InvalidExtensionParameterError < StandardError
|
39
|
-
attr_reader :type_name
|
40
|
-
attr_reader :extension_name
|
41
|
-
attr_reader :location
|
42
|
-
attr_reader :extension_params
|
43
|
-
attr_reader :class_params
|
44
|
-
|
45
|
-
def initialize(type_name:, extension_name:, extension_params:, class_params:, location:)
|
46
|
-
@type_name = type_name
|
47
|
-
@extension_name = extension_name
|
48
|
-
@extension_params = extension_params
|
49
|
-
@class_params = class_params
|
50
|
-
@location = location
|
51
|
-
|
52
|
-
super "#{Location.to_string location}: Expected #{class_params.size} parameters to #{type_name} (#{extension_name}) but has #{extension_params.size} parameters"
|
53
|
-
end
|
54
|
-
|
55
|
-
def self.check!(type_name:, extension_name:, extension_params:, class_params:, location:)
|
56
|
-
unless extension_params.size == class_params.size
|
57
|
-
raise new(type_name: type_name,
|
58
|
-
extension_name: extension_name,
|
59
|
-
extension_params: extension_params,
|
60
|
-
class_params: class_params,
|
61
|
-
location: location)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
38
|
class RecursiveAncestorError < StandardError
|
67
39
|
attr_reader :ancestors
|
68
40
|
attr_reader :location
|
69
41
|
|
70
42
|
def initialize(ancestors:, location:)
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
43
|
+
names = ancestors.map do |ancestor|
|
44
|
+
case ancestor
|
45
|
+
when Definition::Ancestor::Singleton
|
46
|
+
"singleton(#{ancestor.name})"
|
47
|
+
when Definition::Ancestor::Instance
|
48
|
+
if ancestor.args.empty?
|
49
|
+
ancestor.name.to_s
|
50
|
+
else
|
51
|
+
"#{ancestor.name}[#{ancestor.args.join(", ")}]"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
super "#{Location.to_string location}: Detected recursive ancestors: #{names.join(" < ")}"
|
83
57
|
end
|
84
58
|
|
85
59
|
def self.check!(self_ancestor, ancestors:, location:)
|
@@ -160,6 +134,8 @@ module RBS
|
|
160
134
|
env.class_decls
|
161
135
|
when type_name.interface?
|
162
136
|
env.interface_decls
|
137
|
+
else
|
138
|
+
raise
|
163
139
|
end
|
164
140
|
|
165
141
|
dic.key?(type_name) or raise new(type_name: type_name, location: self_type.location)
|
@@ -187,6 +163,8 @@ module RBS
|
|
187
163
|
env.class_decls
|
188
164
|
when type_name.interface?
|
189
165
|
env.interface_decls
|
166
|
+
else
|
167
|
+
raise
|
190
168
|
end
|
191
169
|
|
192
170
|
dic.key?(type_name) or raise new(type_name: type_name, member: member)
|
@@ -194,44 +172,60 @@ module RBS
|
|
194
172
|
end
|
195
173
|
|
196
174
|
class DuplicatedMethodDefinitionError < StandardError
|
197
|
-
attr_reader :
|
198
|
-
attr_reader :
|
175
|
+
attr_reader :type
|
176
|
+
attr_reader :method_name
|
177
|
+
attr_reader :members
|
199
178
|
|
200
|
-
def initialize(
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
when AST::Declarations::Extension
|
205
|
-
"#{decl.name} (#{decl.extension_name})"
|
206
|
-
end
|
179
|
+
def initialize(type:, method_name:, members:)
|
180
|
+
@type = type
|
181
|
+
@method_name = method_name
|
182
|
+
@members = members
|
207
183
|
|
208
|
-
|
184
|
+
message = "#{Location.to_string location}: #{qualified_method_name} has duplicated definitions"
|
185
|
+
if members.size > 1
|
186
|
+
message << " in #{other_locations.map { |loc| Location.to_string loc }.join(', ')}"
|
187
|
+
end
|
188
|
+
super message
|
209
189
|
end
|
210
190
|
|
211
|
-
def
|
212
|
-
|
213
|
-
|
191
|
+
def qualified_method_name
|
192
|
+
case type
|
193
|
+
when Types::ClassSingleton
|
194
|
+
"#{type.name}.#{method_name}"
|
195
|
+
else
|
196
|
+
"#{type.name}##{method_name}"
|
214
197
|
end
|
215
198
|
end
|
216
|
-
end
|
217
199
|
|
218
|
-
|
219
|
-
|
200
|
+
def location
|
201
|
+
members[0].location
|
202
|
+
end
|
220
203
|
|
221
|
-
|
204
|
+
def other_locations
|
205
|
+
members.drop(1).map(&:location)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
class DuplicatedInterfaceMethodDefinitionError < StandardError
|
210
|
+
attr_reader :type
|
222
211
|
attr_reader :method_name
|
223
|
-
attr_reader :
|
224
|
-
attr_reader :mixin_member
|
225
|
-
attr_reader :entries
|
212
|
+
attr_reader :member
|
226
213
|
|
227
|
-
def initialize(
|
228
|
-
@
|
214
|
+
def initialize(type:, method_name:, member:)
|
215
|
+
@type = type
|
229
216
|
@method_name = method_name
|
230
|
-
@
|
231
|
-
@mixin_member = mixin_member
|
232
|
-
@entries = entries
|
217
|
+
@member = member
|
233
218
|
|
234
|
-
super "#{
|
219
|
+
super "#{member.location}: Duplicated method definition: #{qualified_method_name}"
|
220
|
+
end
|
221
|
+
|
222
|
+
def qualified_method_name
|
223
|
+
case type
|
224
|
+
when Types::ClassSingleton
|
225
|
+
"#{type.name}.#{method_name}"
|
226
|
+
else
|
227
|
+
"#{type.name}##{method_name}"
|
228
|
+
end
|
235
229
|
end
|
236
230
|
end
|
237
231
|
|
@@ -247,48 +241,19 @@ module RBS
|
|
247
241
|
|
248
242
|
super "#{Location.to_string location}: Unknown method alias name: #{original_name} => #{aliased_name}"
|
249
243
|
end
|
250
|
-
|
251
|
-
def self.check!(methods:, original_name:, aliased_name:, location:)
|
252
|
-
unless methods.key?(original_name)
|
253
|
-
raise new(original_name: original_name, aliased_name: aliased_name, location: location)
|
254
|
-
end
|
255
|
-
end
|
256
244
|
end
|
257
245
|
|
258
246
|
class SuperclassMismatchError < StandardError
|
259
247
|
attr_reader :name
|
260
248
|
attr_reader :entry
|
261
249
|
|
262
|
-
def initialize(name:,
|
250
|
+
def initialize(name:, entry:)
|
263
251
|
@name = name
|
264
252
|
@entry = entry
|
265
253
|
super "#{Location.to_string entry.primary.decl.location}: Superclass mismatch: #{name}"
|
266
254
|
end
|
267
255
|
end
|
268
256
|
|
269
|
-
class InconsistentMethodVisibilityError < StandardError
|
270
|
-
attr_reader :type_name
|
271
|
-
attr_reader :method_name
|
272
|
-
attr_reader :kind
|
273
|
-
attr_reader :member_pairs
|
274
|
-
|
275
|
-
def initialize(type_name:, method_name:, kind:, member_pairs:)
|
276
|
-
@type_name = type_name
|
277
|
-
@method_name = method_name
|
278
|
-
@kind = kind
|
279
|
-
@member_pairs = member_pairs
|
280
|
-
|
281
|
-
delimiter = case kind
|
282
|
-
when :instance
|
283
|
-
"#"
|
284
|
-
when :singleton
|
285
|
-
"."
|
286
|
-
end
|
287
|
-
|
288
|
-
super "#{Location.to_string member_pairs[0][0].location}: Inconsistent method visibility: #{type_name}#{delimiter}#{method_name}"
|
289
|
-
end
|
290
|
-
end
|
291
|
-
|
292
257
|
class InvalidOverloadMethodError < StandardError
|
293
258
|
attr_reader :type_name
|
294
259
|
attr_reader :method_name
|
@@ -331,38 +296,40 @@ module RBS
|
|
331
296
|
@name = name
|
332
297
|
@decls = decls
|
333
298
|
|
334
|
-
|
299
|
+
last_decl = decls.last or raise
|
300
|
+
super "#{Location.to_string last_decl.location}: Duplicated declaration: #{name}"
|
335
301
|
end
|
336
302
|
end
|
337
303
|
|
338
304
|
class InvalidVarianceAnnotationError < StandardError
|
339
|
-
|
340
|
-
|
341
|
-
|
305
|
+
attr_reader :type_name
|
306
|
+
attr_reader :param
|
307
|
+
attr_reader :location
|
342
308
|
|
343
|
-
|
344
|
-
|
309
|
+
def initialize(type_name:, param:, location:)
|
310
|
+
@type_name = type_name
|
311
|
+
@param = param
|
312
|
+
@location = location
|
345
313
|
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
errors.each do |error|
|
355
|
-
case error
|
356
|
-
when MethodTypeError
|
357
|
-
message << " MethodTypeError (#{error.param.name}): on `#{error.method_name}` #{error.method_type.to_s} (#{error.method_type.location&.start_line})"
|
358
|
-
when InheritanceError
|
359
|
-
message << " InheritanceError: #{error.super_class}"
|
360
|
-
when MixinError
|
361
|
-
message << " MixinError: #{error.include_member.name} (#{error.include_member.location&.start_line})"
|
362
|
-
end
|
363
|
-
end
|
314
|
+
super "#{Location.to_string location}: Type parameter variance error: #{param.name} is #{param.variance} but used as incompatible variance"
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
class RecursiveAliasDefinitionError < StandardError
|
319
|
+
attr_reader :type
|
320
|
+
attr_reader :defs
|
364
321
|
|
365
|
-
|
322
|
+
def initialize(type:, defs:)
|
323
|
+
@type = type
|
324
|
+
@defs = defs
|
325
|
+
|
326
|
+
super "#{Location.to_string location}: Recursive aliases in #{type}: #{defs.map(&:name).join(", ")}"
|
327
|
+
end
|
328
|
+
|
329
|
+
def location
|
330
|
+
first_def = defs.first or raise
|
331
|
+
original = first_def.original or raise
|
332
|
+
original.location
|
366
333
|
end
|
367
334
|
end
|
368
335
|
end
|