steep-relaxed 1.9.3.3

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.
Files changed (165) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.gitmodules +0 -0
  4. data/CHANGELOG.md +1032 -0
  5. data/LICENSE +21 -0
  6. data/README.md +260 -0
  7. data/Rakefile +227 -0
  8. data/STDGEM_DEPENDENCIES.txt +59 -0
  9. data/Steepfile +68 -0
  10. data/bin/console +14 -0
  11. data/bin/generate-diagnostics-docs.rb +112 -0
  12. data/bin/mem_graph.rb +67 -0
  13. data/bin/mem_prof.rb +102 -0
  14. data/bin/output_rebaseline.rb +34 -0
  15. data/bin/output_test.rb +60 -0
  16. data/bin/rbs +20 -0
  17. data/bin/rbs-inline +19 -0
  18. data/bin/setup +9 -0
  19. data/bin/stackprof_test.rb +19 -0
  20. data/bin/steep +19 -0
  21. data/bin/steep-check.rb +251 -0
  22. data/bin/steep-prof +16 -0
  23. data/doc/narrowing.md +195 -0
  24. data/doc/shape.md +194 -0
  25. data/exe/steep +18 -0
  26. data/guides/README.md +5 -0
  27. data/guides/src/gem-rbs-collection/gem-rbs-collection.md +126 -0
  28. data/guides/src/getting-started/getting-started.md +163 -0
  29. data/guides/src/nil-optional/nil-optional.md +195 -0
  30. data/lib/steep/annotation_parser.rb +199 -0
  31. data/lib/steep/ast/annotation/collection.rb +172 -0
  32. data/lib/steep/ast/annotation.rb +137 -0
  33. data/lib/steep/ast/builtin.rb +104 -0
  34. data/lib/steep/ast/ignore.rb +148 -0
  35. data/lib/steep/ast/node/type_application.rb +88 -0
  36. data/lib/steep/ast/node/type_assertion.rb +81 -0
  37. data/lib/steep/ast/types/any.rb +35 -0
  38. data/lib/steep/ast/types/boolean.rb +45 -0
  39. data/lib/steep/ast/types/bot.rb +35 -0
  40. data/lib/steep/ast/types/class.rb +43 -0
  41. data/lib/steep/ast/types/factory.rb +557 -0
  42. data/lib/steep/ast/types/helper.rb +40 -0
  43. data/lib/steep/ast/types/instance.rb +42 -0
  44. data/lib/steep/ast/types/intersection.rb +93 -0
  45. data/lib/steep/ast/types/literal.rb +59 -0
  46. data/lib/steep/ast/types/logic.rb +84 -0
  47. data/lib/steep/ast/types/name.rb +128 -0
  48. data/lib/steep/ast/types/nil.rb +41 -0
  49. data/lib/steep/ast/types/proc.rb +117 -0
  50. data/lib/steep/ast/types/record.rb +79 -0
  51. data/lib/steep/ast/types/self.rb +43 -0
  52. data/lib/steep/ast/types/shared_instance.rb +11 -0
  53. data/lib/steep/ast/types/top.rb +35 -0
  54. data/lib/steep/ast/types/tuple.rb +60 -0
  55. data/lib/steep/ast/types/union.rb +97 -0
  56. data/lib/steep/ast/types/var.rb +65 -0
  57. data/lib/steep/ast/types/void.rb +35 -0
  58. data/lib/steep/cli.rb +401 -0
  59. data/lib/steep/diagnostic/deprecated/else_on_exhaustive_case.rb +20 -0
  60. data/lib/steep/diagnostic/deprecated/unknown_constant_assigned.rb +28 -0
  61. data/lib/steep/diagnostic/helper.rb +18 -0
  62. data/lib/steep/diagnostic/lsp_formatter.rb +78 -0
  63. data/lib/steep/diagnostic/result_printer2.rb +48 -0
  64. data/lib/steep/diagnostic/ruby.rb +1221 -0
  65. data/lib/steep/diagnostic/signature.rb +570 -0
  66. data/lib/steep/drivers/annotations.rb +52 -0
  67. data/lib/steep/drivers/check.rb +339 -0
  68. data/lib/steep/drivers/checkfile.rb +210 -0
  69. data/lib/steep/drivers/diagnostic_printer.rb +105 -0
  70. data/lib/steep/drivers/init.rb +66 -0
  71. data/lib/steep/drivers/langserver.rb +56 -0
  72. data/lib/steep/drivers/print_project.rb +113 -0
  73. data/lib/steep/drivers/stats.rb +203 -0
  74. data/lib/steep/drivers/utils/driver_helper.rb +143 -0
  75. data/lib/steep/drivers/utils/jobs_option.rb +26 -0
  76. data/lib/steep/drivers/vendor.rb +27 -0
  77. data/lib/steep/drivers/watch.rb +194 -0
  78. data/lib/steep/drivers/worker.rb +58 -0
  79. data/lib/steep/equatable.rb +23 -0
  80. data/lib/steep/expectations.rb +228 -0
  81. data/lib/steep/index/rbs_index.rb +350 -0
  82. data/lib/steep/index/signature_symbol_provider.rb +185 -0
  83. data/lib/steep/index/source_index.rb +167 -0
  84. data/lib/steep/interface/block.rb +103 -0
  85. data/lib/steep/interface/builder.rb +843 -0
  86. data/lib/steep/interface/function.rb +1090 -0
  87. data/lib/steep/interface/method_type.rb +330 -0
  88. data/lib/steep/interface/shape.rb +239 -0
  89. data/lib/steep/interface/substitution.rb +159 -0
  90. data/lib/steep/interface/type_param.rb +115 -0
  91. data/lib/steep/located_value.rb +20 -0
  92. data/lib/steep/method_name.rb +42 -0
  93. data/lib/steep/module_helper.rb +24 -0
  94. data/lib/steep/node_helper.rb +273 -0
  95. data/lib/steep/path_helper.rb +30 -0
  96. data/lib/steep/project/dsl.rb +268 -0
  97. data/lib/steep/project/group.rb +31 -0
  98. data/lib/steep/project/options.rb +63 -0
  99. data/lib/steep/project/pattern.rb +59 -0
  100. data/lib/steep/project/target.rb +92 -0
  101. data/lib/steep/project.rb +78 -0
  102. data/lib/steep/rake_task.rb +132 -0
  103. data/lib/steep/range_extension.rb +29 -0
  104. data/lib/steep/server/base_worker.rb +97 -0
  105. data/lib/steep/server/change_buffer.rb +73 -0
  106. data/lib/steep/server/custom_methods.rb +77 -0
  107. data/lib/steep/server/delay_queue.rb +45 -0
  108. data/lib/steep/server/interaction_worker.rb +492 -0
  109. data/lib/steep/server/lsp_formatter.rb +455 -0
  110. data/lib/steep/server/master.rb +922 -0
  111. data/lib/steep/server/target_group_files.rb +205 -0
  112. data/lib/steep/server/type_check_controller.rb +366 -0
  113. data/lib/steep/server/type_check_worker.rb +303 -0
  114. data/lib/steep/server/work_done_progress.rb +64 -0
  115. data/lib/steep/server/worker_process.rb +176 -0
  116. data/lib/steep/services/completion_provider.rb +802 -0
  117. data/lib/steep/services/content_change.rb +61 -0
  118. data/lib/steep/services/file_loader.rb +74 -0
  119. data/lib/steep/services/goto_service.rb +441 -0
  120. data/lib/steep/services/hover_provider/rbs.rb +88 -0
  121. data/lib/steep/services/hover_provider/ruby.rb +221 -0
  122. data/lib/steep/services/hover_provider/singleton_methods.rb +20 -0
  123. data/lib/steep/services/path_assignment.rb +46 -0
  124. data/lib/steep/services/signature_help_provider.rb +202 -0
  125. data/lib/steep/services/signature_service.rb +428 -0
  126. data/lib/steep/services/stats_calculator.rb +68 -0
  127. data/lib/steep/services/type_check_service.rb +394 -0
  128. data/lib/steep/services/type_name_completion.rb +236 -0
  129. data/lib/steep/signature/validator.rb +651 -0
  130. data/lib/steep/source/ignore_ranges.rb +69 -0
  131. data/lib/steep/source.rb +691 -0
  132. data/lib/steep/subtyping/cache.rb +30 -0
  133. data/lib/steep/subtyping/check.rb +1113 -0
  134. data/lib/steep/subtyping/constraints.rb +341 -0
  135. data/lib/steep/subtyping/relation.rb +101 -0
  136. data/lib/steep/subtyping/result.rb +324 -0
  137. data/lib/steep/subtyping/variable_variance.rb +89 -0
  138. data/lib/steep/test.rb +9 -0
  139. data/lib/steep/thread_waiter.rb +43 -0
  140. data/lib/steep/type_construction.rb +5183 -0
  141. data/lib/steep/type_inference/block_params.rb +416 -0
  142. data/lib/steep/type_inference/case_when.rb +303 -0
  143. data/lib/steep/type_inference/constant_env.rb +56 -0
  144. data/lib/steep/type_inference/context.rb +195 -0
  145. data/lib/steep/type_inference/logic_type_interpreter.rb +613 -0
  146. data/lib/steep/type_inference/method_call.rb +193 -0
  147. data/lib/steep/type_inference/method_params.rb +531 -0
  148. data/lib/steep/type_inference/multiple_assignment.rb +194 -0
  149. data/lib/steep/type_inference/send_args.rb +712 -0
  150. data/lib/steep/type_inference/type_env.rb +341 -0
  151. data/lib/steep/type_inference/type_env_builder.rb +138 -0
  152. data/lib/steep/typing.rb +321 -0
  153. data/lib/steep/version.rb +3 -0
  154. data/lib/steep.rb +369 -0
  155. data/manual/annotations.md +181 -0
  156. data/manual/ignore.md +20 -0
  157. data/manual/ruby-diagnostics.md +1879 -0
  158. data/sample/Steepfile +22 -0
  159. data/sample/lib/conference.rb +49 -0
  160. data/sample/lib/length.rb +35 -0
  161. data/sample/sig/conference.rbs +42 -0
  162. data/sample/sig/generics.rbs +15 -0
  163. data/sample/sig/length.rbs +34 -0
  164. data/steep-relaxed.gemspec +56 -0
  165. metadata +340 -0
@@ -0,0 +1,193 @@
1
+ module Steep
2
+ module TypeInference
3
+ module MethodCall
4
+ class MethodDecl
5
+ attr_reader :method_name
6
+ attr_reader :method_def
7
+
8
+ def initialize(method_name:, method_def:)
9
+ @method_name = method_name
10
+ @method_def = method_def
11
+ end
12
+
13
+ def hash
14
+ method_name.hash
15
+ end
16
+
17
+ def ==(other)
18
+ other.is_a?(MethodDecl) && other.method_name == method_name && other.method_def == method_def
19
+ end
20
+
21
+ alias eql? ==
22
+
23
+ def method_type
24
+ method_def.type
25
+ end
26
+ end
27
+
28
+ MethodContext = _ = Struct.new(:method_name, keyword_init: true) do
29
+ # @implements MethodContext
30
+
31
+ def to_s
32
+ "@#{method_name}"
33
+ end
34
+ end
35
+
36
+ ModuleContext = _ = Struct.new(:type_name, keyword_init: true) do
37
+ # @implements ModuleContext
38
+
39
+ def to_s
40
+ "@#{type_name}@"
41
+ end
42
+ end
43
+
44
+ TopLevelContext = _ = Class.new() do
45
+ def to_s
46
+ "@<main>"
47
+ end
48
+
49
+ def ==(other)
50
+ other.is_a?(TopLevelContext)
51
+ end
52
+
53
+ alias eql? ==
54
+
55
+ def hash
56
+ self.class.hash
57
+ end
58
+ end
59
+
60
+ UnknownContext = _ = Class.new() do
61
+ def to_s
62
+ "@<unknown>"
63
+ end
64
+
65
+ def ==(other)
66
+ other.is_a?(UnknownContext)
67
+ end
68
+
69
+ alias eql? ==
70
+
71
+ def hash
72
+ self.class.hash
73
+ end
74
+ end
75
+
76
+ class Base
77
+ attr_reader :node
78
+ attr_reader :context
79
+ attr_reader :method_name
80
+ attr_reader :return_type
81
+ attr_reader :receiver_type
82
+
83
+ def initialize(node:, context:, method_name:, receiver_type:, return_type:)
84
+ @node = node
85
+ @context = context
86
+ @method_name = method_name
87
+ @receiver_type = receiver_type
88
+ @return_type = return_type
89
+ end
90
+
91
+ def with_return_type(new_type)
92
+ dup.tap do |copy|
93
+ copy.instance_eval do
94
+ @return_type = new_type
95
+ end
96
+ end
97
+ end
98
+
99
+ def ==(other)
100
+ other.is_a?(Base) &&
101
+ other.node == node &&
102
+ other.context == context &&
103
+ other.method_name == method_name &&
104
+ other.return_type == return_type &&
105
+ other.receiver_type == receiver_type
106
+ end
107
+
108
+ alias eql? ==
109
+
110
+ def hash
111
+ node.hash ^ context.hash ^ method_name.hash ^ return_type.hash ^ receiver_type.hash
112
+ end
113
+ end
114
+
115
+ class Typed < Base
116
+ attr_reader :actual_method_type
117
+ attr_reader :method_decls
118
+
119
+ def initialize(node:, context:, method_name:, receiver_type:, actual_method_type:, method_decls:, return_type:)
120
+ super(node: node, context: context, method_name: method_name, receiver_type: receiver_type, return_type: return_type)
121
+ @actual_method_type = actual_method_type
122
+ @method_decls = method_decls
123
+ end
124
+
125
+ def pure?
126
+ method_decls.all? do |method_decl|
127
+ case member = method_decl.method_def.member
128
+ when RBS::AST::Members::MethodDefinition
129
+ member.annotations.any? {|annotation| annotation.string == "pure" }
130
+ when RBS::AST::Members::Attribute
131
+ # The attribute writer is not pure
132
+ !method_decl.method_name.method_name.end_with?("=")
133
+ end
134
+ end
135
+ end
136
+
137
+ def update(node: self.node, return_type: self.return_type)
138
+ _ = self.class.new(
139
+ node: node,
140
+ return_type: return_type,
141
+ context: context,
142
+ method_name: method_name,
143
+ receiver_type: receiver_type,
144
+ actual_method_type: actual_method_type,
145
+ method_decls: method_decls
146
+ )
147
+ end
148
+
149
+ def ==(other)
150
+ super &&
151
+ other.is_a?(Typed) &&
152
+ other.actual_method_type == actual_method_type &&
153
+ other.method_decls == method_decls
154
+ end
155
+
156
+ alias eql? ==
157
+
158
+ def hash
159
+ super ^ actual_method_type.hash ^ method_decls.hash
160
+ end
161
+ end
162
+
163
+ class Special < Typed
164
+ end
165
+
166
+ class Untyped < Base
167
+ def initialize(node:, context:, method_name:)
168
+ super(node: node, context: context, method_name: method_name, receiver_type: AST::Types::Any.instance, return_type: AST::Types::Any.instance)
169
+ end
170
+ end
171
+
172
+ class NoMethodError < Base
173
+ attr_reader :error
174
+
175
+ def initialize(node:, context:, method_name:, receiver_type:, error:)
176
+ super(node: node, context: context, method_name: method_name, receiver_type: receiver_type, return_type: AST::Types::Any.instance)
177
+ @error = error
178
+ end
179
+ end
180
+
181
+ class Error < Base
182
+ attr_reader :errors
183
+ attr_reader :method_decls
184
+
185
+ def initialize(node:, context:, method_name:, receiver_type:, errors:, method_decls: Set[], return_type: AST::Types::Any.instance)
186
+ super(node: node, context: context, method_name: method_name, receiver_type: receiver_type, return_type: return_type)
187
+ @method_decls = method_decls
188
+ @errors = errors
189
+ end
190
+ end
191
+ end
192
+ end
193
+ end
@@ -0,0 +1,531 @@
1
+ module Steep
2
+ module TypeInference
3
+ class MethodParams
4
+ class BaseParameter
5
+ attr_reader :name
6
+ attr_reader :type
7
+ attr_reader :node
8
+
9
+ def initialize(name:, type:, node:)
10
+ @name = name
11
+ @type = type
12
+ @node = node
13
+ end
14
+
15
+ def optional?
16
+ case node.type
17
+ when :optarg, :kwoptarg
18
+ true
19
+ else
20
+ false
21
+ end
22
+ end
23
+
24
+ def value
25
+ case node.type
26
+ when :optarg, :kwoptarg
27
+ node.children[1]
28
+ end
29
+ end
30
+
31
+ def var_type
32
+ type || AST::Builtin.any_type
33
+ end
34
+
35
+ def untyped?
36
+ !type
37
+ end
38
+
39
+ def ==(other)
40
+ other.class == self.class &&
41
+ other.name == name &&
42
+ other.type == type &&
43
+ other.value == value &&
44
+ other.node == node
45
+ end
46
+
47
+ alias eql? ==
48
+
49
+ def hash
50
+ self.class.hash ^ name.hash ^ type.hash ^ value.hash ^ node.hash
51
+ end
52
+ end
53
+
54
+ class PositionalParameter < BaseParameter; end
55
+ class KeywordParameter < BaseParameter; end
56
+
57
+ class BaseRestParameter
58
+ attr_reader :name
59
+ attr_reader :type
60
+ attr_reader :node
61
+
62
+ def initialize(name:, type:, node:)
63
+ @name = name
64
+ @type = type
65
+ @node = node
66
+ end
67
+
68
+ def ==(other)
69
+ other.class == self.class &&
70
+ other.name == name &&
71
+ other.type == type &&
72
+ other.node == node
73
+ end
74
+
75
+ alias eql? ==
76
+
77
+ def hash
78
+ self.class.hash ^ name.hash ^ type.hash ^ node.hash
79
+ end
80
+ end
81
+
82
+ class PositionalRestParameter < BaseRestParameter
83
+ def var_type
84
+ AST::Builtin::Array.instance_type(type || AST::Builtin.any_type)
85
+ end
86
+ end
87
+
88
+ class KeywordRestParameter < BaseRestParameter
89
+ def var_type
90
+ AST::Builtin::Hash.instance_type(AST::Builtin::Symbol.instance_type, type || AST::Builtin.any_type)
91
+ end
92
+ end
93
+
94
+ class BlockParameter
95
+ attr_reader :name
96
+ attr_reader :type
97
+ attr_reader :node
98
+ attr_reader :self_type
99
+
100
+ def initialize(name:, type:, node:, optional:, self_type:)
101
+ @name = name
102
+ @type = type
103
+ @node = node
104
+ @optional = optional
105
+ @self_type = self_type
106
+ end
107
+
108
+ def optional?
109
+ @optional ? true : false
110
+ end
111
+
112
+ def var_type
113
+ if type
114
+ proc_type = AST::Types::Proc.new(type: type, block: nil, self_type: self_type)
115
+
116
+ if optional?
117
+ AST::Types::Union.build(types: [proc_type, AST::Builtin.nil_type])
118
+ else
119
+ proc_type
120
+ end
121
+ else
122
+ AST::Builtin.nil_type
123
+ end
124
+ end
125
+
126
+ def ==(other)
127
+ other.class == self.class &&
128
+ other.name == name &&
129
+ other.type == type &&
130
+ other.node == node &&
131
+ other.optional? == optional? &&
132
+ other.self_type == self_type
133
+ end
134
+
135
+ alias eql? ==
136
+
137
+ def hash
138
+ self.class.hash ^ name.hash ^ type.hash ^ node.hash ^ optional?.hash ^ self_type.hash
139
+ end
140
+ end
141
+
142
+ attr_reader :args
143
+ attr_reader :method_type
144
+ attr_reader :params
145
+ attr_reader :errors
146
+ attr_reader :forward_arg_type
147
+
148
+ def initialize(args:, method_type:, forward_arg_type:)
149
+ @args = args
150
+ @method_type = method_type
151
+ @params = {}
152
+ @errors = []
153
+ @forward_arg_type = forward_arg_type
154
+ end
155
+
156
+ def [](name)
157
+ params[name] or raise "Unknown variable name: #{name}"
158
+ end
159
+
160
+ def param?(name)
161
+ params.key?(name)
162
+ end
163
+
164
+ def size
165
+ params.size
166
+ end
167
+
168
+ def each_param(&block)
169
+ if block
170
+ params.each_value(&block)
171
+ else
172
+ params.each_value
173
+ end
174
+ end
175
+
176
+ def each
177
+ if block_given?
178
+ each_param do |param|
179
+ yield param.name, param.var_type
180
+ end
181
+ else
182
+ enum_for :each
183
+ end
184
+ end
185
+
186
+ def update(forward_arg_type: self.forward_arg_type)
187
+ MethodParams.new(args: args, method_type: method_type, forward_arg_type: forward_arg_type)
188
+ end
189
+
190
+ def self.empty(node:)
191
+ # @type var args_node: ::Parser::AST::Node
192
+ args_node =
193
+ case node.type
194
+ when :def
195
+ node.children[1]
196
+ when :defs
197
+ node.children[2]
198
+ else
199
+ raise
200
+ end
201
+
202
+ params = new(args: args_node.children, method_type: nil, forward_arg_type: nil)
203
+
204
+ args_node.children.each do |arg|
205
+ # @type var arg: ::Parser::AST::Node
206
+ case arg.type
207
+ when :arg, :optarg
208
+ name = arg.children[0]
209
+ params.params[name] = PositionalParameter.new(name: name, type: nil, node: arg)
210
+ when :kwarg, :kwoptarg
211
+ name = arg.children[0]
212
+ params.params[name] = KeywordParameter.new(name: name, type: nil, node: arg)
213
+ when :restarg
214
+ name = arg.children[0]
215
+ params.params[name] = PositionalRestParameter.new(name: name, type: nil, node: arg)
216
+ when :kwrestarg
217
+ name = arg.children[0]
218
+ params.params[name] = KeywordRestParameter.new(name: name, type: nil, node: arg)
219
+ when :blockarg
220
+ name = arg.children[0]
221
+ params.params[name] = BlockParameter.new(name: name, type: nil, optional: nil, node: arg, self_type: nil)
222
+ end
223
+ end
224
+
225
+ params
226
+ end
227
+
228
+ def self.build(node:, method_type:)
229
+ # @type var args_node: ::Parser::AST::Node
230
+ args_node =
231
+ case node.type
232
+ when :def
233
+ node.children[1]
234
+ when :defs
235
+ node.children[2]
236
+ else
237
+ raise
238
+ end
239
+ original = args_node.children #: Array[Parser::AST::Node]
240
+ args = original.dup
241
+
242
+ instance = new(args: original, method_type: method_type, forward_arg_type: nil)
243
+
244
+ unless method_type.type.params
245
+ args.each do |arg|
246
+ case arg.type
247
+ when :arg
248
+ name = arg.children[0]
249
+ instance.params[name] = PositionalParameter.new(name: name, type: AST::Builtin.any_type, node: arg)
250
+ when :optarg
251
+ name = arg.children[0]
252
+ instance.params[name] = PositionalParameter.new(name: name, type: AST::Builtin.any_type, node: arg)
253
+ when :forward_arg
254
+ return instance.update(forward_arg_type: true)
255
+ end
256
+ end
257
+ return instance
258
+ end
259
+
260
+ positional_params = method_type.type.params.positional_params
261
+
262
+ loop do
263
+ arg = args.first or break
264
+
265
+ case arg.type
266
+ when :arg
267
+ name = arg.children[0]
268
+ param = positional_params&.head
269
+
270
+ case param
271
+ when Interface::Function::Params::PositionalParams::Required
272
+ instance.params[name] = PositionalParameter.new(name: name, type: param.type, node: arg)
273
+ when Interface::Function::Params::PositionalParams::Optional
274
+ method_param = PositionalParameter.new(name: name, type: param.type, node: arg)
275
+ instance.params[name] = method_param
276
+ instance.errors << Diagnostic::Ruby::MethodParameterMismatch.new(
277
+ method_param: method_param,
278
+ method_type: method_type
279
+ )
280
+ when Interface::Function::Params::PositionalParams::Rest
281
+ method_param = PositionalParameter.new(name: name, type: param.type, node: arg)
282
+ instance.params[name] = method_param
283
+ instance.errors << Diagnostic::Ruby::MethodParameterMismatch.new(
284
+ method_param: method_param,
285
+ method_type: method_type
286
+ )
287
+ when nil
288
+ method_param = PositionalParameter.new(name: name, type: nil, node: arg)
289
+ instance.params[name] = method_param
290
+ instance.errors << Diagnostic::Ruby::MethodParameterMismatch.new(
291
+ method_param: method_param,
292
+ method_type: method_type
293
+ )
294
+ end
295
+
296
+ positional_params = positional_params&.tail
297
+
298
+ when :optarg
299
+ name = arg.children[0]
300
+ param = positional_params&.head
301
+
302
+ case param
303
+ when Interface::Function::Params::PositionalParams::Required
304
+ method_param = PositionalParameter.new(name: name, type: param.type, node: arg)
305
+ instance.params[name] = method_param
306
+ instance.errors << Diagnostic::Ruby::DifferentMethodParameterKind.new(
307
+ method_param: method_param,
308
+ method_type: method_type
309
+ )
310
+ when Interface::Function::Params::PositionalParams::Optional
311
+ instance.params[name] = PositionalParameter.new(name: name, type: param.type, node: arg)
312
+ when Interface::Function::Params::PositionalParams::Rest
313
+ method_param = PositionalParameter.new(name: name, type: param.type, node: arg)
314
+ instance.params[name] = method_param
315
+ instance.errors << Diagnostic::Ruby::DifferentMethodParameterKind.new(
316
+ method_param: method_param,
317
+ method_type: method_type
318
+ )
319
+ when nil
320
+ method_param = PositionalParameter.new(name: name, type: nil, node: arg)
321
+ instance.params[name] = method_param
322
+ instance.errors << Diagnostic::Ruby::DifferentMethodParameterKind.new(
323
+ method_param: method_param,
324
+ method_type: method_type
325
+ )
326
+ end
327
+
328
+ positional_params = positional_params&.tail
329
+ else
330
+ break
331
+ end
332
+
333
+ args.shift
334
+ end
335
+
336
+ if (arg = args.first) && arg.type == :forward_arg
337
+ forward_params = method_type.type.params.update(positional_params: positional_params)
338
+ return instance.update(forward_arg_type: [forward_params, method_type.block])
339
+ end
340
+
341
+ if (arg = args.first) && arg.type == :restarg
342
+ name = arg.children[0]
343
+ rest_types = [] #: Array[AST::Types::t]
344
+ has_error = false
345
+
346
+ loop do
347
+ param = positional_params&.head
348
+
349
+ case param
350
+ when Interface::Function::Params::PositionalParams::Required
351
+ rest_types << param.type
352
+ has_error = true
353
+ when Interface::Function::Params::PositionalParams::Optional
354
+ rest_types << param.type
355
+ has_error = true
356
+ when Interface::Function::Params::PositionalParams::Rest
357
+ rest_types << param.type
358
+ positional_params = nil
359
+ args.shift
360
+ break
361
+ when nil
362
+ has_error = true
363
+ break
364
+ end
365
+
366
+ if positional_params
367
+ positional_params = positional_params.tail
368
+ else
369
+ raise "Fatal error"
370
+ end
371
+ end
372
+
373
+ type = rest_types.empty? ? nil : AST::Types::Union.build(types: rest_types)
374
+
375
+ method_param = PositionalRestParameter.new(name: name, type: type, node: arg)
376
+ instance.params[name] = method_param
377
+ if has_error
378
+ instance.errors << Diagnostic::Ruby::DifferentMethodParameterKind.new(
379
+ method_param: method_param,
380
+ method_type: method_type
381
+ )
382
+ end
383
+ end
384
+
385
+ if positional_params
386
+ instance.errors << Diagnostic::Ruby::MethodArityMismatch.new(node: node, method_type: method_type)
387
+ end
388
+
389
+ keyword_params = method_type.type.params.keyword_params
390
+ keywords = keyword_params.keywords
391
+
392
+ loop do
393
+ arg = args.first or break
394
+
395
+ case arg.type
396
+ when :kwarg
397
+ name = arg.children[0]
398
+
399
+ case
400
+ when type = keyword_params.requireds[name]
401
+ instance.params[name] = KeywordParameter.new(name: name, type: type, node: arg)
402
+ keywords.delete(name)
403
+ when type = keyword_params.optionals[name]
404
+ method_param = KeywordParameter.new(name: name, type: type, node: arg)
405
+ instance.params[name] = method_param
406
+ instance.errors << Diagnostic::Ruby::MethodParameterMismatch.new(
407
+ method_param: method_param,
408
+ method_type: method_type
409
+ )
410
+ keywords.delete(name)
411
+ when type = keyword_params.rest
412
+ method_param = KeywordParameter.new(name: name, type: type, node: arg)
413
+ instance.params[name] = method_param
414
+ instance.errors << Diagnostic::Ruby::MethodParameterMismatch.new(
415
+ method_param: method_param,
416
+ method_type: method_type
417
+ )
418
+ keywords.delete(name)
419
+ else
420
+ method_param = KeywordParameter.new(name: name, type: nil, node: arg)
421
+ instance.params[name] = method_param
422
+ instance.errors << Diagnostic::Ruby::MethodParameterMismatch.new(
423
+ method_param: method_param,
424
+ method_type: method_type
425
+ )
426
+ end
427
+ when :kwoptarg
428
+ name = arg.children[0]
429
+
430
+ case
431
+ when type = keyword_params.requireds[name]
432
+ method_param = KeywordParameter.new(name: name, type: type, node: arg)
433
+ instance.params[name] = method_param
434
+ instance.errors << Diagnostic::Ruby::DifferentMethodParameterKind.new(
435
+ method_param: method_param,
436
+ method_type: method_type
437
+ )
438
+ keywords.delete(name)
439
+ when type = keyword_params.optionals[name]
440
+ method_param = KeywordParameter.new(name: name, type: type, node: arg)
441
+ instance.params[name] = method_param
442
+ keywords.delete(name)
443
+ when type = keyword_params.rest
444
+ method_param = KeywordParameter.new(name: name, type: type, node: arg)
445
+ instance.params[name] = method_param
446
+ instance.errors << Diagnostic::Ruby::DifferentMethodParameterKind.new(
447
+ method_param: method_param,
448
+ method_type: method_type
449
+ )
450
+ keywords.delete(name)
451
+ else
452
+ method_param = KeywordParameter.new(name: name, type: nil, node: arg)
453
+ instance.params[name] = method_param
454
+ instance.errors << Diagnostic::Ruby::DifferentMethodParameterKind.new(
455
+ method_param: method_param,
456
+ method_type: method_type
457
+ )
458
+ end
459
+ else
460
+ break
461
+ end
462
+
463
+ args.shift
464
+ end
465
+
466
+ if (arg = args.first) && arg.type == :kwrestarg
467
+ name = arg.children[0]
468
+ rest_types = [] #: Array[AST::Types::t]
469
+ has_error = false
470
+
471
+ keywords.each do |keyword|
472
+ rest_types << (keyword_params.requireds[keyword] || keyword_params.optionals.fetch(keyword))
473
+ has_error = true
474
+ end
475
+ keywords.clear
476
+
477
+ if keyword_params.rest
478
+ rest_types << keyword_params.rest
479
+ else
480
+ has_error = true
481
+ end
482
+
483
+ type = rest_types.empty? ? nil : AST::Types::Union.build(types: rest_types)
484
+
485
+ method_param = KeywordRestParameter.new(name: name, type: type, node: arg)
486
+ instance.params[name] = method_param
487
+
488
+ if has_error
489
+ instance.errors << Diagnostic::Ruby::DifferentMethodParameterKind.new(
490
+ method_param: method_param,
491
+ method_type: method_type
492
+ )
493
+ end
494
+
495
+ args.shift
496
+ else
497
+ if !keywords.empty? || keyword_params.rest
498
+ instance.errors << Diagnostic::Ruby::MethodArityMismatch.new(
499
+ node: node,
500
+ method_type: method_type
501
+ )
502
+ end
503
+ end
504
+
505
+ if (arg = args.first) && arg.type == :blockarg
506
+ name = arg.children[0] #: Symbol
507
+
508
+ if method_type.block
509
+ instance.params[name] = BlockParameter.new(
510
+ name: name,
511
+ type: method_type.block.type,
512
+ optional: method_type.block.optional?,
513
+ node: arg,
514
+ self_type: method_type.block.self_type
515
+ )
516
+ else
517
+ instance.params[name] = BlockParameter.new(
518
+ name: name,
519
+ type: nil,
520
+ optional: nil,
521
+ node: arg,
522
+ self_type: nil
523
+ )
524
+ end
525
+ end
526
+
527
+ instance
528
+ end
529
+ end
530
+ end
531
+ end