steep 0.34.0 → 0.39.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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +31 -0
  3. data/lib/steep.rb +6 -0
  4. data/lib/steep/ast/types/bot.rb +1 -1
  5. data/lib/steep/ast/types/factory.rb +122 -53
  6. data/lib/steep/ast/types/logic.rb +33 -1
  7. data/lib/steep/ast/types/proc.rb +32 -20
  8. data/lib/steep/ast/types/top.rb +1 -1
  9. data/lib/steep/cli.rb +2 -2
  10. data/lib/steep/drivers/print_project.rb +11 -0
  11. data/lib/steep/drivers/vendor.rb +1 -20
  12. data/lib/steep/errors.rb +67 -38
  13. data/lib/steep/index/rbs_index.rb +334 -0
  14. data/lib/steep/index/signature_symbol_provider.rb +154 -0
  15. data/lib/steep/index/source_index.rb +100 -0
  16. data/lib/steep/interface/block.rb +79 -0
  17. data/lib/steep/interface/function.rb +770 -0
  18. data/lib/steep/interface/method_type.rb +32 -812
  19. data/lib/steep/project/dsl.rb +13 -17
  20. data/lib/steep/project/options.rb +4 -4
  21. data/lib/steep/project/target.rb +21 -12
  22. data/lib/steep/server/master.rb +5 -1
  23. data/lib/steep/server/signature_worker.rb +63 -6
  24. data/lib/steep/signature/errors.rb +51 -5
  25. data/lib/steep/signature/validator.rb +28 -4
  26. data/lib/steep/subtyping/check.rb +72 -34
  27. data/lib/steep/subtyping/variable_occurrence.rb +2 -2
  28. data/lib/steep/subtyping/variable_variance.rb +2 -2
  29. data/lib/steep/type_construction.rb +308 -152
  30. data/lib/steep/type_inference/block_params.rb +1 -1
  31. data/lib/steep/type_inference/constant_env.rb +5 -1
  32. data/lib/steep/type_inference/logic_type_interpreter.rb +102 -26
  33. data/lib/steep/typing.rb +8 -2
  34. data/lib/steep/version.rb +1 -1
  35. data/smoke/tsort/Steepfile +6 -0
  36. data/smoke/tsort/a.rb +15 -0
  37. data/smoke/type_case/a.rb +1 -1
  38. data/steep.gemspec +1 -1
  39. metadata +12 -5
@@ -134,7 +134,7 @@ module Steep
134
134
  rest = rest_param&.yield_self {|param| param.type.args[0] }
135
135
  end
136
136
 
137
- Interface::Params.new(
137
+ Interface::Function::Params.new(
138
138
  required: leadings,
139
139
  optional: optionals,
140
140
  rest: rest,
@@ -15,9 +15,13 @@ module Steep
15
15
  @table = RBS::ConstantTable.new(builder: factory.definition_builder)
16
16
  end
17
17
 
18
+ def lookup_constant(name)
19
+ table.resolve_constant_reference(name, context: context)
20
+ end
21
+
18
22
  def lookup(name)
19
23
  cache[name] ||= begin
20
- constant = table.resolve_constant_reference(name, context: context)
24
+ constant = lookup_constant(name)
21
25
 
22
26
  if constant
23
27
  factory.type(constant.type)
@@ -41,11 +41,17 @@ module Steep
41
41
 
42
42
  if type.is_a?(AST::Types::Logic::Base)
43
43
  vars.each do |var_name|
44
- truthy_env = truthy_env.assign!(var_name, node: node, type: AST::Builtin.true_type)
45
- falsy_env = truthy_env.assign!(var_name, node: node, type: AST::Builtin.false_type)
44
+ var_type = truthy_env[var_name]
45
+ truthy_type, falsy_type = factory.unwrap_optional(var_type)
46
+ falsy_type ||= AST::Builtin.nil_type
47
+ truthy_env = truthy_env.assign!(var_name, node: node, type: truthy_type) {|_, type, _| type }
48
+ falsy_env = truthy_env.assign!(var_name, node: node, type: falsy_type) {|_, type, _| type }
46
49
  end
47
50
 
48
51
  case type
52
+ when AST::Types::Logic::Env
53
+ truthy_env = type.truthy
54
+ falsy_env = type.falsy
49
55
  when AST::Types::Logic::ReceiverIsNil
50
56
  case value_node.type
51
57
  when :send
@@ -74,11 +80,16 @@ module Steep
74
80
 
75
81
  if arg_type.is_a?(AST::Types::Name::Singleton)
76
82
  receiver_vars.each do |var_name|
77
- var_type = env[var_name]
78
- truthy_type, falsy_type = type_case_select(var_type, arg_type.name)
79
-
80
- truthy_env = truthy_env.assign!(var_name, node: node, type: truthy_type)
81
- falsy_env = falsy_env.assign!(var_name, node: node, type: falsy_type)
83
+ case var_name
84
+ when :_, :__any__, :__skip__
85
+ # skip
86
+ else
87
+ var_type = env[var_name]
88
+ truthy_type, falsy_type = type_case_select(var_type, arg_type.name)
89
+
90
+ truthy_env = truthy_env.assign!(var_name, node: node, type: truthy_type)
91
+ falsy_env = falsy_env.assign!(var_name, node: node, type: falsy_type)
92
+ end
82
93
  end
83
94
  end
84
95
  end
@@ -90,7 +101,7 @@ module Steep
90
101
 
91
102
  if receiver
92
103
  _, arg_vars = decompose_value(arg)
93
- receiver_type = typing.type_of(node: receiver)
104
+ receiver_type = factory.deep_expand_alias(typing.type_of(node: receiver))
94
105
 
95
106
  if receiver_type.is_a?(AST::Types::Name::Singleton)
96
107
  arg_vars.each do |var_name|
@@ -103,6 +114,23 @@ module Steep
103
114
  end
104
115
  end
105
116
  end
117
+ when AST::Types::Logic::ArgEqualsReceiver
118
+ case value_node.type
119
+ when :send
120
+ receiver, _, arg = value_node.children
121
+
122
+ if receiver
123
+ _, arg_vars = decompose_value(arg)
124
+
125
+ arg_vars.each do |var_name|
126
+ var_type = factory.deep_expand_alias(env[var_name])
127
+ truthy_types, falsy_types = literal_var_type_case_select(receiver, var_type)
128
+
129
+ truthy_env = truthy_env.assign!(var_name, node: node, type: AST::Types::Union.build(types: truthy_types, location: nil))
130
+ falsy_env = falsy_env.assign!(var_name, node: node, type: AST::Types::Union.build(types: falsy_types, location: nil))
131
+ end
132
+ end
133
+ end
106
134
  when AST::Types::Logic::Not
107
135
  receiver, * = value_node.children
108
136
  receiver_type = typing.type_of(node: receiver)
@@ -153,6 +181,60 @@ module Steep
153
181
  end
154
182
  end
155
183
 
184
+ def literal_var_type_case_select(value_node, arg_type)
185
+ case arg_type
186
+ when AST::Types::Union
187
+ truthy_types = []
188
+ falsy_types = []
189
+
190
+ arg_type.types.each do |type|
191
+ ts, fs = literal_var_type_case_select(value_node, type)
192
+ truthy_types.push(*ts)
193
+ falsy_types.push(*fs)
194
+ end
195
+
196
+ [truthy_types, falsy_types]
197
+ else
198
+ value_type = typing.type_of(node: value_node)
199
+ types = [arg_type]
200
+
201
+ case value_node.type
202
+ when :nil
203
+ types.partition do |type|
204
+ type.is_a?(AST::Types::Nil) || AST::Builtin::NilClass.instance_type?(type)
205
+ end
206
+ when :true
207
+ types.partition do |type|
208
+ AST::Builtin::TrueClass.instance_type?(type) ||
209
+ (type.is_a?(AST::Types::Literal) && type.value == true)
210
+ end
211
+ when :false
212
+ types.partition do |type|
213
+ AST::Builtin::FalseClass.instance_type?(type) ||
214
+ (type.is_a?(AST::Types::Literal) && type.value == false)
215
+ end
216
+ when :int, :str, :sym
217
+ types.each.with_object([[], []]) do |type, pair|
218
+ true_types, false_types = pair
219
+
220
+ case
221
+ when type.is_a?(AST::Types::Literal)
222
+ if type.value == value_node.children[0]
223
+ true_types << type
224
+ else
225
+ false_types << type
226
+ end
227
+ else
228
+ true_types << AST::Types::Literal.new(value: value_node.children[0])
229
+ false_types << type
230
+ end
231
+ end
232
+ else
233
+ [[arg_type], [arg_type]]
234
+ end
235
+ end
236
+ end
237
+
156
238
  def type_case_select(type, klass)
157
239
  truth_types, false_types = type_case_select0(type, klass)
158
240
 
@@ -183,20 +265,6 @@ module Steep
183
265
 
184
266
  [truthy_types, falsy_types]
185
267
 
186
- when AST::Types::Name::Instance
187
- relation = Subtyping::Relation.new(sub_type: type, super_type: instance_type)
188
- if subtyping.check(relation, constraints: Subtyping::Constraints.empty, self_type: AST::Types::Self.new).success?
189
- [
190
- [type],
191
- []
192
- ]
193
- else
194
- [
195
- [],
196
- [type]
197
- ]
198
- end
199
-
200
268
  when AST::Types::Name::Alias
201
269
  ty = factory.expand_alias(type)
202
270
  type_case_select0(ty, klass)
@@ -214,10 +282,18 @@ module Steep
214
282
  ]
215
283
 
216
284
  else
217
- [
218
- [],
219
- [type]
220
- ]
285
+ relation = Subtyping::Relation.new(sub_type: type, super_type: instance_type)
286
+ if subtyping.check(relation, constraints: Subtyping::Constraints.empty, self_type: AST::Types::Self.new).success?
287
+ [
288
+ [type],
289
+ []
290
+ ]
291
+ else
292
+ [
293
+ [],
294
+ [type]
295
+ ]
296
+ end
221
297
  end
222
298
  end
223
299
  end
@@ -21,8 +21,9 @@ module Steep
21
21
  attr_reader :contexts
22
22
  attr_reader :root_context
23
23
  attr_reader :method_calls
24
+ attr_reader :source_index
24
25
 
25
- def initialize(source:, root_context:, parent: nil, parent_last_update: parent&.last_update, contexts: nil)
26
+ def initialize(source:, root_context:, parent: nil, parent_last_update: parent&.last_update, contexts: nil, source_index: nil)
26
27
  @source = source
27
28
 
28
29
  @parent = parent
@@ -35,6 +36,8 @@ module Steep
35
36
  @root_context = root_context
36
37
  @contexts = contexts || TypeInference::ContextArray.from_source(source: source)
37
38
  @method_calls = {}.compare_by_identity
39
+
40
+ @source_index = source_index || Index::SourceIndex.new(source: source)
38
41
  end
39
42
 
40
43
  def add_error(error)
@@ -195,7 +198,8 @@ module Steep
195
198
  child = self.class.new(source: source,
196
199
  parent: self,
197
200
  root_context: root_context,
198
- contexts: TypeInference::ContextArray.new(buffer: contexts.buffer, range: range, context: nil))
201
+ contexts: TypeInference::ContextArray.new(buffer: contexts.buffer, range: range, context: nil),
202
+ source_index: source_index.new_child)
199
203
  @should_update = true
200
204
 
201
205
  if block_given?
@@ -224,6 +228,8 @@ module Steep
224
228
  errors.each do |error|
225
229
  parent.add_error error
226
230
  end
231
+
232
+ parent.source_index.merge!(source_index)
227
233
  end
228
234
  end
229
235
  end
@@ -1,3 +1,3 @@
1
1
  module Steep
2
- VERSION = "0.34.0"
2
+ VERSION = "0.39.0"
3
3
  end
@@ -0,0 +1,6 @@
1
+ target :test do
2
+ signature "."
3
+ check "."
4
+
5
+ library "tsort"
6
+ end
@@ -0,0 +1,15 @@
1
+ # ALLOW FAILURE
2
+
3
+ require "tsort"
4
+
5
+ # @type var g: Hash[Integer, Array[Integer]]
6
+ g = {1=>[2, 3], 2=>[4], 3=>[2, 4], 4=>[]}
7
+
8
+ # @type var each_node: ^() { (Integer) -> void } -> void
9
+ each_node = -> (&b) { g.each_key(&b) }
10
+ # @type var each_child: ^(Integer) { (Integer) -> void } -> void
11
+ each_child = -> (n, &b) { g[n].each(&b) }
12
+
13
+ # @type var xs: Array[String]
14
+ # !expects IncompatibleAssignment: lhs_type=::Array[::String], rhs_type=::Array[::Integer]
15
+ xs = TSort.tsort(each_node, each_child)
@@ -16,7 +16,7 @@ end
16
16
 
17
17
  case x
18
18
  when 1
19
- # !expects NoMethodError: type=(::Integer | ::String | ::Symbol), method=foobar
19
+ # !expects NoMethodError: type=1, method=foobar
20
20
  x.foobar
21
21
  end
22
22
 
@@ -34,5 +34,5 @@ Gem::Specification.new do |spec|
34
34
  spec.add_runtime_dependency "rainbow", ">= 2.2.2", "< 4.0"
35
35
  spec.add_runtime_dependency "listen", "~> 3.0"
36
36
  spec.add_runtime_dependency "language_server-protocol", "~> 3.15.0.1"
37
- spec.add_runtime_dependency "rbs", "~> 0.14.0"
37
+ spec.add_runtime_dependency "rbs", "~> 1.0.0"
38
38
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: steep
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.34.0
4
+ version: 0.39.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Soutaro Matsumoto
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-10-27 00:00:00.000000000 Z
11
+ date: 2020-12-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parser
@@ -106,14 +106,14 @@ dependencies:
106
106
  requirements:
107
107
  - - "~>"
108
108
  - !ruby/object:Gem::Version
109
- version: 0.14.0
109
+ version: 1.0.0
110
110
  type: :runtime
111
111
  prerelease: false
112
112
  version_requirements: !ruby/object:Gem::Requirement
113
113
  requirements:
114
114
  - - "~>"
115
115
  - !ruby/object:Gem::Version
116
- version: 0.14.0
116
+ version: 1.0.0
117
117
  description: Gradual Typing for Ruby
118
118
  email:
119
119
  - matsumoto@soutaro.com
@@ -178,6 +178,11 @@ files:
178
178
  - lib/steep/drivers/watch.rb
179
179
  - lib/steep/drivers/worker.rb
180
180
  - lib/steep/errors.rb
181
+ - lib/steep/index/rbs_index.rb
182
+ - lib/steep/index/signature_symbol_provider.rb
183
+ - lib/steep/index/source_index.rb
184
+ - lib/steep/interface/block.rb
185
+ - lib/steep/interface/function.rb
181
186
  - lib/steep/interface/interface.rb
182
187
  - lib/steep/interface/method.rb
183
188
  - lib/steep/interface/method_type.rb
@@ -355,6 +360,8 @@ files:
355
360
  - smoke/toplevel/Steepfile
356
361
  - smoke/toplevel/a.rb
357
362
  - smoke/toplevel/a.rbs
363
+ - smoke/tsort/Steepfile
364
+ - smoke/tsort/a.rb
358
365
  - smoke/type_case/Steepfile
359
366
  - smoke/type_case/a.rb
360
367
  - smoke/yield/Steepfile
@@ -382,7 +389,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
382
389
  - !ruby/object:Gem::Version
383
390
  version: '0'
384
391
  requirements: []
385
- rubygems_version: 3.1.2
392
+ rubygems_version: 3.1.4
386
393
  signing_key:
387
394
  specification_version: 4
388
395
  summary: Gradual Typing for Ruby