steep 0.19.0 → 0.24.0

Sign up to get free protection for your applications and to get access to all the features.
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