steep 2.1.0.dev.1 → 2.1.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 +4 -4
- data/CHANGELOG.md +35 -0
- data/CLAUDE.md +2 -2
- data/README.md +2 -2
- data/bin/steep-check.rb +4 -4
- data/lib/steep/ast/types/helper.rb +0 -1
- data/lib/steep/ast/types/name.rb +1 -1
- data/lib/steep/cli.rb +32 -3
- data/lib/steep/daemon.rb +49 -9
- data/lib/steep/drivers/init.rb +4 -3
- data/lib/steep/drivers/langserver.rb +33 -1
- data/lib/steep/drivers/query.rb +40 -2
- data/lib/steep/interface/builder.rb +24 -4
- data/lib/steep/server/base_worker.rb +15 -0
- data/lib/steep/server/command_socket.rb +181 -0
- data/lib/steep/server/custom_methods.rb +12 -0
- data/lib/steep/server/master.rb +383 -2
- data/lib/steep/server/type_check_worker.rb +48 -2
- data/lib/steep/services/goto_service.rb +6 -2
- data/lib/steep/services/hover_provider/content.rb +1 -1
- data/lib/steep/source.rb +3 -4
- data/lib/steep/subtyping/check.rb +6 -3
- data/lib/steep/tagged_logging.rb +4 -1
- data/lib/steep/type_construction.rb +20 -13
- data/lib/steep/type_inference/case_when.rb +2 -2
- data/lib/steep/type_inference/send_args.rb +9 -5
- data/lib/steep/version.rb +1 -1
- data/lib/steep.rb +1 -0
- data/steep.gemspec +2 -8
- metadata +6 -5
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
module Steep
|
|
2
2
|
module Server
|
|
3
3
|
class TypeCheckWorker < BaseWorker
|
|
4
|
-
attr_reader :project, :assignment
|
|
4
|
+
attr_reader :project, :assignment
|
|
5
5
|
attr_reader :commandline_args
|
|
6
6
|
attr_reader :current_type_check_guid
|
|
7
7
|
|
|
8
8
|
WorkspaceSymbolJob = _ = Struct.new(:query, :id, keyword_init: true)
|
|
9
9
|
StatsJob = _ = Struct.new(:id, keyword_init: true)
|
|
10
10
|
QueryDefinitionJob = _ = Struct.new(:id, :name, keyword_init: true)
|
|
11
|
+
QueryDiagnosticsJob = _ = Struct.new(:id, keyword_init: true)
|
|
11
12
|
StartTypeCheckJob = _ = Struct.new(:guid, :changes, keyword_init: true)
|
|
12
13
|
TypeCheckCodeJob = _ = Struct.new(:guid, :path, :target, keyword_init: true)
|
|
13
14
|
ValidateAppSignatureJob = _ = Struct.new(:guid, :path, :target, keyword_init: true)
|
|
@@ -68,7 +69,7 @@ module Steep
|
|
|
68
69
|
@io_socket = io_socket
|
|
69
70
|
@service = service if service
|
|
70
71
|
@child_pids = []
|
|
71
|
-
@need_to_warmup =
|
|
72
|
+
@need_to_warmup = true
|
|
72
73
|
|
|
73
74
|
if io_socket
|
|
74
75
|
Signal.trap "SIGCHLD" do
|
|
@@ -112,6 +113,8 @@ module Steep
|
|
|
112
113
|
when CustomMethods::Query__Definition::METHOD
|
|
113
114
|
params = request[:params] #: CustomMethods::Query__Definition::params
|
|
114
115
|
queue << QueryDefinitionJob.new(id: request[:id], name: params[:name])
|
|
116
|
+
when CustomMethods::Query__Diagnostics::METHOD
|
|
117
|
+
queue << QueryDiagnosticsJob.new(id: request[:id])
|
|
115
118
|
when "textDocument/definition"
|
|
116
119
|
queue << GotoJob.definition(id: request[:id], params: request[:params])
|
|
117
120
|
when "textDocument/implementation"
|
|
@@ -307,6 +310,10 @@ module Steep
|
|
|
307
310
|
writer.write(
|
|
308
311
|
CustomMethods::Query__Definition.response(job.id, query_definition_result(job.name))
|
|
309
312
|
)
|
|
313
|
+
when QueryDiagnosticsJob
|
|
314
|
+
writer.write(
|
|
315
|
+
CustomMethods::Query__Diagnostics.response(job.id, query_diagnostics_result())
|
|
316
|
+
)
|
|
310
317
|
end
|
|
311
318
|
end
|
|
312
319
|
|
|
@@ -358,6 +365,45 @@ module Steep
|
|
|
358
365
|
end
|
|
359
366
|
end
|
|
360
367
|
|
|
368
|
+
# Returns the diagnostics of the files this worker has type checked so far
|
|
369
|
+
#
|
|
370
|
+
# An array of `Query__Diagnostics::entry`, with the LSP-formatted diagnostics per file URI.
|
|
371
|
+
# Files that are loaded but not type checked yet are not included.
|
|
372
|
+
#
|
|
373
|
+
def query_diagnostics_result
|
|
374
|
+
result = {} #: Hash[String, Array[untyped]]
|
|
375
|
+
|
|
376
|
+
service.source_files.each_value do |file|
|
|
377
|
+
next if file.typing.nil? && file.errors.nil?
|
|
378
|
+
|
|
379
|
+
absolute_path = project.absolute_path(file.path)
|
|
380
|
+
|
|
381
|
+
group_target =
|
|
382
|
+
project.group_for_source_path(absolute_path) ||
|
|
383
|
+
project.group_for_inline_source_path(absolute_path) ||
|
|
384
|
+
project.target_for_source_path(absolute_path) ||
|
|
385
|
+
project.target_for_inline_source_path(absolute_path)
|
|
386
|
+
next unless group_target
|
|
387
|
+
|
|
388
|
+
formatter = Diagnostic::LSPFormatter.new(group_target.code_diagnostics_config)
|
|
389
|
+
uri = PathHelper.to_uri(absolute_path).to_s
|
|
390
|
+
array = result[uri] ||= []
|
|
391
|
+
array.concat(file.diagnostics.filter_map { formatter.format(_1) })
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
formatter = Diagnostic::LSPFormatter.new({}, **{})
|
|
395
|
+
service.signature_validation_diagnostics.each_value do |path_diagnostics|
|
|
396
|
+
path_diagnostics.each do |path, diagnostics|
|
|
397
|
+
absolute_path = path.absolute? ? path : project.absolute_path(path)
|
|
398
|
+
uri = PathHelper.to_uri(absolute_path).to_s
|
|
399
|
+
array = result[uri] ||= []
|
|
400
|
+
array.concat(diagnostics.filter_map { formatter.format(_1) })
|
|
401
|
+
end
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
result.map { { uri: _1, diagnostics: _2 } }
|
|
405
|
+
end
|
|
406
|
+
|
|
361
407
|
def query_definition_result(name_string)
|
|
362
408
|
name = Services::GotoService.parse_name(name_string)
|
|
363
409
|
|
|
@@ -524,7 +524,9 @@ module Steep
|
|
|
524
524
|
def constant_definition_in_ruby(name, locations:)
|
|
525
525
|
type_check.source_files.each do |path, source|
|
|
526
526
|
if typing = source.typing
|
|
527
|
-
|
|
527
|
+
# Inline sources are type checked too, but they don't have a Ruby definition to go to.
|
|
528
|
+
# Their declarations are found through the RBS lookup instead.
|
|
529
|
+
target = project.target_for_source_path(path) or next
|
|
528
530
|
entry = typing.source_index.entry(constant: name)
|
|
529
531
|
entry.definitions.each do |node|
|
|
530
532
|
case node.type
|
|
@@ -551,7 +553,9 @@ module Steep
|
|
|
551
553
|
if in_ruby
|
|
552
554
|
type_check.source_files.each do |path, source|
|
|
553
555
|
if typing = source.typing
|
|
554
|
-
|
|
556
|
+
# Inline sources are type checked too, but they don't have a Ruby definition to go to.
|
|
557
|
+
# Their declarations are found through the RBS lookup instead.
|
|
558
|
+
target = project.target_for_source_path(path) or next
|
|
555
559
|
entry = typing.source_index.entry(method: name)
|
|
556
560
|
|
|
557
561
|
if entry.definitions.empty?
|
data/lib/steep/source.rb
CHANGED
|
@@ -231,7 +231,7 @@ module Steep
|
|
|
231
231
|
end
|
|
232
232
|
|
|
233
233
|
when :rescue
|
|
234
|
-
body,
|
|
234
|
+
body, _, else_node, loc = deconstruct_rescue_node!(node)
|
|
235
235
|
|
|
236
236
|
if else_node
|
|
237
237
|
loc.else or raise
|
|
@@ -356,7 +356,6 @@ module Steep
|
|
|
356
356
|
|
|
357
357
|
def find_heredoc_nodes(line, column, position)
|
|
358
358
|
each_heredoc_node() do |nodes, location|
|
|
359
|
-
node = nodes[0]
|
|
360
359
|
loc = location.heredoc_body #: Parser::Source::Range
|
|
361
360
|
|
|
362
361
|
if range = loc.to_range
|
|
@@ -470,7 +469,7 @@ module Steep
|
|
|
470
469
|
return false unless send_node
|
|
471
470
|
|
|
472
471
|
if send_node.type == :send
|
|
473
|
-
receiver, method,
|
|
472
|
+
receiver, method, _ = deconstruct_send_node!(send_node)
|
|
474
473
|
|
|
475
474
|
return false unless receiver
|
|
476
475
|
|
|
@@ -657,7 +656,7 @@ module Steep
|
|
|
657
656
|
end
|
|
658
657
|
|
|
659
658
|
if send_node
|
|
660
|
-
receiver_node,
|
|
659
|
+
receiver_node, _, _, location = deconstruct_send_node!(send_node)
|
|
661
660
|
|
|
662
661
|
if receiver_node
|
|
663
662
|
if location.dot && location.selector
|
|
@@ -189,7 +189,7 @@ module Steep
|
|
|
189
189
|
|
|
190
190
|
relation.type!
|
|
191
191
|
|
|
192
|
-
Steep.logger.tagged "#{relation.sub_type} <: #{relation.super_type}" do
|
|
192
|
+
Steep.logger.tagged(-> { "#{relation.sub_type} <: #{relation.super_type}" }) do
|
|
193
193
|
bounds = cache_bounds(relation)
|
|
194
194
|
fvs = relation.sub_type.free_variables + relation.super_type.free_variables
|
|
195
195
|
cached = cache[relation, @self_type, @instance_type, @class_type, bounds]
|
|
@@ -201,7 +201,7 @@ module Steep
|
|
|
201
201
|
else
|
|
202
202
|
push_assumption(relation) do
|
|
203
203
|
check_type0(relation).tap do |result|
|
|
204
|
-
Steep.logger.debug "result=#{result.class}"
|
|
204
|
+
Steep.logger.debug { "result=#{result.class}" }
|
|
205
205
|
cache[relation, @self_type, @instance_type, @class_type, bounds] = result
|
|
206
206
|
end
|
|
207
207
|
end
|
|
@@ -644,6 +644,9 @@ module Steep
|
|
|
644
644
|
|
|
645
645
|
All(relation) do |result|
|
|
646
646
|
sub_args.zip(sup_args, sup_params.each).each do |sub_arg, sup_arg, sup_param|
|
|
647
|
+
sup_arg or raise
|
|
648
|
+
sup_param or raise
|
|
649
|
+
|
|
647
650
|
case sup_param.variance
|
|
648
651
|
when :covariant
|
|
649
652
|
result.add(Relation.new(sub_type: sub_arg, super_type: sup_arg)) do |rel|
|
|
@@ -854,7 +857,7 @@ module Steep
|
|
|
854
857
|
end
|
|
855
858
|
|
|
856
859
|
def check_method_type(name, relation)
|
|
857
|
-
Steep.logger.tagged "#{name} : #{relation.sub_type} <: #{relation.super_type}" do
|
|
860
|
+
Steep.logger.tagged(-> { "#{name} : #{relation.sub_type} <: #{relation.super_type}" }) do
|
|
858
861
|
relation.method!
|
|
859
862
|
|
|
860
863
|
sub_type, super_type = relation
|
data/lib/steep/tagged_logging.rb
CHANGED
|
@@ -653,7 +653,6 @@ module Steep
|
|
|
653
653
|
instance_definition: instance_definition
|
|
654
654
|
)
|
|
655
655
|
|
|
656
|
-
singleton_definition = checker.factory.definition_builder.build_singleton(module_context.class_name)
|
|
657
656
|
type_env =
|
|
658
657
|
TypeInference::TypeEnvBuilder.new(
|
|
659
658
|
TypeInference::TypeEnvBuilder::Command::ImportGlobalDeclarations.new(checker.factory),
|
|
@@ -730,7 +729,7 @@ module Steep
|
|
|
730
729
|
end
|
|
731
730
|
|
|
732
731
|
def synthesize(node, hint: nil, condition: false)
|
|
733
|
-
Steep.logger.tagged "synthesize:(#{node.location&.yield_self {|loc| loc.expression.to_s.split(/:/, 2).last } || "-"})" do
|
|
732
|
+
Steep.logger.tagged(-> { "synthesize:(#{node.location&.yield_self {|loc| loc.expression.to_s.split(/:/, 2).last } || "-"})" }) do
|
|
734
733
|
Steep.logger.debug node.type
|
|
735
734
|
case node.type
|
|
736
735
|
when :begin, :kwbegin
|
|
@@ -781,7 +780,7 @@ module Steep
|
|
|
781
780
|
end
|
|
782
781
|
|
|
783
782
|
if rhs
|
|
784
|
-
rhs_type, rhs_constr,
|
|
783
|
+
rhs_type, rhs_constr, _ = synthesize(rhs, hint: hint).to_ary
|
|
785
784
|
|
|
786
785
|
constr = rhs_constr.update_type_env do |type_env|
|
|
787
786
|
var_type = rhs_type
|
|
@@ -1761,6 +1760,11 @@ module Steep
|
|
|
1761
1760
|
else
|
|
1762
1761
|
if hint
|
|
1763
1762
|
tuples = select_flatten_types(hint) {|type| type.is_a?(AST::Types::Tuple) } #: Array[AST::Types::Tuple]
|
|
1763
|
+
if tuples.empty?
|
|
1764
|
+
if converted = try_convert(hint, :to_ary)
|
|
1765
|
+
tuples = select_flatten_types(converted) {|type| type.is_a?(AST::Types::Tuple) } #: Array[AST::Types::Tuple]
|
|
1766
|
+
end
|
|
1767
|
+
end
|
|
1764
1768
|
unless tuples.empty?
|
|
1765
1769
|
fallback_pair = nil #: Pair?
|
|
1766
1770
|
tuples.each do |tuple|
|
|
@@ -1913,7 +1917,7 @@ module Steep
|
|
|
1913
1917
|
yield_self do
|
|
1914
1918
|
cond, true_clause, false_clause = node.children
|
|
1915
1919
|
|
|
1916
|
-
|
|
1920
|
+
_, constr = synthesize(cond, condition: true).to_ary
|
|
1917
1921
|
interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: constr.typing, config: builder_config)
|
|
1918
1922
|
truthy, falsy = interpreter.eval(env: constr.context.type_env, node: cond)
|
|
1919
1923
|
|
|
@@ -2045,7 +2049,7 @@ module Steep
|
|
|
2045
2049
|
branch_reachable = false
|
|
2046
2050
|
|
|
2047
2051
|
tests.each do |test|
|
|
2048
|
-
|
|
2052
|
+
_, condition_constr = condition_constr.synthesize(test, condition: true)
|
|
2049
2053
|
truthy, falsy = interpreter.eval(env: condition_constr.context.type_env, node: test)
|
|
2050
2054
|
truthy_env = truthy.env
|
|
2051
2055
|
falsy_env = falsy.env
|
|
@@ -2295,7 +2299,7 @@ module Steep
|
|
|
2295
2299
|
when :while, :until
|
|
2296
2300
|
yield_self do
|
|
2297
2301
|
cond, body = node.children
|
|
2298
|
-
|
|
2302
|
+
_, constr = synthesize(cond, condition: true).to_ary
|
|
2299
2303
|
|
|
2300
2304
|
interpreter = TypeInference::LogicTypeInterpreter.new(subtyping: checker, typing: typing, config: builder_config)
|
|
2301
2305
|
truthy, falsy = interpreter.eval(env: constr.context.type_env, node: cond)
|
|
@@ -2347,7 +2351,7 @@ module Steep
|
|
|
2347
2351
|
.for_branch(body, break_context: TypeInference::Context::BreakContext.new(break_type: hint || AST::Builtin.nil_type, next_type: nil))
|
|
2348
2352
|
|
|
2349
2353
|
typing.cursor_context.set_node_context(body, for_loop.context)
|
|
2350
|
-
_,
|
|
2354
|
+
_, _, body_context = for_loop.synthesize(body)
|
|
2351
2355
|
|
|
2352
2356
|
constr = cond_constr.update_type_env {|env| env.join(env, body_context.type_env) }
|
|
2353
2357
|
|
|
@@ -2886,10 +2890,8 @@ module Steep
|
|
|
2886
2890
|
if node.type == :splat
|
|
2887
2891
|
asgn_node = node.children[0]
|
|
2888
2892
|
next unless asgn_node
|
|
2889
|
-
var_type = asgn_node.type
|
|
2890
2893
|
else
|
|
2891
2894
|
asgn_node = node
|
|
2892
|
-
var_type = type
|
|
2893
2895
|
end
|
|
2894
2896
|
|
|
2895
2897
|
case asgn_node.type
|
|
@@ -3164,11 +3166,14 @@ module Steep
|
|
|
3164
3166
|
block =
|
|
3165
3167
|
if block_param = params.block_param
|
|
3166
3168
|
if block_param_type = block_param.type
|
|
3167
|
-
|
|
3169
|
+
# Expanding aliases because the cases below test the structure of the type
|
|
3170
|
+
expanded_type = deep_expand_alias(block_param_type) || block_param_type
|
|
3171
|
+
|
|
3172
|
+
case expanded_type
|
|
3168
3173
|
when AST::Types::Proc
|
|
3169
|
-
Interface::Block.new(type:
|
|
3174
|
+
Interface::Block.new(type: expanded_type.type, optional: false, self_type: expanded_type.self_type)
|
|
3170
3175
|
else
|
|
3171
|
-
if proc_type = optional_proc?(
|
|
3176
|
+
if proc_type = optional_proc?(expanded_type)
|
|
3172
3177
|
Interface::Block.new(type: proc_type.type, optional: true, self_type: proc_type.self_type)
|
|
3173
3178
|
else
|
|
3174
3179
|
block_constr.typing.add_error(
|
|
@@ -4358,7 +4363,9 @@ module Steep
|
|
|
4358
4363
|
when arg.compatible?
|
|
4359
4364
|
if arg.node
|
|
4360
4365
|
# Block pass (&block) is given
|
|
4361
|
-
node_type
|
|
4366
|
+
# Passing `proc_type` instead of `node_type` because a block-pass argument is a proc, not `nil`.
|
|
4367
|
+
# `nil` is still allowed by the `node_type` check below.
|
|
4368
|
+
node_type, constr = constr.synthesize(arg.node, hint: arg.proc_type)
|
|
4362
4369
|
|
|
4363
4370
|
nil_given =
|
|
4364
4371
|
constr.check_relation(sub_type: node_type, super_type: AST::Builtin.nil_type).success? &&
|
|
@@ -20,14 +20,14 @@ module Steep
|
|
|
20
20
|
|
|
21
21
|
latest_constr, unreachable_pattern = latest_result
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
yield(test_node, latest_constr, unreachable_pattern)
|
|
24
24
|
truthy_result, falsy_result = logic.eval(env: latest_constr.context.type_env, node: test_node)
|
|
25
25
|
|
|
26
26
|
pattern_results << [pat, truthy_result, falsy_result]
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
def latest_result
|
|
30
|
-
if (_,
|
|
30
|
+
if (_, _, falsy = pattern_results.last)
|
|
31
31
|
[
|
|
32
32
|
initial_constr.update_type_env { falsy.env },
|
|
33
33
|
falsy.unreachable
|
|
@@ -473,16 +473,20 @@ module Steep
|
|
|
473
473
|
end
|
|
474
474
|
end
|
|
475
475
|
|
|
476
|
-
def
|
|
476
|
+
def proc_type
|
|
477
477
|
raise unless block
|
|
478
478
|
|
|
479
|
-
|
|
479
|
+
AST::Types::Proc.new(type: block.type, block: nil, self_type: block.self_type)
|
|
480
|
+
end
|
|
481
|
+
|
|
482
|
+
def node_type
|
|
483
|
+
raise unless block
|
|
480
484
|
|
|
481
485
|
if block.optional?
|
|
482
|
-
|
|
486
|
+
AST::Types::Union.build(types: [proc_type, AST::Builtin.nil_type])
|
|
487
|
+
else
|
|
488
|
+
proc_type
|
|
483
489
|
end
|
|
484
|
-
|
|
485
|
-
type
|
|
486
490
|
end
|
|
487
491
|
end
|
|
488
492
|
|
data/lib/steep/version.rb
CHANGED
data/lib/steep.rb
CHANGED
|
@@ -133,6 +133,7 @@ require "steep/server/target_group_files"
|
|
|
133
133
|
require "steep/server/type_check_controller"
|
|
134
134
|
require "steep/server/inline_source_change_detector"
|
|
135
135
|
require "steep/server/master"
|
|
136
|
+
require "steep/server/command_socket"
|
|
136
137
|
require "steep/daemon"
|
|
137
138
|
|
|
138
139
|
require "steep/project"
|
data/steep.gemspec
CHANGED
|
@@ -29,20 +29,14 @@ Gem::Specification.new do |spec|
|
|
|
29
29
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
30
30
|
spec.require_paths = ["lib"]
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
# This is to let dependabot use 3.3, instead of 3.1.x.
|
|
34
|
-
# They use `required_ruby_version=` method to detect the Ruby version they use.
|
|
35
|
-
spec.required_ruby_version = ">= 3.3.0"
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
spec.required_ruby_version = '>= 3.2.0'
|
|
32
|
+
spec.required_ruby_version = '>= 3.3.0'
|
|
39
33
|
|
|
40
34
|
spec.add_runtime_dependency "parser", ">= 3.2"
|
|
41
35
|
spec.add_runtime_dependency "prism", ">= 0.25.0"
|
|
42
36
|
spec.add_runtime_dependency "rainbow", ">= 2.2.2", "< 4.0"
|
|
43
37
|
spec.add_runtime_dependency "listen", "~> 3.0"
|
|
44
38
|
spec.add_runtime_dependency "language_server-protocol", ">= 3.17.0.4", "< 4.0"
|
|
45
|
-
spec.add_runtime_dependency "rbs", "~> 4.
|
|
39
|
+
spec.add_runtime_dependency "rbs", "~> 4.2"
|
|
46
40
|
spec.add_runtime_dependency "concurrent-ruby", ">= 1.1.10"
|
|
47
41
|
spec.add_runtime_dependency "terminal-table", ">= 2", "< 5"
|
|
48
42
|
spec.add_runtime_dependency "securerandom", ">= 0.1"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: steep
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.1.0
|
|
4
|
+
version: 2.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Soutaro Matsumoto
|
|
@@ -97,14 +97,14 @@ dependencies:
|
|
|
97
97
|
requirements:
|
|
98
98
|
- - "~>"
|
|
99
99
|
- !ruby/object:Gem::Version
|
|
100
|
-
version: '4.
|
|
100
|
+
version: '4.2'
|
|
101
101
|
type: :runtime
|
|
102
102
|
prerelease: false
|
|
103
103
|
version_requirements: !ruby/object:Gem::Requirement
|
|
104
104
|
requirements:
|
|
105
105
|
- - "~>"
|
|
106
106
|
- !ruby/object:Gem::Version
|
|
107
|
-
version: '4.
|
|
107
|
+
version: '4.2'
|
|
108
108
|
- !ruby/object:Gem::Dependency
|
|
109
109
|
name: concurrent-ruby
|
|
110
110
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -362,6 +362,7 @@ files:
|
|
|
362
362
|
- lib/steep/range_extension.rb
|
|
363
363
|
- lib/steep/server/base_worker.rb
|
|
364
364
|
- lib/steep/server/change_buffer.rb
|
|
365
|
+
- lib/steep/server/command_socket.rb
|
|
365
366
|
- lib/steep/server/custom_methods.rb
|
|
366
367
|
- lib/steep/server/delay_queue.rb
|
|
367
368
|
- lib/steep/server/inline_source_change_detector.rb
|
|
@@ -442,14 +443,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
442
443
|
requirements:
|
|
443
444
|
- - ">="
|
|
444
445
|
- !ruby/object:Gem::Version
|
|
445
|
-
version: 3.
|
|
446
|
+
version: 3.3.0
|
|
446
447
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
447
448
|
requirements:
|
|
448
449
|
- - ">="
|
|
449
450
|
- !ruby/object:Gem::Version
|
|
450
451
|
version: '0'
|
|
451
452
|
requirements: []
|
|
452
|
-
rubygems_version: 4.0.
|
|
453
|
+
rubygems_version: 4.0.19
|
|
453
454
|
specification_version: 4
|
|
454
455
|
summary: Gradual Typing for Ruby
|
|
455
456
|
test_files: []
|