steep 0.49.0 → 0.51.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -0
- data/Gemfile +4 -1
- data/Gemfile.lock +9 -6
- data/lib/steep/ast/annotation/collection.rb +10 -8
- data/lib/steep/ast/types/factory.rb +5 -5
- data/lib/steep/cli.rb +13 -0
- data/lib/steep/diagnostic/deprecated/unknown_constant_assigned.rb +28 -0
- data/lib/steep/diagnostic/ruby.rb +34 -15
- data/lib/steep/drivers/check.rb +3 -2
- data/lib/steep/drivers/langserver.rb +2 -2
- data/lib/steep/drivers/stats.rb +1 -0
- data/lib/steep/drivers/utils/jobs_count.rb +1 -1
- data/lib/steep/drivers/watch.rb +1 -1
- data/lib/steep/index/source_index.rb +18 -1
- data/lib/steep/interface/function.rb +5 -0
- data/lib/steep/module_helper.rb +4 -7
- data/lib/steep/project.rb +15 -1
- data/lib/steep/server/interaction_worker.rb +47 -4
- data/lib/steep/server/master.rb +10 -5
- data/lib/steep/server/type_check_worker.rb +19 -4
- data/lib/steep/server/worker_process.rb +15 -6
- data/lib/steep/services/completion_provider.rb +109 -1
- data/lib/steep/services/goto_service.rb +23 -10
- data/lib/steep/services/hover_content.rb +52 -4
- data/lib/steep/services/type_check_service.rb +8 -3
- data/lib/steep/signature/validator.rb +12 -5
- data/lib/steep/source.rb +19 -13
- data/lib/steep/type_construction.rb +238 -170
- data/lib/steep/type_inference/constant_env.rb +33 -15
- data/lib/steep/type_inference/context.rb +6 -7
- data/lib/steep/type_inference/type_env.rb +16 -54
- data/lib/steep/version.rb +1 -1
- data/smoke/const/test_expectations.yml +24 -19
- data/smoke/diagnostics/proc_type_expected.rb +3 -0
- data/smoke/diagnostics/test_expectations.yml +92 -10
- data/smoke/integer/test_expectations.yml +24 -4
- data/smoke/method/test_expectations.yml +30 -0
- data/smoke/regression/test_expectations.yml +24 -0
- data/smoke/yield/test_expectations.yml +20 -0
- data/steep.gemspec +1 -1
- 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,
|
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 =
|
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
|
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,
|
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
|
-
|
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
|
-
|
347
|
-
|
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,
|
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
|
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
|
-
|
458
|
-
|
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
|
-
|
464
|
-
|
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
|
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,
|
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,
|
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
|
-
|
1501
|
-
|
1502
|
-
|
1503
|
-
|
1504
|
-
|
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
|
-
|
1542
|
-
|
1543
|
-
|
1544
|
-
|
1545
|
-
|
1546
|
-
|
1547
|
-
|
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
|
-
|
1615
|
-
|
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
|
-
|
1624
|
-
|
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
|
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 =
|
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
|
-
|
1641
|
-
|
1642
|
-
|
1623
|
+
if constant_name
|
1624
|
+
typing.source_index.add_definition(constant: constant_name, definition: node)
|
1625
|
+
end
|
1643
1626
|
|
1644
|
-
|
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
|
-
|
1650
|
-
|
1651
|
-
|
1652
|
-
|
1653
|
-
|
1654
|
-
|
1655
|
-
|
1656
|
-
|
1657
|
-
|
1658
|
-
|
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:
|
1640
|
+
constr.add_typing(node, type: constant_type)
|
1680
1641
|
else
|
1681
|
-
|
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
|
-
|
2279
|
-
|
2280
|
-
|
2281
|
-
|
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.
|
2352
|
-
method_type.type.params.
|
2353
|
-
|
2354
|
-
|
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:
|
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,
|
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
|
-
|
2763
|
-
if
|
2764
|
-
|
2765
|
-
|
2766
|
-
|
2767
|
-
|
2768
|
-
|
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
|
-
|
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,
|
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,
|
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,
|
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
|
3667
|
-
module_context&.
|
3719
|
+
def nesting
|
3720
|
+
module_context&.nesting
|
3668
3721
|
end
|
3669
3722
|
|
3670
|
-
def
|
3671
|
-
|
3672
|
-
|
3673
|
-
|
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
|
-
|
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
|
3687
|
-
|
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
|
-
|
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
|