typeprof 0.30.1 → 0.31.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/README.md +23 -4
- data/lib/typeprof/cli/cli.rb +27 -7
- data/lib/typeprof/code_range.rb +9 -7
- data/lib/typeprof/core/ast/base.rb +27 -10
- data/lib/typeprof/core/ast/call.rb +85 -24
- data/lib/typeprof/core/ast/const.rb +7 -12
- data/lib/typeprof/core/ast/control.rb +345 -71
- data/lib/typeprof/core/ast/meta.rb +5 -5
- data/lib/typeprof/core/ast/method.rb +15 -5
- data/lib/typeprof/core/ast/misc.rb +21 -2
- data/lib/typeprof/core/ast/module.rb +10 -7
- data/lib/typeprof/core/ast/pattern.rb +9 -1
- data/lib/typeprof/core/ast/sig_decl.rb +163 -42
- data/lib/typeprof/core/ast/sig_type.rb +394 -24
- data/lib/typeprof/core/ast/value.rb +10 -2
- data/lib/typeprof/core/ast/variable.rb +32 -2
- data/lib/typeprof/core/ast.rb +15 -4
- data/lib/typeprof/core/builtin.rb +15 -9
- data/lib/typeprof/core/env/method.rb +21 -16
- data/lib/typeprof/core/env/method_entity.rb +11 -2
- data/lib/typeprof/core/env/module_entity.rb +57 -0
- data/lib/typeprof/core/env/narrowing.rb +131 -0
- data/lib/typeprof/core/env/static_read.rb +9 -8
- data/lib/typeprof/core/env.rb +37 -12
- data/lib/typeprof/core/graph/box.rb +207 -97
- data/lib/typeprof/core/graph/change_set.rb +44 -37
- data/lib/typeprof/core/graph/vertex.rb +4 -21
- data/lib/typeprof/core/service.rb +30 -1
- data/lib/typeprof/core/type.rb +48 -123
- data/lib/typeprof/core.rb +1 -0
- data/lib/typeprof/diagnostic.rb +5 -6
- data/lib/typeprof/lsp/messages.rb +21 -15
- data/lib/typeprof/lsp/server.rb +132 -39
- data/lib/typeprof/lsp/text.rb +1 -0
- data/lib/typeprof/version.rb +1 -1
- data/typeprof.conf.jsonc +22 -0
- data/typeprof.gemspec +1 -0
- metadata +19 -6
data/lib/typeprof/lsp/server.rb
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
require "cgi/escape"
|
|
2
|
+
require "cgi/util" if RUBY_VERSION < "3.5"
|
|
3
|
+
|
|
1
4
|
module TypeProf::LSP
|
|
2
5
|
module ErrorCodes
|
|
3
6
|
ParseError = -32700
|
|
@@ -8,17 +11,17 @@ module TypeProf::LSP
|
|
|
8
11
|
end
|
|
9
12
|
|
|
10
13
|
class Server
|
|
11
|
-
def self.start_stdio(
|
|
14
|
+
def self.start_stdio(core_options)
|
|
12
15
|
$stdin.binmode
|
|
13
16
|
$stdout.binmode
|
|
14
17
|
reader = Reader.new($stdin)
|
|
15
18
|
writer = Writer.new($stdout)
|
|
16
19
|
# pipe all builtin print output to stderr to avoid conflicting with lsp
|
|
17
20
|
$stdout = $stderr
|
|
18
|
-
new(
|
|
21
|
+
new(core_options, reader, writer).run
|
|
19
22
|
end
|
|
20
23
|
|
|
21
|
-
def self.start_socket(
|
|
24
|
+
def self.start_socket(core_options)
|
|
22
25
|
Socket.tcp_server_sockets("localhost", nil) do |servs|
|
|
23
26
|
serv = servs[0].local_address
|
|
24
27
|
$stdout << JSON.generate({
|
|
@@ -35,7 +38,7 @@ module TypeProf::LSP
|
|
|
35
38
|
begin
|
|
36
39
|
reader = Reader.new(sock)
|
|
37
40
|
writer = Writer.new(sock)
|
|
38
|
-
new(
|
|
41
|
+
new(core_options, reader, writer).run
|
|
39
42
|
ensure
|
|
40
43
|
sock.close
|
|
41
44
|
end
|
|
@@ -44,9 +47,9 @@ module TypeProf::LSP
|
|
|
44
47
|
end
|
|
45
48
|
end
|
|
46
49
|
|
|
47
|
-
def initialize(
|
|
48
|
-
@
|
|
49
|
-
@
|
|
50
|
+
def initialize(core_options, reader, writer, url_schema: nil)
|
|
51
|
+
@core_options = core_options
|
|
52
|
+
@cores = {}
|
|
50
53
|
@reader = reader
|
|
51
54
|
@writer = writer
|
|
52
55
|
@request_id = 0
|
|
@@ -56,52 +59,139 @@ module TypeProf::LSP
|
|
|
56
59
|
@exit = false
|
|
57
60
|
@signature_enabled = true
|
|
58
61
|
@url_schema = url_schema || (File::ALT_SEPARATOR != "\\" ? "file://" : "file:///")
|
|
59
|
-
@
|
|
62
|
+
@diagnostic_severity = :error
|
|
60
63
|
end
|
|
61
64
|
|
|
62
|
-
attr_reader :
|
|
65
|
+
attr_reader :open_texts
|
|
63
66
|
attr_accessor :signature_enabled
|
|
64
67
|
|
|
68
|
+
#: (String) -> String
|
|
65
69
|
def path_to_uri(path)
|
|
66
|
-
@url_schema + File.expand_path(path)
|
|
70
|
+
@url_schema + File.expand_path(path).split("/").map {|s| CGI.escapeURIComponent(s) }.join("/")
|
|
67
71
|
end
|
|
68
72
|
|
|
69
|
-
def uri_to_path(
|
|
70
|
-
|
|
73
|
+
def uri_to_path(uri)
|
|
74
|
+
uri.delete_prefix(@url_schema).split("/").map {|s| CGI.unescapeURIComponent(s) }.join("/")
|
|
71
75
|
end
|
|
72
76
|
|
|
77
|
+
#: (Array[String]) -> void
|
|
73
78
|
def add_workspaces(folders)
|
|
74
79
|
folders.each do |path|
|
|
75
|
-
conf_path =
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
80
|
+
conf_path = [".json", ".jsonc"].map do |ext|
|
|
81
|
+
File.join(path, "typeprof.conf" + ext)
|
|
82
|
+
end.find do |path|
|
|
83
|
+
File.readable?(path)
|
|
84
|
+
end
|
|
85
|
+
unless conf_path
|
|
86
|
+
puts "typeprof.conf.json is not found in #{ path }"
|
|
87
|
+
next
|
|
88
|
+
end
|
|
89
|
+
conf = TypeProf::LSP.load_json_with_comments(conf_path, symbolize_names: true)
|
|
90
|
+
if conf
|
|
91
|
+
if conf[:rbs_dir]
|
|
92
|
+
rbs_dir = File.expand_path(conf[:rbs_dir])
|
|
93
|
+
else
|
|
94
|
+
rbs_dir = File.expand_path(File.expand_path("sig", path))
|
|
95
|
+
end
|
|
96
|
+
@rbs_dir = rbs_dir
|
|
97
|
+
if conf[:typeprof_version] == "experimental"
|
|
98
|
+
if conf[:diagnostic_severity]
|
|
99
|
+
severity = conf[:diagnostic_severity].to_sym
|
|
100
|
+
case severity
|
|
101
|
+
when :error, :warning, :info, :hint
|
|
102
|
+
@diagnostic_severity = severity
|
|
103
|
+
else
|
|
104
|
+
puts "unknown severity: #{ severity }"
|
|
87
105
|
end
|
|
88
|
-
else
|
|
89
|
-
puts "Unknown typeprof_version: #{ conf[:typeprof_version] }"
|
|
90
106
|
end
|
|
107
|
+
conf[:analysis_unit_dirs].each do |dir|
|
|
108
|
+
dir = File.expand_path(dir, path)
|
|
109
|
+
core = @cores[dir] = TypeProf::Core::Service.new(@core_options)
|
|
110
|
+
core.add_workspace(dir, @rbs_dir)
|
|
111
|
+
end
|
|
112
|
+
else
|
|
113
|
+
puts "Unknown typeprof_version: #{ conf[:typeprof_version] }"
|
|
91
114
|
end
|
|
92
|
-
else
|
|
93
|
-
puts "typeprof.conf.json is not found"
|
|
94
115
|
end
|
|
95
116
|
end
|
|
96
117
|
end
|
|
97
118
|
|
|
119
|
+
#: (String) -> bool
|
|
98
120
|
def target_path?(path)
|
|
99
|
-
@
|
|
121
|
+
return true if @rbs_dir && path.start_with?(@rbs_dir)
|
|
122
|
+
@cores.each do |folder, _|
|
|
100
123
|
return true if path.start_with?(folder)
|
|
101
124
|
end
|
|
102
125
|
return false
|
|
103
126
|
end
|
|
104
127
|
|
|
128
|
+
def each_core(path)
|
|
129
|
+
@cores.each do |folder, core|
|
|
130
|
+
if path.start_with?(folder) || @rbs_dir && path.start_with?(@rbs_dir)
|
|
131
|
+
yield core
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def aggregate_each_core(path)
|
|
137
|
+
ret = []
|
|
138
|
+
each_core(path) do |core|
|
|
139
|
+
r = yield(core)
|
|
140
|
+
ret.concat(r) if r
|
|
141
|
+
end
|
|
142
|
+
ret
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def update_file(path, text)
|
|
146
|
+
each_core(path) do |core|
|
|
147
|
+
core.update_file(path, text)
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def definitions(path, pos)
|
|
152
|
+
aggregate_each_core(path) do |core|
|
|
153
|
+
core.definitions(path, pos)
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def type_definitions(path, pos)
|
|
158
|
+
aggregate_each_core(path) do |core|
|
|
159
|
+
core.type_definitions(path, pos)
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def references(path, pos)
|
|
164
|
+
aggregate_each_core(path) do |core|
|
|
165
|
+
core.references(path, pos)
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def hover(path, pos)
|
|
170
|
+
ret = []
|
|
171
|
+
each_core(path) do |core|
|
|
172
|
+
ret << core.hover(path, pos)
|
|
173
|
+
end
|
|
174
|
+
ret.compact.first # TODO
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def code_lens(path, &blk)
|
|
178
|
+
each_core(path) do |core|
|
|
179
|
+
core.code_lens(path, &blk)
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def completion(path, trigger, pos, &blk)
|
|
184
|
+
each_core(path) do |core|
|
|
185
|
+
core.completion(path, trigger, pos, &blk)
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def rename(path, pos)
|
|
190
|
+
aggregate_each_core(path) do |core|
|
|
191
|
+
core.rename(path, pos)
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
105
195
|
def run
|
|
106
196
|
@reader.read do |json|
|
|
107
197
|
if json[:method]
|
|
@@ -147,19 +237,22 @@ module TypeProf::LSP
|
|
|
147
237
|
@exit = true
|
|
148
238
|
end
|
|
149
239
|
|
|
150
|
-
def
|
|
151
|
-
|
|
240
|
+
def publish_updated_diagnostics
|
|
241
|
+
@cores.each do |_, core|
|
|
152
242
|
diags = []
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
243
|
+
core.process_diagnostic_paths do |path|
|
|
244
|
+
uri = path_to_uri(path)
|
|
245
|
+
next false unless @open_texts[uri]
|
|
246
|
+
core.diagnostics(path) do |diag|
|
|
247
|
+
diags << diag.to_lsp(severity: @diagnostic_severity)
|
|
156
248
|
end
|
|
249
|
+
send_notification(
|
|
250
|
+
"textDocument/publishDiagnostics",
|
|
251
|
+
uri: uri,
|
|
252
|
+
diagnostics: diags
|
|
253
|
+
)
|
|
254
|
+
true
|
|
157
255
|
end
|
|
158
|
-
send_notification(
|
|
159
|
-
"textDocument/publishDiagnostics",
|
|
160
|
-
uri: uri,
|
|
161
|
-
diagnostics: diags
|
|
162
|
-
)
|
|
163
256
|
end
|
|
164
257
|
end
|
|
165
258
|
end
|
data/lib/typeprof/lsp/text.rb
CHANGED
data/lib/typeprof/version.rb
CHANGED
data/typeprof.conf.jsonc
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// Experimental TypeProf configuration
|
|
2
|
+
|
|
3
|
+
// The format is completely tentative and subject to change
|
|
4
|
+
// (including whether to use JSON with Comments or TOML or Ruby DSL or something else)
|
|
5
|
+
{
|
|
6
|
+
// The version of TypeProf; you need to specify "experimental"
|
|
7
|
+
"typeprof_version": "experimental",
|
|
8
|
+
|
|
9
|
+
// The directory containing RBS files that defines the interface between the analysis units
|
|
10
|
+
"rbs_dir": "sig/",
|
|
11
|
+
|
|
12
|
+
// The directories containing Ruby files to be analyzed by TypeProf
|
|
13
|
+
// Each directory will be independently analyzed
|
|
14
|
+
"analysis_unit_dirs": [
|
|
15
|
+
"lib/typeprof/core/",
|
|
16
|
+
"lib/typeprof/lsp"
|
|
17
|
+
],
|
|
18
|
+
|
|
19
|
+
// Severity of diagnosis, selectable from "error", "warning", "info", "hint", and "none".
|
|
20
|
+
// Currently, TypeProf reports many false positives, so it is recommended to use "hint" or "none".
|
|
21
|
+
"diagnostic_severity": "warning"
|
|
22
|
+
}
|
data/typeprof.gemspec
CHANGED
metadata
CHANGED
|
@@ -1,15 +1,28 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: typeprof
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.31.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Yusuke Endoh
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: prism
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: 1.4.0
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: 1.4.0
|
|
13
26
|
- !ruby/object:Gem::Dependency
|
|
14
27
|
name: rbs
|
|
15
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -64,6 +77,7 @@ files:
|
|
|
64
77
|
- lib/typeprof/core/env/method.rb
|
|
65
78
|
- lib/typeprof/core/env/method_entity.rb
|
|
66
79
|
- lib/typeprof/core/env/module_entity.rb
|
|
80
|
+
- lib/typeprof/core/env/narrowing.rb
|
|
67
81
|
- lib/typeprof/core/env/static_read.rb
|
|
68
82
|
- lib/typeprof/core/env/type_alias_entity.rb
|
|
69
83
|
- lib/typeprof/core/env/value_entity.rb
|
|
@@ -81,6 +95,7 @@ files:
|
|
|
81
95
|
- lib/typeprof/lsp/text.rb
|
|
82
96
|
- lib/typeprof/lsp/util.rb
|
|
83
97
|
- lib/typeprof/version.rb
|
|
98
|
+
- typeprof.conf.jsonc
|
|
84
99
|
- typeprof.gemspec
|
|
85
100
|
homepage: https://github.com/ruby/typeprof
|
|
86
101
|
licenses:
|
|
@@ -88,7 +103,6 @@ licenses:
|
|
|
88
103
|
metadata:
|
|
89
104
|
homepage_uri: https://github.com/ruby/typeprof
|
|
90
105
|
source_code_uri: https://github.com/ruby/typeprof
|
|
91
|
-
post_install_message:
|
|
92
106
|
rdoc_options: []
|
|
93
107
|
require_paths:
|
|
94
108
|
- lib
|
|
@@ -103,8 +117,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
103
117
|
- !ruby/object:Gem::Version
|
|
104
118
|
version: '0'
|
|
105
119
|
requirements: []
|
|
106
|
-
rubygems_version: 3.
|
|
107
|
-
signing_key:
|
|
120
|
+
rubygems_version: 3.6.9
|
|
108
121
|
specification_version: 4
|
|
109
122
|
summary: TypeProf is a type analysis tool for Ruby code based on abstract interpretation
|
|
110
123
|
test_files: []
|