steep 1.0.2 → 1.1.0.pre.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (121) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +5 -0
  3. data/.gitignore +1 -0
  4. data/CHANGELOG.md +22 -3
  5. data/Gemfile +6 -3
  6. data/Gemfile.lock +12 -16
  7. data/Gemfile.steep +3 -0
  8. data/Gemfile.steep.lock +49 -0
  9. data/Rakefile +5 -0
  10. data/Steepfile +6 -1
  11. data/bin/setup +2 -0
  12. data/bin/steep +19 -0
  13. data/lib/steep/ast/types/factory.rb +1 -1
  14. data/lib/steep/diagnostic/ruby.rb +49 -3
  15. data/lib/steep/diagnostic/signature.rb +18 -0
  16. data/lib/steep/drivers/watch.rb +3 -1
  17. data/lib/steep/method_name.rb +9 -3
  18. data/lib/steep/node_helper.rb +49 -0
  19. data/lib/steep/services/completion_provider.rb +22 -15
  20. data/lib/steep/services/hover_provider/ruby.rb +30 -12
  21. data/lib/steep/services/type_check_service.rb +12 -12
  22. data/lib/steep/shims/symbol_start_with.rb +18 -0
  23. data/lib/steep/signature/validator.rb +19 -0
  24. data/lib/steep/subtyping/constraints.rb +43 -14
  25. data/lib/steep/type_construction.rb +666 -746
  26. data/lib/steep/type_inference/constant_env.rb +0 -2
  27. data/lib/steep/type_inference/context.rb +23 -17
  28. data/lib/steep/type_inference/logic_type_interpreter.rb +210 -119
  29. data/lib/steep/type_inference/method_call.rb +80 -6
  30. data/lib/steep/type_inference/multiple_assignment.rb +189 -0
  31. data/lib/steep/type_inference/type_env.rb +271 -120
  32. data/lib/steep/type_inference/type_env_builder.rb +138 -0
  33. data/lib/steep/typing.rb +2 -0
  34. data/lib/steep/version.rb +1 -1
  35. data/lib/steep.rb +4 -3
  36. data/rbs_collection.steep.lock.yaml +112 -0
  37. data/rbs_collection.steep.yaml +19 -0
  38. data/sample/sig/conference.rbs +8 -0
  39. data/sig/shims/parser/source/map.rbs +146 -0
  40. data/sig/shims/parser/source/range.rbs +237 -0
  41. data/sig/shims/parser.rbs +17 -0
  42. data/sig/steep/ast/annotation/collection.rbs +75 -0
  43. data/sig/steep/ast/annotation.rbs +126 -0
  44. data/sig/steep/ast/builtin.rbs +69 -0
  45. data/sig/steep/ast/type_params.rbs +11 -0
  46. data/sig/steep/ast/types/any.rbs +29 -0
  47. data/sig/steep/ast/types/boolean.rbs +31 -0
  48. data/sig/steep/ast/types/bot.rbs +29 -0
  49. data/sig/steep/ast/types/class.rbs +29 -0
  50. data/sig/steep/ast/types/factory.rbs +76 -0
  51. data/sig/steep/ast/types/helper.rbs +19 -0
  52. data/sig/steep/ast/types/instance.rbs +29 -0
  53. data/sig/steep/ast/types/intersection.rbs +35 -0
  54. data/sig/steep/ast/types/literal.rbs +33 -0
  55. data/sig/steep/ast/types/logic.rbs +78 -0
  56. data/sig/steep/ast/types/name.rbs +71 -0
  57. data/sig/steep/ast/types/nil.rbs +31 -0
  58. data/sig/steep/ast/types/proc.rbs +46 -0
  59. data/sig/steep/ast/types/record.rbs +38 -0
  60. data/sig/steep/ast/types/self.rbs +29 -0
  61. data/sig/steep/ast/types/top.rbs +29 -0
  62. data/sig/steep/ast/types/tuple.rbs +34 -0
  63. data/sig/steep/ast/types/union.rbs +38 -0
  64. data/sig/steep/ast/types/var.rbs +37 -0
  65. data/sig/steep/ast/types/void.rbs +29 -0
  66. data/sig/steep/ast/types.rbs +37 -0
  67. data/sig/steep/diagnostic/deprecated/unknown_constant_assigned.rbs +15 -0
  68. data/sig/steep/diagnostic/helper.rbs +9 -0
  69. data/sig/steep/diagnostic/lsp_formatter.rbs +29 -0
  70. data/sig/steep/diagnostic/ruby.rbs +494 -0
  71. data/sig/steep/diagnostic/signature.rbs +215 -0
  72. data/sig/steep/interface/block.rbs +35 -0
  73. data/sig/steep/interface/function.rbs +253 -0
  74. data/sig/steep/interface/interface.rbs +23 -0
  75. data/sig/steep/interface/method_type.rbs +55 -0
  76. data/sig/steep/interface/substitution.rbs +53 -0
  77. data/sig/steep/interface/type_param.rbs +35 -0
  78. data/sig/steep/method_name.rbs +26 -0
  79. data/sig/steep/module_helper.rbs +7 -0
  80. data/sig/steep/node_helper.rbs +11 -0
  81. data/sig/steep/project/dsl.rbs +94 -0
  82. data/sig/steep/project/options.rbs +15 -0
  83. data/sig/steep/project/pattern.rbs +25 -0
  84. data/sig/steep/project/target.rbs +25 -0
  85. data/sig/steep/project.rbs +19 -0
  86. data/sig/steep/services/completion_provider.rbs +123 -0
  87. data/sig/steep/services/content_change.rbs +35 -0
  88. data/sig/steep/services/file_loader.rbs +13 -0
  89. data/sig/steep/services/goto_service.rbs +45 -0
  90. data/sig/steep/services/hover_provider/rbs.rbs +21 -0
  91. data/sig/steep/services/hover_provider/ruby.rbs +109 -0
  92. data/sig/steep/services/hover_provider/singleton_methods.rbs +11 -0
  93. data/sig/steep/services/path_assignment.rbs +21 -0
  94. data/sig/steep/services/signature_service.rbs +91 -0
  95. data/sig/steep/services/stats_calculator.rbs +17 -0
  96. data/sig/steep/services/type_check_service.rbs +93 -0
  97. data/sig/steep/source.rbs +55 -0
  98. data/sig/steep/subtyping/cache.rbs +17 -0
  99. data/sig/steep/subtyping/check.rbs +93 -0
  100. data/sig/steep/subtyping/constraints.rbs +111 -0
  101. data/sig/steep/subtyping/relation.rbs +51 -0
  102. data/sig/steep/subtyping/result.rbs +157 -0
  103. data/sig/steep/subtyping/variable_variance.rbs +23 -0
  104. data/sig/steep/type_construction.rbs +285 -0
  105. data/sig/steep/type_inference/block_params.rbs +52 -0
  106. data/sig/steep/type_inference/constant_env.rbs +27 -0
  107. data/sig/steep/type_inference/context.rbs +137 -0
  108. data/sig/steep/type_inference/logic_type_interpreter.rbs +72 -0
  109. data/sig/steep/type_inference/method_call.rbs +124 -0
  110. data/sig/steep/type_inference/method_params.rbs +104 -0
  111. data/sig/steep/type_inference/multiple_assignment.rbs +76 -0
  112. data/sig/steep/type_inference/type_env.rbs +158 -0
  113. data/sig/steep/type_inference/type_env_builder.rbs +77 -0
  114. data/sig/steep/typing.rbs +68 -0
  115. data/sig/steep.rbs +31 -0
  116. data/smoke/class/f.rb +1 -0
  117. data/smoke/class/test_expectations.yml +2 -2
  118. data/smoke/diagnostics/test_expectations.yml +4 -2
  119. metadata +90 -6
  120. data/lib/steep/type_inference/local_variable_type_env.rb +0 -249
  121. data/lib/steep/type_inference/logic.rb +0 -161
@@ -2,22 +2,36 @@ module Steep
2
2
  module Services
3
3
  module HoverProvider
4
4
  class Ruby
5
- TypeContent = Struct.new(:node, :type, :location, keyword_init: true)
6
- VariableContent = Struct.new(:node, :name, :type, :location, keyword_init: true)
7
- MethodCallContent = Struct.new(:node, :method_call, :location, keyword_init: true)
8
- DefinitionContent = Struct.new(:node, :method_name, :method_type, :definition, :location, keyword_init: true)
9
- ConstantContent = Struct.new(:location, :full_name, :type, :decl, keyword_init: true) do
5
+ TypeContent = _ = Struct.new(:node, :type, :location, keyword_init: true)
6
+ VariableContent = _ = Struct.new(:node, :name, :type, :location, keyword_init: true)
7
+ MethodCallContent = _ = Struct.new(:node, :method_call, :location, keyword_init: true)
8
+ DefinitionContent = _ = Struct.new(:node, :method_name, :method_type, :definition, :location, keyword_init: true)
9
+ ConstantContent = _ = Struct.new(:location, :full_name, :type, :decl, keyword_init: true) do
10
+ # @implements ConstantContent
11
+
10
12
  def comments
11
13
  case
12
- when class_or_module?
13
- decl.decls.filter_map {|d| d.decl.comment }
14
- when constant?
14
+ when decl = class_decl
15
+ decl.decls.map {|d| d.decl.comment }
16
+ when decl = constant_decl
15
17
  [decl.decl.comment]
16
18
  else
17
- []
19
+ raise
18
20
  end.compact
19
21
  end
20
22
 
23
+ def class_decl
24
+ if (decl = decl()).is_a?(::RBS::Environment::MultiEntry)
25
+ decl
26
+ end
27
+ end
28
+
29
+ def constant_decl
30
+ if (decl = decl()).is_a?(::RBS::Environment::SingleEntry)
31
+ decl
32
+ end
33
+ end
34
+
21
35
  def constant?
22
36
  decl.is_a?(::RBS::Environment::SingleEntry)
23
37
  end
@@ -49,6 +63,8 @@ module Steep
49
63
  else
50
64
  methods[singleton_method]
51
65
  end
66
+ else
67
+ raise "One of the instance_method or singleton_method is required"
52
68
  end
53
69
  end
54
70
 
@@ -72,6 +88,8 @@ module Steep
72
88
  InstanceMethodName.new(type_name: defined_in, method_name: method_name)
73
89
  when builder.build_singleton(defined_in).methods.key?(method_name)
74
90
  SingletonMethodName.new(type_name: defined_in, method_name: method_name)
91
+ else
92
+ raise
75
93
  end
76
94
  else
77
95
  InstanceMethodName.new(type_name: defined_in, method_name: method_name)
@@ -83,19 +101,19 @@ module Steep
83
101
  typing = typecheck(target, path: path, content: file.content, line: line, column: column) or return
84
102
  node, *parents = typing.source.find_nodes(line: line, column: column)
85
103
 
86
- if node
104
+ if node && parents
87
105
  case node.type
88
106
  when :lvar
89
107
  var_name = node.children[0]
90
108
  context = typing.context_at(line: line, column: column)
91
- var_type = context.lvar_env[var_name] || AST::Types::Any.new(location: nil)
109
+ var_type = context.type_env[var_name] || AST::Types::Any.new(location: nil)
92
110
 
93
111
  return VariableContent.new(node: node, name: var_name, type: var_type, location: node.location.name)
94
112
 
95
113
  when :lvasgn
96
114
  var_name, rhs = node.children
97
115
  context = typing.context_at(line: line, column: column)
98
- type = context.lvar_env[var_name] || typing.type_of(node: rhs)
116
+ type = context.type_env[var_name] || typing.type_of(node: node)
99
117
 
100
118
  return VariableContent.new(node: node, name: var_name, type: type, location: node.location.name)
101
119
 
@@ -342,21 +342,22 @@ module Steep
342
342
 
343
343
  def self.type_check(source:, subtyping:)
344
344
  annotations = source.annotations(block: source.node, factory: subtyping.factory, context: nil)
345
+
346
+ definition = subtyping.factory.definition_builder.build_instance(AST::Builtin::Object.module_name)
347
+
345
348
  const_env = TypeInference::ConstantEnv.new(
346
349
  factory: subtyping.factory,
347
350
  context: nil,
348
351
  resolver: RBS::Resolver::ConstantResolver.new(builder: subtyping.factory.definition_builder)
349
352
  )
350
- type_env = TypeInference::TypeEnv.build(annotations: annotations,
351
- subtyping: subtyping,
352
- const_env: const_env,
353
- signatures: subtyping.factory.env)
354
- lvar_env = TypeInference::LocalVariableTypeEnv.empty(
355
- subtyping: subtyping,
356
- self_type: AST::Builtin::Object.instance_type,
357
- instance_type: AST::Builtin::Object.instance_type,
358
- class_type: AST::Builtin::Object.module_type
359
- ).annotate(annotations)
353
+ type_env = TypeInference::TypeEnv.new(const_env)
354
+ type_env = TypeInference::TypeEnvBuilder.new(
355
+ TypeInference::TypeEnvBuilder::Command::ImportConstantAnnotations.new(annotations),
356
+ TypeInference::TypeEnvBuilder::Command::ImportGlobalDeclarations.new(subtyping.factory),
357
+ TypeInference::TypeEnvBuilder::Command::ImportInstanceVariableDefinition.new(definition, subtyping.factory),
358
+ TypeInference::TypeEnvBuilder::Command::ImportInstanceVariableAnnotations.new(annotations),
359
+ TypeInference::TypeEnvBuilder::Command::ImportLocalVariableAnnotations.new(annotations)
360
+ ).build(type_env)
360
361
 
361
362
  context = TypeInference::Context.new(
362
363
  block_context: nil,
@@ -364,7 +365,7 @@ module Steep
364
365
  instance_type: AST::Builtin::Object.instance_type,
365
366
  module_type: AST::Builtin::Object.module_type,
366
367
  implement_name: nil,
367
- const_env: const_env,
368
+ nesting: nil,
368
369
  class_name: AST::Builtin::Object.module_name,
369
370
  instance_definition: subtyping.factory.definition_builder.build_instance(AST::Builtin::Object.module_name),
370
371
  module_definition: subtyping.factory.definition_builder.build_singleton(AST::Builtin::Object.module_name)
@@ -373,7 +374,6 @@ module Steep
373
374
  break_context: nil,
374
375
  self_type: AST::Builtin::Object.instance_type,
375
376
  type_env: type_env,
376
- lvar_env: lvar_env,
377
377
  call_context: TypeInference::MethodCall::TopLevelContext.new,
378
378
  variable_context: TypeInference::Context::TypeVariableContext.empty
379
379
  )
@@ -0,0 +1,18 @@
1
+ # Steep runs on Ruby 2.6 and it needs a shim of `Symbol#start_with?`
2
+
3
+ module Shims
4
+ module SymbolStartWith
5
+ def start_with?(*args)
6
+ to_s.start_with?(*args)
7
+ end
8
+
9
+ def end_with?(*args)
10
+ to_s.end_with?(*args)
11
+ end
12
+ end
13
+
14
+ unless Symbol.method_defined?(:start_with?)
15
+ Symbol.include(SymbolStartWith)
16
+ end
17
+ end
18
+
@@ -324,6 +324,25 @@ module Steep
324
324
  end
325
325
  end
326
326
 
327
+ definition.class_variables.each do |name, var|
328
+ if var.declared_in == definition.type_name
329
+ if (parent = var.parent_variable) && var.declared_in != parent.declared_in
330
+ class_var = definition.entry.decls.flat_map {|decl| decl.decl.members }.find do |member|
331
+ member.is_a?(RBS::AST::Members::ClassVariable) && member.name == name
332
+ end
333
+
334
+ if class_var
335
+ @errors << Diagnostic::Signature::ClassVariableDuplicationError.new(
336
+ class_name: definition.type_name,
337
+ other_class_name: parent.declared_in,
338
+ variable_name: name,
339
+ location: class_var.location[:name]
340
+ )
341
+ end
342
+ end
343
+ end
344
+ end
345
+
327
346
  ancestors = builder.ancestor_builder.one_singleton_ancestors(name)
328
347
  mixin_constraints(definition, ancestors.extended_modules, immediate_self_types: ancestors.self_types).each do |relation, ancestor|
329
348
  checker.check(
@@ -124,10 +124,10 @@ module Steep
124
124
  skips << type if skip
125
125
  end
126
126
 
127
- super_fvs = supers.each.with_object(Set.new) do |type, fvs|
127
+ super_fvs = supers.each_with_object(Set.new) do |type, fvs|
128
128
  fvs.merge(type.free_variables)
129
129
  end
130
- sub_fvs = subs.each.with_object(Set.new) do |type, fvs|
130
+ sub_fvs = subs.each_with_object(Set.new) do |type, fvs|
131
131
  fvs.merge(type.free_variables)
132
132
  end
133
133
 
@@ -169,6 +169,18 @@ module Steep
169
169
  else
170
170
  type
171
171
  end
172
+ when AST::Types::Tuple
173
+ AST::Types::Tuple.new(
174
+ types: type.types.map {|ty| eliminate_variable(ty, to: AST::Builtin.any_type) },
175
+ location: type.location
176
+ )
177
+ when AST::Types::Record
178
+ AST::Types::Record.new(
179
+ elements: type.elements.transform_values {|ty| eliminate_variable(ty, to: AST::Builtin.any_type) },
180
+ location: type.location
181
+ )
182
+ when AST::Types::Proc
183
+ type.map_type {|ty| eliminate_variable(ty, to: AST::Builtin.any_type) }
172
184
  else
173
185
  type
174
186
  end
@@ -193,34 +205,36 @@ module Steep
193
205
  end
194
206
 
195
207
  def upper_bound(var, skip: false)
196
- _, upper_bound, skips = dictionary[var]
197
- upper_bound -= skips if skip
208
+ if skip
209
+ upper_bound = upper_bound_types(var)
210
+ else
211
+ _, upper_bound, _ = dictionary[var]
212
+ end
198
213
 
199
214
  case upper_bound.size
200
215
  when 0
201
216
  AST::Types::Top.new
202
217
  when 1
203
- upper_bound.first
218
+ upper_bound.first || raise
204
219
  else
205
220
  AST::Types::Intersection.build(types: upper_bound.to_a)
206
221
  end
207
222
  end
208
223
 
209
224
  def lower_bound(var, skip: false)
210
- lower_bound, _, skips = dictionary[var]
211
- lower_bound -= skips if skip
225
+ lower_bound = lower_bound_types(var)
212
226
 
213
227
  case lower_bound.size
214
228
  when 0
215
229
  AST::Types::Bot.new
216
230
  when 1
217
- lower_bound.first
231
+ lower_bound.first || raise
218
232
  else
219
233
  AST::Types::Union.build(types: lower_bound.to_a)
220
234
  end
221
235
  end
222
236
 
223
- Context = Struct.new(:variance, :self_type, :instance_type, :class_type, keyword_init: true)
237
+ Context = _ = Struct.new(:variance, :self_type, :instance_type, :class_type, keyword_init: true)
224
238
 
225
239
  def solution(checker, variance: nil, variables:, self_type: nil, instance_type: nil, class_type: nil, context: nil)
226
240
  if context
@@ -288,16 +302,13 @@ module Steep
288
302
  end
289
303
 
290
304
  def has_constraint?(var)
291
- lower, upper, skips = dictionary[var]
292
- lower -= skips
293
- upper -= skips
294
- !lower.empty? || !upper.empty?
305
+ !upper_bound_types(var).empty? || !lower_bound_types(var).empty?
295
306
  end
296
307
 
297
308
  def each
298
309
  if block_given?
299
310
  dictionary.each_key do |var|
300
- yield var, lower_bound(var), upper_bound(var)
311
+ yield [var, lower_bound(var), upper_bound(var)]
301
312
  end
302
313
  else
303
314
  enum_for :each
@@ -311,6 +322,24 @@ module Steep
311
322
 
312
323
  "#{unknowns.to_a.join(",")}/#{vars.to_a.join(",")} |- { #{strings.join(", ")} }"
313
324
  end
325
+
326
+ def lower_bound_types(var_name)
327
+ lower, _, _ = dictionary[var_name]
328
+ lower
329
+ end
330
+
331
+ def upper_bound_types(var_name)
332
+ _, upper, skips = dictionary[var_name]
333
+
334
+ case
335
+ when upper.empty?
336
+ skips
337
+ when skips.empty?
338
+ upper
339
+ else
340
+ upper - skips
341
+ end
342
+ end
314
343
  end
315
344
  end
316
345
  end