steep 0.39.0 → 0.40.0
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/ruby.yml +1 -1
- data/CHANGELOG.md +6 -0
- data/Rakefile +5 -2
- data/bin/output_rebaseline.rb +49 -0
- data/bin/output_test.rb +93 -0
- data/lib/steep.rb +8 -3
- data/lib/steep/cli.rb +1 -1
- data/lib/steep/diagnostic/helper.rb +17 -0
- data/lib/steep/diagnostic/lsp_formatter.rb +16 -0
- data/lib/steep/diagnostic/ruby.rb +623 -0
- data/lib/steep/diagnostic/signature.rb +224 -0
- data/lib/steep/drivers/annotations.rb +13 -6
- data/lib/steep/drivers/check.rb +83 -60
- data/lib/steep/drivers/diagnostic_printer.rb +94 -0
- data/lib/steep/drivers/stats.rb +125 -29
- data/lib/steep/drivers/trace_printer.rb +5 -1
- data/lib/steep/drivers/validate.rb +13 -6
- data/lib/steep/drivers/watch.rb +26 -9
- data/lib/steep/drivers/worker.rb +5 -0
- data/lib/steep/project/options.rb +4 -4
- data/lib/steep/project/signature_file.rb +8 -2
- data/lib/steep/project/stats_calculator.rb +80 -0
- data/lib/steep/project/target.rb +64 -53
- data/lib/steep/range_extension.rb +29 -0
- data/lib/steep/server/base_worker.rb +42 -4
- data/lib/steep/server/code_worker.rb +37 -24
- data/lib/steep/server/interaction_worker.rb +1 -0
- data/lib/steep/server/master.rb +268 -82
- data/lib/steep/server/signature_worker.rb +7 -59
- data/lib/steep/server/worker_process.rb +9 -9
- data/lib/steep/signature/validator.rb +33 -9
- data/lib/steep/type_construction.rb +276 -194
- data/lib/steep/version.rb +1 -1
- data/smoke/alias/a.rb +0 -3
- data/smoke/alias/b.rb +0 -1
- data/smoke/alias/c.rb +0 -2
- data/smoke/alias/test.yaml +73 -0
- data/smoke/and/a.rb +0 -3
- data/smoke/and/test.yaml +24 -0
- data/smoke/array/a.rb +0 -3
- data/smoke/array/b.rb +0 -2
- data/smoke/array/c.rb +0 -1
- data/smoke/array/test.yaml +80 -0
- data/smoke/block/a.rb +0 -2
- data/smoke/block/b.rb +0 -2
- data/smoke/block/d.rb +0 -4
- data/smoke/block/test.yaml +96 -0
- data/smoke/broken/Steepfile +5 -0
- data/smoke/broken/broken.rb +0 -0
- data/smoke/broken/broken.rbs +0 -0
- data/smoke/broken/test.yaml +6 -0
- data/smoke/case/a.rb +0 -3
- data/smoke/case/test.yaml +36 -0
- data/smoke/class/a.rb +0 -3
- data/smoke/class/c.rb +0 -1
- data/smoke/class/f.rb +0 -1
- data/smoke/class/g.rb +0 -2
- data/smoke/class/i.rb +0 -2
- data/smoke/class/test.yaml +89 -0
- data/smoke/const/a.rb +0 -3
- data/smoke/const/b.rb +7 -0
- data/smoke/const/b.rbs +5 -0
- data/smoke/const/test.yaml +96 -0
- data/smoke/diagnostics-rbs-duplicated/Steepfile +5 -0
- data/smoke/diagnostics-rbs-duplicated/a.rbs +5 -0
- data/smoke/diagnostics-rbs-duplicated/test.yaml +10 -0
- data/smoke/diagnostics-rbs/Steepfile +5 -0
- data/smoke/diagnostics-rbs/duplicated-method-definition.rbs +20 -0
- data/smoke/diagnostics-rbs/generic-parameter-mismatch.rbs +7 -0
- data/smoke/diagnostics-rbs/invalid-method-overload.rbs +3 -0
- data/smoke/diagnostics-rbs/invalid-type-application.rbs +7 -0
- data/smoke/diagnostics-rbs/invalid_variance_annotation.rbs +3 -0
- data/smoke/diagnostics-rbs/recursive-alias.rbs +5 -0
- data/smoke/diagnostics-rbs/recursive-class.rbs +8 -0
- data/smoke/diagnostics-rbs/superclass-mismatch.rbs +7 -0
- data/smoke/diagnostics-rbs/test.yaml +142 -0
- data/smoke/diagnostics-rbs/unknown-method-alias.rbs +3 -0
- data/smoke/diagnostics-rbs/unknown-type-name.rbs +13 -0
- data/smoke/diagnostics/Steepfile +5 -0
- data/smoke/diagnostics/a.rbs +26 -0
- data/smoke/diagnostics/argument_type_mismatch.rb +1 -0
- data/smoke/diagnostics/block_body_type_mismatch.rb +1 -0
- data/smoke/diagnostics/block_type_mismatch.rb +3 -0
- data/smoke/diagnostics/break_type_mismatch.rb +1 -0
- data/smoke/diagnostics/else_on_exhaustive_case.rb +12 -0
- data/smoke/diagnostics/incompatible_annotation.rb +6 -0
- data/smoke/diagnostics/incompatible_argument.rb +1 -0
- data/smoke/diagnostics/incompatible_assignment.rb +8 -0
- data/smoke/diagnostics/method_arity_mismatch.rb +11 -0
- data/smoke/diagnostics/method_body_type_mismatch.rb +6 -0
- data/smoke/diagnostics/method_definition_missing.rb +2 -0
- data/smoke/diagnostics/method_return_type_annotation_mismatch.rb +7 -0
- data/smoke/diagnostics/missing_keyword.rb +1 -0
- data/smoke/diagnostics/no_method.rb +1 -0
- data/smoke/diagnostics/required_block_missing.rb +1 -0
- data/smoke/diagnostics/return_type_mismatch.rb +6 -0
- data/smoke/diagnostics/test.yaml +333 -0
- data/smoke/diagnostics/unexpected_block_given.rb +1 -0
- data/smoke/diagnostics/unexpected_dynamic_method.rb +3 -0
- data/smoke/diagnostics/unexpected_jump.rb +4 -0
- data/smoke/diagnostics/unexpected_jump_value.rb +3 -0
- data/smoke/diagnostics/unexpected_keyword.rb +1 -0
- data/smoke/diagnostics/unexpected_splat.rb +1 -0
- data/smoke/diagnostics/unexpected_yield.rb +6 -0
- data/smoke/diagnostics/unknown_constant_assigned.rb +7 -0
- data/smoke/diagnostics/unresolved_overloading.rb +1 -0
- data/smoke/diagnostics/unsatisfiable_constraint.rb +7 -0
- data/smoke/diagnostics/unsupported_syntax.rb +2 -0
- data/smoke/dstr/a.rb +0 -1
- data/smoke/dstr/test.yaml +10 -0
- data/smoke/ensure/a.rb +0 -4
- data/smoke/ensure/test.yaml +47 -0
- data/smoke/enumerator/a.rb +0 -6
- data/smoke/enumerator/b.rb +0 -3
- data/smoke/enumerator/test.yaml +100 -0
- data/smoke/extension/a.rb +0 -1
- data/smoke/extension/b.rb +0 -2
- data/smoke/extension/c.rb +0 -1
- data/smoke/extension/test.yaml +50 -0
- data/smoke/hash/b.rb +0 -1
- data/smoke/hash/c.rb +0 -3
- data/smoke/hash/d.rb +0 -1
- data/smoke/hash/e.rb +0 -1
- data/smoke/hash/test.yaml +62 -0
- data/smoke/hello/hello.rb +0 -2
- data/smoke/hello/test.yaml +18 -0
- data/smoke/if/a.rb +0 -2
- data/smoke/if/test.yaml +27 -0
- data/smoke/implements/a.rb +0 -2
- data/smoke/implements/test.yaml +16 -0
- data/smoke/initialize/test.yaml +4 -0
- data/smoke/integer/a.rb +0 -7
- data/smoke/integer/test.yaml +66 -0
- data/smoke/interface/a.rb +0 -2
- data/smoke/interface/test.yaml +16 -0
- data/smoke/kwbegin/a.rb +0 -1
- data/smoke/kwbegin/test.yaml +14 -0
- data/smoke/lambda/a.rb +1 -4
- data/smoke/lambda/test.yaml +28 -0
- data/smoke/literal/a.rb +0 -5
- data/smoke/literal/b.rb +0 -2
- data/smoke/literal/test.yaml +79 -0
- data/smoke/map/test.yaml +4 -0
- data/smoke/method/a.rb +0 -5
- data/smoke/method/b.rb +0 -1
- data/smoke/method/test.yaml +71 -0
- data/smoke/module/a.rb +0 -2
- data/smoke/module/b.rb +0 -2
- data/smoke/module/c.rb +0 -1
- data/smoke/module/d.rb +0 -1
- data/smoke/module/f.rb +0 -2
- data/smoke/module/test.yaml +51 -0
- data/smoke/regexp/a.rb +0 -38
- data/smoke/regexp/b.rb +0 -26
- data/smoke/regexp/test.yaml +372 -0
- data/smoke/regression/set_divide.rb +0 -4
- data/smoke/regression/test.yaml +38 -0
- data/smoke/rescue/a.rb +0 -5
- data/smoke/rescue/test.yaml +60 -0
- data/smoke/self/a.rb +0 -2
- data/smoke/self/test.yaml +16 -0
- data/smoke/skip/skip.rb +0 -2
- data/smoke/skip/test.yaml +16 -0
- data/smoke/stdout/test.yaml +4 -0
- data/smoke/super/a.rb +0 -4
- data/smoke/super/test.yaml +52 -0
- data/smoke/toplevel/a.rb +0 -1
- data/smoke/toplevel/test.yaml +12 -0
- data/smoke/tsort/a.rb +0 -3
- data/smoke/tsort/test.yaml +32 -0
- data/smoke/type_case/a.rb +0 -4
- data/smoke/type_case/test.yaml +33 -0
- data/smoke/yield/a.rb +0 -3
- data/smoke/yield/b.rb +6 -0
- data/smoke/yield/test.yaml +49 -0
- data/steep.gemspec +3 -3
- metadata +108 -17
- data/bin/smoke_runner.rb +0 -139
- data/lib/steep/drivers/signature_error_printer.rb +0 -25
- data/lib/steep/errors.rb +0 -594
- data/lib/steep/signature/errors.rb +0 -128
- data/lib/steep/type_assignability.rb +0 -367
@@ -1,128 +0,0 @@
|
|
1
|
-
module Steep
|
2
|
-
module Signature
|
3
|
-
module Errors
|
4
|
-
class Base
|
5
|
-
attr_reader :location
|
6
|
-
|
7
|
-
def loc_to_s
|
8
|
-
RBS::Location.to_string location
|
9
|
-
end
|
10
|
-
|
11
|
-
def to_s
|
12
|
-
StringIO.new.tap do |io|
|
13
|
-
puts io
|
14
|
-
end.string
|
15
|
-
end
|
16
|
-
|
17
|
-
def path
|
18
|
-
location.buffer.name
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
class DuplicatedDeclarationError < Base
|
23
|
-
attr_reader :type_name
|
24
|
-
|
25
|
-
def initialize(type_name:, location:)
|
26
|
-
@type_name = type_name
|
27
|
-
@location = location
|
28
|
-
end
|
29
|
-
|
30
|
-
def puts(io)
|
31
|
-
io.puts "#{loc_to_s}\sDuplicatedDeclarationError: name=#{type_name}"
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
class UnknownTypeNameError < Base
|
36
|
-
attr_reader :name
|
37
|
-
|
38
|
-
def initialize(name:, location:)
|
39
|
-
@name = name
|
40
|
-
@location = location
|
41
|
-
end
|
42
|
-
|
43
|
-
def puts(io)
|
44
|
-
io.puts "#{loc_to_s}\tUnknownTypeNameError: name=#{name}"
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
class InvalidTypeApplicationError < Base
|
49
|
-
attr_reader :name
|
50
|
-
attr_reader :args
|
51
|
-
attr_reader :params
|
52
|
-
|
53
|
-
def initialize(name:, args:, params:, location:)
|
54
|
-
@name = name
|
55
|
-
@args = args
|
56
|
-
@params = params
|
57
|
-
@location = location
|
58
|
-
end
|
59
|
-
|
60
|
-
def puts(io)
|
61
|
-
io.puts "#{loc_to_s}\tInvalidTypeApplicationError: name=#{name}, expected=[#{params.join(", ")}], actual=[#{args.join(", ")}]"
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
class InvalidMethodOverloadError < Base
|
66
|
-
attr_reader :class_name
|
67
|
-
attr_reader :method_name
|
68
|
-
|
69
|
-
def initialize(class_name:, method_name:, location:)
|
70
|
-
@class_name = class_name
|
71
|
-
@method_name = method_name
|
72
|
-
@location = location
|
73
|
-
end
|
74
|
-
|
75
|
-
def puts(io)
|
76
|
-
io.puts "#{loc_to_s}\tInvalidMethodOverloadError: class_name=#{class_name}, method_name=#{method_name}"
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
class UnknownMethodAliasError < Base
|
81
|
-
attr_reader :class_name
|
82
|
-
attr_reader :method_name
|
83
|
-
|
84
|
-
def initialize(class_name:, method_name:, location:)
|
85
|
-
@class_name = class_name
|
86
|
-
@method_name = method_name
|
87
|
-
@location = location
|
88
|
-
end
|
89
|
-
|
90
|
-
def puts(io)
|
91
|
-
io.puts "#{loc_to_s}\tUnknownMethodAliasError: class_name=#{class_name}, method_name=#{method_name}"
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
class DuplicatedMethodDefinitionError < Base
|
96
|
-
attr_reader :class_name
|
97
|
-
attr_reader :method_name
|
98
|
-
|
99
|
-
def initialize(class_name:, method_name:, location:)
|
100
|
-
@class_name = class_name
|
101
|
-
@method_name = method_name
|
102
|
-
@location = location
|
103
|
-
end
|
104
|
-
|
105
|
-
def puts(io)
|
106
|
-
io.puts "#{loc_to_s}\tDuplicatedMethodDefinitionError: class_name=#{class_name}, method_name=#{method_name}"
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
class RecursiveAliasError < Base
|
111
|
-
attr_reader :class_name
|
112
|
-
attr_reader :names
|
113
|
-
attr_reader :location
|
114
|
-
|
115
|
-
def initialize(class_name:, names:, location:)
|
116
|
-
@class_name = class_name
|
117
|
-
@names = names
|
118
|
-
@location = location
|
119
|
-
end
|
120
|
-
|
121
|
-
def puts(io)
|
122
|
-
io.puts "#{loc_to_s}\tRecursiveAliasError: class_name=#{class_name}, names=#{names.join(", ")}"
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
@@ -1,367 +0,0 @@
|
|
1
|
-
module Steep
|
2
|
-
class TypeAssignability
|
3
|
-
attr_reader :signatures
|
4
|
-
attr_reader :errors
|
5
|
-
|
6
|
-
def initialize()
|
7
|
-
@signatures = {}
|
8
|
-
@klasses = []
|
9
|
-
@instances = []
|
10
|
-
@errors = []
|
11
|
-
|
12
|
-
if block_given?
|
13
|
-
yield self
|
14
|
-
validate
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def with(klass: nil, instance: nil, &block)
|
19
|
-
@klasses.push(klass) if klass
|
20
|
-
@instances.push(instance) if instance
|
21
|
-
yield
|
22
|
-
ensure
|
23
|
-
@klasses.pop if klass
|
24
|
-
@instances.pop if instance
|
25
|
-
end
|
26
|
-
|
27
|
-
def klass
|
28
|
-
@klasses.last
|
29
|
-
end
|
30
|
-
|
31
|
-
def instance
|
32
|
-
@instances.last
|
33
|
-
end
|
34
|
-
|
35
|
-
def add_signature(signature)
|
36
|
-
raise "Signature Duplicated: #{signature.name}" if signatures.key?(signature.name)
|
37
|
-
signatures[signature.name] = signature
|
38
|
-
end
|
39
|
-
|
40
|
-
def test(src:, dest:, known_pairs: [])
|
41
|
-
case
|
42
|
-
when src.is_a?(Types::Any) || dest.is_a?(Types::Any)
|
43
|
-
true
|
44
|
-
when src == dest
|
45
|
-
true
|
46
|
-
when src.is_a?(Types::Union)
|
47
|
-
src.types.all? do |type|
|
48
|
-
test(src: type, dest: dest, known_pairs: known_pairs)
|
49
|
-
end
|
50
|
-
when dest.is_a?(Types::Union)
|
51
|
-
dest.types.any? do |type|
|
52
|
-
test(src: src, dest: type, known_pairs: known_pairs)
|
53
|
-
end
|
54
|
-
when src.is_a?(Types::Var) || dest.is_a?(Types::Var)
|
55
|
-
known_pairs.include?([src, dest])
|
56
|
-
when src.is_a?(Types::Name) && dest.is_a?(Types::Name)
|
57
|
-
test_interface(resolve_interface(src.name, src.params), resolve_interface(dest.name, dest.params), known_pairs)
|
58
|
-
else
|
59
|
-
raise "Unexpected type: src=#{src.inspect}, dest=#{dest.inspect}, known_pairs=#{known_pairs.inspect}"
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def test_application(params:, argument:, index:)
|
64
|
-
param_type = params.flat_unnamed_params[index]&.last
|
65
|
-
if param_type
|
66
|
-
unless test(src: argument, dest: param_type)
|
67
|
-
yield param_type
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
def test_interface(src, dest, known_pairs)
|
73
|
-
if src == dest
|
74
|
-
return true
|
75
|
-
end
|
76
|
-
|
77
|
-
if known_pairs.include?([src, dest])
|
78
|
-
return true
|
79
|
-
end
|
80
|
-
|
81
|
-
pairs = known_pairs + [[src, dest]]
|
82
|
-
|
83
|
-
dest.methods.all? do |name, dest_methods|
|
84
|
-
if src.methods.key?(name)
|
85
|
-
src_methods = src.methods[name]
|
86
|
-
|
87
|
-
dest_methods.types.all? do |dest_method|
|
88
|
-
src_methods.types.any? do |src_method|
|
89
|
-
test_method(src_method, dest_method, pairs)
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
def test_method(src, dest, known_pairs)
|
97
|
-
test_params(src.params, dest.params, known_pairs) &&
|
98
|
-
test_block(src.block, dest.block, known_pairs) &&
|
99
|
-
test(src: src.return_type, dest: dest.return_type, known_pairs: known_pairs)
|
100
|
-
end
|
101
|
-
|
102
|
-
def test_params(src, dest, known_pairs)
|
103
|
-
assigning_pairs = []
|
104
|
-
|
105
|
-
src_flat = src.flat_unnamed_params
|
106
|
-
dest_flat = dest.flat_unnamed_params
|
107
|
-
|
108
|
-
case
|
109
|
-
when dest.rest
|
110
|
-
return false unless src.rest
|
111
|
-
|
112
|
-
while src_flat.size > 0
|
113
|
-
src_type = src_flat.shift
|
114
|
-
dest_type = dest_flat.shift
|
115
|
-
|
116
|
-
if dest_type
|
117
|
-
assigning_pairs << [src_type.last, dest_type.last]
|
118
|
-
else
|
119
|
-
assigning_pairs << [src_type.last, dest.rest]
|
120
|
-
end
|
121
|
-
end
|
122
|
-
|
123
|
-
if src.rest
|
124
|
-
assigning_pairs << [src.rest, dest.rest]
|
125
|
-
end
|
126
|
-
when src.rest
|
127
|
-
while src_flat.size > 0
|
128
|
-
src_type = src_flat.shift
|
129
|
-
dest_type = dest_flat.shift
|
130
|
-
|
131
|
-
if dest_type
|
132
|
-
assigning_pairs << [src_type.last, dest_type.last]
|
133
|
-
else
|
134
|
-
break
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
if src.rest && !dest_flat.empty?
|
139
|
-
dest_flat.each do |dest_type|
|
140
|
-
assigning_pairs << [src.rest, dest_type.last]
|
141
|
-
end
|
142
|
-
end
|
143
|
-
when src.required.size + src.optional.size >= dest.required.size + dest.optional.size
|
144
|
-
while src_flat.size > 0
|
145
|
-
src_type = src_flat.shift
|
146
|
-
dest_type = dest_flat.shift
|
147
|
-
|
148
|
-
if dest_type
|
149
|
-
assigning_pairs << [src_type.last, dest_type.last]
|
150
|
-
else
|
151
|
-
if src_type.first == :required
|
152
|
-
return false
|
153
|
-
else
|
154
|
-
break
|
155
|
-
end
|
156
|
-
end
|
157
|
-
end
|
158
|
-
else
|
159
|
-
return false
|
160
|
-
end
|
161
|
-
|
162
|
-
src_flat_kws = src.flat_keywords
|
163
|
-
dest_flat_kws = dest.flat_keywords
|
164
|
-
|
165
|
-
dest_flat_kws.each do |name, _|
|
166
|
-
if src_flat_kws.key?(name)
|
167
|
-
assigning_pairs << [src_flat_kws[name], dest_flat_kws[name]]
|
168
|
-
else
|
169
|
-
if src.rest_keywords
|
170
|
-
assigning_pairs << [src.rest_keywords, dest_flat_kws[name]]
|
171
|
-
else
|
172
|
-
return false
|
173
|
-
end
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
src.required_keywords.each do |name, _|
|
178
|
-
unless dest.required_keywords.key?(name)
|
179
|
-
return false
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
if src.rest_keywords && dest.rest_keywords
|
184
|
-
assigning_pairs << [src.rest_keywords, dest.rest_keywords]
|
185
|
-
end
|
186
|
-
|
187
|
-
assigning_pairs.all? do |pair|
|
188
|
-
src_type = pair.first
|
189
|
-
dest_type = pair.last
|
190
|
-
|
191
|
-
test(src: dest_type, dest: src_type, known_pairs: known_pairs)
|
192
|
-
end
|
193
|
-
end
|
194
|
-
|
195
|
-
def test_block(src, dest, known_pairs)
|
196
|
-
return true if !src && !dest
|
197
|
-
return false if !src || !dest
|
198
|
-
|
199
|
-
raise "Keyword args for block is not yet supported" unless src.params&.flat_keywords&.empty?
|
200
|
-
raise "Keyword args for block is not yet supported" unless dest.params&.flat_keywords&.empty?
|
201
|
-
|
202
|
-
ss = src.params.flat_unnamed_params
|
203
|
-
ds = dest.params.flat_unnamed_params
|
204
|
-
|
205
|
-
max = ss.size > ds.size ? ss.size : ds.size
|
206
|
-
|
207
|
-
for i in 0...max
|
208
|
-
s = ss[i]&.last || src.params.rest
|
209
|
-
d = ds[i]&.last || dest.params.rest
|
210
|
-
|
211
|
-
if s && d
|
212
|
-
test(src: s, dest: d, known_pairs: known_pairs) or return false
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
if src.params.rest && dest.params.rest
|
217
|
-
test(src: src.params.rest, dest: dest.params.rest, known_pairs: known_pairs) or return false
|
218
|
-
end
|
219
|
-
|
220
|
-
test(src: dest.return_type, dest: src.return_type, known_pairs: known_pairs)
|
221
|
-
end
|
222
|
-
|
223
|
-
def resolve_interface(name, params, klass: nil, instance: nil, constructor: nil)
|
224
|
-
klass ||= Types::Name.module(name: name.name, params: params)
|
225
|
-
instance ||= Types::Name.instance(name: name.name, params: params)
|
226
|
-
|
227
|
-
case name
|
228
|
-
when TypeName::Interface
|
229
|
-
signatures[name.name].to_interface(klass: klass, instance: instance, params: params)
|
230
|
-
when TypeName::Instance
|
231
|
-
methods = signatures[name.name].instance_methods(assignability: self, klass: klass, instance: instance, params: params)
|
232
|
-
Interface.new(name: name, params: params, methods: methods.reject {|key, _| key == :initialize })
|
233
|
-
when TypeName::Module
|
234
|
-
methods = signatures[name.name].module_methods(assignability: self, klass: klass, instance: instance, params: params, constructor: constructor)
|
235
|
-
Interface.new(name: name, params: params, methods: methods)
|
236
|
-
else
|
237
|
-
raise "Unexpected type name: #{name.inspect}"
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
|
-
def lookup_included_signature(type)
|
242
|
-
raise "#{self.class}#lookup_included_signature expects type name: #{type.inspect}" unless type.is_a?(Types::Name)
|
243
|
-
raise "#{self.class}#lookup_included_signature expects module instance name: #{type.name.inspect}" unless type.name.is_a?(TypeName::Instance)
|
244
|
-
|
245
|
-
signatures[type.name.name]
|
246
|
-
end
|
247
|
-
|
248
|
-
def lookup_super_class_signature(type)
|
249
|
-
raise "#{self.class}#lookup_super_class_signature expects type name: #{type.inspect}" unless type.is_a?(Types::Name)
|
250
|
-
raise "#{self.class}#lookup_super_class_signature expects module instance name: #{type.name.inspect}" unless type.name.is_a?(TypeName::Instance)
|
251
|
-
|
252
|
-
signature = signatures[type.name.name]
|
253
|
-
|
254
|
-
raise "#{self.class}#lookup_super_class_signature expects class: #{type.name.inspect}" unless signature.is_a?(Signature::Class)
|
255
|
-
|
256
|
-
signature
|
257
|
-
end
|
258
|
-
|
259
|
-
def lookup_class_signature(type)
|
260
|
-
raise "#{self.class}#lookup_class_signature expects type name: #{type.inspect}" unless type.is_a?(Types::Name)
|
261
|
-
raise "#{self.class}#lookup_class_signature expects instance name: #{type.name.inspect}" unless type.name.is_a?(TypeName::Instance)
|
262
|
-
|
263
|
-
signature = signatures[type.name.name]
|
264
|
-
|
265
|
-
raise "#{self.class}#lookup_super_class_signature expects class: #{signature.inspect}" unless signature.is_a?(Signature::Class)
|
266
|
-
|
267
|
-
signature
|
268
|
-
end
|
269
|
-
|
270
|
-
def lookup_extensions(module_name)
|
271
|
-
signatures.values.select do |signature|
|
272
|
-
case signature
|
273
|
-
when Signature::Extension
|
274
|
-
signature.module_name == module_name
|
275
|
-
end
|
276
|
-
end
|
277
|
-
end
|
278
|
-
|
279
|
-
def method_type(type, name)
|
280
|
-
case type
|
281
|
-
when Types::Any
|
282
|
-
return type
|
283
|
-
when Types::Merge
|
284
|
-
methods = type.types.map {|t|
|
285
|
-
resolve_interface(t.name, t.params, klass: Types::Var.new(name: :some_klass), instance: Types::Var.new(name: :some_instance))
|
286
|
-
}.each.with_object({}) {|interface, methods|
|
287
|
-
methods.merge! interface.methods
|
288
|
-
}
|
289
|
-
method = methods[name]
|
290
|
-
when Types::Name
|
291
|
-
constructor = type.name.is_a?(TypeName::Module) && type.name.constructor
|
292
|
-
interface = resolve_interface(type.name, type.params, constructor: constructor)
|
293
|
-
method = interface.methods[name]
|
294
|
-
else
|
295
|
-
raise "Unexpected type: #{type}"
|
296
|
-
end
|
297
|
-
|
298
|
-
if method
|
299
|
-
yield(method) || Types::Any.new
|
300
|
-
else
|
301
|
-
yield(nil) || Types::Any.new
|
302
|
-
end
|
303
|
-
end
|
304
|
-
|
305
|
-
def validate
|
306
|
-
signatures.each do |name, signature|
|
307
|
-
signature.validate(self)
|
308
|
-
end
|
309
|
-
end
|
310
|
-
|
311
|
-
def validate_type_presence(signature, type)
|
312
|
-
if type.is_a?(Types::Name)
|
313
|
-
unless signatures[type.name.name]
|
314
|
-
errors << Signature::Errors::UnknownTypeName.new(signature: signature, type: type)
|
315
|
-
end
|
316
|
-
end
|
317
|
-
end
|
318
|
-
|
319
|
-
def validate_method_compatibility(signature, method_name, method)
|
320
|
-
if method.super_method
|
321
|
-
test = method.types.all? {|method_type|
|
322
|
-
method.super_method.types.any? {|super_type|
|
323
|
-
test_method(method_type, super_type, [])
|
324
|
-
}
|
325
|
-
}
|
326
|
-
|
327
|
-
unless test
|
328
|
-
errors << Signature::Errors::IncompatibleOverride.new(signature: signature,
|
329
|
-
method_name: method_name,
|
330
|
-
this_method: method.types,
|
331
|
-
super_method: method.super_method.types)
|
332
|
-
end
|
333
|
-
end
|
334
|
-
end
|
335
|
-
|
336
|
-
def compact(types)
|
337
|
-
types = types.reject {|type| type.is_a?(Types::Any) }
|
338
|
-
|
339
|
-
if types.empty?
|
340
|
-
[Types::Any.new]
|
341
|
-
else
|
342
|
-
compact0(types)
|
343
|
-
end
|
344
|
-
end
|
345
|
-
|
346
|
-
def compact0(types)
|
347
|
-
if types.size == 1
|
348
|
-
types
|
349
|
-
else
|
350
|
-
type, *types_ = types
|
351
|
-
compacted = compact0(types_)
|
352
|
-
compacted.flat_map do |type_|
|
353
|
-
case
|
354
|
-
when type == type_
|
355
|
-
[type]
|
356
|
-
when test(src: type_, dest: type)
|
357
|
-
[type]
|
358
|
-
when test(src: type, dest: type_)
|
359
|
-
[type_]
|
360
|
-
else
|
361
|
-
[type, type_]
|
362
|
-
end
|
363
|
-
end.uniq
|
364
|
-
end
|
365
|
-
end
|
366
|
-
end
|
367
|
-
end
|