steep 0.20.0 → 0.25.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +30 -1
- data/Gemfile +7 -0
- data/bin/steep-prof +16 -0
- data/lib/steep/ast/types/factory.rb +1 -1
- data/lib/steep/ast/types/literal.rb +4 -0
- data/lib/steep/ast/types/union.rb +4 -1
- data/lib/steep/drivers/check.rb +4 -0
- data/lib/steep/project/target.rb +17 -3
- data/lib/steep/server/interaction_worker.rb +3 -3
- data/lib/steep/server/signature_worker.rb +3 -0
- data/lib/steep/signature/errors.rb +28 -0
- data/lib/steep/signature/validator.rb +11 -1
- data/lib/steep/source.rb +2 -1
- data/lib/steep/subtyping/check.rb +224 -52
- data/lib/steep/type_construction.rb +425 -181
- data/lib/steep/type_inference/constant_env.rb +1 -1
- data/lib/steep/type_inference/context.rb +8 -0
- data/lib/steep/type_inference/context_array.rb +4 -3
- data/lib/steep/type_inference/logic.rb +31 -0
- data/lib/steep/typing.rb +7 -0
- data/lib/steep/version.rb +1 -1
- data/smoke/class/a.rbs +1 -2
- data/smoke/class/f.rb +3 -1
- data/steep.gemspec +1 -8
- metadata +7 -96
@@ -638,7 +638,8 @@ module Steep
|
|
638
638
|
when :__skip__
|
639
639
|
add_typing(node, type: AST::Builtin.any_type)
|
640
640
|
else
|
641
|
-
|
641
|
+
hint ||= context.lvar_env.declared_types[name]&.type
|
642
|
+
rhs_result = synthesize(rhs, hint: hint)
|
642
643
|
|
643
644
|
constr = rhs_result.constr.update_lvar_env do |lvar_env|
|
644
645
|
lvar_env.assign(name, node: node, type: rhs_result.type) do |declared_type, actual_type, result|
|
@@ -743,6 +744,23 @@ module Steep
|
|
743
744
|
|
744
745
|
constr.add_typing(node, type: type)
|
745
746
|
|
747
|
+
when :cvasgn
|
748
|
+
var_node = lhs.updated(:cvar)
|
749
|
+
send_node = rhs.updated(:send, [var_node, op, rhs])
|
750
|
+
new_node = node.updated(:cvasgn, [lhs.children[0], send_node])
|
751
|
+
|
752
|
+
type, constr = synthesize(new_node, hint: hint)
|
753
|
+
|
754
|
+
constr.add_typing(node, type: type)
|
755
|
+
|
756
|
+
when :send
|
757
|
+
new_rhs = rhs.updated(:send, [lhs, node.children[1], node.children[2]])
|
758
|
+
new_node = lhs.updated(:send, [lhs.children[0], :"#{lhs.children[1]}=", *lhs.children.drop(2), new_rhs])
|
759
|
+
|
760
|
+
type, constr = synthesize(new_node, hint: hint)
|
761
|
+
|
762
|
+
constr.add_typing(node, type: type)
|
763
|
+
|
746
764
|
else
|
747
765
|
Steep.logger.error("Unexpected op_asgn lhs: #{lhs.type}")
|
748
766
|
|
@@ -810,7 +828,7 @@ module Steep
|
|
810
828
|
new.typing.add_context_for_body(node, context: new.context)
|
811
829
|
|
812
830
|
each_child_node(args_node) do |arg|
|
813
|
-
new.synthesize(arg)
|
831
|
+
_, new = new.synthesize(arg)
|
814
832
|
end
|
815
833
|
|
816
834
|
body_pair = if body_node
|
@@ -998,11 +1016,17 @@ module Steep
|
|
998
1016
|
yield_self do
|
999
1017
|
var = node.children[0]
|
1000
1018
|
type = context.lvar_env[var.name]
|
1001
|
-
|
1019
|
+
|
1020
|
+
if type
|
1021
|
+
add_typing(node, type: type)
|
1022
|
+
else
|
1002
1023
|
type = AST::Builtin.any_type
|
1003
|
-
|
1024
|
+
if context&.method_context&.method_type
|
1025
|
+
Steep.logger.error { "Unknown arg type: #{node}" }
|
1026
|
+
end
|
1027
|
+
|
1028
|
+
lvasgn(node, type)
|
1004
1029
|
end
|
1005
|
-
add_typing(node, type: type)
|
1006
1030
|
end
|
1007
1031
|
|
1008
1032
|
when :optarg, :kwoptarg
|
@@ -1033,7 +1057,9 @@ module Steep
|
|
1033
1057
|
var = node.children[0]
|
1034
1058
|
type = context.lvar_env[var.name]
|
1035
1059
|
unless type
|
1036
|
-
|
1060
|
+
if context&.method_context&.method_type
|
1061
|
+
Steep.logger.error { "Unknown variable: #{node}" }
|
1062
|
+
end
|
1037
1063
|
typing.add_error Errors::FallbackAny.new(node: node)
|
1038
1064
|
type = AST::Builtin::Array.instance_type(AST::Builtin.any_type)
|
1039
1065
|
end
|
@@ -1046,7 +1072,9 @@ module Steep
|
|
1046
1072
|
var = node.children[0]
|
1047
1073
|
type = context.lvar_env[var.name]
|
1048
1074
|
unless type
|
1049
|
-
|
1075
|
+
if context&.method_context&.method_type
|
1076
|
+
Steep.logger.error { "Unknown variable: #{node}" }
|
1077
|
+
end
|
1050
1078
|
typing.add_error Errors::FallbackAny.new(node: node)
|
1051
1079
|
type = AST::Builtin::Hash.instance_type(AST::Builtin::Symbol.instance_type, AST::Builtin.any_type)
|
1052
1080
|
end
|
@@ -1062,7 +1090,7 @@ module Steep
|
|
1062
1090
|
|
1063
1091
|
when :int
|
1064
1092
|
yield_self do
|
1065
|
-
literal_type =
|
1093
|
+
literal_type = test_literal_type(node.children[0], hint)
|
1066
1094
|
|
1067
1095
|
if literal_type
|
1068
1096
|
add_typing(node, type: literal_type)
|
@@ -1073,7 +1101,7 @@ module Steep
|
|
1073
1101
|
|
1074
1102
|
when :sym
|
1075
1103
|
yield_self do
|
1076
|
-
literal_type =
|
1104
|
+
literal_type = test_literal_type(node.children[0], hint)
|
1077
1105
|
|
1078
1106
|
if literal_type
|
1079
1107
|
add_typing(node, type: literal_type)
|
@@ -1084,7 +1112,7 @@ module Steep
|
|
1084
1112
|
|
1085
1113
|
when :str
|
1086
1114
|
yield_self do
|
1087
|
-
literal_type =
|
1115
|
+
literal_type = test_literal_type(node.children[0], hint)
|
1088
1116
|
|
1089
1117
|
if literal_type
|
1090
1118
|
add_typing(node, type: literal_type)
|
@@ -1094,7 +1122,13 @@ module Steep
|
|
1094
1122
|
end
|
1095
1123
|
|
1096
1124
|
when :true, :false
|
1097
|
-
|
1125
|
+
ty = node.type == :true ? AST::Types::Literal.new(value: true) : AST::Types::Literal.new(value: false)
|
1126
|
+
|
1127
|
+
if hint && check_relation(sub_type: ty, super_type: hint).success?
|
1128
|
+
add_typing(node, type: hint)
|
1129
|
+
else
|
1130
|
+
add_typing(node, type: AST::Types::Boolean.new)
|
1131
|
+
end
|
1098
1132
|
|
1099
1133
|
when :hash
|
1100
1134
|
yield_self do
|
@@ -1294,69 +1328,45 @@ module Steep
|
|
1294
1328
|
when :array
|
1295
1329
|
yield_self do
|
1296
1330
|
if node.children.empty?
|
1297
|
-
|
1298
|
-
|
1299
|
-
|
1300
|
-
|
1301
|
-
|
1302
|
-
|
1303
|
-
end
|
1304
|
-
end
|
1305
|
-
|
1306
|
-
add_typing(node, type: array_type || AST::Builtin::Array.instance_type(AST::Builtin.any_type))
|
1307
|
-
else
|
1308
|
-
is_tuple = nil
|
1309
|
-
|
1310
|
-
expand_alias(hint) do |hint|
|
1311
|
-
is_tuple = hint.is_a?(AST::Types::Tuple)
|
1312
|
-
is_tuple &&= node.children.all? {|child| child.type != :splat}
|
1313
|
-
is_tuple &&= node.children.size >= hint.types.size
|
1314
|
-
is_tuple &&= hint.types.map.with_index do |child_type, index|
|
1315
|
-
child_node = node.children[index]
|
1316
|
-
[synthesize(child_node, hint: child_type).type, child_type]
|
1317
|
-
end.all? do |node_type, hint_type|
|
1318
|
-
result = check_relation(sub_type: node_type, super_type: hint_type)
|
1319
|
-
result.success?
|
1331
|
+
if hint
|
1332
|
+
array = AST::Builtin::Array.instance_type(AST::Builtin.any_type)
|
1333
|
+
if check_relation(sub_type: array, super_type: hint).success?
|
1334
|
+
add_typing node, type: hint
|
1335
|
+
else
|
1336
|
+
add_typing node, type: array
|
1320
1337
|
end
|
1321
|
-
end
|
1322
|
-
|
1323
|
-
if is_tuple
|
1324
|
-
array_type = hint
|
1325
1338
|
else
|
1326
|
-
|
1327
|
-
|
1339
|
+
typing.add_error Errors::FallbackAny.new(node: node)
|
1340
|
+
add_typing node, type: AST::Builtin::Array.instance_type(AST::Builtin.any_type)
|
1341
|
+
end
|
1342
|
+
else
|
1343
|
+
node_range = node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos }
|
1344
|
+
|
1345
|
+
if hint && !(tuples = select_flatten_types(hint) {|type| type.is_a?(AST::Types::Tuple) }).empty?
|
1346
|
+
tuples.each do |tuple|
|
1347
|
+
typing.new_child(node_range) do |child_typing|
|
1348
|
+
pair = with_new_typing(child_typing).try_tuple_type(node, tuple)
|
1349
|
+
if pair && pair.constr.check_relation(sub_type: pair.type, super_type: hint).success?
|
1350
|
+
child_typing.save!
|
1351
|
+
return pair.with(constr: pair.constr.with_new_typing(typing))
|
1352
|
+
end
|
1353
|
+
end
|
1328
1354
|
end
|
1355
|
+
end
|
1329
1356
|
|
1330
|
-
|
1331
|
-
|
1332
|
-
|
1333
|
-
|
1334
|
-
|
1335
|
-
|
1336
|
-
|
1337
|
-
ty.types
|
1338
|
-
else
|
1339
|
-
[ty]
|
1340
|
-
end
|
1341
|
-
end
|
1342
|
-
end.map do |type|
|
1343
|
-
case
|
1344
|
-
when AST::Builtin::Array.instance_type?(type)
|
1345
|
-
type.args.first
|
1346
|
-
when AST::Builtin::Range.instance_type?(type)
|
1347
|
-
type.args.first
|
1348
|
-
else
|
1349
|
-
type
|
1350
|
-
end
|
1357
|
+
if hint && !(arrays = select_flatten_types(hint) {|type| AST::Builtin::Array.instance_type?(type) }).empty?
|
1358
|
+
arrays.each do |array|
|
1359
|
+
typing.new_child(node_range) do |child_typing|
|
1360
|
+
pair = with_new_typing(child_typing).try_array_type(node, array)
|
1361
|
+
if pair.constr.check_relation(sub_type: pair.type, super_type: hint).success?
|
1362
|
+
child_typing.save!
|
1363
|
+
return pair.with(constr: pair.constr.with_new_typing(typing))
|
1351
1364
|
end
|
1352
|
-
else
|
1353
|
-
[select_super_type(synthesize(e, hint: element_hint).type, element_hint)]
|
1354
1365
|
end
|
1355
1366
|
end
|
1356
|
-
array_type = AST::Builtin::Array.instance_type(AST::Types::Union.build(types: element_types))
|
1357
1367
|
end
|
1358
1368
|
|
1359
|
-
|
1369
|
+
try_array_type(node, nil)
|
1360
1370
|
end
|
1361
1371
|
end
|
1362
1372
|
|
@@ -1665,6 +1675,49 @@ module Steep
|
|
1665
1675
|
when :masgn
|
1666
1676
|
type_masgn(node)
|
1667
1677
|
|
1678
|
+
when :for
|
1679
|
+
yield_self do
|
1680
|
+
asgn, collection, body = node.children
|
1681
|
+
|
1682
|
+
collection_type, constr = synthesize(collection)
|
1683
|
+
collection_type = expand_self(collection_type)
|
1684
|
+
|
1685
|
+
var_type = case collection_type
|
1686
|
+
when AST::Types::Any
|
1687
|
+
AST::Types::Any.new
|
1688
|
+
else
|
1689
|
+
each = checker.factory.interface(collection_type, private: true).methods[:each]
|
1690
|
+
method_type = (each&.types || []).find {|type| type.block && type.block.type.params.first_param }
|
1691
|
+
method_type&.yield_self do |method_type|
|
1692
|
+
method_type.block.type.params.first_param&.type
|
1693
|
+
end
|
1694
|
+
end
|
1695
|
+
|
1696
|
+
if var_type
|
1697
|
+
if body
|
1698
|
+
body_constr = constr.with_updated_context(
|
1699
|
+
lvar_env: constr.context.lvar_env.assign(asgn.children[0].name, node: asgn, type: var_type)
|
1700
|
+
)
|
1701
|
+
|
1702
|
+
typing.add_context_for_body(node, context: body_constr.context)
|
1703
|
+
_, _, body_context = body_constr.synthesize(body)
|
1704
|
+
|
1705
|
+
constr = constr.update_lvar_env {|env| env.join(constr.context.lvar_env, body_context.lvar_env) }
|
1706
|
+
else
|
1707
|
+
constr = self
|
1708
|
+
end
|
1709
|
+
|
1710
|
+
add_typing(node, type: collection_type, constr: constr)
|
1711
|
+
else
|
1712
|
+
fallback_to_any(node) do
|
1713
|
+
Errors::NoMethod.new(
|
1714
|
+
node: node,
|
1715
|
+
method: :each,
|
1716
|
+
type: collection_type
|
1717
|
+
)
|
1718
|
+
end
|
1719
|
+
end
|
1720
|
+
end
|
1668
1721
|
when :while, :until
|
1669
1722
|
yield_self do
|
1670
1723
|
cond, body = node.children
|
@@ -1746,9 +1799,15 @@ module Steep
|
|
1746
1799
|
|
1747
1800
|
when :or_asgn, :and_asgn
|
1748
1801
|
yield_self do
|
1749
|
-
|
1750
|
-
|
1751
|
-
|
1802
|
+
asgn, rhs = node.children
|
1803
|
+
type, constr = synthesize(rhs, hint: hint)
|
1804
|
+
|
1805
|
+
case asgn.type
|
1806
|
+
when :lvasgn
|
1807
|
+
constr.lvasgn(asgn, type)
|
1808
|
+
when :ivasgn
|
1809
|
+
constr.ivasgn(asgn, type)
|
1810
|
+
end
|
1752
1811
|
end
|
1753
1812
|
|
1754
1813
|
when :defined?
|
@@ -1824,9 +1883,50 @@ module Steep
|
|
1824
1883
|
add_typing node, type: AST::Builtin.any_type
|
1825
1884
|
end
|
1826
1885
|
|
1827
|
-
when :
|
1886
|
+
when :cvasgn
|
1887
|
+
name, rhs = node.children
|
1888
|
+
|
1889
|
+
type, constr = synthesize(rhs, hint: hint)
|
1890
|
+
|
1891
|
+
var_type = if module_context&.class_variables
|
1892
|
+
module_context.class_variables[name]&.yield_self {|ty| checker.factory.type(ty) }
|
1893
|
+
end
|
1894
|
+
|
1895
|
+
if var_type
|
1896
|
+
result = constr.check_relation(sub_type: type, super_type: var_type)
|
1897
|
+
|
1898
|
+
if result.success?
|
1899
|
+
add_typing node, type: type, constr: constr
|
1900
|
+
else
|
1901
|
+
fallback_to_any node do
|
1902
|
+
Errors::IncompatibleAssignment.new(node: node,
|
1903
|
+
lhs_type: var_type,
|
1904
|
+
rhs_type: type,
|
1905
|
+
result: result)
|
1906
|
+
end
|
1907
|
+
end
|
1908
|
+
else
|
1909
|
+
fallback_to_any(node)
|
1910
|
+
end
|
1911
|
+
|
1912
|
+
when :cvar
|
1913
|
+
name = node.children[0]
|
1914
|
+
var_type = if module_context&.class_variables
|
1915
|
+
module_context.class_variables[name]&.yield_self {|ty| checker.factory.type(ty) }
|
1916
|
+
end
|
1917
|
+
|
1918
|
+
if var_type
|
1919
|
+
add_typing node, type: var_type
|
1920
|
+
else
|
1921
|
+
fallback_to_any node
|
1922
|
+
end
|
1923
|
+
|
1924
|
+
when :alias
|
1925
|
+
add_typing node, type: AST::Builtin.nil_type
|
1926
|
+
|
1927
|
+
when :splat
|
1828
1928
|
yield_self do
|
1829
|
-
Steep.logger.
|
1929
|
+
Steep.logger.warn { "Unsupported node #{node.type} (#{node.location.expression.source_buffer.name}:#{node.location.expression.line})" }
|
1830
1930
|
|
1831
1931
|
each_child_node node do |child|
|
1832
1932
|
synthesize(child)
|
@@ -1876,136 +1976,202 @@ module Steep
|
|
1876
1976
|
add_typing(node, type: ivar_type)
|
1877
1977
|
end
|
1878
1978
|
|
1979
|
+
def masgn_lhs?(lhs)
|
1980
|
+
lhs.children.all? do |a|
|
1981
|
+
asgn_type = if a.type == :splat
|
1982
|
+
a.children[0].type
|
1983
|
+
else
|
1984
|
+
a.type
|
1985
|
+
end
|
1986
|
+
asgn_type == :lvasgn || asgn_type == :ivasgn
|
1987
|
+
end
|
1988
|
+
end
|
1989
|
+
|
1990
|
+
def lvasgn(node, type)
|
1991
|
+
name = node.children[0].name
|
1992
|
+
env = context.lvar_env.assign(name, node: node, type: type) do |declared_type, type, result|
|
1993
|
+
typing.add_error(
|
1994
|
+
Errors::IncompatibleAssignment.new(node: node,
|
1995
|
+
lhs_type: declared_type,
|
1996
|
+
rhs_type: type,
|
1997
|
+
result: result)
|
1998
|
+
)
|
1999
|
+
end
|
2000
|
+
|
2001
|
+
add_typing(node, type: type, constr: with_updated_context(lvar_env: env))
|
2002
|
+
end
|
2003
|
+
|
2004
|
+
def ivasgn(node, type)
|
2005
|
+
ivar = node.children[0]
|
2006
|
+
|
2007
|
+
type_env.assign(ivar: ivar, type: type, self_type: self_type) do |error|
|
2008
|
+
case error
|
2009
|
+
when Subtyping::Result::Failure
|
2010
|
+
var_type = type_env.get(ivar: ivar)
|
2011
|
+
typing.add_error(Errors::IncompatibleAssignment.new(node: node,
|
2012
|
+
lhs_type: var_type,
|
2013
|
+
rhs_type: type,
|
2014
|
+
result: error))
|
2015
|
+
when nil
|
2016
|
+
fallback_to_any node
|
2017
|
+
end
|
2018
|
+
end
|
2019
|
+
|
2020
|
+
add_typing(node, type: type)
|
2021
|
+
end
|
2022
|
+
|
1879
2023
|
def type_masgn(node)
|
1880
2024
|
lhs, rhs = node.children
|
1881
2025
|
rhs_pair = synthesize(rhs)
|
1882
|
-
rhs_type =
|
2026
|
+
rhs_type = deep_expand_alias(rhs_pair.type)
|
1883
2027
|
|
1884
2028
|
constr = rhs_pair.constr
|
1885
2029
|
|
1886
|
-
|
1887
|
-
|
1888
|
-
|
1889
|
-
|
2030
|
+
unless masgn_lhs?(lhs)
|
2031
|
+
Steep.logger.error("Unsupported masgn lhs node: only lvasgn, ivasgn, and splat are supported")
|
2032
|
+
_, constr = constr.fallback_to_any(lhs)
|
2033
|
+
return add_typing(node, type: rhs_type, constr: constr)
|
2034
|
+
end
|
1890
2035
|
|
1891
|
-
|
1892
|
-
|
1893
|
-
|
1894
|
-
|
1895
|
-
|
1896
|
-
|
1897
|
-
|
1898
|
-
|
1899
|
-
|
1900
|
-
|
1901
|
-
|
1902
|
-
|
1903
|
-
|
1904
|
-
|
1905
|
-
|
1906
|
-
|
1907
|
-
|
1908
|
-
|
1909
|
-
|
1910
|
-
|
2036
|
+
falseys, truthys = partition_flatten_types(rhs_type) do |type|
|
2037
|
+
type.is_a?(AST::Types::Nil) || (type.is_a?(AST::Types::Literal) && type.value == false)
|
2038
|
+
end
|
2039
|
+
|
2040
|
+
unwrap_rhs_type = AST::Types::Union.build(types: truthys)
|
2041
|
+
|
2042
|
+
case
|
2043
|
+
when unwrap_rhs_type.is_a?(AST::Types::Tuple) || (rhs.type == :array && rhs.children.none? {|n| n.type == :splat })
|
2044
|
+
tuple_types = if unwrap_rhs_type.is_a?(AST::Types::Tuple)
|
2045
|
+
unwrap_rhs_type.types.dup
|
2046
|
+
else
|
2047
|
+
rhs.children.map do |node|
|
2048
|
+
typing.type_of(node: node)
|
2049
|
+
end
|
2050
|
+
end
|
2051
|
+
|
2052
|
+
assignment_nodes = lhs.children.dup
|
2053
|
+
leading_assignments = []
|
2054
|
+
trailing_assignments = []
|
2055
|
+
|
2056
|
+
until assignment_nodes.empty?
|
2057
|
+
cursor = assignment_nodes.first
|
2058
|
+
|
2059
|
+
if cursor.type == :splat
|
2060
|
+
break
|
2061
|
+
else
|
2062
|
+
leading_assignments << assignment_nodes.shift
|
1911
2063
|
end
|
2064
|
+
end
|
1912
2065
|
|
1913
|
-
|
2066
|
+
until assignment_nodes.empty?
|
2067
|
+
cursor = assignment_nodes.last
|
1914
2068
|
|
1915
|
-
|
1916
|
-
|
2069
|
+
if cursor.type == :splat
|
2070
|
+
break
|
2071
|
+
else
|
2072
|
+
trailing_assignments.unshift assignment_nodes.pop
|
2073
|
+
end
|
2074
|
+
end
|
1917
2075
|
|
1918
|
-
|
1919
|
-
|
2076
|
+
leading_assignments.each do |asgn|
|
2077
|
+
type = tuple_types.first
|
1920
2078
|
|
1921
|
-
|
1922
|
-
|
1923
|
-
|
1924
|
-
|
1925
|
-
|
1926
|
-
Errors::IncompatibleAssignment.new(node: lhs,
|
1927
|
-
lhs_type: declared_type,
|
1928
|
-
rhs_type: type,
|
1929
|
-
result: result)
|
1930
|
-
)
|
1931
|
-
end
|
1932
|
-
add_typing(lhs,
|
1933
|
-
type: ty,
|
1934
|
-
constr: ctr.with_updated_context(lvar_env: env)).constr
|
1935
|
-
when :ivasgn
|
1936
|
-
ivar = lhs.children[0]
|
2079
|
+
if type
|
2080
|
+
tuple_types.shift
|
2081
|
+
else
|
2082
|
+
type = AST::Builtin.nil_type
|
2083
|
+
end
|
1937
2084
|
|
1938
|
-
|
1939
|
-
|
1940
|
-
|
1941
|
-
|
1942
|
-
|
1943
|
-
|
1944
|
-
|
1945
|
-
result: error))
|
1946
|
-
when nil
|
1947
|
-
fallback_to_any node
|
1948
|
-
end
|
1949
|
-
end
|
2085
|
+
case asgn.type
|
2086
|
+
when :lvasgn
|
2087
|
+
_, constr = constr.lvasgn(asgn, type)
|
2088
|
+
when :ivasgn
|
2089
|
+
_, constr = constr.ivasgn(asgn, type)
|
2090
|
+
end
|
2091
|
+
end
|
1950
2092
|
|
1951
|
-
|
1952
|
-
|
2093
|
+
trailing_assignments.reverse_each do |asgn|
|
2094
|
+
type = tuple_types.last
|
2095
|
+
|
2096
|
+
if type
|
2097
|
+
tuple_types.pop
|
2098
|
+
else
|
2099
|
+
type = AST::Builtin.nil_type
|
1953
2100
|
end
|
1954
2101
|
|
1955
|
-
|
2102
|
+
case asgn.type
|
2103
|
+
when :lvasgn
|
2104
|
+
_, constr = constr.lvasgn(asgn, type)
|
2105
|
+
when :ivasgn
|
2106
|
+
_, constr = constr.ivasgn(asgn, type)
|
2107
|
+
end
|
2108
|
+
end
|
1956
2109
|
|
1957
|
-
|
1958
|
-
|
2110
|
+
element_type = if tuple_types.empty?
|
2111
|
+
AST::Builtin.nil_type
|
2112
|
+
else
|
2113
|
+
AST::Types::Union.build(types: tuple_types)
|
2114
|
+
end
|
2115
|
+
array_type = AST::Builtin::Array.instance_type(element_type)
|
1959
2116
|
|
1960
|
-
|
1961
|
-
|
2117
|
+
assignment_nodes.each do |asgn|
|
2118
|
+
case asgn.type
|
2119
|
+
when :splat
|
2120
|
+
case asgn.children[0].type
|
1962
2121
|
when :lvasgn
|
1963
|
-
|
1964
|
-
|
1965
|
-
|
1966
|
-
|
1967
|
-
|
1968
|
-
|
1969
|
-
|
1970
|
-
|
1971
|
-
|
2122
|
+
_, constr = constr.lvasgn(asgn.children[0], array_type)
|
2123
|
+
when :ivasgn
|
2124
|
+
_, constr = constr.ivasgn(asgn.children[0], array_type)
|
2125
|
+
end
|
2126
|
+
when :lvasgn
|
2127
|
+
_, constr = constr.lvasgn(asgn, element_type)
|
2128
|
+
when :ivasgn
|
2129
|
+
_,constr = constr.ivasgn(asgn, element_type)
|
2130
|
+
end
|
2131
|
+
end
|
1972
2132
|
|
1973
|
-
|
1974
|
-
|
1975
|
-
|
2133
|
+
unless falseys.empty?
|
2134
|
+
constr = constr.update_lvar_env {|lvar_env| self.context.lvar_env.join(lvar_env, self.context.lvar_env)}
|
2135
|
+
end
|
1976
2136
|
|
1977
|
-
|
1978
|
-
ivar = assignment.children[0]
|
2137
|
+
add_typing(node, type: rhs_type, constr: constr)
|
1979
2138
|
|
1980
|
-
|
1981
|
-
|
1982
|
-
|
1983
|
-
type = type_env.get(ivar: ivar)
|
1984
|
-
typing.add_error(Errors::IncompatibleAssignment.new(node: assignment,
|
1985
|
-
lhs_type: type,
|
1986
|
-
rhs_type: element_type,
|
1987
|
-
result: error))
|
1988
|
-
when nil
|
1989
|
-
fallback_to_any node
|
1990
|
-
end
|
1991
|
-
end
|
2139
|
+
when flatten_union(unwrap_rhs_type).all? {|type| AST::Builtin::Array.instance_type?(type) }
|
2140
|
+
array_elements = flatten_union(unwrap_rhs_type).map {|type| type.args[0] }
|
2141
|
+
element_type = AST::Types::Union.build(types: array_elements + [AST::Builtin.nil_type])
|
1992
2142
|
|
1993
|
-
|
2143
|
+
constr = lhs.children.inject(constr) do |constr, assignment|
|
2144
|
+
case assignment.type
|
2145
|
+
when :lvasgn
|
2146
|
+
_, constr = constr.lvasgn(assignment, element_type)
|
2147
|
+
|
2148
|
+
when :ivasgn
|
2149
|
+
_, constr = constr.ivasgn(assignment, element_type)
|
2150
|
+
when :splat
|
2151
|
+
case assignment.children[0].type
|
2152
|
+
when :lvasgn
|
2153
|
+
_, constr = constr.lvasgn(assignment.children[0], unwrap_rhs_type)
|
2154
|
+
when :ivasgn
|
2155
|
+
_, constr = constr.ivasgn(assignment.children[0], unwrap_rhs_type)
|
2156
|
+
else
|
2157
|
+
raise
|
1994
2158
|
end
|
1995
2159
|
end
|
1996
2160
|
|
1997
|
-
|
1998
|
-
|
1999
|
-
when rhs_type.is_a?(AST::Types::Any)
|
2000
|
-
fallback_to_any(node)
|
2161
|
+
constr
|
2162
|
+
end
|
2001
2163
|
|
2002
|
-
|
2003
|
-
|
2004
|
-
fallback_to_any(node)
|
2164
|
+
unless falseys.empty?
|
2165
|
+
constr = constr.update_lvar_env {|lvar_env| self.context.lvar_env.join(lvar_env, self.context.lvar_env)}
|
2005
2166
|
end
|
2167
|
+
|
2168
|
+
add_typing(node, type: rhs_type, constr: constr)
|
2006
2169
|
else
|
2007
|
-
|
2008
|
-
|
2170
|
+
unless rhs_type.is_a?(AST::Types::Any)
|
2171
|
+
Steep.logger.error("Unsupported masgn rhs type: array or tuple is supported (#{rhs_type})")
|
2172
|
+
end
|
2173
|
+
_, constr = constr.fallback_to_any(lhs)
|
2174
|
+
add_typing(node, type: rhs_type, constr: constr)
|
2009
2175
|
end
|
2010
2176
|
end
|
2011
2177
|
|
@@ -2056,7 +2222,7 @@ module Steep
|
|
2056
2222
|
else
|
2057
2223
|
case expanded_receiver_type = expand_self(receiver_type)
|
2058
2224
|
when AST::Types::Self
|
2059
|
-
Steep.logger.
|
2225
|
+
Steep.logger.debug { "`self` type cannot be resolved to concrete type" }
|
2060
2226
|
fallback_to_any node do
|
2061
2227
|
Errors::NoMethod.new(node: node, method: method_name, type: receiver_type)
|
2062
2228
|
end
|
@@ -2999,7 +3165,12 @@ module Steep
|
|
2999
3165
|
|
3000
3166
|
ty = case type
|
3001
3167
|
when AST::Types::Name::Alias
|
3002
|
-
deep_expand_alias(expand_alias(type), recursive: recursive
|
3168
|
+
deep_expand_alias(expand_alias(type), recursive: recursive.union([type]))
|
3169
|
+
when AST::Types::Union
|
3170
|
+
AST::Types::Union.build(
|
3171
|
+
types: type.types.map {|ty| deep_expand_alias(ty, recursive: recursive, &block) },
|
3172
|
+
location: type.location
|
3173
|
+
)
|
3003
3174
|
else
|
3004
3175
|
type
|
3005
3176
|
end
|
@@ -3011,19 +3182,51 @@ module Steep
|
|
3011
3182
|
end
|
3012
3183
|
end
|
3013
3184
|
|
3185
|
+
def flatten_union(type, acc = [])
|
3186
|
+
case type
|
3187
|
+
when AST::Types::Union
|
3188
|
+
type.types.each {|ty| flatten_union(ty, acc) }
|
3189
|
+
else
|
3190
|
+
acc << type
|
3191
|
+
end
|
3192
|
+
|
3193
|
+
acc
|
3194
|
+
end
|
3195
|
+
|
3196
|
+
def select_flatten_types(type, &block)
|
3197
|
+
types = flatten_union(deep_expand_alias(type))
|
3198
|
+
types.select(&block)
|
3199
|
+
end
|
3200
|
+
|
3201
|
+
def partition_flatten_types(type, &block)
|
3202
|
+
types = flatten_union(deep_expand_alias(type))
|
3203
|
+
types.partition(&block)
|
3204
|
+
end
|
3205
|
+
|
3206
|
+
def flatten_array_elements(type)
|
3207
|
+
flatten_union(deep_expand_alias(type)).flat_map do |type|
|
3208
|
+
if AST::Builtin::Array.instance_type?(type)
|
3209
|
+
type.args
|
3210
|
+
else
|
3211
|
+
[type]
|
3212
|
+
end
|
3213
|
+
end
|
3214
|
+
end
|
3215
|
+
|
3014
3216
|
def expand_alias(type, &block)
|
3015
3217
|
checker.factory.expand_alias(type, &block)
|
3016
3218
|
end
|
3017
3219
|
|
3018
3220
|
def test_literal_type(literal, hint)
|
3019
|
-
|
3020
|
-
|
3021
|
-
|
3022
|
-
|
3023
|
-
|
3024
|
-
|
3025
|
-
|
3026
|
-
|
3221
|
+
if hint
|
3222
|
+
case hint
|
3223
|
+
when AST::Types::Any
|
3224
|
+
nil
|
3225
|
+
else
|
3226
|
+
literal_type = AST::Types::Literal.new(value: literal, location: nil)
|
3227
|
+
if check_relation(sub_type: literal_type, super_type: hint).success?
|
3228
|
+
hint
|
3229
|
+
end
|
3027
3230
|
end
|
3028
3231
|
end
|
3029
3232
|
end
|
@@ -3057,6 +3260,47 @@ module Steep
|
|
3057
3260
|
AST::Types::Name::Instance.new(name: type.name, args: args)
|
3058
3261
|
end
|
3059
3262
|
|
3263
|
+
def try_tuple_type(node, hint)
|
3264
|
+
if node.children.size != hint.types.size
|
3265
|
+
return
|
3266
|
+
end
|
3267
|
+
|
3268
|
+
constr = self
|
3269
|
+
element_types = []
|
3270
|
+
|
3271
|
+
each_child_node(node).with_index do |child, index|
|
3272
|
+
type, constr = constr.synthesize(child, hint: hint.types[index])
|
3273
|
+
element_types << type
|
3274
|
+
end
|
3275
|
+
|
3276
|
+
constr.add_typing(node, type: AST::Types::Tuple.new(types: element_types))
|
3277
|
+
end
|
3278
|
+
|
3279
|
+
def try_array_type(node, hint)
|
3280
|
+
element_hint = hint ? hint.args[0] : nil
|
3281
|
+
|
3282
|
+
constr = self
|
3283
|
+
element_types = []
|
3284
|
+
|
3285
|
+
each_child_node(node) do |child|
|
3286
|
+
case child.type
|
3287
|
+
when :splat
|
3288
|
+
type, constr = constr.synthesize(child.children[0], hint: hint)
|
3289
|
+
if AST::Builtin::Array.instance_type?(type)
|
3290
|
+
element_types << type.args[0]
|
3291
|
+
else
|
3292
|
+
element_types.push(*flatten_array_elements(type))
|
3293
|
+
end
|
3294
|
+
else
|
3295
|
+
type, constr = constr.synthesize(child, hint: element_hint)
|
3296
|
+
element_types << type
|
3297
|
+
end
|
3298
|
+
end
|
3299
|
+
|
3300
|
+
element_type = AST::Types::Union.build(types: element_types)
|
3301
|
+
constr.add_typing(node, type: AST::Builtin::Array.instance_type(element_type))
|
3302
|
+
end
|
3303
|
+
|
3060
3304
|
def try_hash_type(node, hint)
|
3061
3305
|
case hint
|
3062
3306
|
when AST::Types::Record
|