steep 0.15.0 → 0.16.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/.gitmodules +1 -1
- data/CHANGELOG.md +5 -0
- data/lib/steep/cli.rb +16 -1
- data/lib/steep/drivers/annotations.rb +1 -1
- data/lib/steep/drivers/langserver.rb +13 -462
- data/lib/steep/drivers/utils/driver_helper.rb +1 -1
- data/lib/steep/drivers/watch.rb +97 -85
- data/lib/steep/drivers/worker.rb +51 -0
- data/lib/steep/project/completion_provider.rb +4 -2
- data/lib/steep/project/file.rb +1 -0
- data/lib/steep/project/hover_content.rb +5 -2
- data/lib/steep/project/target.rb +30 -20
- data/lib/steep/project.rb +9 -5
- data/lib/steep/server/base_worker.rb +56 -0
- data/lib/steep/server/code_worker.rb +151 -0
- data/lib/steep/server/interaction_worker.rb +281 -0
- data/lib/steep/server/master.rb +196 -0
- data/lib/steep/server/signature_worker.rb +148 -0
- data/lib/steep/server/utils.rb +36 -0
- data/lib/steep/server/worker_process.rb +62 -0
- data/lib/steep/signature/validator.rb +5 -5
- data/lib/steep/version.rb +1 -1
- data/lib/steep.rb +11 -0
- data/steep.gemspec +1 -1
- data/vendor/ruby-signature/README.md +18 -18
- data/vendor/ruby-signature/Rakefile +90 -15
- data/vendor/ruby-signature/rbs.gemspec +1 -0
- data/vendor/ruby-signature/stdlib/builtin/builtin.rbs +1 -0
- data/vendor/ruby-signature/stdlib/builtin/enumerable.rbs +1 -1
- data/vendor/ruby-signature/stdlib/builtin/module.rbs +2 -2
- data/vendor/ruby-signature/stdlib/json/json.rbs +335 -0
- metadata +14 -5
@@ -0,0 +1,62 @@
|
|
1
|
+
module Steep
|
2
|
+
module Server
|
3
|
+
class WorkerProcess
|
4
|
+
attr_reader :reader
|
5
|
+
attr_reader :writer
|
6
|
+
attr_reader :stderr
|
7
|
+
|
8
|
+
attr_reader :wait_thread
|
9
|
+
|
10
|
+
def initialize(reader:, writer:, stderr:, wait_thread:)
|
11
|
+
@reader = reader
|
12
|
+
@writer = writer
|
13
|
+
@stderr = stderr
|
14
|
+
@wait_thread = wait_thread
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.spawn_worker(type, name:, steepfile:)
|
18
|
+
log_level = %w(debug info warn error fatal unknown)[Steep.logger.level]
|
19
|
+
command = case type
|
20
|
+
when :code
|
21
|
+
["steep", "worker", "--code", "--name=#{name}", "--log-level=#{log_level}", "--steepfile=#{steepfile}"]
|
22
|
+
when :signature
|
23
|
+
["steep", "worker", "--signature", "--name=#{name}", "--log-level=#{log_level}", "--steepfile=#{steepfile}"]
|
24
|
+
when :interaction
|
25
|
+
["steep", "worker", "--interaction", "--name=#{name}", "--log-level=#{log_level}", "--steepfile=#{steepfile}"]
|
26
|
+
else
|
27
|
+
raise
|
28
|
+
end
|
29
|
+
|
30
|
+
stdin, stdout, thread = Open3.popen2(*command, pgroup: true)
|
31
|
+
stderr = nil
|
32
|
+
|
33
|
+
writer = LanguageServer::Protocol::Transport::Io::Writer.new(stdin)
|
34
|
+
reader = LanguageServer::Protocol::Transport::Io::Reader.new(stdout)
|
35
|
+
|
36
|
+
new(reader: reader, writer: writer, stderr: stderr, wait_thread: thread)
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.spawn_code_workers(steepfile:, count: [Etc.nprocessors-3, 1].max)
|
40
|
+
count.times.map do |i|
|
41
|
+
spawn_worker(:code, name: "code@#{i}", steepfile: steepfile)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def <<(message)
|
46
|
+
writer.write(message)
|
47
|
+
end
|
48
|
+
|
49
|
+
def read(&block)
|
50
|
+
reader.read(&block)
|
51
|
+
end
|
52
|
+
|
53
|
+
def shutdown
|
54
|
+
self << { method: :shutdown, params: nil }
|
55
|
+
self << { method: :exit, params: nil }
|
56
|
+
|
57
|
+
writer.io.close()
|
58
|
+
@wait_thread.join()
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -51,7 +51,7 @@ module Steep
|
|
51
51
|
case decl
|
52
52
|
when Declarations::Class
|
53
53
|
rescue_validation_errors do
|
54
|
-
Steep.logger.
|
54
|
+
Steep.logger.debug "#{Location.to_string decl.location}:\tValidating class definition `#{name}`..."
|
55
55
|
builder.build_instance(decl.name.absolute!).each_type do |type|
|
56
56
|
env.validate type, namespace: RBS::Namespace.root
|
57
57
|
end
|
@@ -61,7 +61,7 @@ module Steep
|
|
61
61
|
end
|
62
62
|
when Declarations::Interface
|
63
63
|
rescue_validation_errors do
|
64
|
-
Steep.logger.
|
64
|
+
Steep.logger.debug "#{Location.to_string decl.location}:\tValidating interface `#{name}`..."
|
65
65
|
builder.build_interface(decl.name.absolute!, decl).each_type do |type|
|
66
66
|
env.validate type, namespace: RBS::Namespace.root
|
67
67
|
end
|
@@ -78,7 +78,7 @@ module Steep
|
|
78
78
|
def validate_const
|
79
79
|
env.each_constant do |name, decl|
|
80
80
|
rescue_validation_errors do
|
81
|
-
Steep.logger.
|
81
|
+
Steep.logger.debug "#{Location.to_string decl.location}:\tValidating constant `#{name}`..."
|
82
82
|
env.validate(decl.type, namespace: name.namespace)
|
83
83
|
end
|
84
84
|
end
|
@@ -87,7 +87,7 @@ module Steep
|
|
87
87
|
def validate_global
|
88
88
|
env.each_global do |name, decl|
|
89
89
|
rescue_validation_errors do
|
90
|
-
Steep.logger.
|
90
|
+
Steep.logger.debug "#{Location.to_string decl.location}:\tValidating global `#{name}`..."
|
91
91
|
env.validate(decl.type, namespace: RBS::Namespace.root)
|
92
92
|
end
|
93
93
|
end
|
@@ -96,7 +96,7 @@ module Steep
|
|
96
96
|
def validate_alias
|
97
97
|
env.each_alias do |name, decl|
|
98
98
|
rescue_validation_errors do
|
99
|
-
Steep.logger.
|
99
|
+
Steep.logger.debug "#{Location.to_string decl.location}:\tValidating alias `#{name}`..."
|
100
100
|
env.validate(decl.type, namespace: name.namespace)
|
101
101
|
end
|
102
102
|
end
|
data/lib/steep/version.rb
CHANGED
data/lib/steep.rb
CHANGED
@@ -10,6 +10,8 @@ require "rainbow"
|
|
10
10
|
require "listen"
|
11
11
|
require 'pry'
|
12
12
|
require 'language_server-protocol'
|
13
|
+
require "etc"
|
14
|
+
require "open3"
|
13
15
|
|
14
16
|
require "rbs"
|
15
17
|
|
@@ -70,6 +72,14 @@ require "steep/type_inference/local_variable_type_env"
|
|
70
72
|
require "steep/type_inference/logic"
|
71
73
|
require "steep/ast/types"
|
72
74
|
|
75
|
+
require "steep/server/utils"
|
76
|
+
require "steep/server/base_worker"
|
77
|
+
require "steep/server/code_worker"
|
78
|
+
require "steep/server/signature_worker"
|
79
|
+
require "steep/server/worker_process"
|
80
|
+
require "steep/server/interaction_worker"
|
81
|
+
require "steep/server/master"
|
82
|
+
|
73
83
|
require "steep/project"
|
74
84
|
require "steep/project/file"
|
75
85
|
require "steep/project/options"
|
@@ -89,6 +99,7 @@ require "steep/drivers/trace_printer"
|
|
89
99
|
require "steep/drivers/print_project"
|
90
100
|
require "steep/drivers/init"
|
91
101
|
require "steep/drivers/vendor"
|
102
|
+
require "steep/drivers/worker"
|
92
103
|
|
93
104
|
if ENV["NO_COLOR"]
|
94
105
|
Rainbow.enabled = false
|
data/steep.gemspec
CHANGED
@@ -42,5 +42,5 @@ Gem::Specification.new do |spec|
|
|
42
42
|
spec.add_runtime_dependency "rainbow", ">= 2.2.2", "< 4.0"
|
43
43
|
spec.add_runtime_dependency "listen", "~> 3.1"
|
44
44
|
spec.add_runtime_dependency "pry", "~> 0.12.2"
|
45
|
-
spec.add_runtime_dependency "language_server-protocol", "~> 3.14.0.
|
45
|
+
spec.add_runtime_dependency "language_server-protocol", "~> 3.14.0.2"
|
46
46
|
end
|
@@ -10,51 +10,51 @@ You need to install the dependencies, and build its parser with `bin/setup`.
|
|
10
10
|
|
11
11
|
```
|
12
12
|
$ bin/setup
|
13
|
-
$ bundle exec exe/
|
13
|
+
$ bundle exec exe/rbs
|
14
14
|
```
|
15
15
|
|
16
16
|
## Usage
|
17
17
|
|
18
18
|
```
|
19
|
-
$
|
20
|
-
$
|
21
|
-
$
|
22
|
-
$
|
19
|
+
$ rbs list
|
20
|
+
$ rbs ancestors ::Object
|
21
|
+
$ rbs methods ::Object
|
22
|
+
$ rbs method ::Object tap
|
23
23
|
```
|
24
24
|
|
25
|
-
###
|
25
|
+
### rbs [--class|--module|interface] list
|
26
26
|
|
27
27
|
```
|
28
|
-
$
|
28
|
+
$ rbs list
|
29
29
|
```
|
30
30
|
|
31
31
|
This command lists all of the classes/modules/interfaces defined in `.rbs` files.
|
32
32
|
|
33
|
-
###
|
33
|
+
### rbs ancestors [--singleton|--instance] CLASS
|
34
34
|
|
35
35
|
```
|
36
|
-
$
|
37
|
-
$
|
36
|
+
$ rbs ancestors Array # ([].class.ancestors)
|
37
|
+
$ rbs ancestors --singleton Array # (Array.class.ancestors)
|
38
38
|
```
|
39
39
|
|
40
40
|
This command prints the _ancestors_ of the class.
|
41
41
|
The name of the command is borrowed from `Class#ancestors`, but the semantics is a bit different.
|
42
42
|
The `ancestors` command is more precise (I believe).
|
43
43
|
|
44
|
-
###
|
44
|
+
### rbs methods [--singleton|--instance] CLASS
|
45
45
|
|
46
46
|
```
|
47
|
-
$
|
48
|
-
$
|
47
|
+
$ rbs methods ::Integer # 1.methods
|
48
|
+
$ rbs methods --singleton ::Object # Object.methods
|
49
49
|
```
|
50
50
|
|
51
51
|
This command prints all methods provided for the class.
|
52
52
|
|
53
|
-
###
|
53
|
+
### rbs method [--singleton|--instance] CLASS METHOD
|
54
54
|
|
55
55
|
```
|
56
|
-
$
|
57
|
-
$
|
56
|
+
$ rbs method ::Integer '+' # 1+2
|
57
|
+
$ rbs method --singleton ::Object tap # Object.tap { ... }
|
58
58
|
```
|
59
59
|
|
60
60
|
This command prints type and properties of the method.
|
@@ -66,13 +66,13 @@ It accepts two global options, `-r` and `-I`.
|
|
66
66
|
`-r` is for libraries. You can specify the names of libraries.
|
67
67
|
|
68
68
|
```
|
69
|
-
$
|
69
|
+
$ rbs -r set list
|
70
70
|
```
|
71
71
|
|
72
72
|
`-I` is for application signatures. You can specify the name of directory.
|
73
73
|
|
74
74
|
```
|
75
|
-
$
|
75
|
+
$ rbs -I sig list
|
76
76
|
```
|
77
77
|
|
78
78
|
## Guides
|
@@ -15,7 +15,7 @@ task :validate => :parser do
|
|
15
15
|
sh "rbs validate"
|
16
16
|
end
|
17
17
|
|
18
|
-
FileList["test/stdlib
|
18
|
+
FileList["test/stdlib/**/*_test.rb"].each do |test|
|
19
19
|
multitask test => :parser do
|
20
20
|
sh "ruby bin/test_runner.rb #{test}"
|
21
21
|
end
|
@@ -44,21 +44,96 @@ namespace :generate do
|
|
44
44
|
path = Pathname("test/stdlib/#{klass}_test.rb")
|
45
45
|
raise "#{path} already exists!" if path.exist?
|
46
46
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
47
|
+
require "erb"
|
48
|
+
require "ruby/signature"
|
49
|
+
|
50
|
+
class TestTemplateBuilder
|
51
|
+
attr_reader :klass, :env
|
52
|
+
|
53
|
+
def initialize(klass)
|
54
|
+
@klass = klass
|
55
|
+
|
56
|
+
@env = Ruby::Signature::Environment.new
|
57
|
+
Ruby::Signature::EnvironmentLoader.new.load(env: @env)
|
58
|
+
end
|
59
|
+
|
60
|
+
def call
|
61
|
+
ERB.new(<<~ERB, trim_mode: "-").result(binding)
|
62
|
+
require_relative "test_helper"
|
63
|
+
|
64
|
+
class <%= klass %>Test < StdlibTest
|
65
|
+
target <%= klass %>
|
66
|
+
# library "pathname", "set", "securerandom" # Declare library signatures to load
|
67
|
+
using hook.refinement
|
68
|
+
<%- class_methods.each do |method_name, definition| %>
|
69
|
+
def test_class_method_<%= test_name_for(method_name) %>
|
70
|
+
<%- definition.method_types.each do |method_type| -%>
|
71
|
+
# <%= method_type %>
|
72
|
+
<%= klass %>.<%= method_name %>
|
73
|
+
<%- end -%>
|
74
|
+
end
|
75
|
+
<%- end -%>
|
76
|
+
<%- instance_methods.each do |method_name, definition| %>
|
77
|
+
def test_<%= test_name_for(method_name) %>
|
78
|
+
<%- definition.method_types.each do |method_type| -%>
|
79
|
+
# <%= method_type %>
|
80
|
+
<%= klass %>.new.<%= method_name %>
|
81
|
+
<%- end -%>
|
82
|
+
end
|
83
|
+
<%- end -%>
|
84
|
+
end
|
85
|
+
ERB
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def test_name_for(method_name)
|
91
|
+
{
|
92
|
+
:== => 'double_equal',
|
93
|
+
:!= => 'not_equal',
|
94
|
+
:=== => 'triple_equal',
|
95
|
+
:[] => 'square_bracket',
|
96
|
+
:[]= => 'square_bracket_assign',
|
97
|
+
:> => 'greater_than',
|
98
|
+
:< => 'less_than',
|
99
|
+
:>= => 'greater_than_equal_to',
|
100
|
+
:<= => 'less_than_equal_to',
|
101
|
+
:<=> => 'spaceship',
|
102
|
+
:+ => 'plus',
|
103
|
+
:- => 'minus',
|
104
|
+
:* => 'multiply',
|
105
|
+
:/ => 'divide',
|
106
|
+
:** => 'power',
|
107
|
+
:% => 'modulus',
|
108
|
+
:& => 'and',
|
109
|
+
:| => 'or',
|
110
|
+
:^ => 'xor',
|
111
|
+
:>> => 'right_shift',
|
112
|
+
:<< => 'left_shift',
|
113
|
+
:=~ => 'pattern_match',
|
114
|
+
:!~ => 'does_not_match',
|
115
|
+
:~ => 'tilde'
|
116
|
+
}.fetch(method_name, method_name)
|
60
117
|
end
|
61
|
-
|
118
|
+
|
119
|
+
def type_name
|
120
|
+
@type_name ||= Ruby::Signature::TypeName.new(name: klass.to_sym, namespace: Ruby::Signature::Namespace.new(path: [], absolute: true))
|
121
|
+
end
|
122
|
+
|
123
|
+
def class_methods
|
124
|
+
@class_methods ||= Ruby::Signature::DefinitionBuilder.new(env: env).build_singleton(type_name).methods.select {|_, definition|
|
125
|
+
definition.implemented_in.name.absolute! == type_name
|
126
|
+
}
|
127
|
+
end
|
128
|
+
|
129
|
+
def instance_methods
|
130
|
+
@instance_methods ||= Ruby::Signature::DefinitionBuilder.new(env: env).build_instance(type_name).methods.select {|_, definition|
|
131
|
+
definition.implemented_in.name.absolute! == type_name
|
132
|
+
}
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
path.write TestTemplateBuilder.new(klass).call
|
62
137
|
|
63
138
|
puts "Created: #{path}"
|
64
139
|
end
|
@@ -133,7 +133,7 @@ module Enumerable[unchecked out Elem, out Return]: _Each[Elem, Return]
|
|
133
133
|
|
134
134
|
def inject: (untyped init, Symbol method) -> untyped
|
135
135
|
| (Symbol method) -> untyped
|
136
|
-
| [A] (A initial) { (
|
136
|
+
| [A] (A initial) { (A, Elem) -> A } -> A
|
137
137
|
| () { (Elem, Elem) -> Elem } -> Elem
|
138
138
|
|
139
139
|
# Returns the object in *enum* with the maximum value. The first form
|
@@ -1034,7 +1034,7 @@ class Module < Object
|
|
1034
1034
|
# Removes the method identified by *symbol* from the current class. For an
|
1035
1035
|
# example, see Module#undef_method. String arguments are converted to symbols.
|
1036
1036
|
#
|
1037
|
-
def remove_method: (Symbol | String arg0) -> self
|
1037
|
+
def remove_method: (*Symbol | String arg0) -> self
|
1038
1038
|
|
1039
1039
|
# Returns `true` if *mod* is a singleton class or `false` if it is an ordinary
|
1040
1040
|
# class or module.
|
@@ -1087,7 +1087,7 @@ class Module < Object
|
|
1087
1087
|
# In parent
|
1088
1088
|
# prog.rb:23: undefined method `hello' for #<Child:0x401b3bb4> (NoMethodError)
|
1089
1089
|
#
|
1090
|
-
def undef_method: (Symbol | String arg0) -> self
|
1090
|
+
def undef_method: (*Symbol | String arg0) -> self
|
1091
1091
|
|
1092
1092
|
# Import class refinements from *module* into the current class or module
|
1093
1093
|
# definition.
|