rbs 3.5.3 → 3.6.0.dev.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/.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
|