steep 1.4.0 → 1.5.0.pre.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/.vscode/steep-shared.code-snippets +41 -0
- data/CHANGELOG.md +37 -0
- data/Gemfile +2 -5
- data/Gemfile.lock +20 -17
- data/Gemfile.steep +1 -1
- data/Gemfile.steep.lock +6 -6
- data/Rakefile +198 -0
- data/Steepfile +3 -1
- data/lib/steep/ast/builtin.rb +9 -7
- data/lib/steep/ast/node/type_application.rb +13 -5
- data/lib/steep/ast/node/type_assertion.rb +28 -9
- data/lib/steep/ast/types/factory.rb +39 -7
- data/lib/steep/cli.rb +2 -1
- data/lib/steep/diagnostic/deprecated/else_on_exhaustive_case.rb +20 -0
- data/lib/steep/diagnostic/lsp_formatter.rb +3 -3
- data/lib/steep/diagnostic/ruby.rb +73 -12
- data/lib/steep/drivers/annotations.rb +1 -0
- data/lib/steep/drivers/check.rb +18 -13
- data/lib/steep/drivers/checkfile.rb +1 -1
- data/lib/steep/drivers/diagnostic_printer.rb +6 -4
- data/lib/steep/drivers/init.rb +2 -1
- data/lib/steep/drivers/print_project.rb +3 -1
- data/lib/steep/drivers/stats.rb +1 -1
- data/lib/steep/drivers/utils/driver_helper.rb +10 -8
- data/lib/steep/drivers/utils/jobs_option.rb +6 -1
- data/lib/steep/drivers/validate.rb +9 -5
- data/lib/steep/drivers/watch.rb +8 -3
- data/lib/steep/expectations.rb +144 -75
- data/lib/steep/index/signature_symbol_provider.rb +22 -13
- data/lib/steep/node_helper.rb +172 -0
- data/lib/steep/server/base_worker.rb +2 -1
- data/lib/steep/server/change_buffer.rb +17 -15
- data/lib/steep/server/interaction_worker.rb +20 -0
- data/lib/steep/server/lsp_formatter.rb +20 -1
- data/lib/steep/server/master.rb +51 -36
- data/lib/steep/server/type_check_worker.rb +18 -2
- data/lib/steep/server/worker_process.rb +19 -2
- data/lib/steep/services/completion_provider.rb +189 -3
- data/lib/steep/services/file_loader.rb +1 -1
- data/lib/steep/services/goto_service.rb +123 -27
- data/lib/steep/services/signature_help_provider.rb +1 -6
- data/lib/steep/signature/validator.rb +6 -1
- data/lib/steep/source.rb +165 -108
- data/lib/steep/subtyping/check.rb +5 -3
- data/lib/steep/subtyping/variable_variance.rb +11 -0
- data/lib/steep/thread_waiter.rb +35 -0
- data/lib/steep/type_construction.rb +416 -171
- data/lib/steep/type_inference/block_params.rb +50 -9
- data/lib/steep/type_inference/context.rb +4 -0
- data/lib/steep/type_inference/context_array.rb +6 -6
- data/lib/steep/type_inference/logic_type_interpreter.rb +202 -68
- data/lib/steep/typing.rb +5 -4
- data/lib/steep/version.rb +1 -1
- data/lib/steep.rb +21 -14
- data/sample/Steepfile +1 -0
- data/sig/shims/bundler.rbs +3 -0
- data/sig/shims/language-server_protocol.rbs +151 -10
- data/sig/shims/parser/nodes.rbs +210 -0
- data/sig/shims/parser.rbs +10 -0
- data/sig/steep/ast/builtin.rbs +2 -2
- data/sig/steep/ast/node/type_application.rbs +2 -2
- data/sig/steep/ast/node/type_assertion.rbs +8 -2
- data/sig/steep/ast/types/factory.rbs +28 -1
- data/sig/steep/diagnostic/deprecated/else_on_exhaustive_case.rbs +13 -0
- data/sig/steep/diagnostic/lsp_formatter.rbs +5 -2
- data/sig/steep/diagnostic/ruby.rbs +76 -6
- data/sig/steep/drivers/annotations.rbs +5 -5
- data/sig/steep/drivers/check.rbs +11 -11
- data/sig/steep/drivers/diagnostic_printer.rbs +9 -9
- data/sig/steep/drivers/init.rbs +6 -6
- data/sig/steep/drivers/print_project.rbs +4 -4
- data/sig/steep/drivers/utils/driver_helper.rbs +8 -6
- data/sig/steep/drivers/validate.rbs +4 -4
- data/sig/steep/drivers/watch.rbs +1 -1
- data/sig/steep/expectations.rbs +72 -0
- data/sig/steep/index/signature_symbol_provider.rbs +22 -10
- data/sig/steep/interface/block.rbs +2 -0
- data/sig/steep/interface/function.rbs +2 -2
- data/sig/steep/node_helper.rbs +56 -0
- data/sig/steep/path_helper.rbs +1 -1
- data/sig/steep/project/options.rbs +1 -1
- data/sig/steep/range_extension.rbs +2 -2
- data/sig/steep/server/master.rbs +16 -2
- data/sig/steep/server/type_check_worker.rbs +5 -1
- data/sig/steep/server/worker_process.rbs +5 -1
- data/sig/steep/services/completion_provider.rbs +31 -1
- data/sig/steep/services/goto_service.rbs +80 -19
- data/sig/steep/source.rbs +27 -4
- data/sig/steep/subtyping/variable_variance.rbs +9 -9
- data/sig/steep/thread_waiter.rbs +13 -0
- data/sig/steep/type_construction.rbs +26 -9
- data/sig/steep/type_inference/block_params.rbs +13 -1
- data/sig/steep/type_inference/context.rbs +5 -1
- data/sig/steep/type_inference/context_array.rbs +16 -15
- data/sig/steep/type_inference/logic_type_interpreter.rbs +36 -6
- data/sig/steep/type_inference/type_env_builder.rbs +4 -0
- data/sig/steep/typing.rbs +22 -20
- data/sig/steep.rbs +14 -13
- data/smoke/and/a.rb +1 -1
- data/smoke/and/test_expectations.yml +5 -7
- data/smoke/diagnostics/incompatible_annotation.rb +1 -1
- data/smoke/diagnostics/test_expectations.yml +2 -2
- data/smoke/enumerator/a.rb +0 -7
- data/smoke/enumerator/b.rb +0 -2
- data/smoke/enumerator/test_expectations.yml +17 -105
- data/smoke/lambda/a.rb +0 -5
- data/smoke/lambda/test_expectations.yml +0 -22
- data/smoke/type_case/test_expectations.yml +10 -0
- data/steep.gemspec +2 -2
- metadata +16 -9
@@ -877,10 +877,6 @@ module Steep
|
|
877
877
|
yield_self do
|
878
878
|
if self_type && method_context!.method
|
879
879
|
if super_def = method_context!.super_method
|
880
|
-
each_child_node(node) do |child|
|
881
|
-
synthesize(child)
|
882
|
-
end
|
883
|
-
|
884
880
|
super_method = Interface::Shape::Entry.new(
|
885
881
|
method_types: super_def.defs.map {|type_def|
|
886
882
|
decl = TypeInference::MethodCall::MethodDecl.new(
|
@@ -902,7 +898,8 @@ module Steep
|
|
902
898
|
arguments: node.children,
|
903
899
|
block_params: nil,
|
904
900
|
block_body: nil,
|
905
|
-
tapp: nil
|
901
|
+
tapp: nil,
|
902
|
+
hint: hint
|
906
903
|
)
|
907
904
|
|
908
905
|
if call && constr
|
@@ -927,12 +924,12 @@ module Steep
|
|
927
924
|
fallback_to_any(node) { error }
|
928
925
|
end
|
929
926
|
else
|
930
|
-
fallback_to_any
|
927
|
+
type_check_untyped_args(node.children).fallback_to_any(node) do
|
931
928
|
Diagnostic::Ruby::UnexpectedSuper.new(node: node, method: method_context!.name)
|
932
929
|
end
|
933
930
|
end
|
934
931
|
else
|
935
|
-
fallback_to_any
|
932
|
+
type_check_untyped_args(node.children).fallback_to_any(node)
|
936
933
|
end
|
937
934
|
end
|
938
935
|
|
@@ -949,47 +946,75 @@ module Steep
|
|
949
946
|
self_type: module_context&.instance_type,
|
950
947
|
definition: module_context&.instance_definition
|
951
948
|
) do |new|
|
949
|
+
# @type var new: TypeConstruction
|
950
|
+
|
952
951
|
new.typing.add_context_for_node(node, context: new.context)
|
953
952
|
new.typing.add_context_for_body(node, context: new.context)
|
954
953
|
|
955
|
-
new.method_context
|
954
|
+
new.method_context!.tap do |method_context|
|
956
955
|
if method_context.method
|
957
|
-
|
958
|
-
|
956
|
+
if owner = method_context.method.implemented_in || method_context.method.defined_in
|
957
|
+
method_name = InstanceMethodName.new(type_name: owner, method_name: name)
|
958
|
+
new.typing.source_index.add_definition(method: method_name, definition: node)
|
959
|
+
end
|
959
960
|
end
|
960
961
|
end
|
961
962
|
|
962
963
|
new = new.synthesize_children(args_node)
|
963
964
|
|
964
965
|
body_pair = if body_node
|
965
|
-
return_type = expand_alias(new.method_context
|
966
|
-
if
|
966
|
+
return_type = expand_alias(new.method_context!.return_type)
|
967
|
+
if !return_type.is_a?(AST::Types::Void)
|
967
968
|
new.check(body_node, return_type) do |_, actual_type, result|
|
968
|
-
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
969
|
+
if new.method_context!.attribute_setter?
|
970
|
+
typing.add_error(
|
971
|
+
Diagnostic::Ruby::SetterBodyTypeMismatch.new(
|
972
|
+
node: node,
|
973
|
+
expected: new.method_context!.return_type,
|
974
|
+
actual: actual_type,
|
975
|
+
result: result,
|
976
|
+
method_name: new.method_context!.name
|
977
|
+
)
|
974
978
|
)
|
975
|
-
|
979
|
+
else
|
980
|
+
typing.add_error(
|
981
|
+
Diagnostic::Ruby::MethodBodyTypeMismatch.new(
|
982
|
+
node: node,
|
983
|
+
expected: new.method_context!.return_type,
|
984
|
+
actual: actual_type,
|
985
|
+
result: result
|
986
|
+
)
|
987
|
+
)
|
988
|
+
end
|
976
989
|
end
|
977
990
|
else
|
978
991
|
new.synthesize(body_node)
|
979
992
|
end
|
980
993
|
else
|
981
|
-
return_type = expand_alias(new.method_context
|
982
|
-
if
|
994
|
+
return_type = expand_alias(new.method_context!.return_type)
|
995
|
+
if !return_type.is_a?(AST::Types::Void)
|
983
996
|
result = check_relation(sub_type: AST::Builtin.nil_type, super_type: return_type)
|
984
997
|
if result.failure?
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
998
|
+
if new.method_context!.attribute_setter?
|
999
|
+
typing.add_error(
|
1000
|
+
Diagnostic::Ruby::SetterBodyTypeMismatch.new(
|
1001
|
+
node: node,
|
1002
|
+
expected: new.method_context!.return_type,
|
1003
|
+
actual: AST::Builtin.nil_type,
|
1004
|
+
result: result,
|
1005
|
+
method_name: new.method_context!.name
|
1006
|
+
)
|
1007
|
+
)
|
1008
|
+
else
|
1009
|
+
typing.add_error(
|
1010
|
+
Diagnostic::Ruby::MethodBodyTypeMismatch.new(
|
1011
|
+
node: node,
|
1012
|
+
expected: new.method_context!.return_type,
|
1013
|
+
actual: AST::Builtin.nil_type,
|
1014
|
+
result: result
|
1015
|
+
)
|
991
1016
|
)
|
992
|
-
|
1017
|
+
end
|
993
1018
|
end
|
994
1019
|
end
|
995
1020
|
|
@@ -1100,12 +1125,9 @@ module Steep
|
|
1100
1125
|
return_value_node = node.children[0]
|
1101
1126
|
value_type, constr = synthesize(return_value_node, hint: method_return_type)
|
1102
1127
|
else
|
1103
|
-
|
1104
|
-
|
1105
|
-
|
1106
|
-
end
|
1107
|
-
|
1108
|
-
value_type = AST::Builtin::Array.instance_type(union_type(*return_types))
|
1128
|
+
# It returns an array
|
1129
|
+
array = node.updated(:array)
|
1130
|
+
value_type, constr = synthesize(array, hint: method_return_type)
|
1109
1131
|
end
|
1110
1132
|
|
1111
1133
|
if method_return_type
|
@@ -1113,14 +1135,26 @@ module Steep
|
|
1113
1135
|
result = constr.check_relation(sub_type: value_type, super_type: method_return_type)
|
1114
1136
|
|
1115
1137
|
if result.failure?
|
1116
|
-
|
1117
|
-
|
1118
|
-
|
1119
|
-
|
1120
|
-
|
1121
|
-
|
1138
|
+
if method_context.attribute_setter?
|
1139
|
+
typing.add_error(
|
1140
|
+
Diagnostic::Ruby::SetterReturnTypeMismatch.new(
|
1141
|
+
node: node,
|
1142
|
+
method_name: method_context.name,
|
1143
|
+
expected: method_return_type,
|
1144
|
+
actual: value_type,
|
1145
|
+
result: result
|
1146
|
+
)
|
1122
1147
|
)
|
1123
|
-
|
1148
|
+
else
|
1149
|
+
typing.add_error(
|
1150
|
+
Diagnostic::Ruby::ReturnTypeMismatch.new(
|
1151
|
+
node: node,
|
1152
|
+
expected: method_return_type,
|
1153
|
+
actual: value_type,
|
1154
|
+
result: result
|
1155
|
+
)
|
1156
|
+
)
|
1157
|
+
end
|
1124
1158
|
end
|
1125
1159
|
end
|
1126
1160
|
end
|
@@ -1408,11 +1442,17 @@ module Steep
|
|
1408
1442
|
# @type var super_node: Parser::AST::Node?
|
1409
1443
|
|
1410
1444
|
name_node, super_node, _ = node.children
|
1411
|
-
|
1412
|
-
|
1413
|
-
|
1414
|
-
|
1445
|
+
|
1446
|
+
if name_node.type == :const
|
1447
|
+
_, constr, class_name = synthesize_constant_decl(name_node, name_node.children[0], name_node.children[1]) do
|
1448
|
+
typing.add_error(
|
1449
|
+
Diagnostic::Ruby::UnknownConstant.new(node: name_node, name: name_node.children[1]).class!
|
1450
|
+
)
|
1451
|
+
end
|
1452
|
+
else
|
1453
|
+
_, constr = synthesize(name_node)
|
1415
1454
|
end
|
1455
|
+
|
1416
1456
|
if class_name
|
1417
1457
|
typing.source_index.add_definition(constant: class_name, definition: name_node)
|
1418
1458
|
end
|
@@ -1459,8 +1499,13 @@ module Steep
|
|
1459
1499
|
|
1460
1500
|
# @type var name_node: Parser::AST::Node
|
1461
1501
|
name_node, _ = node.children
|
1462
|
-
|
1463
|
-
|
1502
|
+
|
1503
|
+
if name_node.type == :const
|
1504
|
+
_, constr, module_name = synthesize_constant_decl(name_node, name_node.children[0], name_node.children[1]) do
|
1505
|
+
typing.add_error Diagnostic::Ruby::UnknownConstant.new(node: name_node, name: name_node.children[1]).module!
|
1506
|
+
end
|
1507
|
+
else
|
1508
|
+
_, constr = synthesize(name_node)
|
1464
1509
|
end
|
1465
1510
|
|
1466
1511
|
if module_name
|
@@ -1677,7 +1722,7 @@ module Steep
|
|
1677
1722
|
left_type, constr, left_context = synthesize(left_node, hint: hint, condition: true).to_ary
|
1678
1723
|
|
1679
1724
|
interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing, config: builder_config)
|
1680
|
-
|
1725
|
+
left_truthy, left_falsy = interpreter.eval(env: left_context.type_env, node: left_node)
|
1681
1726
|
|
1682
1727
|
if left_type.is_a?(AST::Types::Logic::Env)
|
1683
1728
|
left_type = left_type.type
|
@@ -1685,32 +1730,40 @@ module Steep
|
|
1685
1730
|
|
1686
1731
|
right_type, constr, right_context =
|
1687
1732
|
constr
|
1688
|
-
.update_type_env {
|
1733
|
+
.update_type_env { left_truthy.env }
|
1689
1734
|
.tap {|constr| typing.add_context_for_node(right_node, context: constr.context) }
|
1690
1735
|
.for_branch(right_node)
|
1691
1736
|
.synthesize(right_node, hint: hint, condition: true).to_ary
|
1692
1737
|
|
1693
|
-
|
1738
|
+
right_truthy, right_falsy = interpreter.eval(env: right_context.type_env, node: right_node)
|
1694
1739
|
|
1695
|
-
|
1696
|
-
|
1697
|
-
|
1698
|
-
|
1699
|
-
|
1700
|
-
|
1740
|
+
case
|
1741
|
+
when left_truthy.unreachable
|
1742
|
+
# Always left_falsy
|
1743
|
+
env = left_falsy.env
|
1744
|
+
type = left_falsy.type
|
1745
|
+
when left_falsy.unreachable
|
1746
|
+
# Always left_truthy ==> right
|
1747
|
+
env = right_context.type_env
|
1748
|
+
type = right_type
|
1749
|
+
when right_truthy.unreachable && right_falsy.unreachable
|
1750
|
+
env = left_falsy.env
|
1751
|
+
type = left_falsy.type
|
1752
|
+
else
|
1753
|
+
env = context.type_env.join(left_falsy.env, right_context.type_env)
|
1754
|
+
type = union_type(left_falsy.type, right_type)
|
1701
1755
|
|
1702
|
-
|
1703
|
-
|
1704
|
-
|
1705
|
-
|
1706
|
-
else
|
1707
|
-
union_type(right_type, AST::Builtin.nil_type)
|
1756
|
+
unless type.is_a?(AST::Types::Any)
|
1757
|
+
if check_relation(sub_type: type, super_type: AST::Types::Boolean.new).success?
|
1758
|
+
type = AST::Types::Boolean.new
|
1759
|
+
end
|
1708
1760
|
end
|
1761
|
+
end
|
1709
1762
|
|
1710
1763
|
if condition
|
1711
1764
|
type = AST::Types::Logic::Env.new(
|
1712
|
-
truthy:
|
1713
|
-
falsy: context.type_env.join(
|
1765
|
+
truthy: right_truthy.env,
|
1766
|
+
falsy: context.type_env.join(left_falsy.env, right_falsy.env),
|
1714
1767
|
type: type
|
1715
1768
|
)
|
1716
1769
|
end
|
@@ -1725,40 +1778,47 @@ module Steep
|
|
1725
1778
|
left_type, constr, left_context = synthesize(left_node, hint: hint, condition: true).to_ary
|
1726
1779
|
|
1727
1780
|
interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing, config: builder_config)
|
1728
|
-
|
1781
|
+
left_truthy, left_falsy = interpreter.eval(env: left_context.type_env, node: left_node)
|
1729
1782
|
|
1730
1783
|
if left_type.is_a?(AST::Types::Logic::Env)
|
1731
1784
|
left_type = left_type.type
|
1732
1785
|
end
|
1733
|
-
left_type, _ = checker.factory.unwrap_optional(left_type)
|
1734
1786
|
|
1735
1787
|
right_type, constr, right_context =
|
1736
1788
|
constr
|
1737
|
-
.update_type_env {
|
1789
|
+
.update_type_env { left_falsy.env }
|
1738
1790
|
.tap {|constr| typing.add_context_for_node(right_node, context: constr.context) }
|
1739
1791
|
.for_branch(right_node)
|
1740
|
-
.synthesize(right_node, hint:
|
1792
|
+
.synthesize(right_node, hint: left_truthy.type, condition: true).to_ary
|
1741
1793
|
|
1742
|
-
|
1794
|
+
right_truthy, right_falsy = interpreter.eval(env: left_falsy.env, node: right_node)
|
1743
1795
|
|
1744
|
-
|
1745
|
-
|
1746
|
-
|
1747
|
-
|
1748
|
-
|
1796
|
+
case
|
1797
|
+
when left_falsy.unreachable
|
1798
|
+
env = left_truthy.env
|
1799
|
+
type = left_truthy.type
|
1800
|
+
when left_truthy.unreachable
|
1801
|
+
# Always left_falsy ==> right
|
1802
|
+
env = right_context.type_env
|
1803
|
+
type = right_type
|
1804
|
+
when right_truthy.unreachable && right_falsy.unreachable
|
1805
|
+
env = left_truthy.env
|
1806
|
+
type = left_truthy.type
|
1807
|
+
else
|
1808
|
+
env = context.type_env.join(left_truthy.env, right_context.type_env)
|
1809
|
+
type = union_type(left_truthy.type, right_type)
|
1749
1810
|
|
1750
|
-
|
1751
|
-
|
1752
|
-
|
1753
|
-
|
1754
|
-
else
|
1755
|
-
union_type(left_type, right_type)
|
1811
|
+
unless type.is_a?(AST::Types::Any)
|
1812
|
+
if check_relation(sub_type: type, super_type: AST::Types::Boolean.new).success?
|
1813
|
+
type = AST::Types::Boolean.new
|
1814
|
+
end
|
1756
1815
|
end
|
1816
|
+
end
|
1757
1817
|
|
1758
1818
|
if condition
|
1759
1819
|
type = AST::Types::Logic::Env.new(
|
1760
|
-
truthy: context.type_env.join(
|
1761
|
-
falsy:
|
1820
|
+
truthy: context.type_env.join(left_truthy.env, right_truthy.env),
|
1821
|
+
falsy: right_falsy.env,
|
1762
1822
|
type: type
|
1763
1823
|
)
|
1764
1824
|
end
|
@@ -1772,12 +1832,12 @@ module Steep
|
|
1772
1832
|
|
1773
1833
|
cond_type, constr = synthesize(cond, condition: true).to_ary
|
1774
1834
|
interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: constr.typing, config: builder_config)
|
1775
|
-
|
1835
|
+
truthy, falsy = interpreter.eval(env: constr.context.type_env, node: cond)
|
1776
1836
|
|
1777
1837
|
if true_clause
|
1778
1838
|
true_pair =
|
1779
1839
|
constr
|
1780
|
-
.update_type_env {
|
1840
|
+
.update_type_env { truthy.env }
|
1781
1841
|
.for_branch(true_clause)
|
1782
1842
|
.tap {|constr| typing.add_context_for_node(true_clause, context: constr.context) }
|
1783
1843
|
.synthesize(true_clause, hint: hint)
|
@@ -1786,7 +1846,7 @@ module Steep
|
|
1786
1846
|
if false_clause
|
1787
1847
|
false_pair =
|
1788
1848
|
constr
|
1789
|
-
.update_type_env {
|
1849
|
+
.update_type_env { falsy.env }
|
1790
1850
|
.for_branch(false_clause)
|
1791
1851
|
.tap {|constr| typing.add_context_for_node(false_clause, context: constr.context) }
|
1792
1852
|
.synthesize(false_clause, hint: hint)
|
@@ -1795,25 +1855,49 @@ module Steep
|
|
1795
1855
|
constr = constr.update_type_env do |env|
|
1796
1856
|
envs = [] #: Array[TypeInference::TypeEnv]
|
1797
1857
|
|
1798
|
-
|
1799
|
-
|
1800
|
-
|
1858
|
+
unless truthy.unreachable
|
1859
|
+
if true_pair
|
1860
|
+
unless true_pair.type.is_a?(AST::Types::Bot)
|
1861
|
+
envs << true_pair.context.type_env
|
1862
|
+
end
|
1863
|
+
else
|
1864
|
+
envs << truthy.env
|
1801
1865
|
end
|
1802
|
-
else
|
1803
|
-
envs << truthy_env
|
1804
1866
|
end
|
1805
1867
|
|
1806
1868
|
if false_pair
|
1807
|
-
unless
|
1808
|
-
|
1869
|
+
unless falsy.unreachable
|
1870
|
+
unless false_pair.type.is_a?(AST::Types::Bot)
|
1871
|
+
envs << false_pair.context.type_env
|
1872
|
+
end
|
1809
1873
|
end
|
1810
1874
|
else
|
1811
|
-
envs <<
|
1875
|
+
envs << falsy.env
|
1812
1876
|
end
|
1813
1877
|
|
1814
1878
|
env.join(*envs)
|
1815
1879
|
end
|
1816
1880
|
|
1881
|
+
if truthy.unreachable
|
1882
|
+
if true_clause
|
1883
|
+
typing.add_error(
|
1884
|
+
Diagnostic::Ruby::UnreachableBranch.new(
|
1885
|
+
node: true_clause || node
|
1886
|
+
)
|
1887
|
+
)
|
1888
|
+
end
|
1889
|
+
end
|
1890
|
+
|
1891
|
+
if falsy.unreachable
|
1892
|
+
if false_clause
|
1893
|
+
typing.add_error(
|
1894
|
+
Diagnostic::Ruby::UnreachableBranch.new(
|
1895
|
+
node: false_clause || node
|
1896
|
+
)
|
1897
|
+
)
|
1898
|
+
end
|
1899
|
+
end
|
1900
|
+
|
1817
1901
|
node_type = union_type_unify(true_pair&.type || AST::Builtin.nil_type, false_pair&.type || AST::Builtin.nil_type)
|
1818
1902
|
add_typing(node, type: node_type, constr: constr)
|
1819
1903
|
end
|
@@ -1832,8 +1916,11 @@ module Steep
|
|
1832
1916
|
|
1833
1917
|
cond_type, constr = constr.synthesize(cond)
|
1834
1918
|
_, cond_vars = interpreter.decompose_value(cond)
|
1919
|
+
SPECIAL_LVAR_NAMES.each do |name|
|
1920
|
+
cond_vars.delete(name)
|
1921
|
+
end
|
1835
1922
|
|
1836
|
-
var_name = :"_a#{SecureRandom.
|
1923
|
+
var_name = :"_a#{SecureRandom.alphanumeric(4)}"
|
1837
1924
|
var_cond, value_node = extract_outermost_call(cond, var_name)
|
1838
1925
|
if value_node
|
1839
1926
|
unless constr.context.type_env[value_node]
|
@@ -1846,6 +1933,8 @@ module Steep
|
|
1846
1933
|
end
|
1847
1934
|
end
|
1848
1935
|
|
1936
|
+
next_branch_reachable = true
|
1937
|
+
|
1849
1938
|
when_constr = constr
|
1850
1939
|
whens.each do |clause|
|
1851
1940
|
# @type var tests: Array[Parser::AST::Node]
|
@@ -1856,16 +1945,26 @@ module Steep
|
|
1856
1945
|
# @type var test_envs: Array[TypeInference::TypeEnv]
|
1857
1946
|
test_envs = []
|
1858
1947
|
|
1948
|
+
branch_reachable = false
|
1949
|
+
false_branch_reachable = false
|
1950
|
+
|
1859
1951
|
tests.each do |test|
|
1860
1952
|
test_node = test.updated(:send, [test, :===, cond])
|
1861
1953
|
test_type, test_constr = test_constr.synthesize(test_node, condition: true).to_ary
|
1862
|
-
|
1954
|
+
truthy, falsy = interpreter.eval(node: test_node, env: test_constr.context.type_env)
|
1955
|
+
|
1956
|
+
truthy_env = truthy.env
|
1957
|
+
falsy_env = falsy.env
|
1863
1958
|
|
1864
1959
|
test_envs << truthy_env
|
1865
1960
|
|
1866
1961
|
test_constr = test_constr.update_type_env { falsy_env }
|
1962
|
+
|
1963
|
+
branch_reachable ||= next_branch_reachable && !truthy.unreachable
|
1964
|
+
false_branch_reachable = !falsy.unreachable
|
1867
1965
|
end
|
1868
1966
|
|
1967
|
+
next_branch_reachable &&= false_branch_reachable
|
1869
1968
|
body_constr = when_constr.update_type_env {|env| env.join(*test_envs) }
|
1870
1969
|
|
1871
1970
|
if body
|
@@ -1878,6 +1977,12 @@ module Steep
|
|
1878
1977
|
branch_results << Pair.new(type: AST::Builtin.nil_type, constr: body_constr)
|
1879
1978
|
end
|
1880
1979
|
|
1980
|
+
unless branch_reachable
|
1981
|
+
typing.add_error(
|
1982
|
+
Diagnostic::Ruby::UnreachableBranch.new(node: body || clause)
|
1983
|
+
)
|
1984
|
+
end
|
1985
|
+
|
1881
1986
|
when_constr = test_constr
|
1882
1987
|
end
|
1883
1988
|
|
@@ -1888,7 +1993,11 @@ module Steep
|
|
1888
1993
|
end_pos = node.loc.end.begin_pos
|
1889
1994
|
typing.add_context(begin_pos..end_pos, context: when_constr.context)
|
1890
1995
|
|
1891
|
-
|
1996
|
+
else_result = when_constr.synthesize(els, hint: hint)
|
1997
|
+
|
1998
|
+
if next_branch_reachable
|
1999
|
+
branch_results << else_result
|
2000
|
+
end
|
1892
2001
|
end
|
1893
2002
|
|
1894
2003
|
types = branch_results.map(&:type)
|
@@ -1899,10 +2008,17 @@ module Steep
|
|
1899
2008
|
cond_type ||= when_constr.context.type_env[value_node] if value_node
|
1900
2009
|
cond_type ||= typing.type_of(node: node.children[0])
|
1901
2010
|
|
1902
|
-
if
|
2011
|
+
if !next_branch_reachable
|
1903
2012
|
# Exhaustive
|
1904
|
-
|
1905
|
-
|
2013
|
+
_, _, _, loc = deconstruct_case_node!(node)
|
2014
|
+
|
2015
|
+
# `else` may present even if it's empty
|
2016
|
+
if loc.else
|
2017
|
+
if els
|
2018
|
+
typing.add_error Diagnostic::Ruby::UnreachableBranch.new(node: els)
|
2019
|
+
else
|
2020
|
+
typing.add_error Diagnostic::Ruby::UnreachableBranch.new(node: node, location: loc.else)
|
2021
|
+
end
|
1906
2022
|
end
|
1907
2023
|
else
|
1908
2024
|
unless els
|
@@ -1916,6 +2032,8 @@ module Steep
|
|
1916
2032
|
condition_constr = constr
|
1917
2033
|
clause_constr = constr
|
1918
2034
|
|
2035
|
+
next_branch_reachable = true
|
2036
|
+
|
1919
2037
|
whens.each do |when_clause|
|
1920
2038
|
when_clause_constr = condition_constr
|
1921
2039
|
body_envs = [] #: Array[TypeInference::TypeEnv]
|
@@ -1924,14 +2042,24 @@ module Steep
|
|
1924
2042
|
# @type var body: Parser::AST::Node?
|
1925
2043
|
*tests, body = when_clause.children
|
1926
2044
|
|
2045
|
+
branch_reachable = false
|
2046
|
+
false_branch_reachable = false
|
2047
|
+
|
1927
2048
|
tests.each do |test|
|
1928
2049
|
test_type, condition_constr = condition_constr.synthesize(test, condition: true)
|
1929
|
-
|
2050
|
+
truthy, falsy = interpreter.eval(env: condition_constr.context.type_env, node: test)
|
2051
|
+
truthy_env = truthy.env
|
2052
|
+
falsy_env = falsy.env
|
1930
2053
|
|
1931
2054
|
condition_constr = condition_constr.update_type_env { falsy_env }
|
1932
2055
|
body_envs << truthy_env
|
2056
|
+
|
2057
|
+
branch_reachable ||= next_branch_reachable && !truthy.unreachable
|
2058
|
+
false_branch_reachable ||= !falsy.unreachable
|
1933
2059
|
end
|
1934
2060
|
|
2061
|
+
next_branch_reachable &&= false_branch_reachable
|
2062
|
+
|
1935
2063
|
if body
|
1936
2064
|
branch_results <<
|
1937
2065
|
when_clause_constr
|
@@ -1942,6 +2070,12 @@ module Steep
|
|
1942
2070
|
else
|
1943
2071
|
branch_results << Pair.new(type: AST::Builtin.nil_type, constr: when_clause_constr)
|
1944
2072
|
end
|
2073
|
+
|
2074
|
+
unless branch_reachable
|
2075
|
+
typing.add_error(
|
2076
|
+
Diagnostic::Ruby::UnreachableBranch.new(node: body || when_clause)
|
2077
|
+
)
|
2078
|
+
end
|
1945
2079
|
end
|
1946
2080
|
|
1947
2081
|
if els
|
@@ -2135,7 +2269,9 @@ module Steep
|
|
2135
2269
|
cond_type, constr = synthesize(cond, condition: true).to_ary
|
2136
2270
|
|
2137
2271
|
interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing, config: builder_config)
|
2138
|
-
|
2272
|
+
truthy, falsy = interpreter.eval(env: constr.context.type_env, node: cond)
|
2273
|
+
truthy_env = truthy.env
|
2274
|
+
falsy_env = falsy.env
|
2139
2275
|
|
2140
2276
|
case node.type
|
2141
2277
|
when :while
|
@@ -2221,8 +2357,11 @@ module Steep
|
|
2221
2357
|
# ignore
|
2222
2358
|
add_typing(node, type: AST::Builtin.any_type)
|
2223
2359
|
|
2224
|
-
when :nth_ref
|
2225
|
-
add_typing(node, type: AST::Builtin::String.instance_type)
|
2360
|
+
when :nth_ref
|
2361
|
+
add_typing(node, type: union_type(AST::Builtin::String.instance_type, AST::Builtin.nil_type))
|
2362
|
+
|
2363
|
+
when :back_ref
|
2364
|
+
synthesize(node.updated(:gvar), hint: hint)
|
2226
2365
|
|
2227
2366
|
when :or_asgn, :and_asgn
|
2228
2367
|
yield_self do
|
@@ -2290,43 +2429,58 @@ module Steep
|
|
2290
2429
|
|
2291
2430
|
when :block_pass
|
2292
2431
|
yield_self do
|
2293
|
-
|
2432
|
+
value_node = node.children[0]
|
2294
2433
|
|
2295
|
-
|
2296
|
-
|
2297
|
-
|
2298
|
-
|
2299
|
-
|
2300
|
-
|
2301
|
-
|
2302
|
-
|
2303
|
-
|
2304
|
-
|
2305
|
-
|
2306
|
-
|
2307
|
-
|
2434
|
+
constr = self #: TypeConstruction
|
2435
|
+
|
2436
|
+
if value_node
|
2437
|
+
type, constr = synthesize(value_node, hint: hint)
|
2438
|
+
|
2439
|
+
if hint.is_a?(AST::Types::Proc) && value_node.type == :sym
|
2440
|
+
if hint.one_arg?
|
2441
|
+
# Assumes Symbol#to_proc implementation
|
2442
|
+
param_type = hint.type.params.required[0]
|
2443
|
+
case param_type
|
2444
|
+
when AST::Types::Any
|
2445
|
+
type = AST::Types::Any.new
|
2446
|
+
else
|
2447
|
+
if method = calculate_interface(param_type, private: true)&.methods&.[](value_node.children[0])
|
2448
|
+
return_types = method.method_types.filter_map do |method_type|
|
2449
|
+
if method_type.type.params.optional?
|
2450
|
+
method_type.type.return_type
|
2451
|
+
end
|
2308
2452
|
end
|
2309
|
-
end
|
2310
2453
|
|
2311
|
-
|
2312
|
-
|
2313
|
-
|
2314
|
-
|
2315
|
-
|
2454
|
+
unless return_types.empty?
|
2455
|
+
type = AST::Types::Proc.new(
|
2456
|
+
type: Interface::Function.new(
|
2457
|
+
params: Interface::Function::Params.empty.with_first_param(
|
2458
|
+
Interface::Function::Params::PositionalParams::Required.new(param_type)
|
2459
|
+
),
|
2460
|
+
return_type: return_types[0],
|
2461
|
+
location: nil
|
2316
2462
|
),
|
2317
|
-
|
2318
|
-
|
2319
|
-
)
|
2320
|
-
|
2321
|
-
self_type: nil
|
2322
|
-
)
|
2463
|
+
block: nil,
|
2464
|
+
self_type: nil
|
2465
|
+
)
|
2466
|
+
end
|
2323
2467
|
end
|
2324
2468
|
end
|
2469
|
+
else
|
2470
|
+
Steep.logger.error "Passing multiple args through Symbol#to_proc is not supported yet"
|
2325
2471
|
end
|
2472
|
+
end
|
2473
|
+
|
2474
|
+
case
|
2475
|
+
when type.is_a?(AST::Types::Proc)
|
2476
|
+
# nop
|
2477
|
+
when AST::Builtin::Proc.instance_type?(type)
|
2478
|
+
# nop
|
2326
2479
|
else
|
2327
|
-
|
2480
|
+
type = try_convert(type, :to_proc) || type
|
2328
2481
|
end
|
2329
|
-
|
2482
|
+
else
|
2483
|
+
# Anonymous block_pass only happens inside method definition
|
2330
2484
|
if block_type = method_context!.block_type
|
2331
2485
|
type = AST::Types::Proc.new(
|
2332
2486
|
type: block_type.type,
|
@@ -2334,16 +2488,15 @@ module Steep
|
|
2334
2488
|
block: nil,
|
2335
2489
|
self_type: block_type.self_type
|
2336
2490
|
)
|
2491
|
+
|
2337
2492
|
if block_type.optional?
|
2338
|
-
type =
|
2493
|
+
type = union_type(type, AST::Builtin.nil_type)
|
2339
2494
|
end
|
2340
2495
|
else
|
2341
2496
|
type = AST::Builtin.nil_type
|
2342
2497
|
end
|
2343
2498
|
end
|
2344
2499
|
|
2345
|
-
type ||= synthesize(value, hint: hint).type
|
2346
|
-
|
2347
2500
|
add_typing node, type: type
|
2348
2501
|
end
|
2349
2502
|
|
@@ -2435,7 +2588,7 @@ module Steep
|
|
2435
2588
|
# @type var as_type: AST::Node::TypeAssertion
|
2436
2589
|
asserted_node, as_type = node.children
|
2437
2590
|
|
2438
|
-
if type = as_type.type?(module_context.nesting, checker
|
2591
|
+
if type = as_type.type?(module_context.nesting, checker, [])
|
2439
2592
|
actual_type, constr = synthesize(asserted_node, hint: type)
|
2440
2593
|
|
2441
2594
|
if no_subtyping?(sub_type: type, super_type: actual_type) && no_subtyping?(sub_type: actual_type, super_type: type)
|
@@ -2517,7 +2670,7 @@ module Steep
|
|
2517
2670
|
|
2518
2671
|
add_typing(node, type: type)
|
2519
2672
|
else
|
2520
|
-
type_send(node, send_node: node, block_params: nil, block_body: nil, tapp: tapp)
|
2673
|
+
type_send(node, send_node: node, block_params: nil, block_body: nil, tapp: tapp, hint: hint)
|
2521
2674
|
end
|
2522
2675
|
end
|
2523
2676
|
when :csend
|
@@ -2532,7 +2685,7 @@ module Steep
|
|
2532
2685
|
end
|
2533
2686
|
add_typing(node, type: type).to_ary
|
2534
2687
|
else
|
2535
|
-
type_send(node, send_node: node, block_params: nil, block_body: nil, unwrap: true, tapp: tapp).to_ary
|
2688
|
+
type_send(node, send_node: node, block_params: nil, block_body: nil, unwrap: true, tapp: tapp, hint: hint).to_ary
|
2536
2689
|
end
|
2537
2690
|
|
2538
2691
|
constr
|
@@ -2546,7 +2699,7 @@ module Steep
|
|
2546
2699
|
# @type var node: Parser::AST::Node & Parser::AST::_BlockNode
|
2547
2700
|
type_lambda(node, params_node: params, body_node: body, type_hint: hint)
|
2548
2701
|
else
|
2549
|
-
type_send(node, send_node: send_node, block_params: params, block_body: body, unwrap: send_node.type == :csend, tapp: tapp)
|
2702
|
+
type_send(node, send_node: send_node, block_params: params, block_body: body, unwrap: send_node.type == :csend, tapp: tapp, hint: hint)
|
2550
2703
|
end
|
2551
2704
|
end
|
2552
2705
|
when :numblock
|
@@ -2565,7 +2718,7 @@ module Steep
|
|
2565
2718
|
# @type var node: Parser::AST::Node & Parser::AST::_BlockNode
|
2566
2719
|
type_lambda(node, params_node: params, body_node: body, type_hint: hint)
|
2567
2720
|
else
|
2568
|
-
type_send(node, send_node: send_node, block_params: params, block_body: body, unwrap: send_node.type == :csend, tapp: tapp)
|
2721
|
+
type_send(node, send_node: send_node, block_params: params, block_body: body, unwrap: send_node.type == :csend, tapp: tapp, hint: hint)
|
2569
2722
|
end
|
2570
2723
|
end
|
2571
2724
|
else
|
@@ -2874,7 +3027,7 @@ module Steep
|
|
2874
3027
|
if type.types.size == 2
|
2875
3028
|
if type.types.find {|t| t.is_a?(AST::Types::Nil) }
|
2876
3029
|
if proc_type = type.types.find {|t| t.is_a?(AST::Types::Proc) }
|
2877
|
-
proc_type
|
3030
|
+
proc_type #: AST::Types::Proc
|
2878
3031
|
end
|
2879
3032
|
end
|
2880
3033
|
end
|
@@ -2885,14 +3038,32 @@ module Steep
|
|
2885
3038
|
block_annotations = source.annotations(block: node, factory: checker.factory, context: nesting)
|
2886
3039
|
params = TypeInference::BlockParams.from_node(params_node, annotations: block_annotations)
|
2887
3040
|
|
2888
|
-
|
3041
|
+
if type_hint
|
3042
|
+
original_hint = type_hint
|
2889
3043
|
|
2890
|
-
|
2891
|
-
|
2892
|
-
|
2893
|
-
|
2894
|
-
|
2895
|
-
|
3044
|
+
type_hint = deep_expand_alias(type_hint) || type_hint
|
3045
|
+
|
3046
|
+
procs = flatten_union(type_hint).select do |type|
|
3047
|
+
check_relation(sub_type: type, super_type: AST::Builtin::Proc.instance_type).success?
|
3048
|
+
end
|
3049
|
+
|
3050
|
+
proc_instances, proc_types = procs.partition {|type| AST::Builtin::Proc.instance_type?(type) }
|
3051
|
+
|
3052
|
+
case
|
3053
|
+
when !proc_instances.empty? && proc_types.empty?
|
3054
|
+
# `::Proc` is given as a hint
|
3055
|
+
when proc_types.size == 1
|
3056
|
+
# Proc type is given as a hint
|
3057
|
+
hint_proc = proc_types[0] #: AST::Types::Proc
|
3058
|
+
params_hint = hint_proc.type.params
|
3059
|
+
return_hint = hint_proc.type.return_type
|
3060
|
+
block_hint = hint_proc.block
|
3061
|
+
self_hint = hint_proc.self_type
|
3062
|
+
else
|
3063
|
+
typing.add_error(
|
3064
|
+
Diagnostic::Ruby::ProcHintIgnored.new(hint_type: original_hint, node: node)
|
3065
|
+
)
|
3066
|
+
end
|
2896
3067
|
end
|
2897
3068
|
|
2898
3069
|
block_constr = for_block(
|
@@ -3028,7 +3199,7 @@ module Steep
|
|
3028
3199
|
end
|
3029
3200
|
end
|
3030
3201
|
|
3031
|
-
def type_send_interface(node, interface:, receiver:, receiver_type:, method_name:, arguments:, block_params:, block_body:, tapp:)
|
3202
|
+
def type_send_interface(node, interface:, receiver:, receiver_type:, method_name:, arguments:, block_params:, block_body:, tapp:, hint:)
|
3032
3203
|
method = interface&.methods&.[](method_name)
|
3033
3204
|
|
3034
3205
|
if method
|
@@ -3040,7 +3211,8 @@ module Steep
|
|
3040
3211
|
block_params: block_params,
|
3041
3212
|
block_body: block_body,
|
3042
3213
|
receiver_type: receiver_type,
|
3043
|
-
tapp: tapp
|
3214
|
+
tapp: tapp,
|
3215
|
+
hint: hint
|
3044
3216
|
)
|
3045
3217
|
|
3046
3218
|
if call && constr
|
@@ -3159,17 +3331,17 @@ module Steep
|
|
3159
3331
|
end
|
3160
3332
|
end
|
3161
3333
|
|
3162
|
-
def type_send(node, send_node:, block_params:, block_body:, unwrap: false, tapp:)
|
3334
|
+
def type_send(node, send_node:, block_params:, block_body:, unwrap: false, tapp:, hint:)
|
3163
3335
|
# @type var constr: TypeConstruction
|
3164
3336
|
# @type var receiver: Parser::AST::Node?
|
3165
3337
|
|
3166
3338
|
case send_node.type
|
3167
3339
|
when :super, :zsuper
|
3168
3340
|
receiver = nil
|
3169
|
-
method_name = method_context
|
3341
|
+
method_name = method_context!.name
|
3170
3342
|
arguments = send_node.children
|
3171
3343
|
|
3172
|
-
if method_name.nil? || method_context
|
3344
|
+
if method_name.nil? || method_context!.super_method.nil?
|
3173
3345
|
return fallback_to_any(send_node) do
|
3174
3346
|
Diagnostic::Ruby::UnexpectedSuper.new(
|
3175
3347
|
node: send_node,
|
@@ -3241,7 +3413,8 @@ module Steep
|
|
3241
3413
|
arguments: arguments,
|
3242
3414
|
block_params: block_params,
|
3243
3415
|
block_body: block_body,
|
3244
|
-
tapp: tapp
|
3416
|
+
tapp: tapp,
|
3417
|
+
hint: hint
|
3245
3418
|
)
|
3246
3419
|
else
|
3247
3420
|
constr = constr.synthesize_children(node, skips: [receiver])
|
@@ -3300,10 +3473,14 @@ module Steep
|
|
3300
3473
|
],
|
3301
3474
|
hash_compact: Set[
|
3302
3475
|
MethodName("::Hash#compact")
|
3476
|
+
],
|
3477
|
+
lambda: Set[
|
3478
|
+
MethodName("::Kernel#lambda"),
|
3479
|
+
MethodName("::Kernel.lambda")
|
3303
3480
|
]
|
3304
3481
|
}
|
3305
3482
|
|
3306
|
-
def try_special_method(node, receiver_type:, method_name:, method_type:, arguments:, block_params:, block_body:)
|
3483
|
+
def try_special_method(node, receiver_type:, method_name:, method_type:, arguments:, block_params:, block_body:, hint:)
|
3307
3484
|
decls = method_type.method_decls
|
3308
3485
|
|
3309
3486
|
case
|
@@ -3354,12 +3531,29 @@ module Steep
|
|
3354
3531
|
return [call, constr]
|
3355
3532
|
end
|
3356
3533
|
end
|
3534
|
+
when decl = decls.find {|decl| SPECIAL_METHOD_NAMES[:lambda].include?(decl.method_name) }
|
3535
|
+
if block_params
|
3536
|
+
# @type var node: Parser::AST::Node & Parser::AST::_BlockNode
|
3537
|
+
type, constr = type_lambda(node, params_node: block_params, body_node: block_body, type_hint: hint)
|
3538
|
+
|
3539
|
+
call = TypeInference::MethodCall::Special.new(
|
3540
|
+
node: node,
|
3541
|
+
context: context.call_context,
|
3542
|
+
method_name: decl.method_name.method_name,
|
3543
|
+
receiver_type: receiver_type,
|
3544
|
+
actual_method_type: method_type.with(type: method_type.type.with(return_type: type)),
|
3545
|
+
return_type: type,
|
3546
|
+
method_decls: decls
|
3547
|
+
)
|
3548
|
+
|
3549
|
+
return [call, constr]
|
3550
|
+
end
|
3357
3551
|
end
|
3358
3552
|
|
3359
3553
|
nil
|
3360
3554
|
end
|
3361
3555
|
|
3362
|
-
def type_method_call(node, method_name:, receiver_type:, method:, arguments:, block_params:, block_body:, tapp:)
|
3556
|
+
def type_method_call(node, method_name:, receiver_type:, method:, arguments:, block_params:, block_body:, tapp:, hint:)
|
3363
3557
|
node_range = node.loc.expression.to_range
|
3364
3558
|
|
3365
3559
|
# @type var fails: Array[[TypeInference::MethodCall::t, TypeConstruction]]
|
@@ -3377,7 +3571,8 @@ module Steep
|
|
3377
3571
|
method_type: method_type,
|
3378
3572
|
arguments: arguments,
|
3379
3573
|
block_params: block_params,
|
3380
|
-
block_body: block_body
|
3574
|
+
block_body: block_body,
|
3575
|
+
hint: hint
|
3381
3576
|
) || constr.try_method_type(
|
3382
3577
|
node,
|
3383
3578
|
receiver_type: receiver_type,
|
@@ -3386,7 +3581,8 @@ module Steep
|
|
3386
3581
|
arguments: arguments,
|
3387
3582
|
block_params: block_params,
|
3388
3583
|
block_body: block_body,
|
3389
|
-
tapp: tapp
|
3584
|
+
tapp: tapp,
|
3585
|
+
hint: hint
|
3390
3586
|
)
|
3391
3587
|
|
3392
3588
|
if call.is_a?(TypeInference::MethodCall::Typed)
|
@@ -3473,6 +3669,24 @@ module Steep
|
|
3473
3669
|
end
|
3474
3670
|
end
|
3475
3671
|
|
3672
|
+
def type_check_untyped_args(arguments)
|
3673
|
+
constr = self #: TypeConstruction
|
3674
|
+
|
3675
|
+
arguments.each do |arg|
|
3676
|
+
case arg.type
|
3677
|
+
when :splat
|
3678
|
+
type, constr = constr.synthesize(arg.children[0])
|
3679
|
+
_, constr = constr.add_typing(arg, type: type)
|
3680
|
+
when :kwargs
|
3681
|
+
_, constr = constr.type_hash_record(arg, nil) || constr.type_hash(arg, hint: nil)
|
3682
|
+
else
|
3683
|
+
_, constr = constr.synthesize(arg)
|
3684
|
+
end
|
3685
|
+
end
|
3686
|
+
|
3687
|
+
constr
|
3688
|
+
end
|
3689
|
+
|
3476
3690
|
def type_check_args(method_name, args, constraints, errors)
|
3477
3691
|
# @type var constr: TypeConstruction
|
3478
3692
|
constr = self
|
@@ -3588,10 +3802,10 @@ module Steep
|
|
3588
3802
|
constr
|
3589
3803
|
end
|
3590
3804
|
|
3591
|
-
def try_method_type(node, receiver_type:, method_name:, method_type:, arguments:, block_params:, block_body:, tapp:)
|
3805
|
+
def try_method_type(node, receiver_type:, method_name:, method_type:, arguments:, block_params:, block_body:, tapp:, hint:)
|
3592
3806
|
constr = self
|
3593
3807
|
|
3594
|
-
if tapp && type_args = tapp.types?(module_context.nesting, checker
|
3808
|
+
if tapp && type_args = tapp.types?(module_context.nesting, checker, [])
|
3595
3809
|
type_arity = method_type.type_params.size
|
3596
3810
|
type_param_names = method_type.type_params.map(&:name)
|
3597
3811
|
|
@@ -3703,12 +3917,29 @@ module Steep
|
|
3703
3917
|
|
3704
3918
|
if block_params
|
3705
3919
|
# block is given
|
3920
|
+
|
3706
3921
|
# @type var node: Parser::AST::Node & Parser::AST::_BlockNode
|
3707
3922
|
|
3708
3923
|
block_annotations = source.annotations(block: node, factory: checker.factory, context: nesting)
|
3709
3924
|
block_params_ = TypeInference::BlockParams.from_node(block_params, annotations: block_annotations)
|
3710
3925
|
|
3711
3926
|
if method_type.block
|
3927
|
+
fvs = method_type.type.return_type.free_variables.each.with_object(Set[]) do |var, fvs| #$ Set[Symbol]
|
3928
|
+
if var.is_a?(Symbol)
|
3929
|
+
fvs << var
|
3930
|
+
end
|
3931
|
+
end
|
3932
|
+
|
3933
|
+
if hint && !fvs.empty?
|
3934
|
+
if check_relation(sub_type: method_type.type.return_type, super_type: hint, constraints: constraints).success?
|
3935
|
+
method_type, solved, s = apply_solution(errors, node: node, method_type: method_type) do
|
3936
|
+
constraints.solution(checker, variables: fvs, context: ccontext)
|
3937
|
+
end
|
3938
|
+
end
|
3939
|
+
|
3940
|
+
method_type.block or raise
|
3941
|
+
end
|
3942
|
+
|
3712
3943
|
# Method accepts block
|
3713
3944
|
pairs = block_params_&.zip(method_type.block.type.params, nil, factory: checker.factory)
|
3714
3945
|
|
@@ -3724,6 +3955,7 @@ module Steep
|
|
3724
3955
|
block_self_hint: method_type.block.self_type,
|
3725
3956
|
node_type_hint: method_type.type.return_type
|
3726
3957
|
)
|
3958
|
+
|
3727
3959
|
block_constr = block_constr.with_new_typing(
|
3728
3960
|
block_constr.typing.new_child(block_constr.typing.block_range(node))
|
3729
3961
|
)
|
@@ -3733,7 +3965,7 @@ module Steep
|
|
3733
3965
|
pairs.each do |param, type|
|
3734
3966
|
case param
|
3735
3967
|
when TypeInference::BlockParams::Param
|
3736
|
-
_, block_constr = block_constr.synthesize(param.node, hint: param.type || type)
|
3968
|
+
_, block_constr = block_constr.synthesize(param.node, hint: param.type || type)
|
3737
3969
|
|
3738
3970
|
if param.type
|
3739
3971
|
check_relation(sub_type: type, super_type: param.type, constraints: constraints).else do |result|
|
@@ -3748,7 +3980,7 @@ module Steep
|
|
3748
3980
|
end
|
3749
3981
|
when TypeInference::BlockParams::MultipleParam
|
3750
3982
|
param.each_param do |p|
|
3751
|
-
_, block_constr = block_constr.synthesize(p.node, hint: p.type || type)
|
3983
|
+
_, block_constr = block_constr.synthesize(p.node, hint: p.type || type)
|
3752
3984
|
|
3753
3985
|
if p.type
|
3754
3986
|
check_relation(sub_type: type, super_type: p.type, constraints: constraints).else do |result|
|
@@ -4154,6 +4386,7 @@ module Steep
|
|
4154
4386
|
pins = context.type_env.pin_local_variables(nil)
|
4155
4387
|
|
4156
4388
|
type_env = context.type_env
|
4389
|
+
type_env = type_env.invalidate_pure_node(Parser::AST::Node.new(:self)) if block_self_hint || block_annotations.self_type
|
4157
4390
|
type_env = type_env.merge(local_variable_types: pins)
|
4158
4391
|
type_env = type_env.merge(local_variable_types: param_types)
|
4159
4392
|
type_env = TypeInference::TypeEnvBuilder.new(
|
@@ -4419,8 +4652,7 @@ module Steep
|
|
4419
4652
|
end
|
4420
4653
|
|
4421
4654
|
def unwrap(type)
|
4422
|
-
|
4423
|
-
truthy
|
4655
|
+
checker.factory.unwrap_optional(type) || AST::Types::Bot.new
|
4424
4656
|
end
|
4425
4657
|
|
4426
4658
|
def deep_expand_alias(type)
|
@@ -4490,7 +4722,7 @@ module Steep
|
|
4490
4722
|
def try_tuple_type!(node, hint: nil)
|
4491
4723
|
if node.type == :array
|
4492
4724
|
if hint.nil? || hint.is_a?(AST::Types::Tuple)
|
4493
|
-
node_range = node.loc.expression.
|
4725
|
+
node_range = node.loc.expression.to_range
|
4494
4726
|
|
4495
4727
|
typing.new_child(node_range) do |child_typing|
|
4496
4728
|
if pair = with_new_typing(child_typing).try_tuple_type(node, hint)
|
@@ -4510,15 +4742,28 @@ module Steep
|
|
4510
4742
|
element_types = [] #: Array[AST::Types::t]
|
4511
4743
|
|
4512
4744
|
array_node.children.each_with_index do |child, index|
|
4513
|
-
|
4514
|
-
|
4515
|
-
|
4516
|
-
if
|
4517
|
-
|
4745
|
+
if child.type == :splat
|
4746
|
+
type, constr = constr.synthesize(child.children[0])
|
4747
|
+
typing.add_typing(child, type, nil)
|
4748
|
+
if converted_type = try_convert(type, :to_a)
|
4749
|
+
if converted_type.is_a?(AST::Types::Tuple)
|
4750
|
+
element_types.push(*converted_type.types)
|
4751
|
+
else
|
4752
|
+
# The converted_type may be an array, which cannot be used to construct a tuple type
|
4753
|
+
return
|
4754
|
+
end
|
4755
|
+
else
|
4756
|
+
element_types << type
|
4518
4757
|
end
|
4758
|
+
else
|
4759
|
+
child_hint =
|
4760
|
+
if hint
|
4761
|
+
hint.types[index]
|
4762
|
+
end
|
4519
4763
|
|
4520
|
-
|
4521
|
-
|
4764
|
+
type, constr = constr.synthesize(child, hint: child_hint)
|
4765
|
+
element_types << type
|
4766
|
+
end
|
4522
4767
|
end
|
4523
4768
|
|
4524
4769
|
constr.add_typing(array_node, type: AST::Types::Tuple.new(types: element_types))
|