steep 0.1.0.pre

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 (73) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.travis.yml +6 -0
  4. data/Gemfile +4 -0
  5. data/README.md +95 -0
  6. data/Rakefile +23 -0
  7. data/bin/console +14 -0
  8. data/bin/setup +8 -0
  9. data/bin/smoke_runner.rb +106 -0
  10. data/exe/steep +18 -0
  11. data/lib/steep.rb +33 -0
  12. data/lib/steep/annotation.rb +223 -0
  13. data/lib/steep/cli.rb +79 -0
  14. data/lib/steep/drivers/check.rb +141 -0
  15. data/lib/steep/errors.rb +207 -0
  16. data/lib/steep/interface.rb +280 -0
  17. data/lib/steep/parser.y +311 -0
  18. data/lib/steep/signature/class.rb +358 -0
  19. data/lib/steep/signature/errors.rb +78 -0
  20. data/lib/steep/signature/extension.rb +51 -0
  21. data/lib/steep/signature/interface.rb +48 -0
  22. data/lib/steep/source.rb +98 -0
  23. data/lib/steep/type_assignability.rb +362 -0
  24. data/lib/steep/type_construction.rb +993 -0
  25. data/lib/steep/type_name.rb +37 -0
  26. data/lib/steep/types.rb +4 -0
  27. data/lib/steep/types/any.rb +31 -0
  28. data/lib/steep/types/class.rb +27 -0
  29. data/lib/steep/types/instance.rb +27 -0
  30. data/lib/steep/types/merge.rb +32 -0
  31. data/lib/steep/types/name.rb +57 -0
  32. data/lib/steep/types/union.rb +42 -0
  33. data/lib/steep/types/var.rb +38 -0
  34. data/lib/steep/typing.rb +70 -0
  35. data/lib/steep/version.rb +3 -0
  36. data/manual/annotations.md +144 -0
  37. data/sig/signature.rbi +54 -0
  38. data/sig/types.rbi +43 -0
  39. data/smoke/and/a.rb +9 -0
  40. data/smoke/array/a.rb +22 -0
  41. data/smoke/block/a.rb +12 -0
  42. data/smoke/block/a.rbi +4 -0
  43. data/smoke/case/a.rb +20 -0
  44. data/smoke/class/a.rb +31 -0
  45. data/smoke/class/a.rbi +9 -0
  46. data/smoke/class/b.rb +7 -0
  47. data/smoke/class/c.rb +10 -0
  48. data/smoke/const/a.rb +30 -0
  49. data/smoke/dstr/a.rb +6 -0
  50. data/smoke/extension/a.rb +11 -0
  51. data/smoke/extension/a.rbi +8 -0
  52. data/smoke/extension/b.rb +12 -0
  53. data/smoke/extension/c.rb +9 -0
  54. data/smoke/hello/hello.rb +13 -0
  55. data/smoke/hello/hello.rbi +7 -0
  56. data/smoke/if/a.rb +20 -0
  57. data/smoke/implements/a.rb +14 -0
  58. data/smoke/implements/a.rbi +6 -0
  59. data/smoke/literal/a.rb +16 -0
  60. data/smoke/map/a.rb +5 -0
  61. data/smoke/method/a.rb +26 -0
  62. data/smoke/method/a.rbi +0 -0
  63. data/smoke/module/a.rb +21 -0
  64. data/smoke/module/a.rbi +7 -0
  65. data/smoke/module/b.rb +8 -0
  66. data/smoke/self/a.rb +23 -0
  67. data/smoke/self/a.rbi +4 -0
  68. data/smoke/super/a.rb +34 -0
  69. data/smoke/super/a.rbi +10 -0
  70. data/smoke/yield/a.rb +18 -0
  71. data/stdlib/builtin.rbi +89 -0
  72. data/steep.gemspec +32 -0
  73. metadata +214 -0
@@ -0,0 +1,311 @@
1
+ class Steep::Parser
2
+
3
+ rule
4
+
5
+ target: type_METHOD method_type { result = val[1] }
6
+ | type_SIGNATURE signatures { result = val[1] }
7
+ | type_ANNOTATION annotation { result = val[1] }
8
+
9
+ method_type: type_params params block_opt ARROW return_type
10
+ { result = Interface::MethodType.new(type_params: val[0], params: val[1], block: val[2], return_type: val[4]) }
11
+
12
+ return_type: simple_type
13
+ | LPAREN union_seq RPAREN { result = Types::Union.new(types: val[1]) }
14
+
15
+ params: { result = Interface::Params.empty }
16
+ | LPAREN params0 RPAREN { result = val[1] }
17
+ | type { result = Interface::Params.empty.with(required: [val[0]]) }
18
+
19
+ params0: required_param { result = Interface::Params.empty.with(required: [val[0]]) }
20
+ | required_param COMMA params0 { result = val[2].with(required: [val[0]] + val[2].required) }
21
+ | params1 { result = val[0] }
22
+
23
+ params1: optional_param { result = Interface::Params.empty.with(optional: [val[0]]) }
24
+ | optional_param COMMA params1 { result = val[2].with(optional: [val[0]] + val[2].optional) }
25
+ | params2 { result = val[0] }
26
+
27
+ params2: rest_param { result = Interface::Params.empty.with(rest: val[0]) }
28
+ | rest_param COMMA params3 { result = val[2].with(rest: val[0]) }
29
+ | params3 { result = val[0] }
30
+
31
+ params3: required_keyword { result = Interface::Params.empty.with(required_keywords: val[0]) }
32
+ | optional_keyword { result = Interface::Params.empty.with(optional_keywords: val[0]) }
33
+ | required_keyword COMMA params3 { result = val[2].with(required_keywords: val[2].required_keywords.merge(val[0])) }
34
+ | optional_keyword COMMA params3 { result = val[2].with(optional_keywords: val[2].optional_keywords.merge(val[0])) }
35
+ | params4 { result = val[0] }
36
+
37
+ params4: { result = Interface::Params.empty }
38
+ | STAR2 type { result = Interface::Params.empty.with(rest_keywords: val[1]) }
39
+
40
+ required_param: type { result = val[0] }
41
+ optional_param: QUESTION type { result = val[1] }
42
+ rest_param: STAR type { result = val[1] }
43
+ required_keyword: keyword COLON type { result = { val[0] => val[2] } }
44
+ optional_keyword: QUESTION keyword COLON type { result = { val[1] => val[3] } }
45
+
46
+ block_opt: { result = nil }
47
+ | LBRACE RBRACE { result = Interface::Block.new(params: Interface::Params.empty.with(rest: Types::Any.new),
48
+ return_type: Types::Any.new) }
49
+ | LBRACE block_params ARROW type RBRACE { result = Interface::Block.new(params: val[1], return_type: val[3]) }
50
+
51
+ block_params: LPAREN block_params0 RPAREN { result = val[1] }
52
+ | { result = Interface::Params.empty.with(rest: Types::Any.new) }
53
+
54
+ block_params0: required_param { result = Interface::Params.empty.with(required: [val[0]]) }
55
+ | required_param COMMA block_params0 { result = val[2].with(required: [val[0]] + val[2].required) }
56
+ | block_params1 { result = val[0] }
57
+
58
+ block_params1: optional_param { result = Interface::Params.empty.with(optional: [val[0]]) }
59
+ | optional_param COMMA block_params1 { result = val[2].with(optional: [val[0]] + val[2].optional) }
60
+ | block_params2 { result = val[0] }
61
+
62
+ block_params2: { result = Interface::Params.empty }
63
+ | rest_param { result = Interface::Params.empty.with(rest: val[0]) }
64
+
65
+ simple_type: INTERFACE_NAME { result = Types::Name.interface(name: val[0]) }
66
+ | INTERFACE_NAME LT type_seq GT { result = Types::Name.interface(name: val[0], params: val[2]) }
67
+ | MODULE_NAME { result = Types::Name.instance(name: val[0])}
68
+ | MODULE_NAME LT type_seq GT { result = Types::Name.instance(name: val[0], params: val[2]) }
69
+ | CLASS_IDENT { result = Types::Name.module(name: val[0]) }
70
+ | ANY { result = Types::Any.new }
71
+ | TVAR { result = Types::Var.new(name: val[0]) }
72
+ | CLASS { result = Types::Class.new }
73
+ | MODULE { result = Types::Class.new }
74
+ | INSTANCE { result = Types::Instance.new }
75
+
76
+ type: simple_type
77
+ | union_seq { result = Types::Union.new(types: val[0]) }
78
+
79
+ type_seq: type { result = [val[0]] }
80
+ | type COMMA type_seq { result = [val[0]] + val[2] }
81
+
82
+ union_seq: simple_type BAR simple_type { result = [val[0], val[2]] }
83
+ | simple_type BAR union_seq { result = [val[0]] + val[2] }
84
+
85
+ keyword: IDENT
86
+ | MODULE_NAME
87
+ | INTERFACE_NAME
88
+ | ANY { result = :any }
89
+ | CLASS { result = :class }
90
+ | MODULE { result = :module }
91
+ | INSTANCE { result = :instance }
92
+
93
+ signatures: { result = [] }
94
+ | interface signatures { result = [val[0]] + val[1] }
95
+ | class_decl signatures { result = [val[0]] + val[1] }
96
+ | module_decl signatures { result = [val[0]] + val[1] }
97
+ | extension_decl signatures { result = [val[0]] + val[1] }
98
+
99
+ interface: INTERFACE interface_name type_params method_decls END { result = Signature::Interface.new(name: val[1], params: val[2], methods: val[3]) }
100
+ class_decl: CLASS class_name type_params super_opt class_members END { result = Signature::Class.new(name: val[1], params: val[2], super_class: val[3], members: val[4] )}
101
+ module_decl: MODULE class_name type_params self_type_opt class_members END { result = Signature::Module.new(name: val[1], params: val[2], self_type: val[3], members: val[4]) }
102
+ extension_decl: EXTENSION class_name LPAREN class_name RPAREN class_members END { result = Signature::Extension.new(module_name: val[1], extension_name: val[3], members: val[5]) }
103
+
104
+ self_type_opt: { result = nil }
105
+ | COLON type { result = val[1] }
106
+
107
+ interface_name: INTERFACE_NAME { result = val[0] }
108
+
109
+ class_name: MODULE_NAME { result = val[0] }
110
+
111
+ class_members: { result = [] }
112
+ | class_member class_members { result = [val[0]] + val[1] }
113
+
114
+ class_member: instance_method_member { result = val[0] }
115
+ | class_method_member { result = val[0] }
116
+ | class_instance_method_member { result = val[0] }
117
+ | include_member { result = val[0] }
118
+ | extend_member { result = val[0] }
119
+
120
+ instance_method_member: DEF method_name COLON method_type_union { result = Signature::Members::InstanceMethod.new(name: val[1], types: val[3]) }
121
+ class_method_member: DEF SELF DOT method_name COLON method_type_union { result = Signature::Members::ModuleMethod.new(name: val[3], types: val[5]) }
122
+ class_instance_method_member: DEF SELFQ DOT method_name COLON method_type_union { result = Signature::Members::ModuleInstanceMethod.new(name: val[3], types: val[5]) }
123
+ include_member: INCLUDE type { result = Signature::Members::Include.new(name: val[1]) }
124
+ extend_member: EXTEND type { result = Signature::Members::Extend.new(name: val[1]) }
125
+
126
+ super_opt: { result = nil }
127
+ | LTCOLON type { result = val[1] }
128
+
129
+ type_params: { result = [] }
130
+ | LT type_param_seq GT { result = val[1] }
131
+
132
+ type_param_seq: TVAR { result = [val[0]] }
133
+ | TVAR COMMA type_param_seq { result = [val[0]] + val[2] }
134
+
135
+ method_decls: { result = {} }
136
+ | method_decl method_decls { result = val[1].merge(val[0]) }
137
+
138
+ method_decl: DEF method_name COLON method_type_union { result = { val[1] => val[3] }}
139
+
140
+ method_type_union: method_type { result = [val[0]] }
141
+ | method_type BAR method_type_union { result = [val[0]] + val[2] }
142
+
143
+ method_name: IDENT
144
+ | MODULE_NAME
145
+ | INTERFACE_NAME
146
+ | ANY { result = :any }
147
+ | INTERFACE { result = :interface }
148
+ | END { result = :end }
149
+ | PLUS { result = :+ }
150
+ | CLASS { result = :class }
151
+ | MODULE { result = :module }
152
+ | INSTANCE { result = :instance }
153
+ | OPERATOR
154
+ | METHOD_NAME
155
+
156
+ annotation: AT_TYPE VAR subject COLON type { result = Annotation::VarType.new(var: val[2], type: val[4]) }
157
+ | AT_TYPE METHOD subject COLON method_type { result = Annotation::MethodType.new(method: val[2], type: val[4]) }
158
+ | AT_TYPE RETURN COLON type { result = Annotation::ReturnType.new(type: val[3]) }
159
+ | AT_TYPE BLOCK COLON type { result = Annotation::BlockType.new(type: val[3]) }
160
+ | AT_TYPE SELF COLON type { result = Annotation::SelfType.new(type: val[3]) }
161
+ | AT_TYPE CONST CONST_PATH COLON type { result = Annotation::ConstType.new(name: val[2], type: val[4]) }
162
+ | AT_TYPE CONST MODULE_NAME COLON type { result = Annotation::ConstType.new(name: val[2], type: val[4]) }
163
+ | AT_TYPE INSTANCE COLON type { result = Annotation::InstanceType.new(type: val[3]) }
164
+ | AT_TYPE MODULE COLON type { result = Annotation::ModuleType.new(type: val[3]) }
165
+ | AT_TYPE IVAR IVAR_NAME COLON type { result = Annotation::IvarType.new(name: val[2], type: val[4]) }
166
+ | AT_TYPE { raise "Invalid type annotation" }
167
+ | AT_IMPLEMENTS MODULE_NAME { result = Annotation::Implements.new(module_name: val[1]) }
168
+ | AT_DYNAMIC method_name { result = Annotation::Dynamic.new(name: val[1]) }
169
+
170
+ subject: IDENT { result = val[0] }
171
+
172
+ end
173
+
174
+ ---- inner
175
+
176
+ require "strscan"
177
+
178
+ attr_reader :input
179
+
180
+ def initialize(type, input)
181
+ super()
182
+ @type = type
183
+ @input = StringScanner.new(input)
184
+ end
185
+
186
+ def self.parse_method(input)
187
+ new(:METHOD, input).do_parse
188
+ end
189
+
190
+ def self.parse_signature(input)
191
+ new(:SIGNATURE, input).do_parse
192
+ end
193
+
194
+ def self.parse_annotation_opt(input)
195
+ new(:ANNOTATION, input).do_parse
196
+ rescue
197
+ nil
198
+ end
199
+
200
+ def next_token
201
+ if @type
202
+ type = @type
203
+ @type = nil
204
+ return [:"type_#{type}", nil]
205
+ end
206
+
207
+ case
208
+ when input.scan(/\s+/)
209
+ next_token
210
+ when input.scan(/#.*/)
211
+ next_token
212
+ when input.eos?
213
+ [false, false]
214
+ when input.scan(/->/)
215
+ [:ARROW, nil]
216
+ when input.scan(/\?/)
217
+ [:QUESTION, nil]
218
+ when input.scan(/\(/)
219
+ [:LPAREN, nil]
220
+ when input.scan(/\)/)
221
+ [:RPAREN, nil]
222
+ when input.scan(/{/)
223
+ [:LBRACE, nil]
224
+ when input.scan(/}/)
225
+ [:RBRACE, nil]
226
+ when input.scan(/,/)
227
+ [:COMMA, nil]
228
+ when input.scan(/[A-Z]\w*(::[A-Z]\w*)+/)
229
+ [:CONST_PATH, input.matched.to_sym]
230
+ when input.scan(/::[A-Z]\w*(::[A-Z]\w*)*/)
231
+ [:CONST_PATH, input.matched.to_sym]
232
+ when input.scan(/:/)
233
+ [:COLON, nil]
234
+ when input.scan(/\*\*/)
235
+ [:STAR2, nil]
236
+ when input.scan(/\*/)
237
+ [:STAR, nil]
238
+ when input.scan(/\+/)
239
+ [:PLUS, nil]
240
+ when input.scan(/\./)
241
+ [:DOT, nil]
242
+ when input.scan(/<:/)
243
+ [:LTCOLON, nil]
244
+ when input.scan(/(\[\]=)|(\[\])|===|==|\^|!=|<<|>>/)
245
+ [:OPERATOR, input.matched.to_sym]
246
+ when input.scan(/</)
247
+ [:LT, nil]
248
+ when input.scan(/>/)
249
+ [:GT, nil]
250
+ when input.scan(/any\b/)
251
+ [:ANY, nil]
252
+ when input.scan(/interface\b/)
253
+ [:INTERFACE, nil]
254
+ when input.scan(/end\b/)
255
+ [:END, nil]
256
+ when input.scan(/\|/)
257
+ [:BAR, nil]
258
+ when input.scan(/def\b/)
259
+ [:DEF, nil]
260
+ when input.scan(/@type\b/)
261
+ [:AT_TYPE, nil]
262
+ when input.scan(/@implements\b/)
263
+ [:AT_IMPLEMENTS, nil]
264
+ when input.scan(/@dynamic\b/)
265
+ [:AT_DYNAMIC, nil]
266
+ when input.scan(/const\b/)
267
+ [:CONST, nil]
268
+ when input.scan(/var\b/)
269
+ [:VAR, nil]
270
+ when input.scan(/return\b/)
271
+ [:RETURN, nil]
272
+ when input.scan(/block\b/)
273
+ [:BLOCK, nil]
274
+ when input.scan(/method\b/)
275
+ [:METHOD, nil]
276
+ when input.scan(/self\?/)
277
+ [:SELFQ, nil]
278
+ when input.scan(/self\b/)
279
+ [:SELF, nil]
280
+ when input.scan(/'\w+/)
281
+ [:TVAR, input.matched.gsub(/\A'/, '').to_sym]
282
+ when input.scan(/instance\b/)
283
+ [:INSTANCE, nil]
284
+ when input.scan(/class\b/)
285
+ [:CLASS, nil]
286
+ when input.scan(/module\b/)
287
+ [:MODULE, nil]
288
+ when input.scan(/include\b/)
289
+ [:INCLUDE, nil]
290
+ when input.scan(/extend\b/)
291
+ [:EXTEND, nil]
292
+ when input.scan(/instance\b/)
293
+ [:INSTANCE, nil]
294
+ when input.scan(/ivar\b/)
295
+ [:IVAR, nil]
296
+ when input.scan(/extension\b/)
297
+ [:EXTENSION, nil]
298
+ when input.scan(/[A-Z]\w*\.(class|module)\b/)
299
+ [:CLASS_IDENT, input.matched.gsub(/\.(class|module)$/, '').to_sym]
300
+ when input.scan(/\w+(\!|\?)/)
301
+ [:METHOD_NAME, input.matched.to_sym]
302
+ when input.scan(/[A-Z]\w*/)
303
+ [:MODULE_NAME, input.matched.to_sym]
304
+ when input.scan(/_\w+/)
305
+ [:INTERFACE_NAME, input.matched.to_sym]
306
+ when input.scan(/@[\w_]+/)
307
+ [:IVAR_NAME, input.matched.to_sym]
308
+ when input.scan(/\w+/)
309
+ [:IDENT, input.matched.to_sym]
310
+ end
311
+ end
@@ -0,0 +1,358 @@
1
+ module Steep
2
+ module Signature
3
+ module Members
4
+ class InstanceMethod
5
+ attr_reader :name
6
+ attr_reader :types
7
+
8
+ def initialize(name:, types:)
9
+ @name = name
10
+ @types = types
11
+ end
12
+
13
+ def ==(other)
14
+ other.is_a?(InstanceMethod) && other.name == name && other.types == types
15
+ end
16
+ end
17
+
18
+ class ModuleMethod
19
+ attr_reader :name
20
+ attr_reader :types
21
+
22
+ def initialize(name:, types:)
23
+ @name = name
24
+ @types = types
25
+ end
26
+
27
+ def ==(other)
28
+ other.is_a?(ModuleMethod) && other.name == name && other.types == types
29
+ end
30
+ end
31
+
32
+ class ModuleInstanceMethod
33
+ attr_reader :name
34
+ attr_reader :types
35
+
36
+ def initialize(name:, types:)
37
+ @name = name
38
+ @types = types
39
+ end
40
+
41
+ def ==(other)
42
+ other.is_a?(ModuleInstanceMethod) && other.name == name && other.types == types
43
+ end
44
+ end
45
+
46
+ class Include
47
+ attr_reader :name
48
+
49
+ def initialize(name:)
50
+ @name = name
51
+ end
52
+
53
+ def ==(other)
54
+ other.is_a?(Include) && other.name == name
55
+ end
56
+ end
57
+
58
+ class Extend
59
+ attr_reader :name
60
+
61
+ def initialize(name:)
62
+ @name = name
63
+ end
64
+
65
+ def ==(other)
66
+ other.is_a?(Extend) && other.name == name
67
+ end
68
+ end
69
+ end
70
+
71
+ module WithMethods
72
+ def instance_methods(assignability:, klass:, instance:, params:)
73
+ methods = super
74
+
75
+ hash = type_application_hash(params)
76
+
77
+ members.each do |member|
78
+ case member
79
+ when Members::Include
80
+ module_signature = assignability.lookup_included_signature(member.name)
81
+ merge_methods(methods, module_signature.instance_methods(assignability: assignability,
82
+ klass: klass,
83
+ instance: instance,
84
+ params: module_signature.type_application_hash(member.name.params)))
85
+ end
86
+ end
87
+
88
+ members.each do |member|
89
+ case member
90
+ when Members::InstanceMethod, Members::ModuleInstanceMethod
91
+ method_types = member.types.map {|type| type.substitute(klass: klass, instance: instance, params: hash) }
92
+ merge_methods(methods, member.name => Steep::Interface::Method.new(types: method_types, super_method: nil))
93
+ end
94
+ end
95
+
96
+ extensions = assignability.lookup_extensions(name)
97
+ extensions.each do |extension|
98
+ extension_methods = extension.instance_methods(assignability: assignability, klass: klass, instance: instance, params: [])
99
+ merge_methods(methods, extension_methods)
100
+ end
101
+
102
+ methods
103
+ end
104
+
105
+ def module_methods(assignability:, klass:, instance:, params:)
106
+ methods = super
107
+
108
+ members.each do |member|
109
+ case member
110
+ when Members::Include
111
+ module_signature = assignability.lookup_included_signature(member.name)
112
+ merge_methods(methods, module_signature.module_methods(assignability: assignability,
113
+ klass: klass,
114
+ instance: instance,
115
+ params: module_signature.type_application_hash(member.name.params)))
116
+ when Members::Extend
117
+ module_signature = assignability.lookup_included_signature(member.name)
118
+ merge_methods(methods, module_signature.instance_methods(assignability: assignability,
119
+ klass: klass,
120
+ instance: instance,
121
+ params: module_signature.type_application_hash(member.name.params)))
122
+ end
123
+ end
124
+
125
+ members.each do |member|
126
+ case member
127
+ when Members::ModuleInstanceMethod, Members::ModuleMethod
128
+ method_types = member.types.map {|type| type.substitute(klass: klass, instance: instance, params: {}) }
129
+ merge_methods(methods, member.name => Steep::Interface::Method.new(types: method_types, super_method: nil))
130
+ end
131
+ end
132
+
133
+ if self.is_a?(Class)
134
+ instance_methods = instance_methods(assignability: assignability, klass: klass, instance: instance, params: params)
135
+ new_method = if instance_methods[:initialize]
136
+ types = instance_methods[:initialize].types.map do |method_type|
137
+ method_type.updated(return_type: instance)
138
+ end
139
+ Steep::Interface::Method.new(types: types, super_method: nil)
140
+ else
141
+ Steep::Interface::Method.new(types: [Steep::Interface::MethodType.new(type_params: [],
142
+ params: Steep::Interface::Params.empty,
143
+ block: nil,
144
+ return_type: instance)],
145
+ super_method: nil)
146
+ end
147
+ methods[:new] = new_method
148
+ end
149
+
150
+ methods
151
+ end
152
+
153
+ def merge_methods(methods, hash)
154
+ hash.each_key do |name|
155
+ method = hash[name]
156
+
157
+ methods[name] = Steep::Interface::Method.new(types: method.types,
158
+ super_method: methods[name])
159
+ end
160
+ end
161
+ end
162
+
163
+ module WithMembers
164
+ def each_type
165
+ if block_given?
166
+ members.each do |member|
167
+ case member
168
+ when Members::InstanceMethod, Members::ModuleMethod, Members::ModuleInstanceMethod
169
+ member.types.each do |method_type|
170
+ method_type.params.each_type do |type|
171
+ yield type
172
+ end
173
+ yield method_type.return_type
174
+ if method_type.block
175
+ method_type.block.params.each_type do |type|
176
+ yield type
177
+ end
178
+ yield method_type.block.return_type
179
+ end
180
+ end
181
+ when Members::Include, Members::Extend
182
+ yield member.name
183
+ else
184
+ raise "Unknown member: #{member.class.inspect}"
185
+ end
186
+ end
187
+ else
188
+ enum_for :each_type
189
+ end
190
+ end
191
+
192
+ def validate_mixins(assignability, interface)
193
+ members.each do |member|
194
+ if member.is_a?(Members::Include)
195
+ module_signature = assignability.lookup_included_signature(member.name)
196
+
197
+ if module_signature.self_type
198
+ self_type = module_signature.self_type.substitute(klass: Types::Name.module(name: name),
199
+ instance: Types::Name.instance(name: name),
200
+ params: {})
201
+ self_interface = assignability.resolve_interface(self_type.name, member.name.params)
202
+
203
+ unless assignability.test_interface(interface, self_interface, [])
204
+ assignability.errors << Errors::InvalidSelfType.new(signature: self, member: member)
205
+ end
206
+ end
207
+ end
208
+ end
209
+ end
210
+ end
211
+
212
+ module WithParams
213
+ def type_application_hash(args)
214
+ Hash[params.zip(args)]
215
+ end
216
+ end
217
+
218
+ class Module
219
+ attr_reader :name
220
+ attr_reader :params
221
+ attr_reader :members
222
+ attr_reader :self_type
223
+
224
+ prepend WithMethods
225
+ include WithMembers
226
+ include WithParams
227
+
228
+ def initialize(name:, params:, members:, self_type:)
229
+ @name = name
230
+ @members = members
231
+ @params = params
232
+ @self_type = self_type
233
+ end
234
+
235
+ def ==(other)
236
+ other.is_a?(Module) && other.name == name && other.params == params && other.members == members && other.self_type == self_type
237
+ end
238
+
239
+ def instance_methods(assignability:, klass:, instance:, params:)
240
+ {}
241
+ end
242
+
243
+ def module_methods(assignability:, klass:, instance:, params:)
244
+ {}
245
+ end
246
+
247
+ def each_type
248
+ if block_given?
249
+ yield self_type if self_type
250
+ super do |type|
251
+ yield type
252
+ end
253
+ else
254
+ enum_for :each_type
255
+ end
256
+ end
257
+
258
+ def validate(assignability)
259
+ each_type do |type|
260
+ assignability.validate_type_presence self, type
261
+ end
262
+
263
+ interface = assignability.resolve_interface(TypeName::Instance.new(name: name),
264
+ params.map {|x| Types::Var.new(name: x) })
265
+
266
+ validate_mixins(assignability, interface)
267
+ end
268
+ end
269
+
270
+ class Class
271
+ attr_reader :name
272
+ attr_reader :params
273
+ attr_reader :members
274
+ attr_reader :super_class
275
+
276
+ prepend WithMethods
277
+ include WithMembers
278
+ include WithParams
279
+
280
+ def initialize(name:, params:, members:, super_class:)
281
+ @name = name
282
+ @members = members
283
+ @params = params
284
+ @super_class = super_class
285
+ end
286
+
287
+ def ==(other)
288
+ other.is_a?(Class) && other.name == name && other.params == params && other.members == members && other.super_class == super_class
289
+ end
290
+
291
+ def instance_methods(assignability:, klass:, instance:, params:)
292
+ if self.name == :BasicObject
293
+ {}
294
+ else
295
+ super_class = self.super_class || Types::Name.instance(name: :Object)
296
+ signature = assignability.lookup_super_class_signature(super_class)
297
+
298
+ hash = type_application_hash(params)
299
+ super_class_params = super_class.params.map do |type|
300
+ type.substitute(klass: klass, instance: instance, params: hash)
301
+ end
302
+
303
+ signature.instance_methods(assignability: assignability, klass: klass, instance: instance, params: super_class_params)
304
+ end
305
+ end
306
+
307
+ def module_methods(assignability:, klass:, instance:, params:)
308
+ signature = assignability.lookup_class_signature(Types::Name.instance(name: :Class))
309
+ class_methods = signature.instance_methods(assignability: assignability,
310
+ klass: klass,
311
+ instance: instance,
312
+ params: [instance])
313
+ if self.name == :BasicObject
314
+ class_methods
315
+ else
316
+ super_class = self.super_class || Types::Name.instance(name: :Object)
317
+ signature = assignability.lookup_super_class_signature(super_class)
318
+
319
+ hash = type_application_hash(params)
320
+ super_class_params = super_class.params.map do |type|
321
+ type.substitute(klass: klass, instance: instance, params: hash)
322
+ end
323
+
324
+ class_methods.merge!(signature.module_methods(assignability: assignability, klass: klass, instance: instance, params: super_class_params))
325
+ end
326
+ end
327
+
328
+ def each_type
329
+ if block_given?
330
+ yield super_class if super_class
331
+ super do |type|
332
+ yield type
333
+ end
334
+ else
335
+ enum_for :each_type
336
+ end
337
+ end
338
+
339
+ def validate(assignability)
340
+ each_type do |type|
341
+ assignability.validate_type_presence self, type
342
+ end
343
+
344
+ interface = assignability.resolve_interface(TypeName::Instance.new(name: name),
345
+ params.map {|x| Types::Var.new(name: x) })
346
+
347
+ interface.methods.each_key do |method_name|
348
+ method = interface.methods[method_name]
349
+ if method.super_method
350
+ assignability.validate_method_compatibility(self, method_name, method)
351
+ end
352
+ end
353
+
354
+ validate_mixins(assignability, interface)
355
+ end
356
+ end
357
+ end
358
+ end