typeprof 0.30.0 → 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/doc/doc.ja.md +1 -1
- data/lib/typeprof/cli/cli.rb +28 -10
- data/lib/typeprof/cli.rb +1 -0
- data/lib/typeprof/code_range.rb +9 -7
- data/lib/typeprof/core/ast/base.rb +27 -10
- data/lib/typeprof/core/ast/call.rb +90 -21
- data/lib/typeprof/core/ast/const.rb +7 -12
- data/lib/typeprof/core/ast/control.rb +349 -74
- data/lib/typeprof/core/ast/meta.rb +5 -5
- data/lib/typeprof/core/ast/method.rb +19 -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 +11 -3
- 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 +43 -12
- data/lib/typeprof/core/graph/box.rb +218 -101
- data/lib/typeprof/core/graph/change_set.rb +44 -37
- data/lib/typeprof/core/graph/vertex.rb +7 -21
- data/lib/typeprof/core/service.rb +61 -40
- data/lib/typeprof/core/type.rb +52 -123
- data/lib/typeprof/core.rb +1 -1
- data/lib/typeprof/diagnostic.rb +5 -6
- data/lib/typeprof/lsp/messages.rb +27 -36
- data/lib/typeprof/lsp/server.rb +144 -25
- data/lib/typeprof/lsp/text.rb +1 -0
- data/lib/typeprof/lsp/util.rb +0 -10
- data/lib/typeprof/version.rb +1 -1
- data/typeprof.conf.jsonc +22 -0
- data/typeprof.gemspec +1 -0
- metadata +19 -5
- data/lib/typeprof/core/graph.rb +0 -3
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
|
|
@@ -55,43 +58,140 @@ module TypeProf::LSP
|
|
|
55
58
|
@open_texts = {}
|
|
56
59
|
@exit = false
|
|
57
60
|
@signature_enabled = true
|
|
61
|
+
@url_schema = url_schema || (File::ALT_SEPARATOR != "\\" ? "file://" : "file:///")
|
|
62
|
+
@diagnostic_severity = :error
|
|
58
63
|
end
|
|
59
64
|
|
|
60
|
-
attr_reader :
|
|
65
|
+
attr_reader :open_texts
|
|
61
66
|
attr_accessor :signature_enabled
|
|
62
67
|
|
|
68
|
+
#: (String) -> String
|
|
69
|
+
def path_to_uri(path)
|
|
70
|
+
@url_schema + File.expand_path(path).split("/").map {|s| CGI.escapeURIComponent(s) }.join("/")
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def uri_to_path(uri)
|
|
74
|
+
uri.delete_prefix(@url_schema).split("/").map {|s| CGI.unescapeURIComponent(s) }.join("/")
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
#: (Array[String]) -> void
|
|
63
78
|
def add_workspaces(folders)
|
|
64
79
|
folders.each do |path|
|
|
65
|
-
conf_path =
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
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 }"
|
|
77
105
|
end
|
|
78
|
-
else
|
|
79
|
-
puts "Unknown typeprof_version: #{ conf[:typeprof_version] }"
|
|
80
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] }"
|
|
81
114
|
end
|
|
82
|
-
else
|
|
83
|
-
puts "typeprof.conf.json is not found"
|
|
84
115
|
end
|
|
85
116
|
end
|
|
86
117
|
end
|
|
87
118
|
|
|
119
|
+
#: (String) -> bool
|
|
88
120
|
def target_path?(path)
|
|
89
|
-
@
|
|
121
|
+
return true if @rbs_dir && path.start_with?(@rbs_dir)
|
|
122
|
+
@cores.each do |folder, _|
|
|
90
123
|
return true if path.start_with?(folder)
|
|
91
124
|
end
|
|
92
125
|
return false
|
|
93
126
|
end
|
|
94
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
|
+
|
|
95
195
|
def run
|
|
96
196
|
@reader.read do |json|
|
|
97
197
|
if json[:method]
|
|
@@ -136,6 +236,25 @@ module TypeProf::LSP
|
|
|
136
236
|
def exit
|
|
137
237
|
@exit = true
|
|
138
238
|
end
|
|
239
|
+
|
|
240
|
+
def publish_updated_diagnostics
|
|
241
|
+
@cores.each do |_, core|
|
|
242
|
+
diags = []
|
|
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)
|
|
248
|
+
end
|
|
249
|
+
send_notification(
|
|
250
|
+
"textDocument/publishDiagnostics",
|
|
251
|
+
uri: uri,
|
|
252
|
+
diagnostics: diags
|
|
253
|
+
)
|
|
254
|
+
true
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
end
|
|
139
258
|
end
|
|
140
259
|
|
|
141
260
|
class Reader
|
data/lib/typeprof/lsp/text.rb
CHANGED
data/lib/typeprof/lsp/util.rb
CHANGED
|
@@ -48,14 +48,4 @@ module TypeProf::LSP
|
|
|
48
48
|
|
|
49
49
|
JSON.parse(json, **opts)
|
|
50
50
|
end
|
|
51
|
-
|
|
52
|
-
FILE_URL_PREFIX = File::ALT_SEPARATOR != "\\" ? "file://" : "file:///"
|
|
53
|
-
|
|
54
|
-
def self.file_path_to_uri(path)
|
|
55
|
-
FILE_URL_PREFIX + File.expand_path(path)
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def self.file_uri_to_path(url)
|
|
59
|
-
url.delete_prefix(FILE_URL_PREFIX)
|
|
60
|
-
end
|
|
61
51
|
end
|
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
|
-
original_platform: ''
|
|
7
6
|
authors:
|
|
8
7
|
- Yusuke Endoh
|
|
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,10 +77,10 @@ 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
|
|
70
|
-
- lib/typeprof/core/graph.rb
|
|
71
84
|
- lib/typeprof/core/graph/box.rb
|
|
72
85
|
- lib/typeprof/core/graph/change_set.rb
|
|
73
86
|
- lib/typeprof/core/graph/filter.rb
|
|
@@ -82,6 +95,7 @@ files:
|
|
|
82
95
|
- lib/typeprof/lsp/text.rb
|
|
83
96
|
- lib/typeprof/lsp/util.rb
|
|
84
97
|
- lib/typeprof/version.rb
|
|
98
|
+
- typeprof.conf.jsonc
|
|
85
99
|
- typeprof.gemspec
|
|
86
100
|
homepage: https://github.com/ruby/typeprof
|
|
87
101
|
licenses:
|
|
@@ -103,7 +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.6.
|
|
120
|
+
rubygems_version: 3.6.9
|
|
107
121
|
specification_version: 4
|
|
108
122
|
summary: TypeProf is a type analysis tool for Ruby code based on abstract interpretation
|
|
109
123
|
test_files: []
|
data/lib/typeprof/core/graph.rb
DELETED