rbs 3.5.3 → 3.6.0.dev.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/dependabot.yml +5 -1
- data/.github/workflows/ruby.yml +2 -18
- data/.github/workflows/windows.yml +26 -0
- data/CHANGELOG.md +0 -18
- data/core/array.rbs +10 -10
- data/core/basic_object.rbs +3 -3
- data/core/enumerable.rbs +6 -0
- data/core/enumerator.rbs +7 -0
- data/core/fiber.rbs +1 -1
- data/core/global_variables.rbs +2 -2
- data/core/kernel.rbs +67 -38
- data/core/method.rbs +98 -7
- data/core/module.rbs +2 -2
- data/core/proc.rbs +184 -23
- data/core/ractor.rbs +1 -1
- data/core/range.rbs +30 -0
- data/core/refinement.rbs +16 -26
- data/core/symbol.rbs +34 -26
- data/core/thread.rbs +2 -2
- data/core/trace_point.rbs +12 -12
- data/core/unbound_method.rbs +1 -1
- data/docs/syntax.md +21 -9
- data/ext/rbs_extension/parser.c +119 -51
- data/ext/rbs_extension/ruby_objs.c +2 -1
- data/ext/rbs_extension/ruby_objs.h +1 -1
- data/lib/rbs/ast/declarations.rb +36 -0
- data/lib/rbs/ast/type_param.rb +71 -15
- data/lib/rbs/ast/visitor.rb +137 -0
- data/lib/rbs/cli/validate.rb +41 -7
- data/lib/rbs/cli.rb +3 -3
- data/lib/rbs/definition.rb +2 -1
- data/lib/rbs/definition_builder/ancestor_builder.rb +30 -4
- data/lib/rbs/definition_builder.rb +21 -6
- data/lib/rbs/environment_loader.rb +1 -1
- data/lib/rbs/errors.rb +7 -2
- data/lib/rbs/file_finder.rb +9 -12
- data/lib/rbs/locator.rb +8 -5
- data/lib/rbs/prototype/rbi.rb +2 -1
- data/lib/rbs/prototype/runtime.rb +3 -2
- data/lib/rbs/sorter.rb +9 -6
- data/lib/rbs/test/type_check.rb +6 -0
- data/lib/rbs/types.rb +11 -0
- data/lib/rbs/validator.rb +2 -2
- data/lib/rbs/vendorer.rb +3 -3
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs.rb +1 -0
- data/sig/declarations.rbs +6 -0
- data/sig/definition.rbs +1 -1
- data/sig/definition_builder.rbs +3 -1
- data/sig/errors.rbs +3 -2
- data/sig/file_finder.rbs +24 -2
- data/sig/method_types.rbs +1 -1
- data/sig/sorter.rbs +1 -1
- data/sig/type_param.rbs +41 -9
- data/sig/types.rbs +12 -0
- data/sig/visitor.rbs +47 -0
- data/stdlib/csv/0/csv.rbs +27 -0
- data/stdlib/net-http/0/net-http.rbs +1 -1
- data/stdlib/zlib/0/gzip_reader.rbs +5 -1
- metadata +5 -2
data/lib/rbs/ast/type_param.rb
CHANGED
@@ -3,14 +3,22 @@
|
|
3
3
|
module RBS
|
4
4
|
module AST
|
5
5
|
class TypeParam
|
6
|
-
attr_reader :name, :variance, :location, :
|
6
|
+
attr_reader :name, :variance, :location, :upper_bound_type, :default_type
|
7
7
|
|
8
|
-
def initialize(name:, variance:, upper_bound:, location:)
|
8
|
+
def initialize(name:, variance:, upper_bound:, location:, default_type: nil)
|
9
9
|
@name = name
|
10
10
|
@variance = variance
|
11
|
-
@
|
11
|
+
@upper_bound_type = upper_bound
|
12
12
|
@location = location
|
13
13
|
@unchecked = false
|
14
|
+
@default_type = default_type
|
15
|
+
end
|
16
|
+
|
17
|
+
def upper_bound
|
18
|
+
case upper_bound_type
|
19
|
+
when Types::ClassInstance, Types::ClassSingleton, Types::Interface
|
20
|
+
upper_bound_type
|
21
|
+
end
|
14
22
|
end
|
15
23
|
|
16
24
|
def unchecked!(value = true)
|
@@ -26,14 +34,15 @@ module RBS
|
|
26
34
|
other.is_a?(TypeParam) &&
|
27
35
|
other.name == name &&
|
28
36
|
other.variance == variance &&
|
29
|
-
other.
|
37
|
+
other.upper_bound_type == upper_bound_type &&
|
38
|
+
other.default_type == default_type &&
|
30
39
|
other.unchecked? == unchecked?
|
31
40
|
end
|
32
41
|
|
33
42
|
alias eql? ==
|
34
43
|
|
35
44
|
def hash
|
36
|
-
self.class.hash ^ name.hash ^ variance.hash ^
|
45
|
+
self.class.hash ^ name.hash ^ variance.hash ^ upper_bound_type.hash ^ unchecked?.hash ^ default_type.hash
|
37
46
|
end
|
38
47
|
|
39
48
|
def to_json(state = JSON::State.new)
|
@@ -42,7 +51,8 @@ module RBS
|
|
42
51
|
variance: variance,
|
43
52
|
unchecked: unchecked?,
|
44
53
|
location: location,
|
45
|
-
upper_bound:
|
54
|
+
upper_bound: upper_bound_type,
|
55
|
+
default_type: default_type
|
46
56
|
}.to_json(state)
|
47
57
|
end
|
48
58
|
|
@@ -50,21 +60,27 @@ module RBS
|
|
50
60
|
TypeParam.new(
|
51
61
|
name: name,
|
52
62
|
variance: variance,
|
53
|
-
upper_bound:
|
54
|
-
location: location
|
63
|
+
upper_bound: upper_bound_type,
|
64
|
+
location: location,
|
65
|
+
default_type: default_type
|
55
66
|
).unchecked!(unchecked?)
|
56
67
|
end
|
57
68
|
|
58
69
|
def map_type(&block)
|
59
|
-
if b =
|
60
|
-
|
70
|
+
if b = upper_bound_type
|
71
|
+
_upper_bound_type = yield(b)
|
72
|
+
end
|
73
|
+
|
74
|
+
if dt = default_type
|
75
|
+
_default_type = yield(dt)
|
61
76
|
end
|
62
77
|
|
63
78
|
TypeParam.new(
|
64
79
|
name: name,
|
65
80
|
variance: variance,
|
66
|
-
upper_bound:
|
67
|
-
location: location
|
81
|
+
upper_bound: _upper_bound_type,
|
82
|
+
location: location,
|
83
|
+
default_type: _default_type
|
68
84
|
).unchecked!(unchecked?)
|
69
85
|
end
|
70
86
|
|
@@ -101,8 +117,9 @@ module RBS
|
|
101
117
|
TypeParam.new(
|
102
118
|
name: new_name,
|
103
119
|
variance: param.variance,
|
104
|
-
upper_bound: param.
|
105
|
-
location: param.location
|
120
|
+
upper_bound: param.upper_bound_type&.map_type {|type| type.sub(subst) },
|
121
|
+
location: param.location,
|
122
|
+
default_type: param.default_type&.map_type {|type| type.sub(subst) }
|
106
123
|
).unchecked!(param.unchecked?)
|
107
124
|
end
|
108
125
|
end
|
@@ -125,12 +142,51 @@ module RBS
|
|
125
142
|
|
126
143
|
s << name.to_s
|
127
144
|
|
128
|
-
if type =
|
145
|
+
if type = upper_bound_type
|
129
146
|
s << " < #{type}"
|
130
147
|
end
|
131
148
|
|
149
|
+
if dt = default_type
|
150
|
+
s << " = #{dt}"
|
151
|
+
end
|
152
|
+
|
132
153
|
s
|
133
154
|
end
|
155
|
+
|
156
|
+
def self.application(params, args)
|
157
|
+
subst = Substitution.new()
|
158
|
+
|
159
|
+
if params.empty?
|
160
|
+
return nil
|
161
|
+
end
|
162
|
+
|
163
|
+
min_count = params.count { _1.default_type.nil? }
|
164
|
+
max_count = params.size
|
165
|
+
|
166
|
+
unless min_count <= args.size && args.size <= max_count
|
167
|
+
raise "Invalid type application: required type params=#{min_count}, optional type params=#{max_count - min_count}, given args=#{args.size}"
|
168
|
+
end
|
169
|
+
|
170
|
+
params.zip(args).each do |param, arg|
|
171
|
+
if arg
|
172
|
+
subst.add(from: param.name, to: arg)
|
173
|
+
else
|
174
|
+
subst.add(from: param.name, to: param.default_type || raise)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
subst
|
179
|
+
end
|
180
|
+
|
181
|
+
def self.normalize_args(params, args)
|
182
|
+
params.zip(args).filter_map do |param, arg|
|
183
|
+
if arg
|
184
|
+
arg
|
185
|
+
else
|
186
|
+
param.default_type
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
134
190
|
end
|
135
191
|
end
|
136
192
|
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RBS
|
4
|
+
module AST
|
5
|
+
# The Visitor class implements the Visitor pattern for traversing the RBS Abstract Syntax Tree (AST).
|
6
|
+
#
|
7
|
+
# It provides methods to visit each type of node in the AST, allowing for custom processing of each node type.
|
8
|
+
#
|
9
|
+
# This class is designed to be subclassed, with specific visit methods overridden to implement custom behavior for
|
10
|
+
# different node types.
|
11
|
+
#
|
12
|
+
# Example usage:
|
13
|
+
#
|
14
|
+
# ~~~rb
|
15
|
+
# class MyVisitor < RBS::AST::Visitor
|
16
|
+
# def visit_declaration_class(node)
|
17
|
+
# puts "Visiting class: #{node.name}"
|
18
|
+
#
|
19
|
+
# super # call `super` to run the default visiting behavior
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# visitor = MyVisitor.new
|
24
|
+
# visitor.visit(ast_node)
|
25
|
+
# ~~~
|
26
|
+
class Visitor
|
27
|
+
def visit(node)
|
28
|
+
case node
|
29
|
+
when Declarations::Global
|
30
|
+
visit_declaration_global(node)
|
31
|
+
when Declarations::Class
|
32
|
+
visit_declaration_class(node)
|
33
|
+
when Declarations::Module
|
34
|
+
visit_declaration_module(node)
|
35
|
+
when Declarations::Constant
|
36
|
+
visit_declaration_constant(node)
|
37
|
+
when Declarations::TypeAlias
|
38
|
+
visit_declaration_type_alias(node)
|
39
|
+
when Declarations::Interface
|
40
|
+
visit_declaration_interface(node)
|
41
|
+
when Members::Alias
|
42
|
+
visit_member_alias(node)
|
43
|
+
when Members::ClassInstanceVariable
|
44
|
+
visit_member_class_instance_variable(node)
|
45
|
+
when Members::ClassVariable
|
46
|
+
visit_member_class_variable(node)
|
47
|
+
when Members::InstanceVariable
|
48
|
+
visit_member_instance_variable(node)
|
49
|
+
when Members::Private
|
50
|
+
visit_member_private(node)
|
51
|
+
when Members::Public
|
52
|
+
visit_member_public(node)
|
53
|
+
when Members::MethodDefinition
|
54
|
+
visit_member_method_definition(node)
|
55
|
+
when Members::AttrReader
|
56
|
+
visit_member_attr_reader(node)
|
57
|
+
when Members::AttrWriter
|
58
|
+
visit_member_attr_writer(node)
|
59
|
+
when Members::AttrAccessor
|
60
|
+
visit_member_attr_accessor(node)
|
61
|
+
when Members::Include
|
62
|
+
visit_member_include(node)
|
63
|
+
when Members::Prepend
|
64
|
+
visit_member_prepend(node)
|
65
|
+
when Members::Extend
|
66
|
+
visit_member_extend(node)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def visit_all(nodes)
|
71
|
+
nodes.each do |node|
|
72
|
+
visit(node)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def visit_declaration_global(node)
|
77
|
+
end
|
78
|
+
|
79
|
+
def visit_declaration_class(node)
|
80
|
+
visit_all(node.members)
|
81
|
+
end
|
82
|
+
|
83
|
+
def visit_declaration_module(node)
|
84
|
+
visit_all(node.members)
|
85
|
+
end
|
86
|
+
|
87
|
+
def visit_declaration_constant(node)
|
88
|
+
end
|
89
|
+
|
90
|
+
def visit_declaration_type_alias(node)
|
91
|
+
end
|
92
|
+
|
93
|
+
def visit_declaration_interface(node)
|
94
|
+
visit_all(node.members)
|
95
|
+
end
|
96
|
+
|
97
|
+
def visit_member_alias(node)
|
98
|
+
end
|
99
|
+
|
100
|
+
def visit_member_class_instance_variable(node)
|
101
|
+
end
|
102
|
+
|
103
|
+
def visit_member_class_variable(node)
|
104
|
+
end
|
105
|
+
|
106
|
+
def visit_member_instance_variable(node)
|
107
|
+
end
|
108
|
+
|
109
|
+
def visit_member_private(node)
|
110
|
+
end
|
111
|
+
|
112
|
+
def visit_member_public(node)
|
113
|
+
end
|
114
|
+
|
115
|
+
def visit_member_method_definition(node)
|
116
|
+
end
|
117
|
+
|
118
|
+
def visit_member_attr_reader(node)
|
119
|
+
end
|
120
|
+
|
121
|
+
def visit_member_attr_writer(node)
|
122
|
+
end
|
123
|
+
|
124
|
+
def visit_member_attr_accessor(node)
|
125
|
+
end
|
126
|
+
|
127
|
+
def visit_member_include(node)
|
128
|
+
end
|
129
|
+
|
130
|
+
def visit_member_prepend(node)
|
131
|
+
end
|
132
|
+
|
133
|
+
def visit_member_extend(node)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
data/lib/rbs/cli/validate.rb
CHANGED
@@ -94,7 +94,7 @@ EOU
|
|
94
94
|
private
|
95
95
|
|
96
96
|
def validate_class_module_definition
|
97
|
-
@env.class_decls.each do |name,
|
97
|
+
@env.class_decls.each do |name, entry|
|
98
98
|
RBS.logger.info "Validating class/module definition: `#{name}`..."
|
99
99
|
@builder.build_instance(name).each_type do |type|
|
100
100
|
@validator.validate_type type, context: nil
|
@@ -107,30 +107,47 @@ EOU
|
|
107
107
|
@errors.add(error)
|
108
108
|
end
|
109
109
|
|
110
|
-
case
|
110
|
+
case entry
|
111
111
|
when Environment::ClassEntry
|
112
|
-
|
112
|
+
entry.decls.each do |decl|
|
113
113
|
if super_class = decl.decl.super_class
|
114
114
|
super_class.args.each do |arg|
|
115
115
|
void_type_context_validator(arg, true)
|
116
116
|
no_self_type_validator(arg)
|
117
117
|
no_classish_type_validator(arg)
|
118
|
+
@validator.validate_type(arg, context: nil)
|
119
|
+
end
|
120
|
+
|
121
|
+
if super_entry = @env.normalized_class_entry(super_class.name)
|
122
|
+
InvalidTypeApplicationError.check!(type_name: super_class.name, args: super_class.args, params: super_entry.type_params, location: super_class.location)
|
118
123
|
end
|
119
124
|
end
|
120
125
|
end
|
121
126
|
when Environment::ModuleEntry
|
122
|
-
|
127
|
+
entry.decls.each do |decl|
|
123
128
|
decl.decl.self_types.each do |self_type|
|
124
129
|
self_type.args.each do |arg|
|
125
130
|
void_type_context_validator(arg, true)
|
126
131
|
no_self_type_validator(arg)
|
127
132
|
no_classish_type_validator(arg)
|
133
|
+
@validator.validate_type(arg, context: nil)
|
134
|
+
end
|
135
|
+
|
136
|
+
self_params =
|
137
|
+
if self_type.name.class?
|
138
|
+
@env.normalized_module_entry(self_type.name)&.type_params
|
139
|
+
else
|
140
|
+
@env.interface_decls[self_type.name]&.decl&.type_params
|
141
|
+
end
|
142
|
+
|
143
|
+
if self_params
|
144
|
+
InvalidTypeApplicationError.check!(type_name: self_type.name, params: self_params, args: self_type.args, location: self_type.location)
|
128
145
|
end
|
129
146
|
end
|
130
147
|
end
|
131
148
|
end
|
132
149
|
|
133
|
-
d =
|
150
|
+
d = entry.primary.decl
|
134
151
|
|
135
152
|
@validator.validate_type_params(
|
136
153
|
d.type_params,
|
@@ -139,14 +156,22 @@ EOU
|
|
139
156
|
)
|
140
157
|
|
141
158
|
d.type_params.each do |param|
|
142
|
-
if ub = param.
|
159
|
+
if ub = param.upper_bound_type
|
143
160
|
void_type_context_validator(ub)
|
144
161
|
no_self_type_validator(ub)
|
145
162
|
no_classish_type_validator(ub)
|
163
|
+
@validator.validate_type(ub, context: nil)
|
164
|
+
end
|
165
|
+
|
166
|
+
if dt = param.default_type
|
167
|
+
void_type_context_validator(dt)
|
168
|
+
no_self_type_validator(dt)
|
169
|
+
no_classish_type_validator(dt)
|
170
|
+
@validator.validate_type(dt, context: nil)
|
146
171
|
end
|
147
172
|
end
|
148
173
|
|
149
|
-
|
174
|
+
entry.decls.each do |d|
|
150
175
|
d.decl.each_member do |member|
|
151
176
|
case member
|
152
177
|
when AST::Members::MethodDefinition
|
@@ -163,6 +188,15 @@ EOU
|
|
163
188
|
void_type_context_validator(arg, true)
|
164
189
|
end
|
165
190
|
end
|
191
|
+
params =
|
192
|
+
if member.name.class?
|
193
|
+
module_decl = @env.normalized_module_entry(member.name) or raise
|
194
|
+
module_decl.type_params
|
195
|
+
else
|
196
|
+
interface_decl = @env.interface_decls.fetch(member.name)
|
197
|
+
interface_decl.decl.type_params
|
198
|
+
end
|
199
|
+
InvalidTypeApplicationError.check!(type_name: member.name, params: params, args: member.args, location: member.location)
|
166
200
|
when AST::Members::Var
|
167
201
|
void_type_context_validator(member.type)
|
168
202
|
if member.is_a?(AST::Members::ClassVariable)
|
data/lib/rbs/cli.rb
CHANGED
@@ -109,7 +109,7 @@ module RBS
|
|
109
109
|
end
|
110
110
|
|
111
111
|
def has_parser?
|
112
|
-
defined?(RubyVM::AbstractSyntaxTree)
|
112
|
+
defined?(RubyVM::AbstractSyntaxTree) ? true : false
|
113
113
|
end
|
114
114
|
|
115
115
|
def run(args)
|
@@ -909,7 +909,7 @@ Options:
|
|
909
909
|
syntax_error = false
|
910
910
|
bufs = args.flat_map do |path|
|
911
911
|
path = Pathname(path)
|
912
|
-
FileFinder.each_file(path, skip_hidden: false
|
912
|
+
FileFinder.each_file(path, skip_hidden: false).map do |file_path|
|
913
913
|
Buffer.new(content: file_path.read, name: file_path)
|
914
914
|
end
|
915
915
|
end
|
@@ -1193,7 +1193,7 @@ EOB
|
|
1193
1193
|
end
|
1194
1194
|
|
1195
1195
|
minuend_paths.each do |minuend_path|
|
1196
|
-
FileFinder.each_file(Pathname(minuend_path),
|
1196
|
+
FileFinder.each_file(Pathname(minuend_path), skip_hidden: true) do |rbs_path|
|
1197
1197
|
buf = Buffer.new(name: rbs_path, content: rbs_path.read)
|
1198
1198
|
_, dirs, decls = Parser.parse_signature(buf)
|
1199
1199
|
subtracted = Subtractor.new(decls, subtrahend).call
|
data/lib/rbs/definition.rb
CHANGED
@@ -238,10 +238,11 @@ module RBS
|
|
238
238
|
end
|
239
239
|
|
240
240
|
def apply(args, location:)
|
241
|
+
# Assume default types of type parameters are already added to `args`
|
241
242
|
InvalidTypeApplicationError.check!(
|
242
243
|
type_name: type_name,
|
243
244
|
args: args,
|
244
|
-
params: params,
|
245
|
+
params: params.map { AST::TypeParam.new(name: _1, variance: :invariant, upper_bound: nil, location: nil, default_type: nil) },
|
245
246
|
location: location
|
246
247
|
)
|
247
248
|
|
@@ -213,12 +213,15 @@ module RBS
|
|
213
213
|
end
|
214
214
|
|
215
215
|
super_name = env.normalize_module_name(super_name)
|
216
|
-
|
216
|
+
|
217
217
|
NoSuperclassFoundError.check!(super_name, env: env, location: primary.decl.location)
|
218
218
|
if super_class
|
219
219
|
InheritModuleError.check!(super_class, env: env)
|
220
220
|
end
|
221
221
|
|
222
|
+
super_entry = env.normalized_class_entry(super_name) or raise
|
223
|
+
super_args = AST::TypeParam.normalize_args(super_entry.type_params, super_args)
|
224
|
+
|
222
225
|
ancestors = OneAncestors.class_instance(
|
223
226
|
type_name: type_name,
|
224
227
|
params: params,
|
@@ -243,9 +246,17 @@ module RBS
|
|
243
246
|
|
244
247
|
module_name = module_self.name
|
245
248
|
if module_name.class?
|
246
|
-
|
249
|
+
module_entry = env.normalized_module_class_entry(module_name) or raise
|
250
|
+
module_name = module_entry.name
|
251
|
+
self_args = AST::TypeParam.normalize_args(module_entry.type_params, module_self.args)
|
252
|
+
end
|
253
|
+
if module_name.interface?
|
254
|
+
interface_entry = env.interface_decls.fetch(module_name)
|
255
|
+
self_args = AST::TypeParam.normalize_args(interface_entry.decl.type_params, module_self.args)
|
247
256
|
end
|
248
|
-
|
257
|
+
self_args or raise
|
258
|
+
|
259
|
+
self_types.push Definition::Ancestor::Instance.new(name: module_name, args: self_args, source: module_self)
|
249
260
|
end
|
250
261
|
end
|
251
262
|
end
|
@@ -346,11 +357,17 @@ module RBS
|
|
346
357
|
MixinClassError.check!(type_name: type_name, env: env, member: member)
|
347
358
|
NoMixinFoundError.check!(member.name, env: env, member: member)
|
348
359
|
|
360
|
+
module_decl = env.normalized_module_entry(module_name) or raise
|
361
|
+
module_args = AST::TypeParam.normalize_args(module_decl.type_params, module_args)
|
362
|
+
|
349
363
|
module_name = env.normalize_module_name(module_name)
|
350
364
|
included_modules << Definition::Ancestor::Instance.new(name: module_name, args: module_args, source: member)
|
351
365
|
when member.name.interface? && included_interfaces
|
352
366
|
NoMixinFoundError.check!(member.name, env: env, member: member)
|
353
367
|
|
368
|
+
interface_decl = env.interface_decls.fetch(module_name)
|
369
|
+
module_args = AST::TypeParam.normalize_args(interface_decl.decl.type_params, module_args)
|
370
|
+
|
354
371
|
included_interfaces << Definition::Ancestor::Instance.new(name: module_name, args: module_args, source: member)
|
355
372
|
end
|
356
373
|
|
@@ -359,8 +376,11 @@ module RBS
|
|
359
376
|
MixinClassError.check!(type_name: type_name, env: env, member: member)
|
360
377
|
NoMixinFoundError.check!(member.name, env: env, member: member)
|
361
378
|
|
362
|
-
|
379
|
+
module_decl = env.normalized_module_entry(member.name) or raise
|
380
|
+
module_name = module_decl.name
|
381
|
+
|
363
382
|
module_args = member.args.map {|type| align_params ? type.sub(align_params) : type }
|
383
|
+
module_args = AST::TypeParam.normalize_args(module_decl.type_params, module_args)
|
364
384
|
|
365
385
|
prepended_modules << Definition::Ancestor::Instance.new(name: module_name, args: module_args, source: member)
|
366
386
|
end
|
@@ -374,11 +394,17 @@ module RBS
|
|
374
394
|
MixinClassError.check!(type_name: type_name, env: env, member: member)
|
375
395
|
NoMixinFoundError.check!(member.name, env: env, member: member)
|
376
396
|
|
397
|
+
module_decl = env.normalized_module_entry(module_name) or raise
|
398
|
+
module_args = AST::TypeParam.normalize_args(module_decl.type_params, module_args)
|
399
|
+
|
377
400
|
module_name = env.normalize_module_name(module_name)
|
378
401
|
extended_modules << Definition::Ancestor::Instance.new(name: module_name, args: module_args, source: member)
|
379
402
|
when member.name.interface? && extended_interfaces
|
380
403
|
NoMixinFoundError.check!(member.name, env: env, member: member)
|
381
404
|
|
405
|
+
interface_decl = env.interface_decls.fetch(module_name)
|
406
|
+
module_args = AST::TypeParam.normalize_args(interface_decl.decl.type_params, module_args)
|
407
|
+
|
382
408
|
extended_interfaces << Definition::Ancestor::Instance.new(name: module_name, args: module_args, source: member)
|
383
409
|
end
|
384
410
|
end
|
@@ -37,7 +37,7 @@ module RBS
|
|
37
37
|
interface_methods = interface_methods(included_interfaces)
|
38
38
|
methods = method_builder.build_interface(type_name)
|
39
39
|
|
40
|
-
import_methods(definition, type_name, methods, interface_methods, subst)
|
40
|
+
import_methods(definition, type_name, methods, interface_methods, subst, nil)
|
41
41
|
end
|
42
42
|
|
43
43
|
def build_interface(type_name)
|
@@ -86,6 +86,19 @@ module RBS
|
|
86
86
|
one_ancestors = ancestor_builder.one_instance_ancestors(type_name)
|
87
87
|
methods = method_builder.build_instance(type_name)
|
88
88
|
|
89
|
+
self_type_methods = one_ancestors.each_self_type.with_object({}) do |self_type, hash| #$ Hash[Symbol, Definition::Method]
|
90
|
+
self_type.args.each do |arg|
|
91
|
+
validate_type_presence(arg)
|
92
|
+
end
|
93
|
+
|
94
|
+
self_type_defn = self_type.name.interface? ? build_interface(self_type.name) : build_instance(self_type.name)
|
95
|
+
|
96
|
+
s = subst + tapp_subst(self_type.name, self_type.args)
|
97
|
+
self_type_defn.methods.each do |method_name, method_def|
|
98
|
+
hash[method_name] = method_def.sub(s)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
89
102
|
one_ancestors.each_included_module do |mod|
|
90
103
|
mod.args.each do |arg|
|
91
104
|
validate_type_presence(arg)
|
@@ -100,7 +113,7 @@ module RBS
|
|
100
113
|
[interface, *other_interfaces]
|
101
114
|
end
|
102
115
|
interface_methods = interface_methods(all_interfaces)
|
103
|
-
import_methods(definition, type_name, methods, interface_methods, subst)
|
116
|
+
import_methods(definition, type_name, methods, interface_methods, subst, self_type_methods)
|
104
117
|
|
105
118
|
one_ancestors.each_prepended_module do |mod|
|
106
119
|
mod.args.each do |arg|
|
@@ -254,7 +267,7 @@ module RBS
|
|
254
267
|
[interface, *other_interfaces]
|
255
268
|
end
|
256
269
|
interface_methods = interface_methods(all_interfaces)
|
257
|
-
import_methods(definition, type_name, methods, interface_methods, Substitution.new)
|
270
|
+
import_methods(definition, type_name, methods, interface_methods, Substitution.new, nil)
|
258
271
|
|
259
272
|
entry.decls.each do |d|
|
260
273
|
d.decl.members.each do |member|
|
@@ -529,7 +542,7 @@ module RBS
|
|
529
542
|
)
|
530
543
|
end
|
531
544
|
|
532
|
-
def import_methods(definition, module_name, module_methods, interfaces_methods, subst)
|
545
|
+
def import_methods(definition, module_name, module_methods, interfaces_methods, subst, self_type_methods)
|
533
546
|
new_methods = {} #: Hash[Symbol, Definition::Method]
|
534
547
|
interface_method_duplicates = Set[] #: Set[Symbol]
|
535
548
|
|
@@ -567,6 +580,7 @@ module RBS
|
|
567
580
|
definition,
|
568
581
|
method,
|
569
582
|
subst_,
|
583
|
+
nil,
|
570
584
|
defined_in: interface.name,
|
571
585
|
implemented_in: module_name
|
572
586
|
)
|
@@ -579,6 +593,7 @@ module RBS
|
|
579
593
|
definition,
|
580
594
|
method,
|
581
595
|
subst,
|
596
|
+
self_type_methods,
|
582
597
|
defined_in: module_name,
|
583
598
|
implemented_in: module_name.interface? ? nil : module_name
|
584
599
|
)
|
@@ -587,12 +602,12 @@ module RBS
|
|
587
602
|
definition.methods.merge!(new_methods)
|
588
603
|
end
|
589
604
|
|
590
|
-
def define_method(methods, definition, method, subst, defined_in:, implemented_in: defined_in)
|
605
|
+
def define_method(methods, definition, method, subst, self_type_methods, defined_in:, implemented_in: defined_in)
|
591
606
|
existing_method = methods[method.name] || definition.methods[method.name]
|
592
607
|
|
593
608
|
case original = method.original
|
594
609
|
when AST::Members::Alias
|
595
|
-
original_method = methods[original.old_name] || definition.methods[original.old_name]
|
610
|
+
original_method = methods[original.old_name] || definition.methods[original.old_name] || self_type_methods&.fetch(original.old_name, nil)
|
596
611
|
|
597
612
|
unless original_method
|
598
613
|
raise UnknownMethodAliasError.new(
|
@@ -152,7 +152,7 @@ module RBS
|
|
152
152
|
each_dir do |source, dir|
|
153
153
|
skip_hidden = !source.is_a?(Pathname)
|
154
154
|
|
155
|
-
FileFinder.each_file(dir, skip_hidden: skip_hidden
|
155
|
+
FileFinder.each_file(dir, skip_hidden: skip_hidden) do |path|
|
156
156
|
next if files.include?(path)
|
157
157
|
|
158
158
|
files << path
|
data/lib/rbs/errors.rb
CHANGED
@@ -68,18 +68,23 @@ module RBS
|
|
68
68
|
attr_reader :type_name
|
69
69
|
attr_reader :args
|
70
70
|
attr_reader :params
|
71
|
+
attr_reader :type_params
|
71
72
|
attr_reader :location
|
72
73
|
|
73
74
|
def initialize(type_name:, args:, params:, location:)
|
74
75
|
@type_name = type_name
|
75
76
|
@args = args
|
76
|
-
@
|
77
|
+
@type_params = params
|
78
|
+
@params = params.map(&:name)
|
77
79
|
@location = location
|
78
80
|
super "#{Location.to_string location}: #{type_name} expects parameters [#{params.join(", ")}], but given args [#{args.join(", ")}]"
|
79
81
|
end
|
80
82
|
|
81
83
|
def self.check!(type_name:, args:, params:, location:)
|
82
|
-
|
84
|
+
min_arity = params.count { _1.default_type.nil? }
|
85
|
+
max_arity = params.size
|
86
|
+
|
87
|
+
unless min_arity <= args.size && args.size <= max_arity
|
83
88
|
raise new(type_name: type_name, args: args, params: params, location: location)
|
84
89
|
end
|
85
90
|
end
|
data/lib/rbs/file_finder.rb
CHANGED
@@ -4,27 +4,24 @@ module RBS
|
|
4
4
|
module FileFinder
|
5
5
|
module_function
|
6
6
|
|
7
|
-
def self.each_file(path, immediate
|
7
|
+
def self.each_file(path, immediate: nil, skip_hidden:, &block)
|
8
8
|
return enum_for((__method__ or raise), path, immediate: immediate, skip_hidden: skip_hidden) unless block
|
9
9
|
|
10
10
|
case
|
11
11
|
when path.file?
|
12
|
-
|
13
|
-
yield path
|
14
|
-
end
|
12
|
+
yield path
|
15
13
|
|
16
14
|
when path.directory?
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
15
|
+
paths = Pathname.glob("#{path}/**/*.rbs")
|
16
|
+
|
17
|
+
if skip_hidden
|
18
|
+
paths.select! do |child|
|
19
|
+
child.relative_path_from(path).ascend.drop(1).none? { _1.basename.to_s.start_with?("_") }
|
22
20
|
end
|
23
21
|
end
|
22
|
+
paths.sort_by!(&:to_s)
|
24
23
|
|
25
|
-
|
26
|
-
each_file(child, immediate: false, skip_hidden: skip_hidden, &block)
|
27
|
-
end
|
24
|
+
paths.each(&block)
|
28
25
|
end
|
29
26
|
end
|
30
27
|
end
|