steep 0.13.0 → 0.16.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (214) hide show
  1. checksums.yaml +4 -4
  2. data/.gitmodules +0 -3
  3. data/CHANGELOG.md +28 -0
  4. data/Rakefile +0 -13
  5. data/bin/setup +0 -2
  6. data/bin/smoke_runner.rb +0 -1
  7. data/exe/steep +0 -1
  8. data/lib/steep.rb +33 -1
  9. data/lib/steep/annotation_parser.rb +4 -4
  10. data/lib/steep/ast/buffer.rb +11 -7
  11. data/lib/steep/ast/builtin.rb +8 -0
  12. data/lib/steep/ast/types/factory.rb +124 -89
  13. data/lib/steep/cli.rb +16 -1
  14. data/lib/steep/drivers/annotations.rb +1 -1
  15. data/lib/steep/drivers/check.rb +20 -4
  16. data/lib/steep/drivers/init.rb +5 -5
  17. data/lib/steep/drivers/langserver.rb +13 -287
  18. data/lib/steep/drivers/utils/driver_helper.rb +1 -1
  19. data/lib/steep/drivers/vendor.rb +2 -2
  20. data/lib/steep/drivers/watch.rb +97 -85
  21. data/lib/steep/drivers/worker.rb +51 -0
  22. data/lib/steep/project.rb +9 -5
  23. data/lib/steep/project/completion_provider.rb +298 -0
  24. data/lib/steep/project/dsl.rb +14 -0
  25. data/lib/steep/project/file.rb +54 -47
  26. data/lib/steep/project/hover_content.rb +17 -8
  27. data/lib/steep/project/options.rb +25 -3
  28. data/lib/steep/project/target.rb +40 -24
  29. data/lib/steep/server/base_worker.rb +56 -0
  30. data/lib/steep/server/code_worker.rb +151 -0
  31. data/lib/steep/server/interaction_worker.rb +281 -0
  32. data/lib/steep/server/master.rb +196 -0
  33. data/lib/steep/server/signature_worker.rb +148 -0
  34. data/lib/steep/server/utils.rb +36 -0
  35. data/lib/steep/server/worker_process.rb +62 -0
  36. data/lib/steep/signature/errors.rb +1 -1
  37. data/lib/steep/signature/validator.rb +13 -13
  38. data/lib/steep/source.rb +1 -1
  39. data/lib/steep/type_construction.rb +1004 -727
  40. data/lib/steep/type_inference/constant_env.rb +3 -11
  41. data/lib/steep/type_inference/context.rb +8 -3
  42. data/lib/steep/type_inference/context_array.rb +111 -0
  43. data/lib/steep/type_inference/local_variable_type_env.rb +226 -0
  44. data/lib/steep/type_inference/logic.rb +130 -0
  45. data/lib/steep/type_inference/type_env.rb +5 -69
  46. data/lib/steep/typing.rb +91 -23
  47. data/lib/steep/version.rb +1 -1
  48. data/smoke/alias/Steepfile +1 -0
  49. data/smoke/alias/a.rb +1 -1
  50. data/smoke/and/Steepfile +1 -0
  51. data/smoke/array/Steepfile +1 -0
  52. data/smoke/array/b.rb +0 -2
  53. data/smoke/block/Steepfile +1 -0
  54. data/smoke/case/Steepfile +1 -0
  55. data/smoke/class/Steepfile +1 -0
  56. data/smoke/const/Steepfile +1 -0
  57. data/smoke/dstr/Steepfile +1 -0
  58. data/smoke/ensure/Steepfile +1 -0
  59. data/smoke/enumerator/Steepfile +1 -0
  60. data/smoke/extension/Steepfile +1 -0
  61. data/smoke/extension/c.rb +1 -0
  62. data/smoke/hash/Steepfile +1 -0
  63. data/smoke/hello/Steepfile +1 -0
  64. data/smoke/if/Steepfile +1 -0
  65. data/smoke/if/a.rb +1 -1
  66. data/smoke/implements/Steepfile +1 -0
  67. data/smoke/initialize/Steepfile +1 -0
  68. data/smoke/integer/Steepfile +1 -0
  69. data/smoke/interface/Steepfile +1 -0
  70. data/smoke/kwbegin/Steepfile +1 -0
  71. data/smoke/lambda/Steepfile +1 -0
  72. data/smoke/literal/Steepfile +1 -0
  73. data/smoke/map/Steepfile +1 -0
  74. data/smoke/method/Steepfile +1 -0
  75. data/smoke/module/Steepfile +1 -0
  76. data/smoke/regexp/Steepfile +1 -0
  77. data/smoke/regexp/b.rb +4 -4
  78. data/smoke/regression/Steepfile +1 -0
  79. data/smoke/rescue/Steepfile +1 -0
  80. data/smoke/rescue/a.rb +1 -1
  81. data/smoke/self/Steepfile +1 -0
  82. data/smoke/skip/Steepfile +1 -0
  83. data/smoke/stdout/Steepfile +1 -0
  84. data/smoke/super/Steepfile +1 -0
  85. data/smoke/type_case/Steepfile +1 -0
  86. data/smoke/yield/Steepfile +1 -0
  87. data/steep.gemspec +8 -8
  88. metadata +38 -138
  89. data/exe/rbs +0 -3
  90. data/exe/ruby-signature +0 -3
  91. data/vendor/ruby-signature/.github/workflows/ruby.yml +0 -27
  92. data/vendor/ruby-signature/.gitignore +0 -12
  93. data/vendor/ruby-signature/.rubocop.yml +0 -15
  94. data/vendor/ruby-signature/BSDL +0 -22
  95. data/vendor/ruby-signature/COPYING +0 -56
  96. data/vendor/ruby-signature/Gemfile +0 -6
  97. data/vendor/ruby-signature/README.md +0 -93
  98. data/vendor/ruby-signature/Rakefile +0 -66
  99. data/vendor/ruby-signature/bin/annotate-with-rdoc +0 -156
  100. data/vendor/ruby-signature/bin/console +0 -14
  101. data/vendor/ruby-signature/bin/query-rdoc +0 -103
  102. data/vendor/ruby-signature/bin/setup +0 -10
  103. data/vendor/ruby-signature/bin/sort +0 -88
  104. data/vendor/ruby-signature/bin/test_runner.rb +0 -17
  105. data/vendor/ruby-signature/docs/CONTRIBUTING.md +0 -97
  106. data/vendor/ruby-signature/docs/sigs.md +0 -148
  107. data/vendor/ruby-signature/docs/stdlib.md +0 -152
  108. data/vendor/ruby-signature/docs/syntax.md +0 -528
  109. data/vendor/ruby-signature/exe/rbs +0 -3
  110. data/vendor/ruby-signature/exe/ruby-signature +0 -7
  111. data/vendor/ruby-signature/lib/ruby/signature.rb +0 -64
  112. data/vendor/ruby-signature/lib/ruby/signature/ast/annotation.rb +0 -29
  113. data/vendor/ruby-signature/lib/ruby/signature/ast/comment.rb +0 -29
  114. data/vendor/ruby-signature/lib/ruby/signature/ast/declarations.rb +0 -391
  115. data/vendor/ruby-signature/lib/ruby/signature/ast/members.rb +0 -364
  116. data/vendor/ruby-signature/lib/ruby/signature/buffer.rb +0 -52
  117. data/vendor/ruby-signature/lib/ruby/signature/builtin_names.rb +0 -54
  118. data/vendor/ruby-signature/lib/ruby/signature/cli.rb +0 -534
  119. data/vendor/ruby-signature/lib/ruby/signature/constant.rb +0 -28
  120. data/vendor/ruby-signature/lib/ruby/signature/constant_table.rb +0 -152
  121. data/vendor/ruby-signature/lib/ruby/signature/definition.rb +0 -172
  122. data/vendor/ruby-signature/lib/ruby/signature/definition_builder.rb +0 -921
  123. data/vendor/ruby-signature/lib/ruby/signature/environment.rb +0 -283
  124. data/vendor/ruby-signature/lib/ruby/signature/environment_loader.rb +0 -138
  125. data/vendor/ruby-signature/lib/ruby/signature/environment_walker.rb +0 -126
  126. data/vendor/ruby-signature/lib/ruby/signature/errors.rb +0 -189
  127. data/vendor/ruby-signature/lib/ruby/signature/location.rb +0 -104
  128. data/vendor/ruby-signature/lib/ruby/signature/method_type.rb +0 -125
  129. data/vendor/ruby-signature/lib/ruby/signature/namespace.rb +0 -93
  130. data/vendor/ruby-signature/lib/ruby/signature/parser.y +0 -1343
  131. data/vendor/ruby-signature/lib/ruby/signature/prototype/rb.rb +0 -441
  132. data/vendor/ruby-signature/lib/ruby/signature/prototype/rbi.rb +0 -579
  133. data/vendor/ruby-signature/lib/ruby/signature/prototype/runtime.rb +0 -383
  134. data/vendor/ruby-signature/lib/ruby/signature/substitution.rb +0 -48
  135. data/vendor/ruby-signature/lib/ruby/signature/test.rb +0 -28
  136. data/vendor/ruby-signature/lib/ruby/signature/test/errors.rb +0 -63
  137. data/vendor/ruby-signature/lib/ruby/signature/test/hook.rb +0 -290
  138. data/vendor/ruby-signature/lib/ruby/signature/test/setup.rb +0 -58
  139. data/vendor/ruby-signature/lib/ruby/signature/test/spy.rb +0 -324
  140. data/vendor/ruby-signature/lib/ruby/signature/test/test_helper.rb +0 -185
  141. data/vendor/ruby-signature/lib/ruby/signature/test/type_check.rb +0 -256
  142. data/vendor/ruby-signature/lib/ruby/signature/type_name.rb +0 -72
  143. data/vendor/ruby-signature/lib/ruby/signature/types.rb +0 -932
  144. data/vendor/ruby-signature/lib/ruby/signature/variance_calculator.rb +0 -140
  145. data/vendor/ruby-signature/lib/ruby/signature/vendorer.rb +0 -49
  146. data/vendor/ruby-signature/lib/ruby/signature/version.rb +0 -5
  147. data/vendor/ruby-signature/lib/ruby/signature/writer.rb +0 -271
  148. data/vendor/ruby-signature/ruby-signature.gemspec +0 -45
  149. data/vendor/ruby-signature/stdlib/abbrev/abbrev.rbs +0 -3
  150. data/vendor/ruby-signature/stdlib/base64/base64.rbs +0 -15
  151. data/vendor/ruby-signature/stdlib/builtin/array.rbs +0 -1997
  152. data/vendor/ruby-signature/stdlib/builtin/basic_object.rbs +0 -280
  153. data/vendor/ruby-signature/stdlib/builtin/binding.rbs +0 -177
  154. data/vendor/ruby-signature/stdlib/builtin/builtin.rbs +0 -35
  155. data/vendor/ruby-signature/stdlib/builtin/class.rbs +0 -145
  156. data/vendor/ruby-signature/stdlib/builtin/comparable.rbs +0 -116
  157. data/vendor/ruby-signature/stdlib/builtin/complex.rbs +0 -400
  158. data/vendor/ruby-signature/stdlib/builtin/constants.rbs +0 -37
  159. data/vendor/ruby-signature/stdlib/builtin/data.rbs +0 -5
  160. data/vendor/ruby-signature/stdlib/builtin/deprecated.rbs +0 -2
  161. data/vendor/ruby-signature/stdlib/builtin/dir.rbs +0 -419
  162. data/vendor/ruby-signature/stdlib/builtin/encoding.rbs +0 -606
  163. data/vendor/ruby-signature/stdlib/builtin/enumerable.rbs +0 -404
  164. data/vendor/ruby-signature/stdlib/builtin/enumerator.rbs +0 -260
  165. data/vendor/ruby-signature/stdlib/builtin/errno.rbs +0 -781
  166. data/vendor/ruby-signature/stdlib/builtin/errors.rbs +0 -582
  167. data/vendor/ruby-signature/stdlib/builtin/exception.rbs +0 -193
  168. data/vendor/ruby-signature/stdlib/builtin/false_class.rbs +0 -40
  169. data/vendor/ruby-signature/stdlib/builtin/fiber.rbs +0 -68
  170. data/vendor/ruby-signature/stdlib/builtin/fiber_error.rbs +0 -12
  171. data/vendor/ruby-signature/stdlib/builtin/file.rbs +0 -476
  172. data/vendor/ruby-signature/stdlib/builtin/file_test.rbs +0 -59
  173. data/vendor/ruby-signature/stdlib/builtin/float.rbs +0 -696
  174. data/vendor/ruby-signature/stdlib/builtin/gc.rbs +0 -121
  175. data/vendor/ruby-signature/stdlib/builtin/hash.rbs +0 -1029
  176. data/vendor/ruby-signature/stdlib/builtin/integer.rbs +0 -710
  177. data/vendor/ruby-signature/stdlib/builtin/io.rbs +0 -683
  178. data/vendor/ruby-signature/stdlib/builtin/kernel.rbs +0 -574
  179. data/vendor/ruby-signature/stdlib/builtin/marshal.rbs +0 -135
  180. data/vendor/ruby-signature/stdlib/builtin/match_data.rbs +0 -141
  181. data/vendor/ruby-signature/stdlib/builtin/math.rbs +0 -66
  182. data/vendor/ruby-signature/stdlib/builtin/method.rbs +0 -182
  183. data/vendor/ruby-signature/stdlib/builtin/module.rbs +0 -248
  184. data/vendor/ruby-signature/stdlib/builtin/nil_class.rbs +0 -82
  185. data/vendor/ruby-signature/stdlib/builtin/numeric.rbs +0 -409
  186. data/vendor/ruby-signature/stdlib/builtin/object.rbs +0 -824
  187. data/vendor/ruby-signature/stdlib/builtin/proc.rbs +0 -426
  188. data/vendor/ruby-signature/stdlib/builtin/process.rbs +0 -354
  189. data/vendor/ruby-signature/stdlib/builtin/random.rbs +0 -93
  190. data/vendor/ruby-signature/stdlib/builtin/range.rbs +0 -226
  191. data/vendor/ruby-signature/stdlib/builtin/rational.rbs +0 -424
  192. data/vendor/ruby-signature/stdlib/builtin/rb_config.rbs +0 -10
  193. data/vendor/ruby-signature/stdlib/builtin/regexp.rbs +0 -131
  194. data/vendor/ruby-signature/stdlib/builtin/ruby_vm.rbs +0 -14
  195. data/vendor/ruby-signature/stdlib/builtin/signal.rbs +0 -55
  196. data/vendor/ruby-signature/stdlib/builtin/string.rbs +0 -770
  197. data/vendor/ruby-signature/stdlib/builtin/string_io.rbs +0 -13
  198. data/vendor/ruby-signature/stdlib/builtin/struct.rbs +0 -40
  199. data/vendor/ruby-signature/stdlib/builtin/symbol.rbs +0 -230
  200. data/vendor/ruby-signature/stdlib/builtin/thread.rbs +0 -1112
  201. data/vendor/ruby-signature/stdlib/builtin/thread_group.rbs +0 -23
  202. data/vendor/ruby-signature/stdlib/builtin/time.rbs +0 -739
  203. data/vendor/ruby-signature/stdlib/builtin/trace_point.rbs +0 -91
  204. data/vendor/ruby-signature/stdlib/builtin/true_class.rbs +0 -46
  205. data/vendor/ruby-signature/stdlib/builtin/unbound_method.rbs +0 -159
  206. data/vendor/ruby-signature/stdlib/builtin/warning.rbs +0 -17
  207. data/vendor/ruby-signature/stdlib/erb/erb.rbs +0 -18
  208. data/vendor/ruby-signature/stdlib/find/find.rbs +0 -44
  209. data/vendor/ruby-signature/stdlib/pathname/pathname.rbs +0 -21
  210. data/vendor/ruby-signature/stdlib/prime/integer-extension.rbs +0 -23
  211. data/vendor/ruby-signature/stdlib/prime/prime.rbs +0 -188
  212. data/vendor/ruby-signature/stdlib/securerandom/securerandom.rbs +0 -9
  213. data/vendor/ruby-signature/stdlib/set/set.rbs +0 -77
  214. data/vendor/ruby-signature/stdlib/tmpdir/tmpdir.rbs +0 -53
@@ -12,29 +12,21 @@ module Steep
12
12
  @cache = {}
13
13
  @factory = factory
14
14
  @context = context
15
- @table = Ruby::Signature::ConstantTable.new(builder: factory.definition_builder)
16
- end
17
-
18
- def namespace
19
- @namespace ||= if context
20
- context.namespace.append(context.name)
21
- else
22
- AST::Namespace.root
23
- end
15
+ @table = RBS::ConstantTable.new(builder: factory.definition_builder)
24
16
  end
25
17
 
26
18
  def lookup(name)
27
19
  cache[name] ||= begin
28
20
  constant = table.resolve_constant_reference(
29
21
  factory.type_name_1(name),
30
- context: factory.namespace_1(namespace)
22
+ context: context.map {|namespace| factory.namespace_1(namespace) }
31
23
  )
32
24
 
33
25
  if constant
34
26
  factory.type(constant.type)
35
27
  end
36
28
  rescue => exn
37
- Steep.logger.error "Looking up a constant failed: name=#{name}, context=#{context}, error=#{exn.inspect}"
29
+ Steep.logger.error "Looking up a constant failed: name=#{name}, context=[#{context.join(", ")}], error=#{exn.inspect}"
38
30
  nil
39
31
  end
40
32
  end
@@ -48,6 +48,7 @@ module Steep
48
48
  attr_reader :defined_module_methods
49
49
  attr_reader :const_env
50
50
  attr_reader :implement_name
51
+ attr_reader :namespaces
51
52
  attr_reader :current_namespace
52
53
  attr_reader :class_name
53
54
  attr_reader :instance_definition
@@ -77,14 +78,16 @@ module Steep
77
78
  attr_reader :module_context
78
79
  attr_reader :self_type
79
80
  attr_reader :type_env
81
+ attr_reader :lvar_env
80
82
 
81
- def initialize(method_context:, block_context:, break_context:, module_context:, self_type:, type_env:)
83
+ def initialize(method_context:, block_context:, break_context:, module_context:, self_type:, type_env:, lvar_env:)
82
84
  @method_context = method_context
83
85
  @block_context = block_context
84
86
  @break_context = break_context
85
87
  @module_context = module_context
86
88
  @self_type = self_type
87
89
  @type_env = type_env
90
+ @lvar_env = lvar_env
88
91
  end
89
92
 
90
93
  def with(method_context: self.method_context,
@@ -92,14 +95,16 @@ module Steep
92
95
  break_context: self.break_context,
93
96
  module_context: self.module_context,
94
97
  self_type: self.self_type,
95
- type_env: self.type_env)
98
+ type_env: self.type_env,
99
+ lvar_env: self.lvar_env)
96
100
  self.class.new(
97
101
  method_context: method_context,
98
102
  block_context: block_context,
99
103
  break_context: break_context,
100
104
  module_context: module_context,
101
105
  self_type: self_type,
102
- type_env: type_env
106
+ type_env: type_env,
107
+ lvar_env: lvar_env
103
108
  )
104
109
  end
105
110
  end
@@ -0,0 +1,111 @@
1
+ module Steep
2
+ module TypeInference
3
+ class ContextArray
4
+ class Entry
5
+ attr_reader :range, :context, :sub_entries
6
+
7
+ def initialize(range:, context:)
8
+ @range = range
9
+ @context = context
10
+ @sub_entries = Set[].compare_by_identity
11
+ end
12
+ end
13
+
14
+ attr_reader :buffer
15
+ attr_reader :root
16
+
17
+ def initialize(buffer:, context:, range: 0..buffer.content.size)
18
+ @buffer = buffer
19
+ @root = Entry.new(range: range, context: context)
20
+ end
21
+
22
+ def range
23
+ root.range
24
+ end
25
+
26
+ def self.from_source(source:, range: nil, context: nil)
27
+ content = if source.node
28
+ source.node.location.expression.source_buffer.source
29
+ else
30
+ ""
31
+ end
32
+ buffer = AST::Buffer.new(name: source.path, content: content)
33
+ new(buffer: buffer, context: context, range: range || 0..buffer.content.size)
34
+ end
35
+
36
+ def insert_context(range, context:, entry: self.root)
37
+ entry.sub_entries.each do |sub|
38
+ next if sub.range.begin < range.begin && range.end <= sub.range.end
39
+ next if range.begin < sub.range.begin && sub.range.end <= range.end
40
+ next if range.end <= sub.range.begin
41
+ next if sub.range.end <= range.begin
42
+
43
+ raise "Range crossing: sub range=#{sub.range}, new range=#{range}"
44
+ end
45
+
46
+ sup = entry.sub_entries.find do |sub|
47
+ sub.range.begin < range.begin && range.end <= sub.range.end
48
+ end
49
+
50
+ if sup
51
+ insert_context(range, context: context, entry: sup)
52
+ else
53
+ subs = entry.sub_entries.select do |sub|
54
+ range.begin < sub.range.begin && sub.range.end <= range.end
55
+ end
56
+
57
+ new_entry = Entry.new(range: range, context: context)
58
+ entry.sub_entries.subtract(subs)
59
+ new_entry.sub_entries.merge(subs)
60
+ entry.sub_entries << new_entry
61
+ end
62
+ end
63
+
64
+ def each_entry
65
+ if block_given?
66
+ es = [root]
67
+
68
+ until es.empty?
69
+ e = es.pop
70
+ es.push(*e.sub_entries.to_a)
71
+
72
+ yield e
73
+ end
74
+ else
75
+ enum_for :each_entry
76
+ end
77
+ end
78
+
79
+ def context_at(index, entry: self.root)
80
+ return nil if index < entry.range.begin || entry.range.end < index
81
+
82
+ sub = entry.sub_entries.find do |sub|
83
+ sub.range.begin <= index && index <= sub.range.end
84
+ end
85
+
86
+ if sub
87
+ context_at(index, entry: sub)
88
+ else
89
+ entry.context
90
+ end
91
+ end
92
+
93
+ def [](index)
94
+ context_at(index)
95
+ end
96
+
97
+ def at(line:, column:)
98
+ pos = buffer.loc_to_pos([line, column])
99
+ self[pos]
100
+ end
101
+
102
+ def merge(subtree)
103
+ subtree.each_entry do |entry|
104
+ if entry.context
105
+ insert_context entry.range, context: entry.context
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,226 @@
1
+ module Steep
2
+ module TypeInference
3
+ class LocalVariableTypeEnv
4
+ attr_reader :subtyping
5
+ attr_reader :self_type
6
+
7
+ class Entry
8
+ attr_reader :type
9
+ attr_reader :annotations
10
+ attr_reader :nodes
11
+
12
+ def initialize(type:, annotations: [], nodes: [])
13
+ @type = type
14
+ @annotations = Set.new(annotations)
15
+ @nodes = Set[].compare_by_identity.merge(nodes)
16
+ end
17
+
18
+ def update(type: self.type, annotations: self.annotations, nodes: self.nodes)
19
+ Entry.new(type: type, annotations: annotations, nodes: nodes)
20
+ end
21
+
22
+ def ==(other)
23
+ other.is_a?(Entry) &&
24
+ other.type == type &&
25
+ other.annotations == annotations &&
26
+ other.nodes == nodes
27
+ end
28
+
29
+ def +(other)
30
+ self.class.new(type: AST::Types::Union.build(types: [type, other.type]),
31
+ annotations: annotations + other.annotations,
32
+ nodes: nodes + other.nodes)
33
+ end
34
+
35
+ def optional
36
+ self.class.new(type: AST::Types::Union.build(types: [type, AST::Builtin.nil_type]),
37
+ annotations: annotations,
38
+ nodes: nodes)
39
+ end
40
+ end
41
+
42
+ attr_reader :declared_types
43
+ attr_reader :assigned_types
44
+
45
+ def self.empty(subtyping:, self_type:)
46
+ new(subtyping: subtyping, declared_types: {}, assigned_types: {}, self_type: self_type)
47
+ end
48
+
49
+ def initialize(subtyping:, declared_types:, assigned_types:, self_type:)
50
+ @subtyping = subtyping
51
+ @self_type = self_type
52
+
53
+ @declared_types = declared_types
54
+ @assigned_types = assigned_types
55
+
56
+ unless (intersection = Set.new(declared_types.keys) & Set.new(assigned_types.keys)).empty?
57
+ raise "Declared types and assigned types should be disjoint: #{intersection}"
58
+ end
59
+ end
60
+
61
+ def update(declared_types: self.declared_types, assigned_types: self.assigned_types, self_type: self.self_type)
62
+ self.class.new(
63
+ subtyping: subtyping,
64
+ declared_types: declared_types,
65
+ assigned_types: assigned_types,
66
+ self_type: self_type
67
+ )
68
+ end
69
+
70
+ def assign!(var, node:, type:)
71
+ declared_type = declared_types[var]&.type
72
+
73
+ if declared_type
74
+ relation = Subtyping::Relation.new(sub_type: type, super_type: declared_type)
75
+ constraints = Subtyping::Constraints.new(unknowns: Set.new)
76
+ subtyping.check(relation, constraints: constraints, self_type: self_type).else do |result|
77
+ yield declared_type, type, result
78
+ end
79
+ end
80
+
81
+ assignments = { var => Entry.new(type: type, nodes: [node]) }
82
+ update(assigned_types: assigned_types.merge(assignments),
83
+ declared_types: declared_types.reject {|k, _| k == var })
84
+ end
85
+
86
+ def assign(var, node:, type:)
87
+ declared_type = declared_types[var]&.type
88
+
89
+ if declared_type
90
+ relation = Subtyping::Relation.new(sub_type: type, super_type: declared_type)
91
+ constraints = Subtyping::Constraints.new(unknowns: Set.new)
92
+ subtyping.check(relation, constraints: constraints, self_type: self_type).else do |result|
93
+ yield declared_type, type, result
94
+ end
95
+
96
+ self
97
+ else
98
+ assignments = { var => Entry.new(type: type, nodes: [node]) }
99
+ update(assigned_types: assigned_types.merge(assignments))
100
+ end
101
+ end
102
+
103
+ def annotate(collection)
104
+ decls = collection.var_type_annotations.each.with_object({}) do |(var, annotation), hash|
105
+ type = collection.var_type(lvar: var)
106
+ hash[var] = Entry.new(type: type, annotations: [annotation])
107
+ end
108
+
109
+ decls.each do |var, annot|
110
+ inner_type = annot.type
111
+ outer_type = self[var]
112
+
113
+ if outer_type
114
+ relation = Subtyping::Relation.new(sub_type: inner_type, super_type: outer_type)
115
+ constraints = Subtyping::Constraints.new(unknowns: Set.new)
116
+ subtyping.check(relation, constraints: constraints, self_type: self_type).else do |result|
117
+ yield var, outer_type, inner_type, result
118
+ end
119
+ end
120
+ end
121
+
122
+ new_decls = declared_types.merge(decls)
123
+ new_assigns = assigned_types.reject {|var, _| new_decls.key?(var) }
124
+
125
+ update(declared_types: new_decls, assigned_types: new_assigns)
126
+ end
127
+
128
+ def [](var)
129
+ entry(var)&.type
130
+ end
131
+
132
+ def entry(var)
133
+ declared_types[var] || assigned_types[var]
134
+ end
135
+
136
+ def pin_assignments
137
+ update(
138
+ declared_types: assigned_types.merge(declared_types),
139
+ assigned_types: {}
140
+ )
141
+ end
142
+
143
+ def except(variables)
144
+ update(
145
+ declared_types: declared_types.reject {|var, _| variables.include?(var) },
146
+ assigned_types: assigned_types.reject {|var, _| variables.include?(var) }
147
+ )
148
+ end
149
+
150
+ def each
151
+ if block_given?
152
+ vars.each do |var|
153
+ yield var, self[var]
154
+ end
155
+ else
156
+ enum_for :each
157
+ end
158
+ end
159
+
160
+ def vars
161
+ @vars ||= Set.new(declared_types.keys + assigned_types.keys)
162
+ end
163
+
164
+ def join(*envs)
165
+ if envs.empty?
166
+ self
167
+ else
168
+ env = envs.inject do |env1, env2|
169
+ assigned_types = {}
170
+ declared_types = {}
171
+
172
+ (env1.vars + env2.vars).each do |var|
173
+ e1 = env1.entry(var)
174
+ e2 = env2.entry(var)
175
+ je = join_entry(e1, e2)
176
+
177
+ if env1.declared_types.key?(var) || env2.declared_types.key?(var)
178
+ declared_types[var] = je
179
+ else
180
+ assigned_types[var] = je
181
+ end
182
+ end
183
+
184
+ LocalVariableTypeEnv.new(
185
+ subtyping: subtyping,
186
+ self_type: self_type,
187
+ declared_types: declared_types,
188
+ assigned_types: assigned_types
189
+ )
190
+ end
191
+
192
+ decls = env.declared_types.merge(declared_types)
193
+ assignments = env.assigned_types.reject {|var, _| decls.key?(var) }
194
+
195
+ update(
196
+ declared_types: decls,
197
+ assigned_types: assignments,
198
+ )
199
+ end
200
+ end
201
+
202
+ def join_entry(e1, e2)
203
+ case
204
+ when e1 && e2
205
+ e1 + e2
206
+ when e1
207
+ e1.optional
208
+ when e2
209
+ e2.optional
210
+ else
211
+ raise
212
+ end
213
+ end
214
+
215
+ def to_s
216
+ ss = []
217
+
218
+ vars.each do |var|
219
+ ss << "#{var}: #{self[var].to_s}"
220
+ end
221
+
222
+ "{#{ss.join(", ")}}"
223
+ end
224
+ end
225
+ end
226
+ end
@@ -0,0 +1,130 @@
1
+ module Steep
2
+ module TypeInference
3
+ class Logic
4
+ class Result
5
+ attr_reader :nodes
6
+
7
+ def initialize(nodes = [])
8
+ @nodes = Set[].compare_by_identity.merge(nodes)
9
+ end
10
+
11
+ def +(other)
12
+ Result.new(nodes + other.nodes)
13
+ end
14
+
15
+ def merge(nodes)
16
+ Result.new(self.nodes + nodes)
17
+ end
18
+
19
+ def vars
20
+ vars = Set[]
21
+
22
+ nodes.each do |node|
23
+ case node.type
24
+ when :lvar, :lvasgn
25
+ vars << node.children[0].name
26
+ end
27
+ end
28
+
29
+ vars
30
+ end
31
+ end
32
+
33
+ attr_reader :subtyping
34
+
35
+ def initialize(subtyping:)
36
+ @subtyping = subtyping
37
+ end
38
+
39
+ def nodes(node:)
40
+ case node.type
41
+ when :lvasgn
42
+ rhs = node.children[1]
43
+ t, f = nodes(node: rhs)
44
+
45
+ [
46
+ t.merge([node]),
47
+ f.merge([node])
48
+ ]
49
+
50
+ when :and
51
+ lhs, rhs = node.children
52
+
53
+ lt, _ = nodes(node: lhs)
54
+ rt, _ = nodes(node: rhs)
55
+
56
+ [
57
+ Result.new([node]) + lt + rt,
58
+ Result.new([node])
59
+ ]
60
+
61
+ when :or
62
+ lhs, rhs = node.children
63
+
64
+ _, lf = nodes(node: lhs)
65
+ _, rf = nodes(node: rhs)
66
+
67
+ [
68
+ Result.new([node]),
69
+ Result.new([node]) + lf + rf
70
+ ]
71
+
72
+ when :begin
73
+ nodes(node: node.children.last)
74
+
75
+ else
76
+ [
77
+ Result.new([node]),
78
+ Result.new([node])
79
+ ]
80
+ end
81
+ end
82
+
83
+ def environments(truthy_vars:, falsey_vars:, lvar_env:)
84
+ truthy_hash = lvar_env.assigned_types.dup
85
+ falsey_hash = lvar_env.assigned_types.dup
86
+
87
+ (truthy_vars + falsey_vars).each do |var|
88
+ type = lvar_env[var]
89
+ truthy_type, falsey_type = partition_union(type)
90
+
91
+ if truthy_vars.include?(var)
92
+ truthy_hash[var] = LocalVariableTypeEnv::Entry.new(type: truthy_type)
93
+ end
94
+
95
+ if falsey_vars.include?(var)
96
+ falsey_hash[var] = LocalVariableTypeEnv::Entry.new(type: falsey_type)
97
+ end
98
+ end
99
+
100
+ [
101
+ lvar_env.except(truthy_vars).update(assigned_types: truthy_hash),
102
+ lvar_env.except(falsey_vars).update(assigned_types: falsey_hash)
103
+ ]
104
+ end
105
+
106
+ def partition_union(type)
107
+ case type
108
+ when AST::Types::Union
109
+ falsey_types, truthy_types = type.types.partition do |type|
110
+ case type
111
+ when AST::Types::Nil
112
+ true
113
+ when AST::Types::Literal
114
+ type.value == false
115
+ end
116
+ end
117
+
118
+ [
119
+ truthy_types.empty? ? AST::Types::Bot.new : AST::Types::Union.build(types: truthy_types),
120
+ falsey_types.empty? ? AST::Types::Bot.new : AST::Types::Union.build(types: falsey_types)
121
+ ]
122
+ when AST::Types::Any, AST::Types::Top, AST::Types::Boolean, AST::Types::Void
123
+ [type, type]
124
+ else
125
+ [type, AST::Types::Bot.new]
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end