steep 0.49.1 → 0.52.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 +22 -0
- data/Gemfile +4 -1
- data/Gemfile.lock +8 -5
- data/lib/steep/ast/annotation/collection.rb +10 -8
- data/lib/steep/ast/types/factory.rb +5 -5
- data/lib/steep/cli.rb +83 -1
- data/lib/steep/diagnostic/deprecated/unknown_constant_assigned.rb +28 -0
- data/lib/steep/diagnostic/ruby.rb +21 -15
- data/lib/steep/drivers/check.rb +1 -0
- 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 +6 -3
- data/lib/steep/source.rb +71 -18
- data/lib/steep/type_construction.rb +209 -162
- 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/test_expectations.yml +77 -17
- 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 +5 -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,6 +2684,82 @@ 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
|
+
when AST::Types::Any
|
2735
|
+
# Couldn't detect the type of the parent constant
|
2736
|
+
# Skip reporting error for this node.
|
2737
|
+
if node
|
2738
|
+
_, constr = add_typing(node, type: parent_type)
|
2739
|
+
end
|
2740
|
+
|
2741
|
+
return [parent_type, constr, nil]
|
2742
|
+
end
|
2743
|
+
end
|
2744
|
+
|
2745
|
+
if block_given?
|
2746
|
+
yield
|
2747
|
+
else
|
2748
|
+
if node
|
2749
|
+
constr.typing.add_error(
|
2750
|
+
Diagnostic::Ruby::UnknownConstant.new(node: node, name: constant_name)
|
2751
|
+
)
|
2752
|
+
end
|
2753
|
+
end
|
2754
|
+
|
2755
|
+
if node
|
2756
|
+
_, constr = add_typing(node, type: AST::Builtin.any_type)
|
2757
|
+
end
|
2758
|
+
|
2759
|
+
[AST::Builtin.any_type, constr, nil]
|
2760
|
+
end
|
2761
|
+
end
|
2762
|
+
|
2730
2763
|
def optional_proc?(type)
|
2731
2764
|
if type.is_a?(AST::Types::Union)
|
2732
2765
|
if type.types.size == 2
|
@@ -2740,7 +2773,7 @@ module Steep
|
|
2740
2773
|
end
|
2741
2774
|
|
2742
2775
|
def type_lambda(node, params_node:, body_node:, type_hint:)
|
2743
|
-
block_annotations = source.annotations(block: node, factory: checker.factory,
|
2776
|
+
block_annotations = source.annotations(block: node, factory: checker.factory, context: nesting)
|
2744
2777
|
params = TypeInference::BlockParams.from_node(params_node, annotations: block_annotations)
|
2745
2778
|
|
2746
2779
|
type_hint = deep_expand_alias(type_hint) if type_hint
|
@@ -2897,7 +2930,7 @@ module Steep
|
|
2897
2930
|
|
2898
2931
|
constr = synthesize_children(node, skips: skips)
|
2899
2932
|
if block_params
|
2900
|
-
block_annotations = source.annotations(block: node, factory: checker.factory,
|
2933
|
+
block_annotations = source.annotations(block: node, factory: checker.factory, context: nesting)
|
2901
2934
|
|
2902
2935
|
constr.type_block_without_hint(
|
2903
2936
|
node: node,
|
@@ -2918,7 +2951,7 @@ module Steep
|
|
2918
2951
|
|
2919
2952
|
constr = synthesize_children(node, skips: skips)
|
2920
2953
|
if block_params
|
2921
|
-
block_annotations = source.annotations(block: node, factory: checker.factory,
|
2954
|
+
block_annotations = source.annotations(block: node, factory: checker.factory, context: nesting)
|
2922
2955
|
|
2923
2956
|
constr.type_block_without_hint(
|
2924
2957
|
node: node,
|
@@ -3299,7 +3332,7 @@ module Steep
|
|
3299
3332
|
|
3300
3333
|
if block_params
|
3301
3334
|
# block is given
|
3302
|
-
block_annotations = source.annotations(block: node, factory: checker.factory,
|
3335
|
+
block_annotations = source.annotations(block: node, factory: checker.factory, context: nesting)
|
3303
3336
|
block_params_ = TypeInference::BlockParams.from_node(block_params, annotations: block_annotations)
|
3304
3337
|
|
3305
3338
|
if method_type.block
|
@@ -3641,8 +3674,7 @@ module Steep
|
|
3641
3674
|
if implements = block_annotations.implement_module_annotation
|
3642
3675
|
module_context = default_module_context(
|
3643
3676
|
implements.name,
|
3644
|
-
const_env: self.module_context.const_env
|
3645
|
-
current_namespace: current_namespace
|
3677
|
+
const_env: self.module_context.const_env
|
3646
3678
|
)
|
3647
3679
|
|
3648
3680
|
self_type = module_context.module_type
|
@@ -3696,30 +3728,25 @@ module Steep
|
|
3696
3728
|
end
|
3697
3729
|
end
|
3698
3730
|
|
3699
|
-
def
|
3700
|
-
module_context&.
|
3731
|
+
def nesting
|
3732
|
+
module_context&.nesting
|
3701
3733
|
end
|
3702
3734
|
|
3703
|
-
def
|
3704
|
-
|
3705
|
-
|
3706
|
-
|
3707
|
-
module_name.to_namespace
|
3735
|
+
def absolute_nested_module_name(module_name)
|
3736
|
+
n = nesting
|
3737
|
+
while n && !n[1]
|
3738
|
+
n = n[0]
|
3708
3739
|
end
|
3709
|
-
end
|
3710
3740
|
|
3711
|
-
|
3712
|
-
if current_namespace
|
3713
|
-
module_name.with_prefix(current_namespace)
|
3714
|
-
else
|
3741
|
+
if n
|
3715
3742
|
module_name.absolute!
|
3743
|
+
else
|
3744
|
+
n + module_name
|
3716
3745
|
end
|
3717
3746
|
end
|
3718
3747
|
|
3719
|
-
def
|
3720
|
-
|
3721
|
-
checker.builder.absolute_type(type, current: current_namespace)
|
3722
|
-
end
|
3748
|
+
def absolute_name(name)
|
3749
|
+
checker.factory.absolute_type_name(name, context: nesting)
|
3723
3750
|
end
|
3724
3751
|
|
3725
3752
|
def union_type(*types)
|
@@ -3948,6 +3975,20 @@ module Steep
|
|
3948
3975
|
constr.add_typing(node, type: AST::Types::Tuple.new(types: element_types))
|
3949
3976
|
end
|
3950
3977
|
|
3978
|
+
def try_convert(type, method)
|
3979
|
+
interface = checker.factory.interface(type, private: false)
|
3980
|
+
if entry = interface.methods[method]
|
3981
|
+
method_type = entry.method_types.find do |method_type|
|
3982
|
+
method_type.type.params.optional?
|
3983
|
+
end
|
3984
|
+
|
3985
|
+
method_type.type.return_type
|
3986
|
+
end
|
3987
|
+
rescue => exn
|
3988
|
+
Steep.log_error(exn, message: "Unexpected error when converting #{type.to_s} with #{method}")
|
3989
|
+
nil
|
3990
|
+
end
|
3991
|
+
|
3951
3992
|
def try_array_type(node, hint)
|
3952
3993
|
element_hint = hint ? hint.args[0] : nil
|
3953
3994
|
|
@@ -3958,8 +3999,14 @@ module Steep
|
|
3958
3999
|
case child.type
|
3959
4000
|
when :splat
|
3960
4001
|
type, constr = constr.synthesize(child.children[0], hint: hint)
|
3961
|
-
|
4002
|
+
|
4003
|
+
type = try_convert(type, :to_a) || type
|
4004
|
+
|
4005
|
+
case
|
4006
|
+
when AST::Builtin::Array.instance_type?(type)
|
3962
4007
|
element_types << type.args[0]
|
4008
|
+
when type.is_a?(AST::Types::Tuple)
|
4009
|
+
element_types.push(*type.types)
|
3963
4010
|
else
|
3964
4011
|
element_types.push(*flatten_array_elements(type))
|
3965
4012
|
end
|
@@ -2,33 +2,51 @@ module Steep
|
|
2
2
|
module TypeInference
|
3
3
|
class ConstantEnv
|
4
4
|
attr_reader :context
|
5
|
-
attr_reader :cache
|
6
5
|
attr_reader :factory
|
7
|
-
attr_reader :
|
6
|
+
attr_reader :resolver
|
8
7
|
|
9
8
|
# ConstantEnv receives an TypeName as a context, not a Namespace, because this is a simulation of Ruby.
|
10
9
|
# Any namespace is a module or class.
|
11
|
-
def initialize(factory:, context:)
|
10
|
+
def initialize(factory:, context:, resolver:)
|
12
11
|
@cache = {}
|
13
12
|
@factory = factory
|
14
13
|
@context = context
|
15
|
-
@
|
14
|
+
@resolver = resolver
|
16
15
|
end
|
17
16
|
|
18
|
-
def
|
19
|
-
|
17
|
+
def resolve(name)
|
18
|
+
decompose_constant(
|
19
|
+
resolver.resolve(name, context: context)
|
20
|
+
)
|
20
21
|
end
|
21
22
|
|
22
|
-
def
|
23
|
-
|
24
|
-
|
23
|
+
def toplevel(name)
|
24
|
+
decompose_constant(
|
25
|
+
resolver.table.toplevel[name]
|
26
|
+
)
|
27
|
+
end
|
28
|
+
|
29
|
+
def constants
|
30
|
+
resolver.constants(context).transform_values {|c| decompose_constant(c) }
|
31
|
+
end
|
32
|
+
|
33
|
+
def resolve_child(module_name, constant_name)
|
34
|
+
decompose_constant(
|
35
|
+
resolver.resolve_child(module_name, constant_name)
|
36
|
+
)
|
37
|
+
end
|
38
|
+
|
39
|
+
def children(module_name)
|
40
|
+
resolver.children(module_name).transform_values {|c| decompose_constant(c) }
|
41
|
+
end
|
25
42
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
43
|
+
def decompose_constant(constant)
|
44
|
+
if constant
|
45
|
+
[
|
46
|
+
factory.type(constant.type),
|
47
|
+
constant.name,
|
48
|
+
constant.entry
|
49
|
+
]
|
32
50
|
end
|
33
51
|
end
|
34
52
|
end
|