typeprof 0.15.1 → 0.20.1

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