steep 0.19.0 → 0.24.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a2c1abcf64958fd547dbb336a0489d9e310e71bc66d208a67c6328c1ac09e62b
4
- data.tar.gz: eecd4d437442a85356525c31d10697d73f06fd319930371a7f2710b77f3e86a3
3
+ metadata.gz: 3fc0de639f659b9b59f83ca0f8968550e7230ee1dbb6ae8e0d005325267ab46e
4
+ data.tar.gz: a1f73b521a222fa1313c2f58b1e0d3fb2a07149aba42c17e91c8df495e3319de
5
5
  SHA512:
6
- metadata.gz: 57957103491d678aa843f9155a757d9f903968d272e2d117b659bcb46659ada397cf82db1bf4e54e25f77a5548db32b6ea2da7be0fba6920d033340c44448c19
7
- data.tar.gz: 94eeb79af2e1fdab28b5f2c6237e343d9f174d7ff5a65c9d25d3860e042820027c1f4fab8c6571492967c74b37161572b8ab1dea91d8d60d0e7f2c1cbf4c31fe
6
+ metadata.gz: bcedd630c3b51bc4d3a24549c6bcde88156af410be2b64ec51d813c238f3cb5d5f9f85b980302cae3cacd007e478ae51f99019ed10f3b6a31df84723bd43f35b
7
+ data.tar.gz: da09a3c3e7f762ec48b378533b6c624c1b9590a0cfd58ffc7aed87212fde2c67897bc1aa745eaa8f4baeaa19b1e6c7b0a4826e7fb6e582a6ef6798ee3b4a47a4
@@ -2,6 +2,31 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 0.24.0 (2020-08-11)
6
+
7
+ * Update RBS to 0.10 ([#180](https://github.com/soutaro/steep/pull/180))
8
+
9
+ ## 0.23.0 (2020-08-06)
10
+
11
+ * Fix literal typing with hint ([#179](https://github.com/soutaro/steep/pull/179))
12
+ * Fix literal type subtyping ([#178](https://github.com/soutaro/steep/pull/178))
13
+
14
+ ## 0.22.0 (2020-08-03)
15
+
16
+ * Improve signature validation ([#175](https://github.com/soutaro/steep/pull/175), [#177](https://github.com/soutaro/steep/pull/177))
17
+ * Fix boolean literal typing ([#172](https://github.com/soutaro/steep/pull/172))
18
+ * Make exit code success when Steep has unreported type errors ([#171](https://github.com/soutaro/steep/pull/171))
19
+ * Allow `./` prefix for signature pattern ([#170](https://github.com/soutaro/steep/pull/170))
20
+
21
+ ## 0.21.0 (2020-07-20)
22
+
23
+ * Fix LSP hover ([#168](https://github.com/soutaro/steep/pull/168))
24
+ * Nominal subtyping ([#167](https://github.com/soutaro/steep/pull/167))
25
+
26
+ ## 0.20.0 (2020-07-17)
27
+
28
+ * Support singleton class definitions ([#166](https://github.com/soutaro/steep/pull/166))
29
+
5
30
  ## 0.19.0 (2020-07-12)
6
31
 
7
32
  * Update RBS. ([#157](https://github.com/soutaro/steep/pull/157))
@@ -35,7 +60,7 @@
35
60
 
36
61
  * Fix constant resolution ([#143](https://github.com/soutaro/steep/pull/143))
37
62
  * Fix RBS diagnostics line number in LSP ([#142](https://github.com/soutaro/steep/pull/142))
38
- * Fix crash caused by hover on `def` in LSP ([#140](https://github.com/soutaro/steep/pull/140))
63
+ * Fix crash caused by hover on `def` in LSP ([#140](https://github.com/soutaro/steep/pull/140))
39
64
 
40
65
  ## 0.16.0 (2020-05-19)
41
66
 
data/Gemfile CHANGED
@@ -5,3 +5,10 @@ gemspec
5
5
 
6
6
  gem "with_steep_types", path: "test/gems/with_steep_types"
7
7
  gem "without_steep_types", path: "test/gems/without_steep_types"
8
+
9
+ gem "rake"
10
+ gem "minitest", "~> 5.0"
11
+ gem "racc", "~> 1.4"
12
+ gem "minitest-reporters"
13
+ gem "minitest-hooks"
14
+ gem "stackprof"
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "stackprof"
4
+
5
+ mode = (ENV["STEEP_STACKPROF_MODE"] || :wall).to_sym
6
+ out = ENV["STEEP_STACKPROF_OUT"] || "tmp/stackprof-#{mode}-steep.dump"
7
+
8
+ def exit(*)
9
+
10
+ end
11
+
12
+
13
+ STDERR.puts "Running profiler: mode=#{mode}, out=#{out}"
14
+ StackProf.run(mode: mode, out: out) do
15
+ load File.join(__dir__, "../exe/steep")
16
+ end
@@ -288,7 +288,7 @@ module Steep
288
288
  def expand_alias(type)
289
289
  unfolded = case type
290
290
  when AST::Types::Name::Alias
291
- unfolded = unfold(type.name)
291
+ unfold(type.name)
292
292
  else
293
293
  type
294
294
  end
@@ -49,6 +49,10 @@ module Steep
49
49
  Builtin::String
50
50
  when Symbol
51
51
  Builtin::Symbol
52
+ when true
53
+ Builtin::TrueClass
54
+ when false
55
+ Builtin::FalseClass
52
56
  else
53
57
  raise "Unexpected literal type: #{value.inspect}"
54
58
  end
@@ -79,6 +79,7 @@ module Steep
79
79
  def self.test_pattern(patterns, path, ext:)
80
80
  patterns.any? do |pattern|
81
81
  p = pattern.end_with?(File::Separator) ? pattern : pattern + File::Separator
82
+ p.delete_prefix!('./')
82
83
  (path.to_s.start_with?(p) && path.extname == ext) || File.fnmatch(pattern, path.to_s)
83
84
  end
84
85
  end
@@ -160,6 +161,16 @@ module Steep
160
161
  else
161
162
  yield env, check, Time.now
162
163
  end
164
+ rescue RBS::DuplicatedDeclarationError => exn
165
+ @status = SignatureValidationErrorStatus.new(
166
+ errors: [
167
+ Signature::Errors::DuplicatedDefinitionError.new(
168
+ name: exn.name,
169
+ location: exn.decls[0].location
170
+ )
171
+ ],
172
+ timestamp: Time.now
173
+ )
163
174
  rescue => exn
164
175
  @status = SignatureOtherErrorStatus.new(error: exn, timestamp: Time.now)
165
176
  end
@@ -205,7 +216,7 @@ module Steep
205
216
  def errors
206
217
  case status
207
218
  when TypeCheckStatus
208
- source_files.each_value.flat_map(&:errors)
219
+ source_files.each_value.flat_map(&:errors).select { |error | options.error_to_report?(error) }
209
220
  else
210
221
  []
211
222
  end
@@ -95,8 +95,8 @@ module Steep
95
95
  ```
96
96
  HOVER
97
97
  if content.definition
98
- if content.definition.comment
99
- string << "\n----\n\n#{content.definition.comment.string}"
98
+ if content.definition.comments
99
+ string << "\n----\n\n#{content.definition.comments.map(&:string).join("\n\n")}"
100
100
  end
101
101
 
102
102
  string << "\n----\n\n#{content.definition.method_types.map {|x| "- `#{x}`\n" }.join()}"
@@ -111,7 +111,7 @@ def #{content.method_name}: #{content.method_type}
111
111
  ```
112
112
  HOVER
113
113
  if (comment = content.comment_string)
114
- string << "\n----\n\n#{comment.string}\n"
114
+ string << "\n----\n\n#{comment}\n"
115
115
  end
116
116
 
117
117
  if content.definition.method_types.size > 1
@@ -112,6 +112,9 @@ module Steep
112
112
  target.signature_files.each_key.with_object({}) do |path, hash|
113
113
  hash[path] = []
114
114
  end
115
+ when Project::Target::SignatureOtherErrorStatus
116
+ Steep.log_error status.error
117
+ {}
115
118
  else
116
119
  Steep.logger.info "Unexpected target status: #{status.class}"
117
120
  {}
@@ -19,6 +19,19 @@ module Steep
19
19
  end
20
20
  end
21
21
 
22
+ class DuplicatedDefinitionError < Base
23
+ attr_reader :name
24
+
25
+ def initialize(name:, location:)
26
+ @name = name
27
+ @location = location
28
+ end
29
+
30
+ def puts(io)
31
+ io.puts "#{loc_to_s}\sDuplicatedDefinitionError: name=#{name}"
32
+ end
33
+ end
34
+
22
35
  class UnknownTypeNameError < Base
23
36
  attr_reader :name
24
37
 
@@ -48,6 +61,21 @@ module Steep
48
61
  io.puts "#{loc_to_s}\tInvalidTypeApplicationError: name=#{name}, expected=[#{params.join(", ")}], actual=[#{args.join(", ")}]"
49
62
  end
50
63
  end
64
+
65
+ class InvalidMethodOverloadError < Base
66
+ attr_reader :class_name
67
+ attr_reader :method_name
68
+
69
+ def initialize(class_name:, method_name:, location:)
70
+ @class_name = class_name
71
+ @method_name = method_name
72
+ @location = location
73
+ end
74
+
75
+ def puts(io)
76
+ io.puts "#{loc_to_s}\tInvalidMethodOverloadError: class_name=#{class_name}, method_name=#{method_name}"
77
+ end
78
+ end
51
79
  end
52
80
  end
53
81
  end
@@ -53,6 +53,7 @@ module Steep
53
53
  validate_decl
54
54
  validate_const
55
55
  validate_global
56
+ validate_alias
56
57
  end
57
58
 
58
59
  def validate_type(type)
@@ -99,6 +100,7 @@ module Steep
99
100
  env.constant_decls.each do |name, entry|
100
101
  rescue_validation_errors do
101
102
  Steep.logger.debug "Validating constant `#{name}`..."
103
+ builder.ensure_namespace!(name.namespace, location: entry.decl.location)
102
104
  validate_type entry.decl.type
103
105
  end
104
106
  end
@@ -117,7 +119,9 @@ module Steep
117
119
  env.alias_decls.each do |name, entry|
118
120
  rescue_validation_errors do
119
121
  Steep.logger.debug "Validating alias `#{name}`..."
120
- validate_type(entry.decl.type)
122
+ builder.expand_alias(name).tap do |type|
123
+ validate_type(type)
124
+ end
121
125
  end
122
126
  end
123
127
  end
@@ -136,6 +140,12 @@ module Steep
136
140
  name: factory.type_name(exn.type_name),
137
141
  location: exn.location
138
142
  )
143
+ rescue RBS::InvalidOverloadMethodError => exn
144
+ @errors << Errors::InvalidMethodOverloadError.new(
145
+ class_name: factory.type_name(exn.type_name),
146
+ method_name: exn.method_name,
147
+ location: exn.members[0].location
148
+ )
139
149
  end
140
150
  end
141
151
  end
@@ -9,6 +9,84 @@ module Steep
9
9
  @cache = {}
10
10
  end
11
11
 
12
+ def instance_super_types(type_name, args:)
13
+ type_name_1 = factory.type_name_1(type_name)
14
+ ancestors = factory.definition_builder.one_instance_ancestors(type_name_1)
15
+
16
+ subst = unless args.empty?
17
+ args_ = args.map {|type| factory.type_1(type) }
18
+ RBS::Substitution.build(ancestors.params, args_)
19
+ end
20
+
21
+ ancestors.each_ancestor.map do |ancestor|
22
+ name = factory.type_name(ancestor.name)
23
+
24
+ case ancestor
25
+ when RBS::Definition::Ancestor::Instance
26
+ args = ancestor.args.map do |type|
27
+ type = type.sub(subst) if subst
28
+ factory.type(type)
29
+ end
30
+
31
+ if ancestor.name.class?
32
+ AST::Types::Name::Instance.new(
33
+ name: name,
34
+ args: args,
35
+ location: nil
36
+ )
37
+ else
38
+ AST::Types::Name::Interface.new(
39
+ name: name,
40
+ args: args,
41
+ location: nil
42
+ )
43
+ end
44
+ when RBS::Definition::Ancestor::Singleton
45
+ AST::Types::Name::Class.new(
46
+ name: name,
47
+ constructor: nil,
48
+ location: nil
49
+ )
50
+ end
51
+ end
52
+ end
53
+
54
+ def singleton_super_types(type_name)
55
+ type_name_1 = factory.type_name_1(type_name)
56
+ ancestors = factory.definition_builder.one_singleton_ancestors(type_name_1)
57
+
58
+ ancestors.each_ancestor.map do |ancestor|
59
+ name = factory.type_name(ancestor.name)
60
+
61
+ case ancestor
62
+ when RBS::Definition::Ancestor::Instance
63
+ args = ancestor.args.map do |type|
64
+ factory.type(type)
65
+ end
66
+
67
+ if ancestor.name.class?
68
+ AST::Types::Name::Instance.new(
69
+ name: name,
70
+ args: args,
71
+ location: nil
72
+ )
73
+ else
74
+ AST::Types::Name::Interface.new(
75
+ name: name,
76
+ args: args,
77
+ location: nil
78
+ )
79
+ end
80
+ when RBS::Definition::Ancestor::Singleton
81
+ AST::Types::Name::Class.new(
82
+ name: name,
83
+ constructor: nil,
84
+ location: nil
85
+ )
86
+ end
87
+ end
88
+ end
89
+
12
90
  def check(relation, constraints:, self_type:, assumption: Set.new, trace: Trace.new)
13
91
  Steep.logger.tagged "#{relation.sub_type} <: #{relation.super_type}" do
14
92
  prefix = trace.size
@@ -102,15 +180,6 @@ module Steep
102
180
  constraints: constraints
103
181
  )
104
182
 
105
- when relation.sub_type.is_a?(AST::Types::Literal)
106
- check(
107
- Relation.new(sub_type: relation.sub_type.back_type, super_type: relation.super_type),
108
- self_type: self_type,
109
- assumption: assumption,
110
- trace: trace,
111
- constraints: constraints
112
- )
113
-
114
183
  when relation.sub_type.is_a?(AST::Types::Union)
115
184
  results = relation.sub_type.types.map do |sub_type|
116
185
  check(Relation.new(sub_type: sub_type, super_type: relation.super_type),
@@ -175,30 +244,45 @@ module Steep
175
244
  failure(error: Result::Failure::UnknownPairError.new(relation: relation),
176
245
  trace: trace)
177
246
 
178
- when relation.sub_type.is_a?(AST::Types::Name::Base) && relation.super_type.is_a?(AST::Types::Name::Base)
179
- if (pairs = extract_nominal_pairs(relation))
180
- results = pairs.flat_map do |(sub, sup)|
181
- Relation.new(sub_type: sub, super_type: sup).yield_self do |rel|
182
- [rel, rel.flip]
183
- end
184
- end.map do |relation|
185
- check(relation,
186
- self_type: self_type,
187
- assumption: assumption,
188
- trace: trace,
189
- constraints: constraints)
190
- end
247
+ when relation.super_type.is_a?(AST::Types::Name::Interface)
248
+ sub_interface = factory.interface(relation.sub_type, private: false)
249
+ super_interface = factory.interface(relation.super_type, private: false)
191
250
 
192
- if results.all?(&:success?)
193
- results.first
251
+ check_interface(sub_interface,
252
+ super_interface,
253
+ self_type: self_type,
254
+ assumption: assumption,
255
+ trace: trace,
256
+ constraints: constraints)
257
+
258
+ when relation.sub_type.is_a?(AST::Types::Name::Base) && relation.super_type.is_a?(AST::Types::Name::Base)
259
+ if relation.sub_type.name == relation.super_type.name && relation.sub_type.class == relation.super_type.class
260
+ if arg_type?(relation.sub_type) && arg_type?(relation.super_type)
261
+ check_type_arg(relation, self_type: self_type, assumption: assumption, trace: trace, constraints: constraints)
194
262
  else
195
- results.find(&:failure?)
263
+ success(constraints: constraints)
196
264
  end
197
265
  else
198
- sub_interface = factory.interface(relation.sub_type, private: false)
199
- super_interface = factory.interface(relation.super_type, private: false)
200
-
201
- check_interface(sub_interface, super_interface, self_type: self_type, assumption: assumption, trace: trace, constraints: constraints)
266
+ possible_sub_types = case relation.sub_type
267
+ when AST::Types::Name::Instance
268
+ instance_super_types(relation.sub_type.name, args: relation.sub_type.args)
269
+ when AST::Types::Name::Class
270
+ singleton_super_types(relation.sub_type.name)
271
+ else
272
+ []
273
+ end
274
+
275
+ unless possible_sub_types.empty?
276
+ success_any?(possible_sub_types) do |sub_type|
277
+ check(Relation.new(sub_type: sub_type, super_type: relation.super_type),
278
+ self_type: self_type,
279
+ assumption: assumption,
280
+ trace: trace,
281
+ constraints: constraints)
282
+ end
283
+ else
284
+ failure(error: Result::Failure::UnknownPairError.new(relation: relation), trace: trace)
285
+ end
202
286
  end
203
287
 
204
288
  when relation.sub_type.is_a?(AST::Types::Proc) && relation.super_type.is_a?(AST::Types::Proc)
@@ -276,6 +360,32 @@ module Steep
276
360
  trace: trace,
277
361
  constraints: constraints)
278
362
 
363
+ when relation.super_type.is_a?(AST::Types::Literal)
364
+ case
365
+ when relation.super_type.value == true && AST::Builtin::TrueClass.instance_type?(relation.sub_type)
366
+ success(constraints: constraints)
367
+ when relation.super_type.value == false && AST::Builtin::FalseClass.instance_type?(relation.sub_type)
368
+ success(constraints: constraints)
369
+ else
370
+ failure(error: Result::Failure::UnknownPairError.new(relation: relation),
371
+ trace: trace)
372
+ end
373
+
374
+ when relation.super_type.is_a?(AST::Types::Nil) && AST::Builtin::NilClass.instance_type?(relation.sub_type)
375
+ success(constraints: constraints)
376
+
377
+ when relation.sub_type.is_a?(AST::Types::Nil) && AST::Builtin::NilClass.instance_type?(relation.super_type)
378
+ success(constraints: constraints)
379
+
380
+ when relation.sub_type.is_a?(AST::Types::Literal)
381
+ check(
382
+ Relation.new(sub_type: relation.sub_type.back_type, super_type: relation.super_type),
383
+ self_type: self_type,
384
+ assumption: assumption,
385
+ trace: trace,
386
+ constraints: constraints
387
+ )
388
+
279
389
  else
280
390
  failure(error: Result::Failure::UnknownPairError.new(relation: relation),
281
391
  trace: trace)
@@ -283,6 +393,80 @@ module Steep
283
393
  end
284
394
  end
285
395
 
396
+ def definition_for_type(type)
397
+ type_name = factory.type_name_1(type.name)
398
+
399
+ case type
400
+ when AST::Types::Name::Instance
401
+ factory.definition_builder.build_instance(type_name)
402
+ when AST::Types::Name::Class
403
+ factory.definition_builder.build_singleton(type_name)
404
+ when AST::Types::Name::Interface
405
+ factory.definition_builder.build_interface(type_name)
406
+ else
407
+ raise
408
+ end
409
+ end
410
+
411
+ def arg_type?(type)
412
+ case type
413
+ when AST::Types::Name::Instance, AST::Types::Name::Interface
414
+ type.args.size > 0
415
+ else
416
+ false
417
+ end
418
+ end
419
+
420
+ def check_type_arg(relation, self_type:, assumption:, trace:, constraints:)
421
+ sub_args = relation.sub_type.args
422
+ sup_args = relation.super_type.args
423
+
424
+ sup_def = definition_for_type(relation.super_type)
425
+ sup_params = sup_def.type_params_decl
426
+
427
+ success_all?(sub_args.zip(sup_args, sup_params.each)) do |sub_arg, sup_arg, sup_param|
428
+ case sup_param.variance
429
+ when :covariant
430
+ check(Relation.new(sub_type: sub_arg, super_type: sup_arg), self_type: self_type, assumption: assumption, trace: trace, constraints: constraints)
431
+ when :contravariant
432
+ check(Relation.new(sub_type: sup_arg, super_type: sub_arg), self_type: self_type, assumption: assumption, trace: trace, constraints: constraints)
433
+ when :invariant
434
+ rel = Relation.new(sub_type: sub_arg, super_type: sup_arg)
435
+ success_all?([rel, rel.flip]) do |r|
436
+ check(r, self_type: self_type, assumption: assumption, trace: trace, constraints: constraints)
437
+ end
438
+ end
439
+ end
440
+ end
441
+
442
+ def success_all?(collection, &block)
443
+ results = collection.map do |obj|
444
+ result = yield(obj)
445
+
446
+ if result.failure?
447
+ return result
448
+ end
449
+
450
+ result
451
+ end
452
+
453
+ results[0]
454
+ end
455
+
456
+ def success_any?(collection, &block)
457
+ results = collection.map do |obj|
458
+ result = yield(obj)
459
+
460
+ if result.success?
461
+ return result
462
+ end
463
+
464
+ result
465
+ end
466
+
467
+ results[0]
468
+ end
469
+
286
470
  def extract_nominal_pairs(relation)
287
471
  sub_type = relation.sub_type
288
472
  super_type = relation.super_type
@@ -316,20 +500,7 @@ module Steep
316
500
  return true
317
501
  end
318
502
 
319
- case
320
- when relation.sub_type == relation.super_type
321
- true
322
- when relation.sub_type.is_a?(AST::Types::Name::Base) && relation.super_type.is_a?(AST::Types::Name::Base)
323
- if (pairs = extract_nominal_pairs(relation))
324
- pairs.all? do |(s, t)|
325
- same_type?(Relation.new(sub_type: s, super_type: t), assumption: assumption)
326
- end
327
- else
328
- false
329
- end
330
- else
331
- false
332
- end
503
+ relation.sub_type == relation.super_type
333
504
  end
334
505
 
335
506
  def check_interface(sub_interface, super_interface, self_type:, assumption:, trace:, constraints:)
@@ -230,6 +230,39 @@ module Steep
230
230
  )
231
231
  end
232
232
 
233
+ def implement_module(module_name:, super_name: nil, annotations:)
234
+ if (annotation = annotations.implement_module_annotation)
235
+ absolute_name(annotation.name.name).yield_self do |absolute_name|
236
+ if checker.factory.class_name?(absolute_name) || checker.factory.module_name?(absolute_name)
237
+ AST::Annotation::Implements::Module.new(
238
+ name: absolute_name,
239
+ args: annotation.name.args
240
+ )
241
+ else
242
+ Steep.logger.error "Unknown class name given to @implements: #{annotation.name.name}"
243
+ nil
244
+ end
245
+ end
246
+ else
247
+ name = nil
248
+ name ||= absolute_name(module_name).yield_self do |absolute_name|
249
+ absolute_name if checker.factory.class_name?(absolute_name) || checker.factory.module_name?(absolute_name)
250
+ end
251
+ name ||= super_name && absolute_name(super_name).yield_self do |absolute_name|
252
+ absolute_name if checker.factory.class_name?(absolute_name) || checker.factory.module_name?(absolute_name)
253
+ end
254
+
255
+ if name
256
+ absolute_name_ = checker.factory.type_name_1(name)
257
+ entry = checker.factory.env.class_decls[absolute_name_]
258
+ AST::Annotation::Implements::Module.new(
259
+ name: name,
260
+ args: entry.type_params.each.map(&:name)
261
+ )
262
+ end
263
+ end
264
+ end
265
+
233
266
  def for_module(node)
234
267
  new_module_name = Names::Module.from_node(node.children.first) or raise "Unexpected module name: #{node.children.first}"
235
268
  new_namespace = nested_namespace_for_module(new_module_name)
@@ -240,28 +273,7 @@ module Steep
240
273
  annots = source.annotations(block: node, factory: checker.factory, current_module: new_namespace)
241
274
  module_type = AST::Builtin::Module.instance_type
242
275
 
243
- implement_module_name = yield_self do
244
- if (annotation = annots.implement_module_annotation)
245
- absolute_name(annotation.name.name).yield_self do |absolute_name|
246
- if checker.factory.module_name?(absolute_name)
247
- AST::Annotation::Implements::Module.new(name: absolute_name,
248
- args: annotation.name.args)
249
- else
250
- Steep.logger.error "Unknown module name given to @implements: #{annotation.name.name}"
251
- nil
252
- end
253
- end
254
- else
255
- absolute_name(new_module_name).yield_self do |absolute_name|
256
- if checker.factory.module_name?(absolute_name)
257
- absolute_name_ = checker.factory.type_name_1(absolute_name)
258
- entry = checker.factory.env.class_decls[absolute_name_]
259
- AST::Annotation::Implements::Module.new(name: absolute_name,
260
- args: entry.type_params.each.map(&:name))
261
- end
262
- end
263
- end
264
- end
276
+ implement_module_name = implement_module(module_name: new_module_name, annotations: annots)
265
277
 
266
278
  if implement_module_name
267
279
  module_name = implement_module_name.name
@@ -352,36 +364,7 @@ module Steep
352
364
 
353
365
  annots = source.annotations(block: node, factory: checker.factory, current_module: new_namespace)
354
366
 
355
- implement_module_name = yield_self do
356
- if (annotation = annots.implement_module_annotation)
357
- absolute_name(annotation.name.name).yield_self do |absolute_name|
358
- if checker.factory.class_name?(absolute_name)
359
- AST::Annotation::Implements::Module.new(name: absolute_name,
360
- args: annotation.name.args)
361
- else
362
- Steep.logger.error "Unknown class name given to @implements: #{annotation.name.name}"
363
- nil
364
- end
365
- end
366
- else
367
- name = nil
368
- name ||= absolute_name(new_class_name).yield_self do |absolute_name|
369
- absolute_name if checker.factory.class_name?(absolute_name)
370
- end
371
- name ||= super_class_name && absolute_name(super_class_name).yield_self do |absolute_name|
372
- absolute_name if checker.factory.class_name?(absolute_name)
373
- end
374
-
375
- if name
376
- absolute_name_ = checker.factory.type_name_1(name)
377
- entry = checker.factory.env.class_decls[absolute_name_]
378
- AST::Annotation::Implements::Module.new(
379
- name: name,
380
- args: entry.type_params.each.map(&:name)
381
- )
382
- end
383
- end
384
- end
367
+ implement_module_name = implement_module(module_name: new_class_name, super_name: super_class_name, annotations: annots)
385
368
 
386
369
  if annots.implement_module_annotation
387
370
  new_class_name = implement_module_name.name
@@ -450,6 +433,83 @@ module Steep
450
433
  )
451
434
  end
452
435
 
436
+ def for_sclass(node, type)
437
+ annots = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
438
+
439
+ instance_type = if type.is_a?(AST::Types::Self)
440
+ context.self_type
441
+ else
442
+ type
443
+ end
444
+
445
+ module_type = case instance_type
446
+ when AST::Types::Name::Class
447
+ AST::Builtin::Class.instance_type
448
+ when AST::Types::Name::Module
449
+ AST::Builtin::Module.instance_type
450
+ when AST::Types::Name::Instance
451
+ instance_type.to_class(constructor: nil)
452
+ else
453
+ raise "Unexpected type for sclass node: #{type}"
454
+ end
455
+
456
+ instance_definition = case instance_type
457
+ when AST::Types::Name::Class, AST::Types::Name::Module
458
+ type_name = checker.factory.type_name_1(instance_type.name)
459
+ checker.factory.definition_builder.build_singleton(type_name)
460
+ when AST::Types::Name::Instance
461
+ type_name = checker.factory.type_name_1(instance_type.name)
462
+ checker.factory.definition_builder.build_instance(type_name)
463
+ end
464
+
465
+ module_definition = case module_type
466
+ when AST::Types::Name::Class, AST::Types::Name::Module
467
+ type_name = checker.factory.type_name_1(instance_type.name)
468
+ checker.factory.definition_builder.build_singleton(type_name)
469
+ else
470
+ nil
471
+ end
472
+
473
+ module_context = TypeInference::Context::ModuleContext.new(
474
+ instance_type: annots.instance_type || instance_type,
475
+ module_type: annots.self_type || annots.module_type || module_type,
476
+ implement_name: nil,
477
+ current_namespace: current_namespace,
478
+ const_env: self.module_context.const_env,
479
+ class_name: self.module_context.class_name,
480
+ module_definition: module_definition,
481
+ instance_definition: instance_definition
482
+ )
483
+
484
+ type_env = TypeInference::TypeEnv.build(annotations: annots,
485
+ subtyping: checker,
486
+ const_env: self.module_context.const_env,
487
+ signatures: checker.factory.env)
488
+
489
+ lvar_env = TypeInference::LocalVariableTypeEnv.empty(
490
+ subtyping: checker,
491
+ self_type: module_context.module_type
492
+ ).annotate(annots)
493
+
494
+ body_context = TypeInference::Context.new(
495
+ method_context: nil,
496
+ block_context: nil,
497
+ module_context: module_context,
498
+ break_context: nil,
499
+ self_type: module_context.module_type,
500
+ type_env: type_env,
501
+ lvar_env: lvar_env
502
+ )
503
+
504
+ self.class.new(
505
+ checker: checker,
506
+ source: source,
507
+ annotations: annots,
508
+ typing: typing,
509
+ context: body_context
510
+ )
511
+ end
512
+
453
513
  def for_branch(node, truthy_vars: Set.new, type_case_override: nil, break_context: context.break_context)
454
514
  annots = source.annotations(block: node, factory: checker.factory, current_module: current_namespace)
455
515
 
@@ -578,7 +638,8 @@ module Steep
578
638
  when :__skip__
579
639
  add_typing(node, type: AST::Builtin.any_type)
580
640
  else
581
- rhs_result = synthesize(rhs, hint: hint || context.lvar_env.declared_types[name]&.type)
641
+ hint ||= context.lvar_env.declared_types[name]&.type
642
+ rhs_result = synthesize(rhs, hint: hint)
582
643
 
583
644
  constr = rhs_result.constr.update_lvar_env do |lvar_env|
584
645
  lvar_env.assign(name, node: node, type: rhs_result.type) do |declared_type, actual_type, result|
@@ -1002,7 +1063,7 @@ module Steep
1002
1063
 
1003
1064
  when :int
1004
1065
  yield_self do
1005
- literal_type = expand_alias(hint) {|hint_| test_literal_type(node.children[0], hint_) }
1066
+ literal_type = test_literal_type(node.children[0], hint)
1006
1067
 
1007
1068
  if literal_type
1008
1069
  add_typing(node, type: literal_type)
@@ -1013,7 +1074,7 @@ module Steep
1013
1074
 
1014
1075
  when :sym
1015
1076
  yield_self do
1016
- literal_type = expand_alias(hint) {|hint| test_literal_type(node.children[0], hint) }
1077
+ literal_type = test_literal_type(node.children[0], hint)
1017
1078
 
1018
1079
  if literal_type
1019
1080
  add_typing(node, type: literal_type)
@@ -1024,7 +1085,7 @@ module Steep
1024
1085
 
1025
1086
  when :str
1026
1087
  yield_self do
1027
- literal_type = expand_alias(hint) {|hint_| test_literal_type(node.children[0], hint_)}
1088
+ literal_type = test_literal_type(node.children[0], hint)
1028
1089
 
1029
1090
  if literal_type
1030
1091
  add_typing(node, type: literal_type)
@@ -1034,7 +1095,13 @@ module Steep
1034
1095
  end
1035
1096
 
1036
1097
  when :true, :false
1037
- add_typing(node, type: AST::Types::Boolean.new)
1098
+ ty = node.type == :true ? AST::Types::Literal.new(value: true) : AST::Types::Literal.new(value: false)
1099
+
1100
+ if hint && check_relation(sub_type: ty, super_type: hint).success?
1101
+ add_typing(node, type: hint)
1102
+ else
1103
+ add_typing(node, type: AST::Types::Boolean.new)
1104
+ end
1038
1105
 
1039
1106
  when :hash
1040
1107
  yield_self do
@@ -1130,6 +1197,25 @@ module Steep
1130
1197
  add_typing(node, type: AST::Builtin.nil_type)
1131
1198
  end
1132
1199
 
1200
+ when :sclass
1201
+ yield_self do
1202
+ type, constr = synthesize(node.children[0])
1203
+ constructor = constr.for_sclass(node, type)
1204
+
1205
+ constructor.typing.add_context_for_node(node, context: constructor.context)
1206
+ constructor.typing.add_context_for_body(node, context: constructor.context)
1207
+
1208
+ constructor.synthesize(node.children[1]) if node.children[1]
1209
+
1210
+ if constructor.module_context.instance_definition && module_context.module_definition
1211
+ if constructor.module_context.instance_definition.type_name == module_context.module_definition.type_name
1212
+ module_context.defined_module_methods.merge(constructor.module_context.defined_instance_methods)
1213
+ end
1214
+ end
1215
+
1216
+ add_typing(node, type: AST::Builtin.nil_type)
1217
+ end
1218
+
1133
1219
  when :self
1134
1220
  add_typing node, type: AST::Types::Self.new
1135
1221
 
@@ -2937,14 +3023,15 @@ module Steep
2937
3023
  end
2938
3024
 
2939
3025
  def test_literal_type(literal, hint)
2940
- case hint
2941
- when AST::Types::Literal
2942
- if hint.value == literal
2943
- hint
2944
- end
2945
- when AST::Types::Union
2946
- if hint.types.any? {|ty| ty.is_a?(AST::Types::Literal) && ty.value == literal}
2947
- hint
3026
+ if hint
3027
+ case hint
3028
+ when AST::Types::Any
3029
+ nil
3030
+ else
3031
+ literal_type = AST::Types::Literal.new(value: literal, location: nil)
3032
+ if check_relation(sub_type: literal_type, super_type: hint).success?
3033
+ hint
3034
+ end
2948
3035
  end
2949
3036
  end
2950
3037
  end
@@ -95,6 +95,12 @@ module Steep
95
95
  end_pos = node.loc.end.begin_pos
96
96
  add_context(begin_pos..end_pos, context: context)
97
97
 
98
+ when :sclass
99
+ name_node = node.children[0]
100
+ begin_pos = name_node.loc.expression.end_pos
101
+ end_pos = node.loc.end.begin_pos
102
+ add_context(begin_pos..end_pos, context: context)
103
+
98
104
  when :def, :defs
99
105
  args_node = case node.type
100
106
  when :def
@@ -1,3 +1,3 @@
1
1
  module Steep
2
- VERSION = "0.19.0"
2
+ VERSION = "0.24.0"
3
3
  end
@@ -18,7 +18,6 @@ class D
18
18
  def foo: -> untyped
19
19
  end
20
20
 
21
- class E
22
- def initialize: () -> untyped
21
+ interface _E
23
22
  def foo: -> untyped
24
23
  end
@@ -1,8 +1,10 @@
1
- # @type var e: E
1
+ # @type var e: _E
2
2
  # @type var d: D
3
3
 
4
4
  e = (_ = nil)
5
5
  d = (_ = nil)
6
6
 
7
7
  e = d
8
+
9
+ # !expects IncompatibleAssignment: lhs_type=::D, rhs_type=::_E
8
10
  d = e
@@ -28,18 +28,11 @@ Gem::Specification.new do |spec|
28
28
 
29
29
  spec.required_ruby_version = '>= 2.6.0'
30
30
 
31
- spec.add_development_dependency "bundler", ">= 1.13"
32
- spec.add_development_dependency "rake", "~> 13.0"
33
- spec.add_development_dependency "minitest", "~> 5.0"
34
- spec.add_development_dependency "racc", "~> 1.4"
35
- spec.add_development_dependency "minitest-reporters", "~> 1.4.2"
36
- spec.add_development_dependency "minitest-hooks", "~> 1.5.0"
37
-
38
31
  spec.add_runtime_dependency "parser", "~> 2.7.0"
39
32
  spec.add_runtime_dependency "ast_utils", "~> 0.3.0"
40
33
  spec.add_runtime_dependency "activesupport", ">= 5.1"
41
34
  spec.add_runtime_dependency "rainbow", ">= 2.2.2", "< 4.0"
42
35
  spec.add_runtime_dependency "listen", "~> 3.1"
43
36
  spec.add_runtime_dependency "language_server-protocol", "~> 3.14.0.2"
44
- spec.add_runtime_dependency "rbs", ">= 0.6.0", '< 0.7.0'
37
+ spec.add_runtime_dependency "rbs", "~> 0.10.0"
45
38
  end
metadata CHANGED
@@ -1,99 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: steep
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.19.0
4
+ version: 0.24.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-07-12 00:00:00.000000000 Z
11
+ date: 2020-08-10 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: bundler
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '1.13'
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '1.13'
27
- - !ruby/object:Gem::Dependency
28
- name: rake
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '13.0'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '13.0'
41
- - !ruby/object:Gem::Dependency
42
- name: minitest
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '5.0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '5.0'
55
- - !ruby/object:Gem::Dependency
56
- name: racc
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '1.4'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '1.4'
69
- - !ruby/object:Gem::Dependency
70
- name: minitest-reporters
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: 1.4.2
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: 1.4.2
83
- - !ruby/object:Gem::Dependency
84
- name: minitest-hooks
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: 1.5.0
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
95
- - !ruby/object:Gem::Version
96
- version: 1.5.0
97
13
  - !ruby/object:Gem::Dependency
98
14
  name: parser
99
15
  requirement: !ruby/object:Gem::Requirement
@@ -188,22 +104,16 @@ dependencies:
188
104
  name: rbs
189
105
  requirement: !ruby/object:Gem::Requirement
190
106
  requirements:
191
- - - ">="
192
- - !ruby/object:Gem::Version
193
- version: 0.6.0
194
- - - "<"
107
+ - - "~>"
195
108
  - !ruby/object:Gem::Version
196
- version: 0.7.0
109
+ version: 0.10.0
197
110
  type: :runtime
198
111
  prerelease: false
199
112
  version_requirements: !ruby/object:Gem::Requirement
200
113
  requirements:
201
- - - ">="
202
- - !ruby/object:Gem::Version
203
- version: 0.6.0
204
- - - "<"
114
+ - - "~>"
205
115
  - !ruby/object:Gem::Version
206
- version: 0.7.0
116
+ version: 0.10.0
207
117
  description: Gradual Typing for Ruby
208
118
  email:
209
119
  - matsumoto@soutaro.com
@@ -224,6 +134,7 @@ files:
224
134
  - bin/console
225
135
  - bin/setup
226
136
  - bin/smoke_runner.rb
137
+ - bin/steep-prof
227
138
  - exe/steep
228
139
  - lib/steep.rb
229
140
  - lib/steep/annotation_parser.rb