typeprof 0.15.3 → 0.20.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (366) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +1 -1
  3. data/Gemfile.lock +5 -5
  4. data/doc/ide.md +81 -0
  5. data/doc/typeprof-for-ide-log.png +0 -0
  6. data/doc/typeprof-for-ide.png +0 -0
  7. data/exe/typeprof +5 -1
  8. data/lib/typeprof/analyzer.rb +235 -56
  9. data/lib/typeprof/arguments.rb +1 -0
  10. data/lib/typeprof/builtin.rb +23 -23
  11. data/lib/typeprof/cli.rb +23 -5
  12. data/lib/typeprof/code-range.rb +177 -0
  13. data/lib/typeprof/config.rb +41 -20
  14. data/lib/typeprof/container-type.rb +3 -0
  15. data/lib/typeprof/export.rb +191 -15
  16. data/lib/typeprof/import.rb +33 -9
  17. data/lib/typeprof/insns-def.rb +1 -0
  18. data/lib/typeprof/iseq.rb +224 -17
  19. data/lib/typeprof/lsp.rb +884 -0
  20. data/lib/typeprof/method.rb +15 -11
  21. data/lib/typeprof/type.rb +50 -42
  22. data/lib/typeprof/utils.rb +18 -1
  23. data/lib/typeprof/version.rb +1 -1
  24. data/lib/typeprof.rb +3 -5
  25. data/typeprof-lsp +3 -0
  26. data/typeprof.gemspec +2 -2
  27. data/vscode/.gitignore +5 -0
  28. data/vscode/.vscode/launch.json +16 -0
  29. data/vscode/.vscodeignore +7 -0
  30. data/vscode/README.md +22 -0
  31. data/vscode/development.md +31 -0
  32. data/vscode/package-lock.json +3249 -0
  33. data/vscode/package.json +71 -0
  34. data/vscode/sandbox/test.rb +24 -0
  35. data/vscode/src/extension.ts +299 -0
  36. data/vscode/tsconfig.json +15 -0
  37. metadata +21 -334
  38. data/smoke/alias.rb +0 -31
  39. data/smoke/alias2.rb +0 -21
  40. data/smoke/any-cbase.rb +0 -5
  41. data/smoke/any1.rb +0 -16
  42. data/smoke/any2.rb +0 -18
  43. data/smoke/arguments.rb +0 -17
  44. data/smoke/arguments2.rb +0 -56
  45. data/smoke/array-each.rb +0 -15
  46. data/smoke/array-each2.rb +0 -16
  47. data/smoke/array-each3.rb +0 -13
  48. data/smoke/array-ltlt.rb +0 -14
  49. data/smoke/array-ltlt2.rb +0 -17
  50. data/smoke/array-map.rb +0 -12
  51. data/smoke/array-map2.rb +0 -11
  52. data/smoke/array-map3.rb +0 -23
  53. data/smoke/array-mul.rb +0 -18
  54. data/smoke/array-plus1.rb +0 -11
  55. data/smoke/array-plus2.rb +0 -16
  56. data/smoke/array-pop.rb +0 -12
  57. data/smoke/array-range-aref.rb +0 -71
  58. data/smoke/array-replace.rb +0 -13
  59. data/smoke/array-s-aref.rb +0 -12
  60. data/smoke/array1.rb +0 -27
  61. data/smoke/array10.rb +0 -15
  62. data/smoke/array11.rb +0 -14
  63. data/smoke/array12.rb +0 -25
  64. data/smoke/array13.rb +0 -31
  65. data/smoke/array14.rb +0 -14
  66. data/smoke/array15.rb +0 -16
  67. data/smoke/array2.rb +0 -28
  68. data/smoke/array3.rb +0 -26
  69. data/smoke/array4.rb +0 -15
  70. data/smoke/array5.rb +0 -14
  71. data/smoke/array6.rb +0 -17
  72. data/smoke/array7.rb +0 -14
  73. data/smoke/array8.rb +0 -13
  74. data/smoke/array9.rb +0 -13
  75. data/smoke/attr-module.rb +0 -24
  76. data/smoke/attr-vis.rb +0 -43
  77. data/smoke/attr-vis.rbs +0 -4
  78. data/smoke/attr.rb +0 -28
  79. data/smoke/autoload.rb +0 -14
  80. data/smoke/backtrace.rb +0 -33
  81. data/smoke/block-ambiguous.rb +0 -37
  82. data/smoke/block-args1-rest.rb +0 -64
  83. data/smoke/block-args1.rb +0 -60
  84. data/smoke/block-args2-rest.rb +0 -64
  85. data/smoke/block-args2.rb +0 -60
  86. data/smoke/block-args3-rest.rb +0 -75
  87. data/smoke/block-args3.rb +0 -71
  88. data/smoke/block-blockarg.rb +0 -28
  89. data/smoke/block-kwarg.rb +0 -53
  90. data/smoke/block1.rb +0 -23
  91. data/smoke/block10.rb +0 -15
  92. data/smoke/block11.rb +0 -40
  93. data/smoke/block12.rb +0 -23
  94. data/smoke/block13.rb +0 -9
  95. data/smoke/block13.rbs +0 -3
  96. data/smoke/block14.rb +0 -18
  97. data/smoke/block2.rb +0 -15
  98. data/smoke/block3.rb +0 -38
  99. data/smoke/block4.rb +0 -19
  100. data/smoke/block5.rb +0 -21
  101. data/smoke/block6.rb +0 -21
  102. data/smoke/block7.rb +0 -19
  103. data/smoke/block8.rb +0 -28
  104. data/smoke/block9.rb +0 -13
  105. data/smoke/block_given.rb +0 -37
  106. data/smoke/blown.rb +0 -13
  107. data/smoke/break1.rb +0 -19
  108. data/smoke/break2.rb +0 -16
  109. data/smoke/break3.rb +0 -13
  110. data/smoke/break4.rb +0 -17
  111. data/smoke/case.rb +0 -17
  112. data/smoke/case2.rb +0 -18
  113. data/smoke/case3.rb +0 -17
  114. data/smoke/class-hierarchy.rb +0 -54
  115. data/smoke/class-hierarchy2.rb +0 -27
  116. data/smoke/class-new.rb +0 -15
  117. data/smoke/class.rb +0 -7
  118. data/smoke/class_eval.rb +0 -22
  119. data/smoke/class_instance_var.rb +0 -9
  120. data/smoke/class_method.rb +0 -25
  121. data/smoke/class_method2.rb +0 -21
  122. data/smoke/class_method3.rb +0 -29
  123. data/smoke/constant1.rb +0 -46
  124. data/smoke/constant2.rb +0 -36
  125. data/smoke/constant3.rb +0 -10
  126. data/smoke/constant4.rb +0 -12
  127. data/smoke/context-sensitive1.rb +0 -13
  128. data/smoke/cvar.rb +0 -31
  129. data/smoke/cvar2.rb +0 -17
  130. data/smoke/define_method.rb +0 -16
  131. data/smoke/define_method2.rb +0 -18
  132. data/smoke/define_method3.rb +0 -14
  133. data/smoke/define_method3.rbs +0 -3
  134. data/smoke/define_method4.rb +0 -15
  135. data/smoke/define_method4.rbs +0 -3
  136. data/smoke/define_method5.rb +0 -12
  137. data/smoke/define_method6.rb +0 -19
  138. data/smoke/define_method7.rb +0 -18
  139. data/smoke/demo.rb +0 -81
  140. data/smoke/demo1.rb +0 -17
  141. data/smoke/demo10.rb +0 -21
  142. data/smoke/demo11.rb +0 -12
  143. data/smoke/demo2.rb +0 -15
  144. data/smoke/demo3.rb +0 -17
  145. data/smoke/demo4.rb +0 -27
  146. data/smoke/demo5.rb +0 -16
  147. data/smoke/demo6.rb +0 -22
  148. data/smoke/demo7.rb +0 -15
  149. data/smoke/demo8.rb +0 -19
  150. data/smoke/demo9.rb +0 -18
  151. data/smoke/dummy-execution1.rb +0 -15
  152. data/smoke/dummy-execution2.rb +0 -16
  153. data/smoke/dummy_element.rb +0 -14
  154. data/smoke/ensure1.rb +0 -21
  155. data/smoke/enum_for.rb +0 -15
  156. data/smoke/enum_for2.rb +0 -17
  157. data/smoke/enumerator.rb +0 -16
  158. data/smoke/expandarray1.rb +0 -23
  159. data/smoke/expandarray2.rb +0 -24
  160. data/smoke/extended.rb +0 -38
  161. data/smoke/fib.rb +0 -28
  162. data/smoke/flip-flop.rb +0 -28
  163. data/smoke/flow1.rb +0 -17
  164. data/smoke/flow10.rb +0 -17
  165. data/smoke/flow11.rb +0 -17
  166. data/smoke/flow2.rb +0 -15
  167. data/smoke/flow3.rb +0 -15
  168. data/smoke/flow4.rb +0 -5
  169. data/smoke/flow5.rb +0 -20
  170. data/smoke/flow6.rb +0 -20
  171. data/smoke/flow7.rb +0 -21
  172. data/smoke/flow8.rb +0 -14
  173. data/smoke/flow9.rb +0 -12
  174. data/smoke/for.rb +0 -9
  175. data/smoke/freeze.rb +0 -12
  176. data/smoke/function.rb +0 -17
  177. data/smoke/gvar.rb +0 -14
  178. data/smoke/gvar2.rb +0 -15
  179. data/smoke/gvar2.rbs +0 -1
  180. data/smoke/hash-bot.rb +0 -12
  181. data/smoke/hash-fetch.rb +0 -28
  182. data/smoke/hash-merge-bang.rb +0 -12
  183. data/smoke/hash1.rb +0 -20
  184. data/smoke/hash2.rb +0 -13
  185. data/smoke/hash3.rb +0 -14
  186. data/smoke/hash4.rb +0 -11
  187. data/smoke/hash5.rb +0 -14
  188. data/smoke/huge_union.rb +0 -86
  189. data/smoke/identifier_keywords.rb +0 -17
  190. data/smoke/included.rb +0 -38
  191. data/smoke/inheritance.rb +0 -34
  192. data/smoke/inheritance2.rb +0 -35
  193. data/smoke/inherited.rb +0 -26
  194. data/smoke/initialize.rb +0 -28
  195. data/smoke/instance_eval.rb +0 -18
  196. data/smoke/instance_eval2.rb +0 -10
  197. data/smoke/instance_eval3.rb +0 -25
  198. data/smoke/instance_eval4.rb +0 -12
  199. data/smoke/int_times.rb +0 -15
  200. data/smoke/integer.rb +0 -11
  201. data/smoke/ivar.rb +0 -31
  202. data/smoke/ivar2.rb +0 -30
  203. data/smoke/ivar3.rb +0 -17
  204. data/smoke/ivar3.rbs +0 -3
  205. data/smoke/ivar4.rb +0 -21
  206. data/smoke/kernel-class.rb +0 -13
  207. data/smoke/keyword1.rb +0 -12
  208. data/smoke/keyword2.rb +0 -12
  209. data/smoke/keyword3.rb +0 -12
  210. data/smoke/keyword4.rb +0 -12
  211. data/smoke/keyword5.rb +0 -16
  212. data/smoke/kwrest.rb +0 -13
  213. data/smoke/kwrest.rbs +0 -3
  214. data/smoke/kwsplat1.rb +0 -43
  215. data/smoke/kwsplat2.rb +0 -13
  216. data/smoke/lit-complex.rb +0 -10
  217. data/smoke/lit-encoding.rb +0 -10
  218. data/smoke/manual-rbs.rb +0 -29
  219. data/smoke/manual-rbs.rbs +0 -3
  220. data/smoke/manual-rbs2.rb +0 -21
  221. data/smoke/manual-rbs2.rbs +0 -8
  222. data/smoke/manual-rbs3.rb +0 -13
  223. data/smoke/manual-rbs3.rbs +0 -3
  224. data/smoke/masgn1.rb +0 -14
  225. data/smoke/masgn2.rb +0 -18
  226. data/smoke/masgn3.rb +0 -13
  227. data/smoke/method_in_branch.rb +0 -23
  228. data/smoke/method_missing.rb +0 -29
  229. data/smoke/module1.rb +0 -29
  230. data/smoke/module2.rb +0 -28
  231. data/smoke/module3.rb +0 -33
  232. data/smoke/module4.rb +0 -35
  233. data/smoke/module5.rb +0 -17
  234. data/smoke/module6.rb +0 -40
  235. data/smoke/module_function1.rb +0 -29
  236. data/smoke/module_function2.rb +0 -29
  237. data/smoke/multiple-include.rb +0 -15
  238. data/smoke/multiple-superclass.rb +0 -28
  239. data/smoke/next1.rb +0 -21
  240. data/smoke/next2.rb +0 -17
  241. data/smoke/noname.rb +0 -9
  242. data/smoke/object-send1.rb +0 -23
  243. data/smoke/object-send2.rb +0 -10
  244. data/smoke/object-send3.rb +0 -18
  245. data/smoke/once.rb +0 -13
  246. data/smoke/optional1.rb +0 -14
  247. data/smoke/optional2.rb +0 -16
  248. data/smoke/optional3.rb +0 -11
  249. data/smoke/or_raise.rb +0 -18
  250. data/smoke/parameterizedd-self.rb +0 -20
  251. data/smoke/parameterizedd-self2.rb +0 -15
  252. data/smoke/pathname1.rb +0 -14
  253. data/smoke/pathname2.rb +0 -14
  254. data/smoke/pattern-match1.rb +0 -19
  255. data/smoke/pattern-match2.rb +0 -16
  256. data/smoke/prepend1.rb +0 -33
  257. data/smoke/prepend2.rb +0 -10
  258. data/smoke/prepend2.rbs +0 -9
  259. data/smoke/primitive_method.rb +0 -19
  260. data/smoke/printf.rb +0 -20
  261. data/smoke/proc.rb +0 -20
  262. data/smoke/proc2.rb +0 -17
  263. data/smoke/proc3.rb +0 -15
  264. data/smoke/proc4.rb +0 -12
  265. data/smoke/proc5.rb +0 -19
  266. data/smoke/proc6.rb +0 -13
  267. data/smoke/proc7.rb +0 -32
  268. data/smoke/public.rb +0 -38
  269. data/smoke/range.rb +0 -14
  270. data/smoke/rbs-alias.rb +0 -10
  271. data/smoke/rbs-alias.rbs +0 -4
  272. data/smoke/rbs-attr.rb +0 -27
  273. data/smoke/rbs-attr.rbs +0 -5
  274. data/smoke/rbs-attr2.rb +0 -11
  275. data/smoke/rbs-attr2.rbs +0 -3
  276. data/smoke/rbs-extend.rb +0 -10
  277. data/smoke/rbs-extend.rbs +0 -7
  278. data/smoke/rbs-interface.rb +0 -25
  279. data/smoke/rbs-interface.rbs +0 -12
  280. data/smoke/rbs-module.rb +0 -26
  281. data/smoke/rbs-module.rbs +0 -4
  282. data/smoke/rbs-opt-and-rest.rb +0 -10
  283. data/smoke/rbs-opt-and-rest.rbs +0 -3
  284. data/smoke/rbs-proc1.rb +0 -10
  285. data/smoke/rbs-proc1.rbs +0 -3
  286. data/smoke/rbs-proc2.rb +0 -21
  287. data/smoke/rbs-proc2.rbs +0 -3
  288. data/smoke/rbs-proc3.rb +0 -14
  289. data/smoke/rbs-proc3.rbs +0 -4
  290. data/smoke/rbs-record.rb +0 -18
  291. data/smoke/rbs-record.rbs +0 -4
  292. data/smoke/rbs-tyvar.rb +0 -19
  293. data/smoke/rbs-tyvar.rbs +0 -5
  294. data/smoke/rbs-tyvar2.rb +0 -21
  295. data/smoke/rbs-tyvar2.rbs +0 -9
  296. data/smoke/rbs-tyvar3.rb +0 -18
  297. data/smoke/rbs-tyvar3.rbs +0 -5
  298. data/smoke/rbs-tyvar4.rb +0 -37
  299. data/smoke/rbs-tyvar5.rb +0 -13
  300. data/smoke/rbs-tyvar5.rbs +0 -8
  301. data/smoke/rbs-tyvar6.rb +0 -18
  302. data/smoke/rbs-tyvar6.rbs +0 -12
  303. data/smoke/rbs-tyvar7.rb +0 -12
  304. data/smoke/rbs-tyvar7.rbs +0 -7
  305. data/smoke/rbs-vars.rb +0 -35
  306. data/smoke/rbs-vars.rbs +0 -7
  307. data/smoke/redo1.rb +0 -22
  308. data/smoke/redo2.rb +0 -23
  309. data/smoke/req-keyword.rb +0 -13
  310. data/smoke/require1.rb +0 -13
  311. data/smoke/require2.rb +0 -13
  312. data/smoke/rescue1.rb +0 -21
  313. data/smoke/rescue2.rb +0 -23
  314. data/smoke/rescue3.rb +0 -20
  315. data/smoke/rescue4.rb +0 -17
  316. data/smoke/respond_to.rb +0 -23
  317. data/smoke/rest-farg.rb +0 -11
  318. data/smoke/rest1.rb +0 -26
  319. data/smoke/rest2.rb +0 -31
  320. data/smoke/rest3.rb +0 -37
  321. data/smoke/rest4.rb +0 -19
  322. data/smoke/rest5.rb +0 -11
  323. data/smoke/rest6.rb +0 -12
  324. data/smoke/retry1.rb +0 -21
  325. data/smoke/return.rb +0 -14
  326. data/smoke/reveal.rb +0 -13
  327. data/smoke/simple.rb +0 -12
  328. data/smoke/singleton_class.rb +0 -8
  329. data/smoke/singleton_method.rb +0 -12
  330. data/smoke/step.rb +0 -18
  331. data/smoke/string-split.rb +0 -12
  332. data/smoke/struct-keyword_init.rb +0 -10
  333. data/smoke/struct.rb +0 -13
  334. data/smoke/struct2.rb +0 -25
  335. data/smoke/struct3.rb +0 -14
  336. data/smoke/struct4.rb +0 -7
  337. data/smoke/struct5.rb +0 -16
  338. data/smoke/struct6.rb +0 -15
  339. data/smoke/struct7.rb +0 -17
  340. data/smoke/stub-keyword.rb +0 -10
  341. data/smoke/super1.rb +0 -69
  342. data/smoke/super2.rb +0 -16
  343. data/smoke/super3.rb +0 -20
  344. data/smoke/super4.rb +0 -45
  345. data/smoke/super5.rb +0 -38
  346. data/smoke/svar1.rb +0 -13
  347. data/smoke/symbol-proc-attr.rb +0 -22
  348. data/smoke/symbol-proc-attr2.rb +0 -15
  349. data/smoke/symbol-proc-bot.rb +0 -13
  350. data/smoke/symbol-proc.rb +0 -25
  351. data/smoke/tap1.rb +0 -18
  352. data/smoke/toplevel.rb +0 -13
  353. data/smoke/two-map.rb +0 -18
  354. data/smoke/type_var.rb +0 -11
  355. data/smoke/typed_method.rb +0 -16
  356. data/smoke/uninitialize-var.rb +0 -13
  357. data/smoke/union-recv.rb +0 -35
  358. data/smoke/user-demo.rb +0 -15
  359. data/smoke/wrong-extend.rb +0 -27
  360. data/smoke/wrong-include.rb +0 -27
  361. data/smoke/wrong-include2.rb +0 -17
  362. data/smoke/wrong-rbs.rb +0 -15
  363. data/smoke/wrong-rbs.rbs +0 -7
  364. data/testbed/ao.rb +0 -297
  365. data/testbed/diff-lcs-entrypoint.rb +0 -4
  366. data/testbed/goodcheck-Gemfile.lock +0 -51
@@ -26,7 +26,7 @@ module TypeProf
26
26
  end
27
27
 
28
28
  def show_message(terminated, output)
29
- if Config.options[:show_typeprof_version]
29
+ if Config.current.options[:show_typeprof_version]
30
30
  output.puts "# TypeProf #{ VERSION }"
31
31
  output.puts
32
32
  end
@@ -38,7 +38,7 @@ module TypeProf
38
38
 
39
39
  def show_error(errors, backward_edge, output)
40
40
  return if errors.empty?
41
- return unless Config.options[:show_errors]
41
+ return unless Config.current.options[:show_errors]
42
42
 
43
43
  output.puts "# Errors"
44
44
  errors.each do |ep, msg|
@@ -110,16 +110,17 @@ module TypeProf
110
110
  @scratch.namespace = class_def.name
111
111
 
112
112
  consts = {}
113
- class_def.consts.each do |name, (ty, absolute_path)|
113
+ class_def.consts.each do |name, (ty, loc)|
114
+ next unless loc
114
115
  next if ty.is_a?(Type::Class)
115
- next if !absolute_path || Config.check_dir_filter(absolute_path) == :exclude
116
+ next if Config.current.check_dir_filter(loc[0]) == :exclude
116
117
  consts[name] = ty.screen_name(@scratch)
117
118
  end
118
119
 
119
120
  modules = class_def.modules.to_h do |kind, mods|
120
121
  mods = mods.to_h do |singleton, mods|
121
122
  mods = mods.filter_map do |mod_def, _type_args, absolute_paths|
122
- next if absolute_paths.all? {|path| !path || Config.check_dir_filter(path) == :exclude }
123
+ next if absolute_paths.all? {|path| !path || Config.current.check_dir_filter(path) == :exclude }
123
124
  Type::Instance.new(mod_def.klass_obj).screen_name(@scratch)
124
125
  end
125
126
  [singleton, mods]
@@ -142,7 +143,7 @@ module TypeProf
142
143
 
143
144
  ctx = ctxs.find {|ctx| ctx.mid == mid } || ctxs.first
144
145
 
145
- next if Config.check_dir_filter(ctx.iseq.absolute_path) == :exclude
146
+ next if Config.current.check_dir_filter(ctx.iseq.absolute_path) == :exclude
146
147
 
147
148
  method_name = mid
148
149
  method_name = "self.#{ method_name }" if singleton
@@ -152,7 +153,7 @@ module TypeProf
152
153
  source_locations[key] ||= ctx.iseq.source_location(0)
153
154
  (methods[key] ||= []) << @scratch.show_method_signature(ctx)
154
155
  when AliasMethodDef
155
- next if mdef.def_ep && Config.check_dir_filter(mdef.def_ep.source_location) == :exclude
156
+ next if mdef.def_ep && Config.current.check_dir_filter(mdef.def_ep.source_location) == :exclude
156
157
  alias_name, orig_name = mid, mdef.orig_mid
157
158
  if singleton
158
159
  alias_name = "self.#{ alias_name }"
@@ -165,7 +166,7 @@ module TypeProf
165
166
  when AttrMethodDef
166
167
  next if !mdef.def_ep
167
168
  absolute_path = mdef.def_ep.ctx.iseq.absolute_path
168
- next if !absolute_path || Config.check_dir_filter(absolute_path) == :exclude
169
+ next if !absolute_path || Config.current.check_dir_filter(absolute_path) == :exclude
169
170
  mid = mid.to_s[0..-2].to_sym if mid.to_s.end_with?("=")
170
171
  method_name = mid
171
172
  method_name = "self.#{ mid }" if singleton
@@ -188,13 +189,14 @@ module TypeProf
188
189
  key = [:rbs, method_name]
189
190
  methods[key] = sigs
190
191
  visibilities[key] ||= mdef.pub_meth
192
+ source_locations[key] ||= mdef.iseq&.source_location(0)
191
193
  end
192
194
  end
193
195
  end
194
196
  end
195
197
 
196
198
  ivars = ivars.map do |(singleton, var), entry|
197
- next if entry.absolute_paths.all? {|path| Config.check_dir_filter(path) == :exclude }
199
+ next if entry.absolute_paths.all? {|path| Config.current.check_dir_filter(path) == :exclude }
198
200
  ty = entry.type
199
201
  next unless var.to_s.start_with?("@")
200
202
  var = "self.#{ var }" if singleton
@@ -204,12 +206,12 @@ module TypeProf
204
206
  end.compact
205
207
 
206
208
  cvars = cvars.map do |var, entry|
207
- next if entry.absolute_paths.all? {|path| Config.check_dir_filter(path) == :exclude }
209
+ next if entry.absolute_paths.all? {|path| Config.current.check_dir_filter(path) == :exclude }
208
210
  next if entry.rbs_declared
209
211
  [var, entry.type.screen_name(@scratch)]
210
212
  end.compact
211
213
 
212
- if !class_def.absolute_path || Config.check_dir_filter(class_def.absolute_path) == :exclude
214
+ if !class_def.absolute_path || Config.current.check_dir_filter(class_def.absolute_path) == :exclude
213
215
  if methods.keys.all? {|type,| type == :rbs }
214
216
  return nil if consts.empty? && modules[:before][true].empty? && modules[:before][false].empty? && modules[:after][true].empty? && modules[:after][false].empty? && ivars.empty? && cvars.empty? && inner_classes.empty?
215
217
  end
@@ -232,8 +234,182 @@ module TypeProf
232
234
  )
233
235
  end
234
236
 
237
+ def conv_class_lsp(namespace, class_def)
238
+ @scratch.namespace = namespace
239
+
240
+ if class_def.klass_obj.superclass != :__root__ && class_def.klass_obj.superclass
241
+ omit = class_def.klass_obj.superclass == Type::Builtin[:obj] || class_def.klass_obj == Type::Builtin[:obj]
242
+ superclass = omit ? nil : @scratch.get_class_name(class_def.klass_obj.superclass)
243
+ type_args = class_def.klass_obj.superclass_type_args
244
+ if type_args && !type_args.empty?
245
+ superclass += "[#{ type_args.map {|ty| ty.screen_name(@scratch) }.join(", ") }]"
246
+ end
247
+ end
248
+
249
+ @scratch.namespace = class_def.name
250
+
251
+ consts = {}
252
+ class_def.consts.each do |name, (ty, loc)|
253
+ next unless loc
254
+ next if ty.is_a?(Type::Class)
255
+ next if Config.current.check_dir_filter(loc[0]) == :exclude
256
+ consts[name] = ty.screen_name(@scratch)
257
+ end
258
+
259
+ modules = class_def.modules.to_h do |kind, mods|
260
+ mods = mods.to_h do |singleton, mods|
261
+ mods = mods.filter_map do |mod_def, _type_args, absolute_paths|
262
+ next if absolute_paths.all? {|path| !path || Config.current.check_dir_filter(path) == :exclude }
263
+ Type::Instance.new(mod_def.klass_obj).screen_name(@scratch)
264
+ end
265
+ [singleton, mods]
266
+ end
267
+ [kind, mods]
268
+ end
269
+
270
+ visibilities = {}
271
+ source_locations = {}
272
+ methods = {}
273
+ ivars = class_def.ivars.dump
274
+ cvars = class_def.cvars.dump
275
+
276
+ class_def.methods.each do |(singleton, mid), mdefs|
277
+ mdefs.each do |mdef|
278
+ case mdef
279
+ when ISeqMethodDef
280
+ ctxs = @iseq_method_to_ctxs[mdef]
281
+ next unless ctxs
282
+
283
+ ctx = ctxs.find {|ctx| ctx.mid == mid } || ctxs.first
284
+
285
+ next if Config.current.check_dir_filter(ctx.iseq.absolute_path) == :exclude
286
+
287
+ method_name = mid
288
+ method_name = "self.#{ method_name }" if singleton
289
+
290
+ key = [:iseq, method_name]
291
+ visibilities[key] ||= mdef.pub_meth
292
+ source_locations[key] ||= [ctx.iseq.source_location(0)]
293
+ sig = @scratch.show_method_signature(ctx)
294
+ (methods[key] ||= []) << sig if sig
295
+ when AliasMethodDef
296
+ alias_name, orig_name = mid, mdef.orig_mid
297
+ if singleton
298
+ alias_name = "self.#{ alias_name }"
299
+ orig_name = "self.#{ orig_name }"
300
+ end
301
+ key = [:alias, alias_name]
302
+ visibilities[key] ||= mdef.pub_meth
303
+ source_locations[key] ||= [mdef.def_ep&.source_location]
304
+ methods[key] = orig_name
305
+ when AttrMethodDef
306
+ next if !mdef.def_ep
307
+ absolute_path = mdef.def_ep.ctx.iseq.absolute_path
308
+ next if !absolute_path || Config.current.check_dir_filter(absolute_path) == :exclude
309
+ mid = mid.to_s[0..-2].to_sym if mid.to_s.end_with?("=")
310
+ method_name = mid
311
+ method_name = "self.#{ mid }" if singleton
312
+ method_name = [method_name, :"@#{ mid }" != mdef.ivar]
313
+ key = [:attr, method_name]
314
+ visibilities[key] ||= mdef.pub_meth
315
+ source_locations[key] ||= [mdef.def_ep.source_location]
316
+ if methods[key]
317
+ if methods[key][0] != mdef.kind
318
+ methods[key][0] = :accessor
319
+ end
320
+ else
321
+ entry = ivars[[singleton, mdef.ivar]]
322
+ ty = entry ? entry.type : Type.any
323
+ methods[key] = [mdef.kind, ty.screen_name(@scratch), ty.include_untyped?(@scratch)]
324
+ end
325
+ when TypedMethodDef
326
+ if mdef.rbs_source
327
+ method_name, sigs, rbs_code_range = mdef.rbs_source
328
+ key = [:rbs, method_name]
329
+ methods[key] = sigs
330
+ visibilities[key] ||= mdef.pub_meth
331
+ source_locations[key] ||= [mdef.iseq&.source_location(0), rbs_code_range]
332
+ end
333
+ end
334
+ end
335
+ end
336
+
337
+ ivars = ivars.map do |(singleton, var), entry|
338
+ next if entry.absolute_paths.all? {|path| Config.current.check_dir_filter(path) == :exclude }
339
+ ty = entry.type
340
+ next unless var.to_s.start_with?("@")
341
+ var = "self.#{ var }" if singleton
342
+ next if methods[[:attr, [singleton ? "self.#{ var.to_s[1..] }" : var.to_s[1..].to_sym, false]]]
343
+ next if entry.rbs_declared
344
+ [var, ty.screen_name(@scratch)]
345
+ end.compact
346
+
347
+ cvars = cvars.map do |var, entry|
348
+ next if entry.absolute_paths.all? {|path| Config.current.check_dir_filter(path) == :exclude }
349
+ next if entry.rbs_declared
350
+ [var, entry.type.screen_name(@scratch)]
351
+ end.compact
352
+
353
+ if !class_def.absolute_path || Config.current.check_dir_filter(class_def.absolute_path) == :exclude
354
+ if methods.keys.all? {|type,| type == :rbs }
355
+ return nil if consts.empty? && modules[:before][true].empty? && modules[:before][false].empty? && modules[:after][true].empty? && modules[:after][false].empty? && ivars.empty? && cvars.empty?
356
+ end
357
+ end
358
+
359
+ @scratch.namespace = nil
360
+
361
+ ClassData.new(
362
+ kind: class_def.kind,
363
+ name: class_def.name,
364
+ superclass: superclass,
365
+ consts: consts,
366
+ modules: modules,
367
+ ivars: ivars,
368
+ cvars: cvars,
369
+ methods: methods,
370
+ visibilities: visibilities,
371
+ source_locations: source_locations,
372
+ )
373
+ end
374
+
235
375
  ClassData = Struct.new(:kind, :name, :superclass, :consts, :modules, :ivars, :cvars, :methods, :visibilities, :source_locations, :inner_classes, keyword_init: true)
236
376
 
377
+ def show_lsp
378
+ res = []
379
+ @class_defs.each_value do |class_def|
380
+ class_data = conv_class_lsp([], class_def)
381
+ next unless class_data
382
+ class_data.methods.each do |key, arg|
383
+ source_location, rbs_code_range = class_data.source_locations[key]
384
+ type, (method_name, hidden) = key
385
+ case type
386
+ when :attr
387
+ kind, ty, untyped = *arg
388
+ line = "attr_#{ kind } #{ method_name }#{ hidden ? "()" : "" }: #{ ty }"
389
+ when :rbs
390
+ sigs = arg.sort.join(" | ")
391
+ line = "# def #{ method_name }: #{ sigs }"
392
+ when :iseq
393
+ sigs = []
394
+ untyped = false
395
+ arg.each do |sig, untyped0|
396
+ sigs << sig
397
+ untyped ||= untyped0
398
+ end
399
+ sigs = sigs.sort.join(" | ")
400
+ line = "def #{ method_name }: #{ sigs }"
401
+ when :alias
402
+ orig_name = arg
403
+ line = "alias #{ method_name } #{ orig_name }"
404
+ end
405
+ if source_location =~ /:(\d+)$/
406
+ res << [$`, $1.to_i, line, rbs_code_range, class_data.kind, class_data.name]
407
+ end
408
+ end
409
+ end
410
+ res
411
+ end
412
+
237
413
  def show(stat_eps, output)
238
414
  # make the class hierarchy
239
415
  root = {}
@@ -270,7 +446,7 @@ module TypeProf
270
446
  coverage = {}
271
447
  stat_eps.each do |ep|
272
448
  path = ep.ctx.iseq.path
273
- lineno = ep.ctx.iseq.linenos[ep.pc] - 1
449
+ lineno = ep.ctx.iseq.insns[ep.pc].lineno - 1
274
450
  (coverage[path] ||= [])[lineno] ||= 0
275
451
  (coverage[path] ||= [])[lineno] += 1
276
452
  end
@@ -340,7 +516,7 @@ module TypeProf
340
516
  prev_vis = vis
341
517
  end
342
518
  source_location = class_data.source_locations[key]
343
- if Config.options[:show_source_locations] && source_location
519
+ if Config.current.options[:show_source_locations] && source_location
344
520
  lines << nil
345
521
  lines << (indent + " # #{ source_location }")
346
522
  end
@@ -348,7 +524,7 @@ module TypeProf
348
524
  case type
349
525
  when :attr
350
526
  kind, ty, untyped = *arg
351
- exclude = Config.options[:exclude_untyped] && untyped ? "#" : " " # XXX
527
+ exclude = Config.current.options[:exclude_untyped] && untyped ? "#" : " " # XXX
352
528
  lines << (indent + "#{ exclude } attr_#{ kind } #{ method_name }#{ hidden ? "()" : "" }: #{ ty }")
353
529
  when :rbs
354
530
  sigs = arg.sort.join("\n" + indent + "#" + " " * (method_name.size + 5) + "| ")
@@ -361,7 +537,7 @@ module TypeProf
361
537
  untyped ||= untyped0
362
538
  end
363
539
  sigs = sigs.sort.join("\n" + indent + " " * (method_name.size + 6) + "| ")
364
- exclude = Config.options[:exclude_untyped] && untyped ? "#" : " " # XXX
540
+ exclude = Config.current.options[:exclude_untyped] && untyped ? "#" : " " # XXX
365
541
  lines << (indent + "#{ exclude } def #{ method_name }: #{ sigs }")
366
542
  when :alias
367
543
  orig_name = arg
@@ -4,31 +4,49 @@ module TypeProf
4
4
  class RBSReader
5
5
  def initialize
6
6
  @repo = RBS::Repository.new
7
- Config.gem_repo_dirs.each do |dir|
8
- @repo.add(Pathname(dir))
7
+ collection_path = Config.current.collection_path
8
+ if collection_path&.exist?
9
+ collection_lock = RBS::Collection::Config.lockfile_of(collection_path)
10
+ @repo.add(collection_lock.repo_path)
9
11
  end
10
- @env, @builtin_env_json = RBSReader.get_builtin_env
12
+ @env, @loaded_gems, @builtin_env_json = RBSReader.get_builtin_env
11
13
  end
12
14
 
13
15
  @builtin_env = @builtin_env_json = nil
14
16
  def self.get_builtin_env
17
+ @loaded_gems = []
15
18
  unless @builtin_env
16
19
  @builtin_env = RBS::Environment.new
17
20
 
18
- loader = RBS::EnvironmentLoader.new(repository: @repo)
21
+ loader = RBS::EnvironmentLoader.new
22
+
23
+ # TODO: invalidate this cache when rbs_collection.yml was changed
24
+ collection_path = Config.current.collection_path
25
+ if collection_path&.exist?
26
+ collection_lock = RBS::Collection::Config.lockfile_of(collection_path)
27
+ collection_lock.gems.each {|gem| @loaded_gems << gem["name"] }
28
+ loader.add_collection(collection_lock)
29
+ end
30
+
19
31
  new_decls = loader.load(env: @builtin_env).map {|decl,| decl }
20
32
  @builtin_env_json = load_rbs(@builtin_env, new_decls)
21
33
  end
22
34
 
23
- return @builtin_env.dup, @builtin_env_json
35
+ return @builtin_env.dup, @loaded_gems.dup, @builtin_env_json
24
36
  end
25
37
 
26
38
  def load_builtin
27
39
  @builtin_env_json
28
40
  end
29
41
 
42
+ class RBSCollectionDefined < StandardError; end
43
+
30
44
  def load_library(lib)
31
45
  loader = RBS::EnvironmentLoader.new(core_root: nil, repository: @repo)
46
+ if @loaded_gems.include?(lib)
47
+ raise RBSCollectionDefined
48
+ end
49
+ @loaded_gems << lib
32
50
  loader.add(library: lib)
33
51
 
34
52
  case lib
@@ -157,7 +175,11 @@ module TypeProf
157
175
  end
158
176
 
159
177
  method_def = conv_method_def(method_types, visibility)
160
- rbs_source = [(member.kind == :singleton ? "self." : "") + member.name.to_s, member.types.map {|type| type.location.source }]
178
+ rbs_source = [
179
+ (member.kind == :singleton ? "self." : "") + member.name.to_s,
180
+ member.types.map {|type| type.location.source },
181
+ [member.location.name, CodeRange.from_rbs(member.location)],
182
+ ]
161
183
  if member.instance?
162
184
  methods[[false, name]] = method_def
163
185
  rbs_sources[[false, name]] = rbs_source
@@ -466,6 +488,7 @@ module TypeProf
466
488
  when RBS::Types::Interface
467
489
  # XXX: Currently, only a few builtin interfaces are supported
468
490
  case ty.to_s
491
+ when "::_ToS" then [:str]
469
492
  when "::_ToStr" then [:str]
470
493
  when "::_ToInt" then [:int]
471
494
  when "::_ToAry[U]" then [:array, [:Array], [], [:var, :U]]
@@ -473,6 +496,7 @@ module TypeProf
473
496
  [:instance, conv_type_name(ty.name)]
474
497
  end
475
498
  when RBS::Types::Bases::Instance then [:any] # XXX: not implemented yet
499
+ when RBS::Types::Bases::Class then [:any] # XXX: not implemented yet
476
500
  when RBS::Types::Record
477
501
  [:hash_record, [:Hash], ty.fields.map {|key, ty| [key, conv_type(ty)] }]
478
502
  when RBS::Types::Proc
@@ -498,7 +522,7 @@ module TypeProf
498
522
  json = scratch.rbs_reader.load_library(feature)
499
523
  rescue RBS::EnvironmentLoader::UnknownLibraryError
500
524
  return nil
501
- rescue RBS::DuplicatedDeclarationError
525
+ rescue RBS::DuplicatedDeclarationError, RBSReader::RBSCollectionDefined
502
526
  return true
503
527
  end
504
528
  # need cache?
@@ -529,7 +553,7 @@ module TypeProf
529
553
  superclass = path_to_klass(superclass) if superclass
530
554
  base_klass = path_to_klass(classpath[0..-2])
531
555
 
532
- klass = @scratch.get_constant(base_klass, name)
556
+ klass, = @scratch.get_constant(base_klass, name)
533
557
  if klass.is_a?(Type::Any)
534
558
  klass = @scratch.new_class(base_klass, name, type_params, superclass, nil)
535
559
 
@@ -748,7 +772,7 @@ module TypeProf
748
772
  def path_to_klass(path)
749
773
  klass = Type::Builtin[:obj]
750
774
  path.each do |name|
751
- klass = @scratch.get_constant(klass, name)
775
+ klass, = @scratch.get_constant(klass, name)
752
776
  if klass == Type.any
753
777
  raise TypeProfError.new("A constant `#{ path.join("::") }' is used but not defined in RBS")
754
778
  end
@@ -21,6 +21,7 @@ TypeProf::INSN_TABLE = {:nop=>[],
21
21
  :putstring=>["VALUE"],
22
22
  :concatstrings=>["rb_num_t"],
23
23
  :tostring=>[],
24
+ :anytostring=>[],
24
25
  :freezestring=>["VALUE"],
25
26
  :toregexp=>["rb_num_t", "rb_num_t"],
26
27
  :intern=>[],