typeprof 0.21.6 → 0.21.8
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/.github/workflows/main.yml +1 -1
- data/.gitignore +0 -1
- data/Gemfile.lock +2 -2
- data/lib/typeprof/analyzer.rb +52 -33
- data/lib/typeprof/cli.rb +14 -5
- data/lib/typeprof/import.rb +1 -1
- data/lib/typeprof/lsp.rb +22 -0
- data/lib/typeprof/method.rb +11 -0
- data/lib/typeprof/version.rb +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 71c74382cb8602ed9c902218ec5066d20865cc8040e5af6737e8d8a0d19beca9
|
4
|
+
data.tar.gz: 2646a63cd334443a8dc716f99a5828fac960afdf80f8a0f8c8b5f289e6fb957d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c0ca22252a4804152efafafb63c9c8d1d1fb2e796a9d17251f1634dc1393c7fcaac7f924d4a341a0699c5113c3fea8bb03714ceb287ded60bc7057cac7a640c
|
7
|
+
data.tar.gz: 899c481fc8a4a05787ab0e66064220b33b17f8f1f0f045b9a1d05d4ebdae1ea4cd62cfe552342588b5a2834491638303be5a2e05c4b00d99713fe4693a6c557a
|
data/.github/workflows/main.yml
CHANGED
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
typeprof (0.21.
|
4
|
+
typeprof (0.21.8)
|
5
5
|
rbs (>= 1.8.1)
|
6
6
|
|
7
7
|
GEM
|
@@ -11,7 +11,7 @@ GEM
|
|
11
11
|
docile (1.4.0)
|
12
12
|
power_assert (2.0.1)
|
13
13
|
rake (13.0.1)
|
14
|
-
rbs (3.0
|
14
|
+
rbs (3.2.0)
|
15
15
|
simplecov (0.21.2)
|
16
16
|
docile (~> 1.1)
|
17
17
|
simplecov-html (~> 0.11)
|
data/lib/typeprof/analyzer.rb
CHANGED
@@ -2231,6 +2231,34 @@ module TypeProf
|
|
2231
2231
|
merge_env(ep.next, env)
|
2232
2232
|
end
|
2233
2233
|
|
2234
|
+
private def ruby_3_3_keywords?
|
2235
|
+
@ruby_3_3_keywords ||=
|
2236
|
+
RubyVM::InstructionSequence.compile("foo(*a, **b)").to_a.last[-2][1][:orig_argc] == 2
|
2237
|
+
end
|
2238
|
+
|
2239
|
+
private def type_to_keywords(ty, ep)
|
2240
|
+
case ty
|
2241
|
+
when Type::Hash
|
2242
|
+
ty.elems.to_keywords
|
2243
|
+
when Type::Union
|
2244
|
+
hash_elems = nil
|
2245
|
+
ty.elems&.each do |(container_kind, base_type), elems|
|
2246
|
+
if container_kind == Type::Hash
|
2247
|
+
elems.to_keywords
|
2248
|
+
hash_elems = hash_elems ? hash_elems.union(elems) : elems
|
2249
|
+
end
|
2250
|
+
end
|
2251
|
+
if hash_elems
|
2252
|
+
hash_elems.to_keywords
|
2253
|
+
else
|
2254
|
+
{ nil => Type.any }
|
2255
|
+
end
|
2256
|
+
else
|
2257
|
+
warn(ep, "non hash is passed to **kwarg?") unless ty == Type.any
|
2258
|
+
{ nil => Type.any }
|
2259
|
+
end
|
2260
|
+
end
|
2261
|
+
|
2234
2262
|
private def setup_actual_arguments(kind, operands, ep, env)
|
2235
2263
|
opt, blk_iseq = operands
|
2236
2264
|
flags = opt[:flag]
|
@@ -2245,7 +2273,7 @@ module TypeProf
|
|
2245
2273
|
_flag_args_fcall = flags[ 2] != 0
|
2246
2274
|
_flag_args_vcall = flags[ 3] != 0
|
2247
2275
|
_flag_args_simple = flags[ 4] != 0 # unused in TP
|
2248
|
-
|
2276
|
+
flags <<= 1 if RUBY_VERSION >= "3.3" # blockiseq flag was removed in 3.3
|
2249
2277
|
flag_args_kwarg = flags[ 6] != 0
|
2250
2278
|
flag_args_kw_splat = flags[ 7] != 0
|
2251
2279
|
_flag_tailcall = flags[ 8] != 0
|
@@ -2284,42 +2312,33 @@ module TypeProf
|
|
2284
2312
|
blk_ty = new_blk_ty
|
2285
2313
|
|
2286
2314
|
if flag_args_splat
|
2287
|
-
|
2288
|
-
|
2289
|
-
|
2290
|
-
|
2291
|
-
|
2292
|
-
|
2293
|
-
|
2294
|
-
|
2295
|
-
|
2296
|
-
|
2297
|
-
|
2298
|
-
|
2299
|
-
|
2300
|
-
|
2301
|
-
|
2302
|
-
|
2303
|
-
|
2304
|
-
|
2305
|
-
|
2306
|
-
|
2307
|
-
|
2308
|
-
end
|
2309
|
-
if hash_elems
|
2310
|
-
kw_tys = hash_elems.to_keywords
|
2311
|
-
else
|
2312
|
-
kw_tys = { nil => Type.any }
|
2313
|
-
end
|
2315
|
+
if ruby_3_3_keywords?
|
2316
|
+
if flag_args_kw_splat
|
2317
|
+
kw_tys = type_to_keywords(globalize_type(aargs[-1], env, ep), ep)
|
2318
|
+
aargs = aargs[0..-2]
|
2319
|
+
else
|
2320
|
+
kw_tys = {}
|
2321
|
+
end
|
2322
|
+
rest_ty = aargs.last
|
2323
|
+
aargs = aargs[0..-2]
|
2324
|
+
else
|
2325
|
+
rest_ty = aargs.last
|
2326
|
+
aargs = aargs[0..-2]
|
2327
|
+
if flag_args_kw_splat
|
2328
|
+
# XXX: The types contained in ActualArguments are expected to be all local types.
|
2329
|
+
# This "globalize_type" breaks the invariant, and violates the assertion of Union#globalize that asserts @elems be nil.
|
2330
|
+
# To fix this issue fundamentally, ActualArguments should keep all arguments as-is (as like the VM does),
|
2331
|
+
# and globalize some types on the on-demand bases.
|
2332
|
+
ty = globalize_type(rest_ty, env, ep)
|
2333
|
+
if ty.is_a?(Type::Array)
|
2334
|
+
_, (ty,) = ty.elems.take_last(1)
|
2335
|
+
kw_tys = type_to_keywords(ty, ep)
|
2314
2336
|
else
|
2315
|
-
|
2316
|
-
kw_tys = { nil => Type.any }
|
2337
|
+
raise NotImplementedError
|
2317
2338
|
end
|
2318
2339
|
else
|
2319
|
-
|
2340
|
+
kw_tys = {}
|
2320
2341
|
end
|
2321
|
-
else
|
2322
|
-
kw_tys = {}
|
2323
2342
|
end
|
2324
2343
|
aargs = ActualArguments.new(aargs, rest_ty, kw_tys, blk_ty)
|
2325
2344
|
elsif flag_args_kw_splat
|
data/lib/typeprof/cli.rb
CHANGED
@@ -23,7 +23,8 @@ module TypeProf
|
|
23
23
|
gem_rbs_features = []
|
24
24
|
show_version = false
|
25
25
|
max_sec = max_iter = nil
|
26
|
-
collection_path =
|
26
|
+
collection_path = nil
|
27
|
+
no_collection = false
|
27
28
|
|
28
29
|
load_path_ext = []
|
29
30
|
|
@@ -35,8 +36,8 @@ module TypeProf
|
|
35
36
|
opt.on("--version", "Display typeprof version") { show_version = true }
|
36
37
|
opt.on("-I DIR", "Add DIR to the load/require path") {|v| load_path_ext << v }
|
37
38
|
opt.on("-r FEATURE", "Require RBS of the FEATURE gem") {|v| gem_rbs_features << v }
|
38
|
-
opt.on("--collection PATH", "File path of collection configuration") { |v| collection_path = v }
|
39
|
-
opt.on("--no-collection", "Ignore collection configuration") {
|
39
|
+
opt.on("--collection PATH", "File path of collection configuration") { |v| collection_path = Pathname(v) }
|
40
|
+
opt.on("--no-collection", "Ignore collection configuration") { no_collection = true }
|
40
41
|
opt.on("--lsp", "LSP mode") {|v| options[:lsp] = true }
|
41
42
|
|
42
43
|
opt.separator ""
|
@@ -104,6 +105,14 @@ module TypeProf
|
|
104
105
|
raise OptionParser::InvalidOption.new("lsp options with non-lsp mode")
|
105
106
|
end
|
106
107
|
|
108
|
+
if !no_collection && collection_path && !collection_path.exist?
|
109
|
+
exit if show_version
|
110
|
+
raise OptionParser::InvalidOption.new("collection path not found (#{collection_path})")
|
111
|
+
end
|
112
|
+
|
113
|
+
collection_path ||= RBS::Collection::Config::PATH
|
114
|
+
collection_path = nil if no_collection
|
115
|
+
|
107
116
|
ConfigData.new(
|
108
117
|
rb_files: rb_files,
|
109
118
|
rbs_files: rbs_files,
|
@@ -118,9 +127,9 @@ module TypeProf
|
|
118
127
|
lsp_options: lsp_options,
|
119
128
|
)
|
120
129
|
|
121
|
-
rescue OptionParser::InvalidOption
|
130
|
+
rescue OptionParser::InvalidOption, OptionParser::MissingArgument
|
122
131
|
puts $!
|
123
|
-
exit
|
132
|
+
exit 1
|
124
133
|
end
|
125
134
|
end
|
126
135
|
end
|
data/lib/typeprof/import.rb
CHANGED
@@ -31,7 +31,7 @@ module TypeProf
|
|
31
31
|
lock_path = RBS::Collection::Config.to_lockfile_path(collection_path)
|
32
32
|
if lock_path.exist?
|
33
33
|
collection_lock = RBS::Collection::Config::Lockfile.from_lockfile(lockfile_path: lock_path, data: YAML.load_file(lock_path.to_s))
|
34
|
-
collection_lock.gems.
|
34
|
+
collection_lock.gems.each_value {|gem| @loaded_gems << gem[:name] }
|
35
35
|
loader.add_collection(collection_lock)
|
36
36
|
else
|
37
37
|
raise "Please execute 'rbs collection install'"
|
data/lib/typeprof/lsp.rb
CHANGED
@@ -352,6 +352,7 @@ module TypeProf
|
|
352
352
|
}
|
353
353
|
end
|
354
354
|
|
355
|
+
@server.send_notification('typeprof.enableToggleButton')
|
355
356
|
@server.send_request("workspace/codeLens/refresh")
|
356
357
|
|
357
358
|
@server.send_notification(
|
@@ -827,6 +828,13 @@ module TypeProf
|
|
827
828
|
end
|
828
829
|
end
|
829
830
|
|
831
|
+
module MessageType
|
832
|
+
Error = 1
|
833
|
+
Warning = 2
|
834
|
+
Info = 3
|
835
|
+
Log = 4
|
836
|
+
end
|
837
|
+
|
830
838
|
class Server
|
831
839
|
class Exit < StandardError; end
|
832
840
|
|
@@ -861,6 +869,20 @@ module TypeProf
|
|
861
869
|
end
|
862
870
|
end
|
863
871
|
rescue Exit
|
872
|
+
rescue => e
|
873
|
+
msg = "Tyeprof fatal error: #{e.message}"
|
874
|
+
send_notification(
|
875
|
+
'window/showMessage',
|
876
|
+
type: MessageType::Error,
|
877
|
+
message: msg
|
878
|
+
)
|
879
|
+
send_notification(
|
880
|
+
'window/logMessage',
|
881
|
+
type: MessageType::Error,
|
882
|
+
message: "#{msg} Backtrace: #{e.backtrace}"
|
883
|
+
)
|
884
|
+
send_notification('typeprof.showErrorStatus')
|
885
|
+
retry
|
864
886
|
end
|
865
887
|
|
866
888
|
def send_response(**msg)
|
data/lib/typeprof/method.rb
CHANGED
@@ -117,6 +117,12 @@ module TypeProf
|
|
117
117
|
ty = Type::Array.new(Type::Array::Elements.new([], msig.rest_ty), Type::Instance.new(Type::Builtin[:ary]))
|
118
118
|
ty = ty.substitute(cur_subst, Config.current.options[:type_depth_limit]).remove_type_vars
|
119
119
|
nenv, rest_ty = scratch.localize_type(ty, nenv, callee_ep, alloc_site2)
|
120
|
+
# TODO: handle a case where rest_start is not found
|
121
|
+
nenv = nenv.local_update(rest_start, rest_ty)
|
122
|
+
elsif rest_start
|
123
|
+
alloc_site2 = alloc_site.add_id(idx += 1)
|
124
|
+
ty = Type::Array.new(Type::Array::Elements.new([], Type.any), Type::Instance.new(Type::Builtin[:ary]))
|
125
|
+
nenv, rest_ty = scratch.localize_type(ty, nenv, callee_ep, alloc_site2)
|
120
126
|
nenv = nenv.local_update(rest_start, rest_ty)
|
121
127
|
end
|
122
128
|
if msig.post_tys
|
@@ -146,6 +152,11 @@ module TypeProf
|
|
146
152
|
ty = ty.substitute(cur_subst, Config.current.options[:type_depth_limit]).remove_type_vars
|
147
153
|
nenv, ty = scratch.localize_type(ty, nenv, callee_ep, alloc_site2)
|
148
154
|
nenv = nenv.local_update(kw_rest, ty)
|
155
|
+
elsif kw_rest
|
156
|
+
alloc_site2 = alloc_site.add_id(:**)
|
157
|
+
ty = Type.gen_hash {}
|
158
|
+
nenv, ty = scratch.localize_type(ty, nenv, callee_ep, alloc_site2)
|
159
|
+
nenv = nenv.local_update(kw_rest, ty)
|
149
160
|
end
|
150
161
|
nenv = nenv.local_update(block_start, msig.blk_ty) if block_start
|
151
162
|
|
data/lib/typeprof/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: typeprof
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.21.
|
4
|
+
version: 0.21.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yusuke Endoh
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-08-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rbs
|
@@ -74,7 +74,7 @@ licenses:
|
|
74
74
|
metadata:
|
75
75
|
homepage_uri: https://github.com/ruby/typeprof
|
76
76
|
source_code_uri: https://github.com/ruby/typeprof
|
77
|
-
post_install_message:
|
77
|
+
post_install_message:
|
78
78
|
rdoc_options: []
|
79
79
|
require_paths:
|
80
80
|
- lib
|
@@ -90,7 +90,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
90
90
|
version: '0'
|
91
91
|
requirements: []
|
92
92
|
rubygems_version: 3.5.0.dev
|
93
|
-
signing_key:
|
93
|
+
signing_key:
|
94
94
|
specification_version: 4
|
95
95
|
summary: TypeProf is a type analysis tool for Ruby code based on abstract interpretation
|
96
96
|
test_files: []
|