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