steep 0.25.0 → 0.27.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c290301da65ed473b092cd6c2ea39eebe02f566124a1fa32e0f420d290513cbf
4
- data.tar.gz: ca4fca20e9f3f0b19c57b98d6cdfce0023aeeff8cd0fcd2ee0fc91346e5e0816
3
+ metadata.gz: '09e364b23ebecd35868dbde7ea09938fa8208219ee1fcd19a0faaa9a160f6aab'
4
+ data.tar.gz: c4374adcf1b0c54663e04380229322d9c07865fac69b1b74fa2eeabecd26cd7d
5
5
  SHA512:
6
- metadata.gz: 76c3b0c76e303bcc558bf20efeebe3ddaa3caef432f5d325261261f6d8431f5bbd36bc44af9a4a4dd6a90f2db30ac35ca044181b25063890c0e68c5499d7792c
7
- data.tar.gz: a5fa8fba718f599806d9d0ad62a66c138261469d41694bb39ebafe1b8736ad255e890c55f0e3b4f180f4e0212f0b65b31b5957b5c337cba42d1129b9e935e577
6
+ metadata.gz: e59635b6fba6e2dac0c7ba8fb12d9a4e4734ffd95a48b8af1cb2cdbb0a5280d660c46fbf724ea48a61247165319b448598f702d6ef0dbf78d28b78dcb7ba536c
7
+ data.tar.gz: 62ca2d4504a4d75922abf3b76def89f0146a298b3452a874d98a869fa3f39942984224324cdec93f7894918b4386a07aabb4a1be6f572bcbbb5d3081086b1cda
@@ -2,6 +2,19 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 0.27.0 (2020-08-31)
6
+
7
+ * Make tuple types _covariant_ ([#195](https://github.com/soutaro/steep/pull/195))
8
+ * Support `or_asgn`/`and_asgn` with `send` node lhs ([#194](https://github.com/soutaro/steep/pull/194))
9
+ * Performance improvement ([#193](https://github.com/soutaro/steep/pull/193))
10
+ * Add specialized versions of `#first` and `#last` on tuples ([#191](https://github.com/soutaro/steep/pull/191))
11
+ * Typing bug fix on `[]` (empty array) ([#190](https://github.com/soutaro/steep/pull/190))
12
+ * Earlier shutdown with interruption while `steep watch` ([#173](https://github.com/soutaro/steep/pull/173))
13
+
14
+ ## 0.26.0
15
+
16
+ * Skipped
17
+
5
18
  ## 0.25.0 (2020-08-18)
6
19
 
7
20
  * Improve `op_send` typing ([#186](https://github.com/soutaro/steep/pull/186))
@@ -35,9 +35,11 @@ module Steep
35
35
  "masked(#{type}|#{mask})"
36
36
  end
37
37
 
38
- def free_variables(set = Set.new)
39
- type.free_variables(set)
40
- mask.free_variables(set)
38
+ def free_variables
39
+ @fvs ||= Set.new.tap do |set|
40
+ set.merge(type.free_variables)
41
+ set.merge(mask.free_variables)
42
+ end
41
43
  end
42
44
 
43
45
  def each_type(&block)
@@ -26,9 +26,7 @@ module Steep
26
26
  "untyped"
27
27
  end
28
28
 
29
- def free_variables
30
- Set.new
31
- end
29
+ include Helper::NoFreeVariables
32
30
 
33
31
  def level
34
32
  [1]
@@ -26,9 +26,7 @@ module Steep
26
26
  "bool"
27
27
  end
28
28
 
29
- def free_variables
30
- Set.new
31
- end
29
+ include Helper::NoFreeVariables
32
30
 
33
31
  def level
34
32
  [0]
@@ -26,9 +26,7 @@ module Steep
26
26
  "⟘"
27
27
  end
28
28
 
29
- def free_variables
30
- Set.new
31
- end
29
+ include Helper::NoFreeVariables
32
30
 
33
31
  def level
34
32
  [2]
@@ -22,8 +22,8 @@ module Steep
22
22
  s.module_type or raise "Unexpected substitution: #{inspect}"
23
23
  end
24
24
 
25
- def free_variables
26
- Set.new
25
+ def free_variables()
26
+ @fvs = Set.new([self])
27
27
  end
28
28
 
29
29
  def level
@@ -4,8 +4,14 @@ module Steep
4
4
  class Factory
5
5
  attr_reader :definition_builder
6
6
 
7
+ attr_reader :type_name_cache
8
+ attr_reader :type_cache
9
+
7
10
  def initialize(builder:)
8
11
  @definition_builder = builder
12
+
13
+ @type_name_cache = {}
14
+ @type_cache = {}
9
15
  end
10
16
 
11
17
  def type_name_resolver
@@ -13,7 +19,9 @@ module Steep
13
19
  end
14
20
 
15
21
  def type(type)
16
- case type
22
+ ty = type_cache[type] and return ty
23
+
24
+ type_cache[type] = case type
17
25
  when RBS::Types::Bases::Any
18
26
  Any.new(location: nil)
19
27
  when RBS::Types::Bases::Class
@@ -144,14 +152,17 @@ module Steep
144
152
  end
145
153
 
146
154
  def type_name(name)
147
- case
148
- when name.class?
149
- Names::Module.new(name: name.name, namespace: namespace(name.namespace), location: nil)
150
- when name.interface?
151
- Names::Interface.new(name: name.name, namespace: namespace(name.namespace), location: nil)
152
- when name.alias?
153
- Names::Alias.new(name: name.name, namespace: namespace(name.namespace), location: nil)
154
- end
155
+ n = type_name_cache[name] and return n
156
+
157
+ type_name_cache[name] =
158
+ (case
159
+ when name.class?
160
+ Names::Module.new(name: name.name, namespace: namespace(name.namespace), location: nil)
161
+ when name.interface?
162
+ Names::Interface.new(name: name.name, namespace: namespace(name.namespace), location: nil)
163
+ when name.alias?
164
+ Names::Alias.new(name: name.name, namespace: namespace(name.namespace), location: nil)
165
+ end)
155
166
  end
156
167
 
157
168
  def type_name_1(name)
@@ -190,7 +201,7 @@ module Steep
190
201
  )
191
202
  end
192
203
 
193
- def method_type(method_type, self_type:)
204
+ def method_type(method_type, self_type:, subst2: nil)
194
205
  fvs = self_type.free_variables()
195
206
 
196
207
  type_params = []
@@ -208,6 +219,7 @@ module Steep
208
219
  end
209
220
  end
210
221
  subst = Interface::Substitution.build(alpha_vars, alpha_types)
222
+ subst.merge!(subst2) if subst2
211
223
 
212
224
  type = Interface::MethodType.new(
213
225
  type_params: type_params,
@@ -332,7 +344,7 @@ module Steep
332
344
 
333
345
  interface.methods[name] = Interface::Interface::Combination.overload(
334
346
  method.method_types.map do |type|
335
- method_type(type, self_type: self_type) {|ty| ty.subst(subst) }
347
+ method_type(type, self_type: self_type, subst2: subst)
336
348
  end,
337
349
  incompatible: name == :initialize || name == :new
338
350
  )
@@ -353,9 +365,9 @@ module Steep
353
365
  definition.methods.each do |name, method|
354
366
  interface.methods[name] = Interface::Interface::Combination.overload(
355
367
  method.method_types.map do |type|
356
- method_type(type, self_type: self_type) {|type| type.subst(subst) }
368
+ method_type(type, self_type: self_type, subst2: subst)
357
369
  end,
358
- incompatible: method.attributes.include?(:incompatible)
370
+ incompatible: false
359
371
  )
360
372
  end
361
373
  end
@@ -379,9 +391,9 @@ module Steep
379
391
 
380
392
  interface.methods[name] = Interface::Interface::Combination.overload(
381
393
  method.method_types.map do |type|
382
- method_type(type, self_type: self_type) {|type| type.subst(subst) }
394
+ method_type(type, self_type: self_type, subst2: subst)
383
395
  end,
384
- incompatible: method.attributes.include?(:incompatible)
396
+ incompatible: false
385
397
  )
386
398
  end
387
399
  end
@@ -468,6 +480,36 @@ module Steep
468
480
  incompatible: false
469
481
  )
470
482
  end
483
+
484
+ array_interface.methods[:first] = array_interface.methods[:first].yield_self do |first|
485
+ Interface::Interface::Combination.overload(
486
+ [
487
+ Interface::MethodType.new(
488
+ type_params: [],
489
+ params: Interface::Params.empty,
490
+ block: nil,
491
+ return_type: type.types[0] || AST::Builtin.nil_type,
492
+ location: nil
493
+ )
494
+ ],
495
+ incompatible: false
496
+ )
497
+ end
498
+
499
+ array_interface.methods[:last] = array_interface.methods[:last].yield_self do |last|
500
+ Interface::Interface::Combination.overload(
501
+ [
502
+ Interface::MethodType.new(
503
+ type_params: [],
504
+ params: Interface::Params.empty,
505
+ block: nil,
506
+ return_type: type.types.last || AST::Builtin.nil_type,
507
+ location: nil
508
+ )
509
+ ],
510
+ incompatible: false
511
+ )
512
+ end
471
513
  end
472
514
  end
473
515
 
@@ -15,6 +15,12 @@ module Steep
15
15
  end || []
16
16
  end
17
17
  end
18
+
19
+ module NoFreeVariables
20
+ def free_variables()
21
+ @fvs ||= Set.new
22
+ end
23
+ end
18
24
  end
19
25
  end
20
26
  end
@@ -22,8 +22,8 @@ module Steep
22
22
  s.instance_type or raise "Unexpected substitution: #{inspect}"
23
23
  end
24
24
 
25
- def free_variables
26
- Set.new
25
+ def free_variables()
26
+ @fvs = Set.new([self])
27
27
  end
28
28
 
29
29
  def to_s
@@ -57,10 +57,14 @@ module Steep
57
57
  "(#{types.map(&:to_s).sort.join(" & ")})"
58
58
  end
59
59
 
60
- def free_variables
61
- types.each.with_object(Set.new) do |type, set|
62
- set.merge(type.free_variables)
63
- end
60
+ def free_variables()
61
+ @fvs ||= begin
62
+ set = Set.new
63
+ types.each do |type|
64
+ set.merge(type.free_variables)
65
+ end
66
+ set
67
+ end
64
68
  end
65
69
 
66
70
  include Helper::ChildrenLevel
@@ -29,9 +29,7 @@ module Steep
29
29
  value.inspect
30
30
  end
31
31
 
32
- def free_variables
33
- Set.new
34
- end
32
+ include Helper::NoFreeVariables
35
33
 
36
34
  def level
37
35
  [0]
@@ -11,9 +11,7 @@ module Steep
11
11
  @name = name
12
12
  end
13
13
 
14
- def free_variables
15
- Set.new
16
- end
14
+ include Helper::NoFreeVariables
17
15
 
18
16
  def subst(s)
19
17
  self
@@ -41,7 +39,7 @@ module Steep
41
39
  alias eql? ==
42
40
 
43
41
  def hash
44
- self.class.hash ^ name.hash ^ args.hash
42
+ @hash ||= self.class.hash ^ name.hash ^ args.hash
45
43
  end
46
44
 
47
45
  def to_s
@@ -57,14 +55,20 @@ module Steep
57
55
  end
58
56
 
59
57
  def subst(s)
60
- self.class.new(location: location,
61
- name: name,
62
- args: args.map {|a| a.subst(s) })
58
+ if free_variables.intersect?(s.domain)
59
+ self.class.new(location: location,
60
+ name: name,
61
+ args: args.map {|a| a.subst(s) })
62
+ else
63
+ self
64
+ end
63
65
  end
64
66
 
65
67
  def free_variables
66
- args.each.with_object(Set.new) do |type, vars|
67
- vars.merge(type.free_variables)
68
+ @fvs ||= Set.new().tap do |set|
69
+ args.each do |type|
70
+ set.merge(type.free_variables)
71
+ end
68
72
  end
69
73
  end
70
74
 
@@ -26,9 +26,7 @@ module Steep
26
26
  "nil"
27
27
  end
28
28
 
29
- def free_variables
30
- Set.new
31
- end
29
+ include Helper::NoFreeVariables
32
30
 
33
31
  def level
34
32
  [0]
@@ -36,8 +36,11 @@ module Steep
36
36
  "^#{params} -> #{return_type}"
37
37
  end
38
38
 
39
- def free_variables
40
- params.free_variables + return_type.free_variables
39
+ def free_variables()
40
+ @fvs ||= Set.new.tap do |set|
41
+ set.merge(params.free_variables)
42
+ set.merge(return_type.free_variables)
43
+ end
41
44
  end
42
45
 
43
46
  def level
@@ -26,12 +26,17 @@ module Steep
26
26
  end
27
27
 
28
28
  def to_s
29
- "{ #{elements.map {|key, value| "#{key.inspect} => #{value}" }.join(", ")} }"
29
+ strings = elements.keys.sort.map do |key|
30
+ "#{key.inspect} => #{elements[key]}"
31
+ end
32
+ "{ #{strings.join(", ")} }"
30
33
  end
31
34
 
32
- def free_variables
33
- elements.each_value.with_object(Set.new) do |type, set|
34
- set.merge(type.free_variables)
35
+ def free_variables()
36
+ @fvs ||= Set.new.tap do |set|
37
+ elements.each_value do |type|
38
+ set.merge(type.free_variables)
39
+ end
35
40
  end
36
41
  end
37
42
 
@@ -27,7 +27,7 @@ module Steep
27
27
  end
28
28
 
29
29
  def free_variables
30
- Set.new
30
+ @fvs ||= Set.new([self])
31
31
  end
32
32
 
33
33
  def level
@@ -26,9 +26,7 @@ module Steep
26
26
  "⟙"
27
27
  end
28
28
 
29
- def free_variables
30
- Set.new
31
- end
29
+ include Helper::NoFreeVariables
32
30
 
33
31
  def level
34
32
  [2]
@@ -30,9 +30,11 @@ module Steep
30
30
  "[#{types.join(", ")}]"
31
31
  end
32
32
 
33
- def free_variables
34
- types.each.with_object(Set.new) do |type, set|
35
- set.merge(type.free_variables)
33
+ def free_variables()
34
+ @fvs ||= Set.new.tap do |set|
35
+ types.each do |type|
36
+ set.merge(type.free_variables)
37
+ end
36
38
  end
37
39
  end
38
40
 
@@ -11,6 +11,9 @@ module Steep
11
11
  end
12
12
 
13
13
  def self.build(types:, location: nil)
14
+ return AST::Types::Bot.new if types.empty?
15
+ return types.first if types.size == 1
16
+
14
17
  types.flat_map do |type|
15
18
  if type.is_a?(Union)
16
19
  type.types
@@ -29,7 +32,7 @@ module Steep
29
32
  type
30
33
  end
31
34
  end.compact.uniq.yield_self do |tys|
32
- case tys.length
35
+ case tys.size
33
36
  when 0
34
37
  AST::Types::Bot.new
35
38
  when 1
@@ -61,8 +64,10 @@ module Steep
61
64
  end
62
65
 
63
66
  def free_variables
64
- types.each.with_object(Set.new) do |type, set|
65
- set.merge(type.free_variables)
67
+ @fvs ||= Set.new.tap do |set|
68
+ types.each do |type|
69
+ set.merge(type.free_variables)
70
+ end
66
71
  end
67
72
  end
68
73
 
@@ -44,8 +44,8 @@ module Steep
44
44
  end
45
45
  end
46
46
 
47
- def free_variables
48
- Set.new([name])
47
+ def free_variables()
48
+ @fvs ||= Set.new([name])
49
49
  end
50
50
 
51
51
  def level
@@ -26,9 +26,7 @@ module Steep
26
26
  "void"
27
27
  end
28
28
 
29
- def free_variables
30
- Set.new
31
- end
29
+ include Helper::NoFreeVariables
32
30
 
33
31
  def level
34
32
  [0]
@@ -211,10 +211,10 @@ module Steep
211
211
  end
212
212
  end
213
213
 
214
- def free_variables
215
- Set.new.tap do |fvs|
214
+ def free_variables()
215
+ @fvs ||= Set.new.tap do |set|
216
216
  each_type do |type|
217
- fvs.merge type.free_variables
217
+ set.merge(type.free_variables)
218
218
  end
219
219
  end
220
220
  end
@@ -224,14 +224,29 @@ module Steep
224
224
  end
225
225
 
226
226
  def subst(s)
227
- self.class.new(
228
- required: required.map {|t| t.subst(s) },
229
- optional: optional.map {|t| t.subst(s) },
230
- rest: rest&.subst(s),
231
- required_keywords: required_keywords.transform_values {|t| t.subst(s) },
232
- optional_keywords: optional_keywords.transform_values {|t| t.subst(s) },
233
- rest_keywords: rest_keywords&.subst(s)
234
- )
227
+ return self if s.empty?
228
+ return self if empty?
229
+ return self if free_variables.disjoint?(s.domain)
230
+
231
+ rs = required.map {|t| t.subst(s) }
232
+ os = optional.map {|t| t.subst(s) }
233
+ r = rest&.subst(s)
234
+ rk = required_keywords.transform_values {|t| t.subst(s) }
235
+ ok = optional_keywords.transform_values {|t| t.subst(s) }
236
+ k = rest_keywords&.subst(s)
237
+
238
+ if rs == required && os == optional && r == rest && rk == required_keywords && ok == optional_keywords && k == rest_keywords
239
+ self
240
+ else
241
+ self.class.new(
242
+ required: required.map {|t| t.subst(s) },
243
+ optional: optional.map {|t| t.subst(s) },
244
+ rest: rest&.subst(s),
245
+ required_keywords: required_keywords.transform_values {|t| t.subst(s) },
246
+ optional_keywords: optional_keywords.transform_values {|t| t.subst(s) },
247
+ rest_keywords: rest_keywords&.subst(s)
248
+ )
249
+ end
235
250
  end
236
251
 
237
252
  def size
@@ -557,14 +572,19 @@ module Steep
557
572
  end
558
573
 
559
574
  def subst(s)
560
- self.class.new(
561
- type: type.subst(s),
562
- optional: optional
563
- )
575
+ ty = type.subst(s)
576
+ if ty == type
577
+ self
578
+ else
579
+ self.class.new(
580
+ type: ty,
581
+ optional: optional
582
+ )
583
+ end
564
584
  end
565
585
 
566
- def free_variables
567
- type.free_variables
586
+ def free_variables()
587
+ @fvs ||= type.free_variables
568
588
  end
569
589
 
570
590
  def to_s
@@ -617,10 +637,20 @@ module Steep
617
637
  end
618
638
 
619
639
  def free_variables
620
- (params.free_variables + (block&.free_variables || Set.new) + return_type.free_variables) - Set.new(type_params)
640
+ @fvs ||= Set.new.tap do |set|
641
+ set.merge(params.free_variables)
642
+ if block
643
+ set.merge(block.free_variables)
644
+ end
645
+ set.merge(return_type.free_variables)
646
+ set.subtract(type_params)
647
+ end
621
648
  end
622
649
 
623
650
  def subst(s)
651
+ return self if s.empty?
652
+ return self if free_variables.disjoint?(s.domain)
653
+
624
654
  s_ = s.except(type_params)
625
655
 
626
656
  self.class.new(
@@ -26,7 +26,32 @@ module Steep
26
26
  end
27
27
 
28
28
  def self.empty
29
- new(dictionary: {}, instance_type: AST::Types::Instance.new, module_type: AST::Types::Class.new, self_type: AST::Types::Self.new)
29
+ new(dictionary: {},
30
+ instance_type: INSTANCE_TYPE,
31
+ module_type: CLASS_TYPE,
32
+ self_type: SELF_TYPE)
33
+ end
34
+
35
+ def empty?
36
+ dictionary.empty? &&
37
+ instance_type.is_a?(AST::Types::Instance) &&
38
+ module_type.is_a?(AST::Types::Class) &&
39
+ self_type.is_a?(AST::Types::Self)
40
+ end
41
+
42
+ INSTANCE_TYPE = AST::Types::Instance.new
43
+ CLASS_TYPE = AST::Types::Class.new
44
+ SELF_TYPE = AST::Types::Self.new
45
+
46
+ def domain
47
+ set = Set.new
48
+
49
+ set.merge(dictionary.keys)
50
+ set << INSTANCE_TYPE unless instance_type.is_a?(AST::Types::Instance)
51
+ set << CLASS_TYPE unless instance_type.is_a?(AST::Types::Class)
52
+ set << SELF_TYPE unless instance_type.is_a?(AST::Types::Self)
53
+
54
+ set
30
55
  end
31
56
 
32
57
  def to_s
@@ -81,6 +106,11 @@ module Steep
81
106
  raise "Duplicated key on merge!: #{key}, #{a}, #{b}"
82
107
  end
83
108
  end
109
+
110
+ @instance_type = instance_type.subst(s)
111
+ @module_type = module_type.subst(s)
112
+ @self_type = self_type.subst(s)
113
+
84
114
  self
85
115
  end
86
116
 
@@ -92,7 +122,7 @@ module Steep
92
122
  end
93
123
 
94
124
  def add!(v, ty)
95
- merge!(Substitution.new(dictionary: { v => ty }, instance_type: nil, module_type: nil, self_type: nil))
125
+ merge!(Substitution.new(dictionary: { v => ty }, instance_type: instance_type, module_type: module_type, self_type: self_type))
96
126
  end
97
127
  end
98
128
  end
@@ -12,6 +12,7 @@ module Steep
12
12
  @project = project
13
13
  @reader = reader
14
14
  @writer = writer
15
+ @shutdown = false
15
16
  end
16
17
 
17
18
  def handle_request(request)
@@ -28,7 +29,7 @@ module Steep
28
29
  Steep.logger.formatter.push_tags(*tags)
29
30
  Steep.logger.tagged "background" do
30
31
  while job = queue.pop
31
- handle_job(job)
32
+ handle_job(job) unless @shutdown
32
33
  end
33
34
  end
34
35
  end
@@ -38,11 +39,11 @@ module Steep
38
39
  reader.read do |request|
39
40
  case request[:method]
40
41
  when "shutdown"
41
- # nop
42
+ @shutdown = true
42
43
  when "exit"
43
44
  break
44
45
  else
45
- handle_request(request)
46
+ handle_request(request) unless @shutdown
46
47
  end
47
48
  end
48
49
  ensure
@@ -23,6 +23,7 @@ module Steep
23
23
  @signature_worker = signature_worker
24
24
  @code_workers = code_workers
25
25
  @worker_to_paths = {}
26
+ @shutdown = false
26
27
  end
27
28
 
28
29
  def start
@@ -59,7 +60,7 @@ module Steep
59
60
  end
60
61
 
61
62
  while job = queue.pop
62
- writer.write(job)
63
+ writer.write(job) unless @shutdown
63
64
  end
64
65
 
65
66
  writer.io.close
@@ -154,6 +155,7 @@ module Steep
154
155
 
155
156
  when "shutdown"
156
157
  queue << { id: id, result: nil }
158
+ @shutdown = true
157
159
 
158
160
  when "exit"
159
161
  queue << nil
@@ -302,10 +302,9 @@ module Steep
302
302
  when relation.sub_type.is_a?(AST::Types::Tuple) && relation.super_type.is_a?(AST::Types::Tuple)
303
303
  if relation.sub_type.types.size >= relation.super_type.types.size
304
304
  pairs = relation.sub_type.types.take(relation.super_type.types.size).zip(relation.super_type.types)
305
- results = pairs.flat_map do |t1, t2|
305
+ results = pairs.map do |t1, t2|
306
306
  relation = Relation.new(sub_type: t1, super_type: t2)
307
- [check(relation, self_type: self_type, assumption: assumption, trace: trace, constraints: constraints),
308
- check(relation.flip, self_type: self_type, assumption: assumption, trace: trace, constraints: constraints)]
307
+ check(relation, self_type: self_type, assumption: assumption, trace: trace, constraints: constraints)
309
308
  end
310
309
 
311
310
  if results.all?(&:success?)
@@ -1800,13 +1800,34 @@ module Steep
1800
1800
  when :or_asgn, :and_asgn
1801
1801
  yield_self do
1802
1802
  asgn, rhs = node.children
1803
- type, constr = synthesize(rhs, hint: hint)
1804
1803
 
1805
1804
  case asgn.type
1806
1805
  when :lvasgn
1806
+ type, constr = synthesize(rhs, hint: hint)
1807
1807
  constr.lvasgn(asgn, type)
1808
1808
  when :ivasgn
1809
+ type, constr = synthesize(rhs, hint: hint)
1809
1810
  constr.ivasgn(asgn, type)
1811
+ when :send
1812
+ rhs_ = node.updated(:send,
1813
+ [
1814
+ asgn.children[0],
1815
+ :"#{asgn.children[1]}=",
1816
+ asgn.children[2],
1817
+ rhs
1818
+ ])
1819
+ node_type = case node.type
1820
+ when :or_asgn
1821
+ :or
1822
+ when :and_asgn
1823
+ :and
1824
+ end
1825
+ node_ = node.updated(node_type, [asgn, rhs_])
1826
+
1827
+ synthesize(node_, hint: hint)
1828
+ else
1829
+ Steep.logger.error { "#{node.type} with #{asgn.type} lhs is not supported"}
1830
+ fallback_to_any(node)
1810
1831
  end
1811
1832
  end
1812
1833
 
@@ -1,3 +1,3 @@
1
1
  module Steep
2
- VERSION = "0.25.0"
2
+ VERSION = "0.27.0"
3
3
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  params = { id: 30, name: "Matz" }
4
4
 
5
- # !expects IncompatibleAssignment: lhs_type={ :name => ::String, :id => ::Integer }, rhs_type={ :id => ::String, :name => ::String, :email => ::String }
5
+ # !expects IncompatibleAssignment: lhs_type={ :id => ::Integer, :name => ::String }, rhs_type={ :email => ::String, :id => ::String, :name => ::String }
6
6
  params = { id: "30", name: "foo", email: "matsumoto@soutaro.com" }
@@ -34,5 +34,5 @@ Gem::Specification.new do |spec|
34
34
  spec.add_runtime_dependency "rainbow", ">= 2.2.2", "< 4.0"
35
35
  spec.add_runtime_dependency "listen", "~> 3.1"
36
36
  spec.add_runtime_dependency "language_server-protocol", "~> 3.14.0.2"
37
- spec.add_runtime_dependency "rbs", "~> 0.10.0"
37
+ spec.add_runtime_dependency "rbs", "~> 0.11.0"
38
38
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: steep
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.25.0
4
+ version: 0.27.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Soutaro Matsumoto
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-08-17 00:00:00.000000000 Z
11
+ date: 2020-08-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parser
@@ -106,14 +106,14 @@ dependencies:
106
106
  requirements:
107
107
  - - "~>"
108
108
  - !ruby/object:Gem::Version
109
- version: 0.10.0
109
+ version: 0.11.0
110
110
  type: :runtime
111
111
  prerelease: false
112
112
  version_requirements: !ruby/object:Gem::Requirement
113
113
  requirements:
114
114
  - - "~>"
115
115
  - !ruby/object:Gem::Version
116
- version: 0.10.0
116
+ version: 0.11.0
117
117
  description: Gradual Typing for Ruby
118
118
  email:
119
119
  - matsumoto@soutaro.com