steep 0.49.0 → 0.51.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +23 -0
  3. data/Gemfile +4 -1
  4. data/Gemfile.lock +9 -6
  5. data/lib/steep/ast/annotation/collection.rb +10 -8
  6. data/lib/steep/ast/types/factory.rb +5 -5
  7. data/lib/steep/cli.rb +13 -0
  8. data/lib/steep/diagnostic/deprecated/unknown_constant_assigned.rb +28 -0
  9. data/lib/steep/diagnostic/ruby.rb +34 -15
  10. data/lib/steep/drivers/check.rb +3 -2
  11. data/lib/steep/drivers/langserver.rb +2 -2
  12. data/lib/steep/drivers/stats.rb +1 -0
  13. data/lib/steep/drivers/utils/jobs_count.rb +1 -1
  14. data/lib/steep/drivers/watch.rb +1 -1
  15. data/lib/steep/index/source_index.rb +18 -1
  16. data/lib/steep/interface/function.rb +5 -0
  17. data/lib/steep/module_helper.rb +4 -7
  18. data/lib/steep/project.rb +15 -1
  19. data/lib/steep/server/interaction_worker.rb +47 -4
  20. data/lib/steep/server/master.rb +10 -5
  21. data/lib/steep/server/type_check_worker.rb +19 -4
  22. data/lib/steep/server/worker_process.rb +15 -6
  23. data/lib/steep/services/completion_provider.rb +109 -1
  24. data/lib/steep/services/goto_service.rb +23 -10
  25. data/lib/steep/services/hover_content.rb +52 -4
  26. data/lib/steep/services/type_check_service.rb +8 -3
  27. data/lib/steep/signature/validator.rb +12 -5
  28. data/lib/steep/source.rb +19 -13
  29. data/lib/steep/type_construction.rb +238 -170
  30. data/lib/steep/type_inference/constant_env.rb +33 -15
  31. data/lib/steep/type_inference/context.rb +6 -7
  32. data/lib/steep/type_inference/type_env.rb +16 -54
  33. data/lib/steep/version.rb +1 -1
  34. data/smoke/const/test_expectations.yml +24 -19
  35. data/smoke/diagnostics/proc_type_expected.rb +3 -0
  36. data/smoke/diagnostics/test_expectations.yml +92 -10
  37. data/smoke/integer/test_expectations.yml +24 -4
  38. data/smoke/method/test_expectations.yml +30 -0
  39. data/smoke/regression/test_expectations.yml +24 -0
  40. data/smoke/yield/test_expectations.yml +20 -0
  41. data/steep.gemspec +1 -1
  42. metadata +6 -4
@@ -130,9 +130,8 @@ module Steep
130
130
  end
131
131
 
132
132
  def for_new_method(method_name, node, args:, self_type:, definition:)
133
- annots = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
134
- type_env = TypeInference::TypeEnv.new(subtyping: checker,
135
- const_env: module_context&.const_env || self.type_env.const_env)
133
+ annots = source.annotations(block: node, factory: checker.factory, context: nesting)
134
+ type_env = TypeInference::TypeEnv.new(subtyping: checker, const_env: module_context&.const_env || self.type_env.const_env)
136
135
 
137
136
  self.type_env.const_types.each do |name, type|
138
137
  type_env.set(const: name, type: type)
@@ -285,17 +284,9 @@ module Steep
285
284
  end
286
285
  end
287
286
  else
288
- name = nil
289
- name ||= absolute_name(module_name).yield_self do |absolute_name|
290
- absolute_name if checker.factory.class_name?(absolute_name) || checker.factory.module_name?(absolute_name)
291
- end
292
- name ||= super_name && absolute_name(super_name).yield_self do |absolute_name|
293
- absolute_name if checker.factory.class_name?(absolute_name) || checker.factory.module_name?(absolute_name)
294
- end
287
+ name = module_name || super_name
295
288
 
296
- if name
297
- absolute_name_ = name
298
- entry = checker.factory.env.class_decls[absolute_name_]
289
+ if name && entry = checker.factory.env.class_decls[name]
299
290
  AST::Annotation::Implements::Module.new(
300
291
  name: name,
301
292
  args: entry.type_params.each.map(&:name)
@@ -304,9 +295,9 @@ module Steep
304
295
  end
305
296
  end
306
297
 
307
- def default_module_context(implement_module_name, const_env:, current_namespace:)
298
+ def default_module_context(implement_module_name, const_env:)
308
299
  if implement_module_name
309
- module_name = checker.factory.absolute_type_name(implement_module_name.name, namespace: current_namespace)
300
+ module_name = checker.factory.absolute_type_name(implement_module_name.name, context: const_env.context)
310
301
  module_args = implement_module_name.args.map {|name| AST::Types::Var.new(name: name) }
311
302
 
312
303
  instance_def = checker.factory.definition_builder.build_instance(module_name)
@@ -319,7 +310,6 @@ module Steep
319
310
  instance_type: instance_type,
320
311
  module_type: module_type,
321
312
  implement_name: implement_module_name,
322
- current_namespace: current_namespace,
323
313
  const_env: const_env,
324
314
  class_name: module_name,
325
315
  instance_definition: instance_def,
@@ -330,7 +320,6 @@ module Steep
330
320
  instance_type: nil,
331
321
  module_type: nil,
332
322
  implement_name: nil,
333
- current_namespace: current_namespace,
334
323
  const_env: self.module_context.const_env,
335
324
  class_name: self.module_context.class_name,
336
325
  module_definition: nil,
@@ -339,17 +328,19 @@ module Steep
339
328
  end
340
329
  end
341
330
 
342
- def for_module(node)
343
- new_module_name = module_name_from_node(node.children.first) or raise "Unexpected module name: #{node.children.first}"
344
- new_namespace = nested_namespace_for_module(new_module_name)
331
+ def for_module(node, new_module_name)
332
+ new_nesting = [nesting, new_module_name || false]
345
333
 
346
- const_context = [new_namespace] + self.module_context.const_env.context
347
- module_const_env = TypeInference::ConstantEnv.new(factory: checker.factory, context: const_context)
334
+ module_const_env = TypeInference::ConstantEnv.new(
335
+ factory: checker.factory,
336
+ context: new_nesting,
337
+ resolver: self.module_context.const_env.resolver
338
+ )
348
339
 
349
- annots = source.annotations(block: node, factory: checker.factory, current_module: new_namespace)
340
+ annots = source.annotations(block: node, factory: checker.factory, context: new_nesting)
350
341
 
351
342
  implement_module_name = implement_module(module_name: new_module_name, annotations: annots)
352
- module_context = default_module_context(implement_module_name, const_env: module_const_env, current_namespace: new_namespace)
343
+ module_context = default_module_context(implement_module_name, const_env: module_const_env)
353
344
 
354
345
  unless implement_module_name
355
346
  module_context = module_context.update(
@@ -446,25 +437,25 @@ module Steep
446
437
  )
447
438
  end
448
439
 
449
- def with_module_constr(node)
450
- constr = for_module(node)
440
+ def with_module_constr(node, module_name)
441
+ constr = for_module(node, module_name)
451
442
  constr.checker.push_variable_bounds(constr.variable_context.upper_bounds) do
452
443
  yield constr
453
444
  end
454
445
  end
455
446
 
456
- def for_class(node)
457
- new_class_name = module_name_from_node(node.children.first) or raise "Unexpected class name: #{node.children.first}"
458
- super_class_name = node.children[1] && module_name_from_node(node.children[1])
459
- new_namespace = nested_namespace_for_module(new_class_name)
460
-
461
- annots = source.annotations(block: node, factory: checker.factory, current_module: new_namespace)
447
+ def for_class(node, new_class_name, super_class_name)
448
+ new_nesting = [nesting, new_class_name || false]
449
+ annots = source.annotations(block: node, factory: checker.factory, context: new_nesting)
462
450
 
463
- const_context = [new_namespace] + self.module_context.const_env.context
464
- class_const_env = TypeInference::ConstantEnv.new(factory: checker.factory, context: const_context)
451
+ class_const_env = TypeInference::ConstantEnv.new(
452
+ factory: checker.factory,
453
+ context: new_nesting,
454
+ resolver: self.module_context.const_env.resolver
455
+ )
465
456
 
466
457
  implement_module_name = implement_module(module_name: new_class_name, super_name: super_class_name, annotations: annots)
467
- module_context = default_module_context(implement_module_name, const_env: class_const_env, current_namespace: new_namespace)
458
+ module_context = default_module_context(implement_module_name, const_env: class_const_env)
468
459
 
469
460
  if implement_module_name
470
461
  if super_class_name && implement_module_name.name == absolute_name(super_class_name)
@@ -534,8 +525,8 @@ module Steep
534
525
  )
535
526
  end
536
527
 
537
- def with_class_constr(node)
538
- constr = for_class(node)
528
+ def with_class_constr(node, new_class_name, super_class_name)
529
+ constr = for_class(node, new_class_name, super_class_name)
539
530
 
540
531
  constr.checker.push_variable_bounds(constr.variable_context.upper_bounds) do
541
532
  yield constr
@@ -553,7 +544,7 @@ module Steep
553
544
  end
554
545
 
555
546
  def for_sclass(node, type)
556
- annots = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
547
+ annots = source.annotations(block: node, factory: checker.factory, context: nesting)
557
548
 
558
549
  instance_type = if type.is_a?(AST::Types::Self)
559
550
  context.self_type
@@ -601,7 +592,6 @@ module Steep
601
592
  instance_type: annots.instance_type || instance_type,
602
593
  module_type: annots.self_type || annots.module_type || module_type,
603
594
  implement_name: nil,
604
- current_namespace: current_namespace,
605
595
  const_env: self.module_context.const_env,
606
596
  class_name: self.module_context.class_name,
607
597
  module_definition: module_definition,
@@ -642,7 +632,7 @@ module Steep
642
632
  end
643
633
 
644
634
  def for_branch(node, truthy_vars: Set.new, type_case_override: nil, break_context: context.break_context)
645
- annots = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
635
+ annots = source.annotations(block: node, factory: checker.factory, context: nesting)
646
636
 
647
637
  lvar_env = context.lvar_env
648
638
 
@@ -1497,33 +1487,37 @@ module Steep
1497
1487
  yield_self do
1498
1488
  constr = self
1499
1489
 
1500
- name, sup, _ = node.children
1501
- if name.type == :const
1502
- # skip the last constant reference
1503
- if const_parent = name.children[0]
1504
- _, constr = constr.synthesize(const_parent)
1490
+ name_node, super_node, _ = node.children
1491
+ _, constr, class_name = synthesize_constant(name_node, name_node.children[0], name_node.children[1]) do
1492
+ typing.add_error(
1493
+ Diagnostic::Ruby::UnknownConstant.new(node: name_node, name: name_node.children[1]).class!
1494
+ )
1495
+ end
1496
+ if class_name
1497
+ typing.source_index.add_definition(constant: class_name, definition: name_node)
1498
+ end
1499
+
1500
+ if super_node
1501
+ _, constr, super_name = constr.synthesize_constant(super_node, super_node.children[0], super_node.children[1]) do
1502
+ typing.add_error(
1503
+ Diagnostic::Ruby::UnknownConstant.new(node: super_node, name: super_node.children[1]).class!
1504
+ )
1505
+ end
1506
+ if super_name
1507
+ typing.source_index.add_reference(constant: super_name, ref: super_node)
1505
1508
  end
1506
- else
1507
- _, constr = constr.synthesize(name)
1508
1509
  end
1509
- _, constr = constr.synthesize(sup) if sup
1510
1510
 
1511
- with_class_constr(node) do |constructor|
1511
+ with_class_constr(node, class_name, super_name) do |constructor|
1512
1512
  if module_type = constructor.module_context&.module_type
1513
1513
  _, constructor = constructor.add_typing(name, type: module_type)
1514
1514
  else
1515
1515
  _, constructor = constructor.fallback_to_any(name)
1516
1516
  end
1517
1517
 
1518
- constructor.typing.source_index.add_definition(
1519
- constant: constructor.module_context.class_name,
1520
- definition: node
1521
- )
1522
-
1523
1518
  constructor.typing.add_context_for_node(node, context: constructor.context)
1524
1519
  constructor.typing.add_context_for_body(node, context: constructor.context)
1525
1520
 
1526
- constructor.synthesize(node.children[1]) if node.children[1]
1527
1521
  constructor.synthesize(node.children[2]) if node.children[2]
1528
1522
 
1529
1523
  if constructor.module_context&.implement_name && !namespace_module?(node)
@@ -1538,28 +1532,22 @@ module Steep
1538
1532
  yield_self do
1539
1533
  constr = self
1540
1534
 
1541
- name, _ = node.children
1542
- if name.type == :const
1543
- # skip the last constant reference
1544
- if const_parent = name.children[0]
1545
- _, constr = constr.synthesize(const_parent)
1546
- end
1547
- else
1548
- _, constr = constr.synthesize(name)
1535
+ name_node, _ = node.children
1536
+ _, constr, module_name = synthesize_constant(name_node, name_node.children[0], name_node.children[1]) do
1537
+ typing.add_error Diagnostic::Ruby::UnknownConstant.new(node: name_node, name: name_node.children[1]).module!
1538
+ end
1539
+
1540
+ if module_name
1541
+ constr.typing.source_index.add_definition(constant: module_name, definition: name_node)
1549
1542
  end
1550
1543
 
1551
- with_module_constr(node) do |constructor|
1544
+ with_module_constr(node, module_name) do |constructor|
1552
1545
  if module_type = constructor.module_context&.module_type
1553
1546
  _, constructor = constructor.add_typing(name, type: module_type)
1554
1547
  else
1555
1548
  _, constructor = constructor.fallback_to_any(name)
1556
1549
  end
1557
1550
 
1558
- constructor.typing.source_index.add_definition(
1559
- constant: constructor.module_context.class_name,
1560
- definition: node
1561
- )
1562
-
1563
1551
  constructor.typing.add_context_for_node(node, context: constructor.context)
1564
1552
  constructor.typing.add_context_for_body(node, context: constructor.context)
1565
1553
 
@@ -1611,75 +1599,47 @@ module Steep
1611
1599
  add_typing node, type: AST::Types::Void.new
1612
1600
 
1613
1601
  when :const
1614
- parent = node.children[0]
1615
- if parent
1616
- _, constr = synthesize(parent)
1617
- else
1618
- constr = self
1619
- end
1620
-
1621
- const_name = constr.module_name_from_node(node)
1602
+ yield_self do
1603
+ type, constr, name = synthesize_constant(node, node.children[0], node.children[1])
1622
1604
 
1623
- if const_name
1624
- if constant = module_context.const_env.lookup_constant(const_name)
1625
- typing.source_index.add_reference(constant: constant.name, ref: node)
1605
+ if name
1606
+ typing.source_index.add_reference(constant: name, ref: node)
1626
1607
  end
1627
1608
 
1628
- type = type_env.get(const: const_name) do
1629
- constr.fallback_to_any(node)
1630
- end
1631
- constr.add_typing(node, type: type)
1632
- else
1633
- constr.fallback_to_any(node)
1609
+ Pair.new(type: type, constr: constr)
1634
1610
  end
1635
1611
 
1636
1612
  when :casgn
1637
1613
  yield_self do
1638
- constr = self
1614
+ constant_type, constr, constant_name = synthesize_constant(nil, node.children[0], node.children[1]) do
1615
+ typing.add_error(
1616
+ Diagnostic::Ruby::UnknownConstant.new(
1617
+ node: node,
1618
+ name: node.children[1]
1619
+ )
1620
+ )
1621
+ end
1639
1622
 
1640
- parent = node.children[0]
1641
- _, constr = constr.synthesize(parent) if parent
1642
- const_name = constr.module_name_from_node(node)
1623
+ if constant_name
1624
+ typing.source_index.add_definition(constant: constant_name, definition: node)
1625
+ end
1643
1626
 
1644
- if const_name
1645
- if constant = module_context.const_env.lookup_constant(const_name)
1646
- typing.source_index.add_definition(constant: constant.name, definition: node)
1647
- end
1627
+ value_type, constr = constr.synthesize(node.children.last, hint: constant_type)
1648
1628
 
1649
- const_type = type_env.get(const: const_name) {}
1650
- value_type, constr = constr.synthesize(node.children.last, hint: const_type)
1651
- type = type_env.assign(
1652
- const: const_name,
1653
- type: value_type,
1654
- self_type: self_type,
1655
- instance_type: module_context.instance_type,
1656
- class_type: module_context.module_type
1657
- ) do |error|
1658
- if error
1659
- const_type = type_env.get(const: const_name)
1660
- typing.add_error(
1661
- Diagnostic::Ruby::IncompatibleAssignment.new(
1662
- node: node,
1663
- lhs_type: const_type,
1664
- rhs_type: value_type,
1665
- result: error
1666
- )
1667
- )
1668
- else
1669
- typing.add_error(
1670
- Diagnostic::Ruby::UnknownConstantAssigned.new(
1671
- node: node,
1672
- name: const_name,
1673
- context: module_context
1674
- )
1675
- )
1676
- end
1677
- end
1629
+ result = check_relation(sub_type: value_type, super_type: constant_type)
1630
+ if result.failure?
1631
+ typing.add_error(
1632
+ Diagnostic::Ruby::IncompatibleAssignment.new(
1633
+ node: node,
1634
+ lhs_type: constant_type,
1635
+ rhs_type: value_type,
1636
+ result: result
1637
+ )
1638
+ )
1678
1639
 
1679
- constr.add_typing(node, type: type)
1640
+ constr.add_typing(node, type: constant_type)
1680
1641
  else
1681
- _, constr = constr.synthesize(node.children.last)
1682
- constr.fallback_to_any(node)
1642
+ constr.add_typing(node, type: value_type)
1683
1643
  end
1684
1644
  end
1685
1645
 
@@ -2275,13 +2235,10 @@ module Steep
2275
2235
  type, constr = synthesize(rhs, hint: hint)
2276
2236
  constr.ivasgn(asgn, type)
2277
2237
  when :send
2278
- rhs_ = node.updated(:send,
2279
- [
2280
- asgn.children[0],
2281
- :"#{asgn.children[1]}=",
2282
- asgn.children[2],
2283
- rhs
2284
- ])
2238
+ children = asgn.children.dup
2239
+ children[1] = :"#{children[1]}="
2240
+ send_arg_nodes = [*children, rhs]
2241
+ rhs_ = node.updated(:send, send_arg_nodes)
2285
2242
  node_type = case node.type
2286
2243
  when :or_asgn
2287
2244
  :or
@@ -2348,11 +2305,11 @@ module Steep
2348
2305
  interface = calculate_interface(param_type, private: true)
2349
2306
  method = interface.methods[value.children[0]]
2350
2307
  if method
2351
- return_types = method.method_types.select {|method_type|
2352
- method_type.type.params.empty?
2353
- }.map {|method_type|
2354
- method_type.type.return_type
2355
- }
2308
+ return_types = method.method_types.filter_map do |method_type|
2309
+ if method_type.type.params.optional?
2310
+ method_type.type.return_type
2311
+ end
2312
+ end
2356
2313
 
2357
2314
  unless return_types.empty?
2358
2315
  type = AST::Types::Proc.new(
@@ -2360,7 +2317,7 @@ module Steep
2360
2317
  params: Interface::Function::Params.empty.with_first_param(
2361
2318
  Interface::Function::Params::PositionalParams::Required.new(param_type)
2362
2319
  ),
2363
- return_type: AST::Types::Union.build(types: return_types),
2320
+ return_type: return_types[0],
2364
2321
  location: nil
2365
2322
  ),
2366
2323
  block: nil
@@ -2727,10 +2684,88 @@ module Steep
2727
2684
  end
2728
2685
  end
2729
2686
 
2687
+ def synthesize_constant(node, parent_node, constant_name)
2688
+ const_name = module_name_from_node(parent_node, constant_name)
2689
+
2690
+ if const_name && type = type_env.get(const: const_name) { break }
2691
+ # const-type annotation wins
2692
+ if node
2693
+ constr = synthesize_children(node)
2694
+ type, constr = constr.add_typing(node, type: type)
2695
+ [type, constr, nil]
2696
+ else
2697
+ [type, self, nil]
2698
+ end
2699
+ else
2700
+ case
2701
+ when !parent_node
2702
+ constr = self
2703
+
2704
+ if (type, name = module_context.const_env.resolve(constant_name))
2705
+ if node
2706
+ _, constr = add_typing(node, type: type)
2707
+ end
2708
+
2709
+ return [type, constr, name]
2710
+ end
2711
+ when parent_node.type == :cbase
2712
+ _, constr = add_typing(parent_node, type: AST::Builtin.nil_type)
2713
+
2714
+ if (type, name = constr.module_context.const_env.toplevel(constant_name))
2715
+ if node
2716
+ _, constr = constr.add_typing(node, type: type)
2717
+ end
2718
+
2719
+ return [type, constr, name]
2720
+ end
2721
+ else
2722
+ parent_type, constr = synthesize(parent_node)
2723
+ parent_type = deep_expand_alias(parent_type)
2724
+
2725
+ case parent_type
2726
+ when AST::Types::Name::Singleton
2727
+ if (type, name = module_context.const_env.resolve_child(parent_type.name, constant_name))
2728
+ if node
2729
+ _, constr = add_typing(node, type: type)
2730
+ end
2731
+
2732
+ return [type, constr, name]
2733
+ end
2734
+ end
2735
+ end
2736
+
2737
+ if block_given?
2738
+ yield
2739
+ else
2740
+ if node
2741
+ constr.typing.add_error(
2742
+ Diagnostic::Ruby::UnknownConstant.new(node: node, name: constant_name)
2743
+ )
2744
+ end
2745
+ end
2746
+
2747
+ [AST::Builtin.any_type, constr, nil]
2748
+ end
2749
+ end
2750
+
2751
+ def optional_proc?(type)
2752
+ if type.is_a?(AST::Types::Union)
2753
+ if type.types.size == 2
2754
+ if type.types.find {|t| t.is_a?(AST::Types::Nil) }
2755
+ if proc_type = type.types.find {|t| t.is_a?(AST::Types::Proc) }
2756
+ proc_type
2757
+ end
2758
+ end
2759
+ end
2760
+ end
2761
+ end
2762
+
2730
2763
  def type_lambda(node, params_node:, body_node:, type_hint:)
2731
- block_annotations = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
2764
+ block_annotations = source.annotations(block: node, factory: checker.factory, context: nesting)
2732
2765
  params = TypeInference::BlockParams.from_node(params_node, annotations: block_annotations)
2733
2766
 
2767
+ type_hint = deep_expand_alias(type_hint) if type_hint
2768
+
2734
2769
  case type_hint
2735
2770
  when AST::Types::Proc
2736
2771
  params_hint = type_hint.type.params
@@ -2749,6 +2784,13 @@ module Steep
2749
2784
 
2750
2785
  block_constr.typing.add_context_for_body(node, context: block_constr.context)
2751
2786
 
2787
+ default_proc_function =
2788
+ Interface::Function.new(
2789
+ params: Interface::Function::Params.empty,
2790
+ return_type: AST::Builtin.any_type,
2791
+ location: nil
2792
+ )
2793
+
2752
2794
  params.params.each do |param|
2753
2795
  _, block_constr = block_constr.synthesize(param.node, hint: param.type)
2754
2796
  end
@@ -2759,17 +2801,29 @@ module Steep
2759
2801
  case block_param_type
2760
2802
  when AST::Types::Proc
2761
2803
  Interface::Block.new(type: block_param_type.type, optional: false)
2762
- when AST::Types::Union
2763
- if block_param_type.types.size == 2
2764
- if block_param_type.types.find {|t| t.is_a?(AST::Types::Nil) }
2765
- if proc_type = block_param_type.types.find {|t| t.is_a?(AST::Types::Proc) }
2766
- Interface::Block.new(type: proc_type.type, optional: true)
2767
- end
2768
- end
2804
+ else
2805
+ if proc_type = optional_proc?(block_param_type)
2806
+ Interface::Block.new(type: proc_type.type, optional: true)
2807
+ else
2808
+ block_constr.typing.add_error(
2809
+ Diagnostic::Ruby::ProcTypeExpected.new(
2810
+ node: block_param.node,
2811
+ type: block_param_type
2812
+ )
2813
+ )
2814
+
2815
+ Interface::Block.new(
2816
+ type: Interface::Function.new(
2817
+ params: Interface::Function::Params.empty,
2818
+ return_type: AST::Builtin.any_type,
2819
+ location: nil
2820
+ ),
2821
+ optional: false
2822
+ )
2769
2823
  end
2770
2824
  end
2771
2825
  else
2772
- type_hint.block
2826
+ block_hint
2773
2827
  end
2774
2828
  end
2775
2829
 
@@ -2864,7 +2918,7 @@ module Steep
2864
2918
 
2865
2919
  constr = synthesize_children(node, skips: skips)
2866
2920
  if block_params
2867
- block_annotations = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
2921
+ block_annotations = source.annotations(block: node, factory: checker.factory, context: nesting)
2868
2922
 
2869
2923
  constr.type_block_without_hint(
2870
2924
  node: node,
@@ -2885,7 +2939,7 @@ module Steep
2885
2939
 
2886
2940
  constr = synthesize_children(node, skips: skips)
2887
2941
  if block_params
2888
- block_annotations = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
2942
+ block_annotations = source.annotations(block: node, factory: checker.factory, context: nesting)
2889
2943
 
2890
2944
  constr.type_block_without_hint(
2891
2945
  node: node,
@@ -3266,7 +3320,7 @@ module Steep
3266
3320
 
3267
3321
  if block_params
3268
3322
  # block is given
3269
- block_annotations = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
3323
+ block_annotations = source.annotations(block: node, factory: checker.factory, context: nesting)
3270
3324
  block_params_ = TypeInference::BlockParams.from_node(block_params, annotations: block_annotations)
3271
3325
 
3272
3326
  if method_type.block
@@ -3608,8 +3662,7 @@ module Steep
3608
3662
  if implements = block_annotations.implement_module_annotation
3609
3663
  module_context = default_module_context(
3610
3664
  implements.name,
3611
- const_env: self.module_context.const_env,
3612
- current_namespace: current_namespace
3665
+ const_env: self.module_context.const_env
3613
3666
  )
3614
3667
 
3615
3668
  self_type = module_context.module_type
@@ -3663,30 +3716,25 @@ module Steep
3663
3716
  end
3664
3717
  end
3665
3718
 
3666
- def current_namespace
3667
- module_context&.current_namespace || AST::Namespace.root
3719
+ def nesting
3720
+ module_context&.nesting
3668
3721
  end
3669
3722
 
3670
- def nested_namespace_for_module(module_name)
3671
- if module_name.namespace.relative?
3672
- (current_namespace + module_name.namespace).append(module_name.name)
3673
- else
3674
- module_name.to_namespace
3723
+ def absolute_nested_module_name(module_name)
3724
+ n = nesting
3725
+ while n && !n[1]
3726
+ n = n[0]
3675
3727
  end
3676
- end
3677
3728
 
3678
- def absolute_name(module_name)
3679
- if current_namespace
3680
- module_name.with_prefix(current_namespace)
3681
- else
3729
+ if n
3682
3730
  module_name.absolute!
3731
+ else
3732
+ n + module_name
3683
3733
  end
3684
3734
  end
3685
3735
 
3686
- def absolute_type(type)
3687
- if type
3688
- checker.builder.absolute_type(type, current: current_namespace)
3689
- end
3736
+ def absolute_name(name)
3737
+ checker.factory.absolute_type_name(name, context: nesting)
3690
3738
  end
3691
3739
 
3692
3740
  def union_type(*types)
@@ -3915,6 +3963,20 @@ module Steep
3915
3963
  constr.add_typing(node, type: AST::Types::Tuple.new(types: element_types))
3916
3964
  end
3917
3965
 
3966
+ def try_convert(type, method)
3967
+ interface = checker.factory.interface(type, private: false)
3968
+ if entry = interface.methods[method]
3969
+ method_type = entry.method_types.find do |method_type|
3970
+ method_type.type.params.optional?
3971
+ end
3972
+
3973
+ method_type.type.return_type
3974
+ end
3975
+ rescue => exn
3976
+ Steep.log_error(exn, message: "Unexpected error when converting #{type.to_s} with #{method}")
3977
+ nil
3978
+ end
3979
+
3918
3980
  def try_array_type(node, hint)
3919
3981
  element_hint = hint ? hint.args[0] : nil
3920
3982
 
@@ -3925,8 +3987,14 @@ module Steep
3925
3987
  case child.type
3926
3988
  when :splat
3927
3989
  type, constr = constr.synthesize(child.children[0], hint: hint)
3928
- if AST::Builtin::Array.instance_type?(type)
3990
+
3991
+ type = try_convert(type, :to_a) || type
3992
+
3993
+ case
3994
+ when AST::Builtin::Array.instance_type?(type)
3929
3995
  element_types << type.args[0]
3996
+ when type.is_a?(AST::Types::Tuple)
3997
+ element_types.push(*type.types)
3930
3998
  else
3931
3999
  element_types.push(*flatten_array_elements(type))
3932
4000
  end