typeprof 0.15.3 → 0.20.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/.github/workflows/main.yml +1 -1
- data/Gemfile.lock +4 -4
- data/exe/typeprof +5 -1
- data/lib/typeprof/analyzer.rb +228 -54
- data/lib/typeprof/arguments.rb +1 -0
- data/lib/typeprof/builtin.rb +23 -23
- data/lib/typeprof/cli.rb +22 -2
- data/lib/typeprof/code-range.rb +177 -0
- data/lib/typeprof/config.rb +43 -18
- data/lib/typeprof/container-type.rb +3 -0
- data/lib/typeprof/export.rb +191 -15
- data/lib/typeprof/import.rb +25 -4
- data/lib/typeprof/iseq.rb +218 -16
- data/lib/typeprof/lsp.rb +865 -0
- data/lib/typeprof/method.rb +15 -11
- data/lib/typeprof/type.rb +46 -38
- data/lib/typeprof/utils.rb +18 -1
- data/lib/typeprof/version.rb +1 -1
- data/lib/typeprof.rb +3 -0
- data/typeprof-lsp +3 -0
- data/typeprof.gemspec +1 -1
- data/vscode/.gitignore +5 -0
- data/vscode/.vscode/launch.json +16 -0
- data/vscode/.vscodeignore +7 -0
- data/vscode/README.md +22 -0
- data/vscode/development.md +31 -0
- data/vscode/package-lock.json +2211 -0
- data/vscode/package.json +71 -0
- data/vscode/sandbox/test.rb +24 -0
- data/vscode/src/extension.ts +285 -0
- data/vscode/tsconfig.json +15 -0
- metadata +18 -5
data/lib/typeprof/method.rb
CHANGED
@@ -14,6 +14,8 @@ module TypeProf
|
|
14
14
|
@pub_meth = pub_meth
|
15
15
|
end
|
16
16
|
|
17
|
+
attr_reader :iseq
|
18
|
+
|
17
19
|
def do_send(recv, mid, aargs, caller_ep, caller_env, scratch, &ctn)
|
18
20
|
recv = recv.base_type while recv.respond_to?(:base_type)
|
19
21
|
recv = scratch.globalize_type(recv, caller_env, caller_ep)
|
@@ -35,7 +37,7 @@ module TypeProf
|
|
35
37
|
locals.each_with_index do |ty, i|
|
36
38
|
alloc_site2 = alloc_site.add_id(i)
|
37
39
|
# nenv is top-level, so it is okay to call Type#localize directly
|
38
|
-
nenv, ty = ty.localize(nenv, alloc_site2, Config.options[:type_depth_limit])
|
40
|
+
nenv, ty = ty.localize(nenv, alloc_site2, Config.current.options[:type_depth_limit])
|
39
41
|
nenv = nenv.local_update(i, ty)
|
40
42
|
end
|
41
43
|
|
@@ -95,14 +97,14 @@ module TypeProf
|
|
95
97
|
idx = 0
|
96
98
|
msig.lead_tys.each_with_index do |ty, i|
|
97
99
|
alloc_site2 = alloc_site.add_id(idx += 1)
|
98
|
-
ty = ty.substitute(cur_subst, Config.options[:type_depth_limit]).remove_type_vars
|
100
|
+
ty = ty.substitute(cur_subst, Config.current.options[:type_depth_limit]).remove_type_vars
|
99
101
|
nenv, ty = scratch.localize_type(ty, nenv, callee_ep, alloc_site2)
|
100
102
|
nenv = nenv.local_update(i, ty)
|
101
103
|
end
|
102
104
|
if msig.opt_tys
|
103
105
|
msig.opt_tys.each_with_index do |ty, i|
|
104
106
|
alloc_site2 = alloc_site.add_id(idx += 1)
|
105
|
-
ty = ty.substitute(cur_subst, Config.options[:type_depth_limit]).remove_type_vars
|
107
|
+
ty = ty.substitute(cur_subst, Config.current.options[:type_depth_limit]).remove_type_vars
|
106
108
|
nenv, ty = scratch.localize_type(ty, nenv, callee_ep, alloc_site2)
|
107
109
|
nenv = nenv.local_update(lead_num + i, ty)
|
108
110
|
end
|
@@ -110,14 +112,14 @@ module TypeProf
|
|
110
112
|
if msig.rest_ty
|
111
113
|
alloc_site2 = alloc_site.add_id(idx += 1)
|
112
114
|
ty = Type::Array.new(Type::Array::Elements.new([], msig.rest_ty), Type::Instance.new(Type::Builtin[:ary]))
|
113
|
-
ty = ty.substitute(cur_subst, Config.options[:type_depth_limit]).remove_type_vars
|
115
|
+
ty = ty.substitute(cur_subst, Config.current.options[:type_depth_limit]).remove_type_vars
|
114
116
|
nenv, rest_ty = scratch.localize_type(ty, nenv, callee_ep, alloc_site2)
|
115
117
|
nenv = nenv.local_update(rest_start, rest_ty)
|
116
118
|
end
|
117
119
|
if msig.post_tys
|
118
120
|
msig.post_tys.each_with_index do |ty, i|
|
119
121
|
alloc_site2 = alloc_site.add_id(idx += 1)
|
120
|
-
ty = ty.substitute(cur_subst, Config.options[:type_depth_limit]).remove_type_vars
|
122
|
+
ty = ty.substitute(cur_subst, Config.current.options[:type_depth_limit]).remove_type_vars
|
121
123
|
nenv, ty = scratch.localize_type(ty, nenv, callee_ep, alloc_site2)
|
122
124
|
nenv = nenv.local_update(post_start + i, ty)
|
123
125
|
end
|
@@ -130,7 +132,7 @@ module TypeProf
|
|
130
132
|
next
|
131
133
|
end
|
132
134
|
alloc_site2 = alloc_site.add_id(key)
|
133
|
-
ty = ty.substitute(cur_subst, Config.options[:type_depth_limit]).remove_type_vars
|
135
|
+
ty = ty.substitute(cur_subst, Config.current.options[:type_depth_limit]).remove_type_vars
|
134
136
|
nenv, ty = scratch.localize_type(ty, nenv, callee_ep, alloc_site2)
|
135
137
|
nenv = nenv.local_update(kw_start + i, ty)
|
136
138
|
end
|
@@ -138,7 +140,7 @@ module TypeProf
|
|
138
140
|
if msig.kw_rest_ty
|
139
141
|
ty = msig.kw_rest_ty
|
140
142
|
alloc_site2 = alloc_site.add_id(:**)
|
141
|
-
ty = ty.substitute(cur_subst, Config.options[:type_depth_limit]).remove_type_vars
|
143
|
+
ty = ty.substitute(cur_subst, Config.current.options[:type_depth_limit]).remove_type_vars
|
142
144
|
nenv, ty = scratch.localize_type(ty, nenv, callee_ep, alloc_site2)
|
143
145
|
nenv = nenv.local_update(kw_rest, ty)
|
144
146
|
end
|
@@ -209,9 +211,10 @@ module TypeProf
|
|
209
211
|
@sig_rets = sig_rets
|
210
212
|
@rbs_source = rbs_source
|
211
213
|
@pub_meth = pub_meth
|
214
|
+
@iseq = nil
|
212
215
|
end
|
213
216
|
|
214
|
-
attr_reader :rbs_source
|
217
|
+
attr_reader :rbs_source, :iseq
|
215
218
|
|
216
219
|
def do_send(recv_orig, mid, aargs, caller_ep, caller_env, scratch, &ctn)
|
217
220
|
recv = scratch.globalize_type(recv_orig, caller_env, caller_ep)
|
@@ -254,7 +257,7 @@ module TypeProf
|
|
254
257
|
bsig = msig.blk_ty.block_body.msig
|
255
258
|
alloc_site = AllocationSite.new(caller_ep).add_id(self)
|
256
259
|
nlead_tys = (bsig.lead_tys + bsig.opt_tys).map.with_index do |ty, i|
|
257
|
-
ty = ty.substitute(subst, Config.options[:type_depth_limit]).remove_type_vars
|
260
|
+
ty = ty.substitute(subst, Config.current.options[:type_depth_limit]).remove_type_vars
|
258
261
|
dummy_env, ty = scratch.localize_type(ty, dummy_env, dummy_ep, alloc_site.add_id(i))
|
259
262
|
ty
|
260
263
|
end
|
@@ -268,7 +271,7 @@ module TypeProf
|
|
268
271
|
ncaller_env = recv_orig.update_container_elem_type(subst2, ncaller_env, caller_ep, scratch)
|
269
272
|
scratch.merge_return_env(caller_ep) {|env| env ? env.merge(ncaller_env) : ncaller_env }
|
270
273
|
end
|
271
|
-
ret_ty2 = ret_ty.substitute(subst2, Config.options[:type_depth_limit]).remove_type_vars
|
274
|
+
ret_ty2 = ret_ty.substitute(subst2, Config.current.options[:type_depth_limit]).remove_type_vars
|
272
275
|
else
|
273
276
|
ret_ty2 = Type.any
|
274
277
|
end
|
@@ -286,7 +289,7 @@ module TypeProf
|
|
286
289
|
ctn[ret_ty, caller_ep, ncaller_env] if ret_ty != Type.bot
|
287
290
|
end
|
288
291
|
else
|
289
|
-
ret_ty = ret_ty.substitute(subst, Config.options[:type_depth_limit])
|
292
|
+
ret_ty = ret_ty.substitute(subst, Config.current.options[:type_depth_limit])
|
290
293
|
ret_ty = ret_ty.remove_type_vars
|
291
294
|
ctn[ret_ty, caller_ep, ncaller_env] if ret_ty != Type.bot
|
292
295
|
end
|
@@ -303,6 +306,7 @@ module TypeProf
|
|
303
306
|
@sig_rets.each do |msig, _ret_ty|
|
304
307
|
iseq_mdef.do_check_send(msig, recv, mid, ep, scratch)
|
305
308
|
end
|
309
|
+
@iseq ||= iseq_mdef.iseq
|
306
310
|
end
|
307
311
|
end
|
308
312
|
|
data/lib/typeprof/type.rb
CHANGED
@@ -168,7 +168,7 @@ module TypeProf
|
|
168
168
|
end
|
169
169
|
|
170
170
|
def remove_type_vars
|
171
|
-
substitute(DummySubstitution, Config.options[:type_depth_limit])
|
171
|
+
substitute(DummySubstitution, Config.current.options[:type_depth_limit])
|
172
172
|
end
|
173
173
|
|
174
174
|
def include_untyped?(_scratch)
|
@@ -239,7 +239,7 @@ module TypeProf
|
|
239
239
|
non_class_instances << ty
|
240
240
|
end
|
241
241
|
end
|
242
|
-
if (Config.options[:union_width_limit] >= 2 && class_instances.size >= Config.options[:union_width_limit]) || (degenerated && class_instances.size >= 2)
|
242
|
+
if (Config.current.options[:union_width_limit] >= 2 && class_instances.size >= Config.current.options[:union_width_limit]) || (degenerated && class_instances.size >= 2)
|
243
243
|
create(Utils::Set[Instance.new_degenerate(class_instances), *non_class_instances], elems)
|
244
244
|
else
|
245
245
|
new(tys, elems)
|
@@ -322,7 +322,7 @@ module TypeProf
|
|
322
322
|
types.delete(Type::Instance.new(Type::Builtin[:true]))
|
323
323
|
bool = true
|
324
324
|
end
|
325
|
-
types.delete(Type.any) unless Config.options[:show_untyped]
|
325
|
+
types.delete(Type.any) unless Config.current.options[:show_untyped]
|
326
326
|
proc_tys, types = types.partition {|ty| ty.is_a?(Proc) }
|
327
327
|
types = types.map {|ty| ty.screen_name(scratch) }
|
328
328
|
types << scratch.show_proc_signature(proc_tys) unless proc_tys.empty?
|
@@ -339,9 +339,6 @@ module TypeProf
|
|
339
339
|
types.join (" | ")
|
340
340
|
end
|
341
341
|
end
|
342
|
-
rescue SystemStackError
|
343
|
-
p self
|
344
|
-
raise
|
345
342
|
end
|
346
343
|
|
347
344
|
def globalize(env, visited, depth)
|
@@ -786,7 +783,7 @@ module TypeProf
|
|
786
783
|
when ::Hash
|
787
784
|
Type.gen_hash do |h|
|
788
785
|
obj.each do |k, v|
|
789
|
-
k_ty = guess_literal_type(k).globalize(nil, {}, Config.options[:type_depth_limit])
|
786
|
+
k_ty = guess_literal_type(k).globalize(nil, {}, Config.current.options[:type_depth_limit])
|
790
787
|
v_ty = guess_literal_type(v)
|
791
788
|
h[k_ty] = v_ty
|
792
789
|
end
|
@@ -854,33 +851,46 @@ module TypeProf
|
|
854
851
|
include Utils::StructuralEquality
|
855
852
|
|
856
853
|
def screen_name(iseq, scratch)
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
|
854
|
+
fargs_str = "("
|
855
|
+
sig_help = {}
|
856
|
+
add_farg = -> farg, name, help: false, key: sig_help.size do
|
857
|
+
name = "`#{ name }`" if RBS::Parser::KEYWORDS.key?(name.to_s)
|
858
|
+
name = "noname_#{ name }" if name.is_a?(Integer)
|
859
|
+
fargs_str << ", " if fargs_str != "("
|
860
|
+
i = fargs_str.size
|
861
|
+
fargs_str << (Config.current.options[:show_parameter_names] && name ? "#{ farg } #{ name }" : farg)
|
862
|
+
sig_help[key] = (i...fargs_str.size)
|
863
863
|
end
|
864
|
+
|
865
|
+
@lead_tys.zip(iseq ? iseq.locals : []) do |ty, name|
|
866
|
+
add_farg.call(ty.screen_name(scratch), name, help: true)
|
867
|
+
end
|
868
|
+
|
869
|
+
@opt_tys&.zip(iseq ? iseq.locals[@lead_tys.size, @opt_tys.size] : []) do |ty, name|
|
870
|
+
add_farg.call("?" + ty.screen_name(scratch), name, help: true)
|
871
|
+
end
|
872
|
+
|
864
873
|
if @rest_ty
|
865
|
-
fargs << ("*" + @rest_ty.screen_name(scratch))
|
866
874
|
if iseq
|
867
875
|
rest_index = iseq.fargs_format[:rest_start]
|
868
|
-
|
876
|
+
name = rest_index ? iseq.locals[rest_index] : nil
|
869
877
|
end
|
878
|
+
add_farg.call("*" + @rest_ty.screen_name(scratch), name)
|
870
879
|
end
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
farg_names += (post_start ? iseq.locals[post_start, @post_tys.size] : [nil] * @post_tys.size)
|
876
|
-
end
|
880
|
+
|
881
|
+
if iseq
|
882
|
+
post_start = iseq.fargs_format[:post_start]
|
883
|
+
names = post_start ? iseq.locals[post_start, @post_tys.size] : []
|
877
884
|
end
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
885
|
+
@post_tys&.zip(names || []) do |ty, name|
|
886
|
+
add_farg.call(ty.screen_name(scratch), name)
|
887
|
+
end
|
888
|
+
|
889
|
+
@kw_tys&.each do |req, sym, ty|
|
890
|
+
opt = req ? "" : "?"
|
891
|
+
add_farg.call("#{ opt }#{ sym }: #{ ty.screen_name(scratch) }", nil, help: true, key: sym)
|
883
892
|
end
|
893
|
+
|
884
894
|
if @kw_rest_ty
|
885
895
|
all_val_ty = Type.bot
|
886
896
|
@kw_rest_ty.each_child_global do |ty|
|
@@ -892,18 +902,16 @@ module TypeProf
|
|
892
902
|
end
|
893
903
|
all_val_ty = all_val_ty.union(val_ty)
|
894
904
|
end
|
895
|
-
|
905
|
+
add_farg.call("**" + all_val_ty.screen_name(scratch), nil)
|
896
906
|
end
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
end
|
902
|
-
fargs = fargs.empty? ? "" : "(#{ fargs.join(", ") })"
|
907
|
+
|
908
|
+
fargs_str << ")"
|
909
|
+
|
910
|
+
fargs_str = "" if fargs_str == "()"
|
903
911
|
|
904
912
|
# Dirty Hack: Stop the iteration at most once!
|
905
913
|
# I'll remove this hack if RBS removes the limitation of nesting blocks
|
906
|
-
return
|
914
|
+
return fargs_str, sig_help if caller_locations.any? {|frame| frame.label == "show_block_signature" }
|
907
915
|
|
908
916
|
optional = false
|
909
917
|
blks = []
|
@@ -916,12 +924,12 @@ module TypeProf
|
|
916
924
|
end
|
917
925
|
end
|
918
926
|
if blks != []
|
919
|
-
|
920
|
-
|
921
|
-
|
927
|
+
fargs_str << " " if fargs_str != ""
|
928
|
+
fargs_str << "?" if optional
|
929
|
+
fargs_str << scratch.show_block_signature(blks)
|
922
930
|
end
|
923
931
|
|
924
|
-
|
932
|
+
return fargs_str, sig_help
|
925
933
|
end
|
926
934
|
end
|
927
935
|
|
data/lib/typeprof/utils.rb
CHANGED
@@ -9,7 +9,7 @@ module TypeProf
|
|
9
9
|
def self.included(klass)
|
10
10
|
klass.instance_eval do
|
11
11
|
def new(*args)
|
12
|
-
(
|
12
|
+
(Thread.current[:table] ||= {})[[self] + args] ||= super
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
@@ -191,5 +191,22 @@ module TypeProf
|
|
191
191
|
"#<#{ self.class }:#{ @heap.map {|_key, val| val }.inspect }>"
|
192
192
|
end
|
193
193
|
end
|
194
|
+
|
195
|
+
class CancelToken
|
196
|
+
def cancelled?
|
197
|
+
return false
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
class TimerCancelToken < CancelToken
|
202
|
+
def initialize(max_sec)
|
203
|
+
@max_sec = max_sec
|
204
|
+
@start_time = Time.now
|
205
|
+
end
|
206
|
+
|
207
|
+
def cancelled?
|
208
|
+
@max_sec && Time.now - @start_time >= @max_sec
|
209
|
+
end
|
210
|
+
end
|
194
211
|
end
|
195
212
|
end
|
data/lib/typeprof/version.rb
CHANGED
data/lib/typeprof.rb
CHANGED
data/typeprof-lsp
ADDED
data/typeprof.gemspec
CHANGED
data/vscode/.gitignore
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
{
|
2
|
+
"version": "0.1.0",
|
3
|
+
"configurations": [
|
4
|
+
{
|
5
|
+
"name": "Launch Extension",
|
6
|
+
"type": "extensionHost",
|
7
|
+
"request": "launch",
|
8
|
+
"runtimeExecutable": "${execPath}",
|
9
|
+
"args": ["--extensionDevelopmentPath=${workspaceRoot}" ],
|
10
|
+
"stopOnEntry": false,
|
11
|
+
"sourceMaps": true,
|
12
|
+
"outFiles": [ "${workspaceRoot}/out/src/**/*.js" ],
|
13
|
+
"preLaunchTask": "npm: vscode:prepublish"
|
14
|
+
}
|
15
|
+
]
|
16
|
+
}
|
data/vscode/README.md
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# Ruby TypeProf VSCode Integration
|
2
|
+
|
3
|
+
*NOTE: This extenstion is very preliminary.*
|
4
|
+
|
5
|
+
This is a VSCode extension to help you write Ruby code by using an code analyzer called [Ruby TypeProf](https://github.com/ruby/typeprof/) as a backend.
|
6
|
+
|
7
|
+
## How to use this extension
|
8
|
+
|
9
|
+
*TBD*
|
10
|
+
|
11
|
+
Requirements:
|
12
|
+
|
13
|
+
1. Use Ruby 3.1.0 or later, and TypeProf 0.20.0 or later
|
14
|
+
2. Add `gem "typeprof"` to your `Gemfile`, and execute `bundle install`
|
15
|
+
|
16
|
+
Troubleshooting:
|
17
|
+
|
18
|
+
*TBD*
|
19
|
+
|
20
|
+
## How to develop this extension
|
21
|
+
|
22
|
+
See [development.md](https://github.com/ruby/typeprof/blob/master/development.md).
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# LSP client for vscode
|
2
|
+
|
3
|
+
Note: this is under development
|
4
|
+
|
5
|
+
## How to run
|
6
|
+
|
7
|
+
```
|
8
|
+
$ cd vscode
|
9
|
+
$ npm install
|
10
|
+
$ npx run tsc -p ./
|
11
|
+
$ cd ..
|
12
|
+
$ code --extensionDevelopmentPath=vscode/ .
|
13
|
+
```
|
14
|
+
|
15
|
+
Alternatively, you can do it in vscode itself.
|
16
|
+
|
17
|
+
```
|
18
|
+
$ cd vscode
|
19
|
+
$ code
|
20
|
+
```
|
21
|
+
|
22
|
+
And then press F5 to run another vscode with extension.
|
23
|
+
|
24
|
+
## How to release
|
25
|
+
|
26
|
+
```
|
27
|
+
$ npm run package
|
28
|
+
$ npx vsce publish
|
29
|
+
```
|
30
|
+
|
31
|
+
See also: https://code.visualstudio.com/api/working-with-extensions/publishing-extension
|