typeprof 0.15.2 → 0.20.2

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 +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 +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 +10 -1
  15. data/lib/typeprof/export.rb +191 -15
  16. data/lib/typeprof/import.rb +38 -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 +46 -38
  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 +2211 -0
  33. data/vscode/package.json +71 -0
  34. data/vscode/sandbox/test.rb +24 -0
  35. data/vscode/src/extension.ts +285 -0
  36. data/vscode/tsconfig.json +15 -0
  37. metadata +20 -333
  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
@@ -624,7 +624,7 @@ module TypeProf
624
624
  end
625
625
 
626
626
  def self.file_load(path, ep, env, scratch, &ctn)
627
- iseq = ISeq.compile(path)
627
+ iseq, = ISeq.compile(path)
628
628
  callee_ep, callee_env = TypeProf.starting_state(iseq)
629
629
  scratch.merge_env(callee_ep, callee_env)
630
630
 
@@ -793,27 +793,27 @@ module TypeProf
793
793
 
794
794
  Import.import_builtin(scratch)
795
795
 
796
- Type::Builtin[:vmcore] = scratch.new_class(klass_obj, :VMCore, [], klass_obj, nil)
797
- Type::Builtin[:int] = scratch.get_constant(klass_obj, :Integer)
798
- Type::Builtin[:float] = scratch.get_constant(klass_obj, :Float)
799
- Type::Builtin[:rational] = scratch.get_constant(klass_obj, :Rational)
800
- Type::Builtin[:complex] = scratch.get_constant(klass_obj, :Complex)
801
- Type::Builtin[:sym] = scratch.get_constant(klass_obj, :Symbol)
802
- Type::Builtin[:str] = scratch.get_constant(klass_obj, :String)
803
- Type::Builtin[:struct] = scratch.get_constant(klass_obj, :Struct)
804
- Type::Builtin[:ary] = scratch.get_constant(klass_obj, :Array)
805
- Type::Builtin[:hash] = scratch.get_constant(klass_obj, :Hash)
806
- Type::Builtin[:io] = scratch.get_constant(klass_obj, :IO)
807
- Type::Builtin[:proc] = scratch.get_constant(klass_obj, :Proc)
808
- Type::Builtin[:range] = scratch.get_constant(klass_obj, :Range)
809
- Type::Builtin[:regexp] = scratch.get_constant(klass_obj, :Regexp)
810
- Type::Builtin[:matchdata] = scratch.get_constant(klass_obj, :MatchData)
811
- Type::Builtin[:class] = scratch.get_constant(klass_obj, :Class)
812
- Type::Builtin[:module] = scratch.get_constant(klass_obj, :Module)
813
- Type::Builtin[:exc] = scratch.get_constant(klass_obj, :Exception)
814
- Type::Builtin[:encoding] = scratch.get_constant(klass_obj, :Encoding)
815
- Type::Builtin[:enumerator] = scratch.get_constant(klass_obj, :Enumerator)
816
- Type::Builtin[:kernel] = scratch.get_constant(klass_obj, :Kernel)
796
+ Type::Builtin[:vmcore] , = scratch.new_class(klass_obj, :VMCore, [], klass_obj, nil)
797
+ Type::Builtin[:int] , = scratch.get_constant(klass_obj, :Integer)
798
+ Type::Builtin[:float] , = scratch.get_constant(klass_obj, :Float)
799
+ Type::Builtin[:rational] , = scratch.get_constant(klass_obj, :Rational)
800
+ Type::Builtin[:complex] , = scratch.get_constant(klass_obj, :Complex)
801
+ Type::Builtin[:sym] , = scratch.get_constant(klass_obj, :Symbol)
802
+ Type::Builtin[:str] , = scratch.get_constant(klass_obj, :String)
803
+ Type::Builtin[:struct] , = scratch.get_constant(klass_obj, :Struct)
804
+ Type::Builtin[:ary] , = scratch.get_constant(klass_obj, :Array)
805
+ Type::Builtin[:hash] , = scratch.get_constant(klass_obj, :Hash)
806
+ Type::Builtin[:io] , = scratch.get_constant(klass_obj, :IO)
807
+ Type::Builtin[:proc] , = scratch.get_constant(klass_obj, :Proc)
808
+ Type::Builtin[:range] , = scratch.get_constant(klass_obj, :Range)
809
+ Type::Builtin[:regexp] , = scratch.get_constant(klass_obj, :Regexp)
810
+ Type::Builtin[:matchdata] , = scratch.get_constant(klass_obj, :MatchData)
811
+ Type::Builtin[:class] , = scratch.get_constant(klass_obj, :Class)
812
+ Type::Builtin[:module] , = scratch.get_constant(klass_obj, :Module)
813
+ Type::Builtin[:exc] , = scratch.get_constant(klass_obj, :Exception)
814
+ Type::Builtin[:encoding] , = scratch.get_constant(klass_obj, :Encoding)
815
+ Type::Builtin[:enumerator] , = scratch.get_constant(klass_obj, :Enumerator)
816
+ Type::Builtin[:kernel] , = scratch.get_constant(klass_obj, :Kernel)
817
817
 
818
818
  klass_vmcore = Type::Builtin[:vmcore]
819
819
  klass_ary = Type::Builtin[:ary]
@@ -881,7 +881,7 @@ module TypeProf
881
881
  # ENV: Hash[String, String]
882
882
  str_ty = Type::Instance.new(Type::Builtin[:str])
883
883
  env_ty = Type.gen_hash {|h| h[str_ty] = Type.optional(str_ty) }
884
- scratch.add_constant(klass_obj, :ENV, env_ty, false)
884
+ scratch.add_constant(klass_obj, :ENV, env_ty, nil)
885
885
 
886
886
  scratch.search_method(Type::Builtin[:kernel], false, :sprintf) do |mdefs,|
887
887
  mdefs.each do |mdef|
data/lib/typeprof/cli.rb CHANGED
@@ -18,11 +18,14 @@ module TypeProf
18
18
  verbose = 1
19
19
 
20
20
  options = {}
21
+ lsp_options = {}
21
22
  dir_filter = nil
22
23
  gem_rbs_features = []
23
- gem_repo_dirs = []
24
24
  show_version = false
25
25
  max_sec = max_iter = nil
26
+ collection_path = RBS::Collection::Config::PATH
27
+
28
+ load_path_ext = []
26
29
 
27
30
  opt.separator ""
28
31
  opt.separator "Options:"
@@ -30,9 +33,11 @@ module TypeProf
30
33
  opt.on("-q", "--quiet", "Do not display progress indicator") { options[:show_indicator] = false }
31
34
  opt.on("-v", "--verbose", "Alias to --show-errors") { options[:show_errors] = true }
32
35
  opt.on("--version", "Display typeprof version") { show_version = true }
33
- opt.on("-I DIR", "Add DIR to the load/require path") {|v| $LOAD_PATH << v }
36
+ opt.on("-I DIR", "Add DIR to the load/require path") {|v| load_path_ext << v }
34
37
  opt.on("-r FEATURE", "Require RBS of the FEATURE gem") {|v| gem_rbs_features << v }
35
- opt.on("--repo DIR", "Add DIR to the RBS repository") {|v| gem_repo_dirs << v }
38
+ opt.on("--collection PATH", "File path of collection configuration") { |v| collection_path = v }
39
+ opt.on("--no-collection", "Ignore collection configuration") { collection_path = nil }
40
+ opt.on("--lsp", "LSP mode") {|v| options[:lsp] = true }
36
41
 
37
42
  opt.separator ""
38
43
  opt.separator "Analysis output options:"
@@ -68,8 +73,15 @@ module TypeProf
68
73
  opt.on("--debug", "Display analysis log (for debugging purpose)") { verbose = 2 }
69
74
  opt.on("--[no-]stackprof MODE", /\Acpu|wall|object\z/, "Enable stackprof (for debugging purpose)") {|v| options[:stackprof] = v.to_sym }
70
75
 
76
+ opt.separator ""
77
+ opt.separator "LSP options:"
78
+ opt.on("--port PORT", Integer, "Specify a port number to listen for requests on") {|v| lsp_options[:port] = v }
79
+ opt.on("--stdio", "Use stdio for LSP transport") {|v| lsp_options[:stdio] = v }
80
+
71
81
  opt.parse!(argv)
72
82
 
83
+ $LOAD_PATH.unshift(*load_path_ext)
84
+
73
85
  dir_filter ||= ConfigData::DEFAULT_DIR_FILTER
74
86
  rb_files = []
75
87
  rbs_files = []
@@ -82,22 +94,28 @@ module TypeProf
82
94
  end
83
95
 
84
96
  puts "typeprof #{ VERSION }" if show_version
85
- if rb_files.empty?
97
+ if rb_files.empty? && !options[:lsp]
86
98
  exit if show_version
87
99
  raise OptionParser::InvalidOption.new("no input files")
88
100
  end
89
101
 
102
+ if !options[:lsp] && !lsp_options.empty?
103
+ exit if show_version
104
+ raise OptionParser::InvalidOption.new("lsp options with non-lsp mode")
105
+ end
106
+
90
107
  ConfigData.new(
91
108
  rb_files: rb_files,
92
109
  rbs_files: rbs_files,
93
110
  output: output,
94
111
  gem_rbs_features: gem_rbs_features,
95
- gem_repo_dirs: gem_repo_dirs,
112
+ collection_path: collection_path,
96
113
  verbose: verbose,
97
114
  dir_filter: dir_filter,
98
115
  max_sec: max_sec,
99
116
  max_iter: max_iter,
100
117
  options: options,
118
+ lsp_options: lsp_options,
101
119
  )
102
120
 
103
121
  rescue OptionParser::InvalidOption
@@ -0,0 +1,177 @@
1
+ module TypeProf
2
+ class CodeLocation
3
+ # In Ruby, lineno is 1-origin, and column is 0-origin
4
+ def initialize(lineno, column)
5
+ @lineno = lineno
6
+ @column = column
7
+ end
8
+
9
+ def inspect
10
+ "(%d,%d)" % [@lineno, @column]
11
+ end
12
+
13
+ attr_reader :lineno, :column
14
+
15
+ def self.from_lsp(lsp_loc)
16
+ # In the Language Server Protocol, lineno and column are both 0-origin
17
+ CodeLocation.new(lsp_loc[:line] + 1, lsp_loc[:character])
18
+ end
19
+
20
+ def to_lsp
21
+ { line: @lineno - 1, character: @column }
22
+ end
23
+
24
+ def advance_cursor(offset, source_text)
25
+ new_lineno = @lineno
26
+ new_column = @column
27
+ while offset > 0
28
+ line_text = source_text.lines[new_lineno - 1]
29
+ if new_column + offset >= line_text.length
30
+ advanced = line_text.length - new_column
31
+ offset -= advanced
32
+ new_lineno += 1
33
+ new_column = 0
34
+ else
35
+ new_column += offset
36
+ break
37
+ end
38
+ end
39
+ CodeLocation.new(new_lineno, new_column)
40
+ end
41
+
42
+ def <=>(other)
43
+ ret = @lineno <=> other.lineno
44
+ return ret if ret != 0
45
+ @column <=> other.column
46
+ end
47
+
48
+ include Comparable
49
+ end
50
+
51
+ class CodeRange
52
+ def initialize(first, last)
53
+ @first, @last = first, last
54
+ end
55
+
56
+ def inspect
57
+ "%p-%p" % [@first, @last]
58
+ end
59
+
60
+ attr_reader :first
61
+ attr_reader :last
62
+
63
+ def self.from_lsp(lsp_range)
64
+ CodeRange.new(CodeLocation.from_lsp(lsp[:start]), CodeLocation.from_lsp(lsp[:end]))
65
+ end
66
+
67
+ def self.from_rbs(rbs_loc)
68
+ CodeRange.new(
69
+ CodeLocation.new(rbs_loc.start_line, rbs_loc.start_column),
70
+ CodeLocation.new(rbs_loc.end_line, rbs_loc.end_column),
71
+ )
72
+ end
73
+
74
+ def to_lsp
75
+ { start: @first.to_lsp, end: @last.to_lsp }
76
+ end
77
+
78
+ def contain_loc?(loc)
79
+ @first <= loc && loc < @last
80
+ end
81
+
82
+ def contain?(other)
83
+ @first <= other.first && other.last <= @last
84
+ end
85
+
86
+ def overlap?(other)
87
+ if @first <= other.first
88
+ return @last > other.first
89
+ else
90
+ return @first < other.last
91
+ end
92
+ end
93
+ end
94
+
95
+ class CodeRangeTable
96
+ Entry = Struct.new(:range, :value, :children)
97
+
98
+ class Entry
99
+ def inspect
100
+ "[%p, %p, %p]" % [range, value, children]
101
+ end
102
+ end
103
+
104
+ def initialize(list = [])
105
+ @list = list # Array[Entry]
106
+ end
107
+
108
+ def []=(range, value)
109
+ i_b = @list.bsearch_index {|e| e.range.last > range.first } || @list.size
110
+ i_e = @list.bsearch_index {|e| e.range.first >= range.last } || @list.size
111
+ if i_b < i_e
112
+ # for all i in i_b...i_e, @list[i] overlaps with the range
113
+ if i_e - i_b == 1
114
+ if range.contain?(@list[i_b].range)
115
+ @list[i_b] = Entry[range, value, CodeRangeTable.new(@list[i_b, 1])]
116
+ elsif @list[i_b].range.contain?(range)
117
+ @list[i_b].children[range] = value
118
+ else
119
+ raise
120
+ end
121
+ else
122
+ if range.contain?(@list[i_b].range) && range.contain?(@list[i_e - 1].range)
123
+ @list[i_b...i_e] = [Entry[range, value, CodeRangeTable.new(@list[i_b...i_e])]]
124
+ else
125
+ raise
126
+ end
127
+ end
128
+ else
129
+ @list[i_b, 0] = [Entry[range, value, CodeRangeTable.new]]
130
+ end
131
+ end
132
+
133
+ def [](loc)
134
+ e = @list.bsearch {|e| e.range.last > loc }
135
+ if e && e.range.contain_loc?(loc)
136
+ return e.children[loc] || e.value
137
+ end
138
+ return nil
139
+ end
140
+ end
141
+ end
142
+
143
+ if $0 == __FILE__
144
+ include TypeProf
145
+ cr1 = CodeRange.new(CodeLocation.new(1, 0), CodeLocation.new(1, 2))
146
+ cr2 = CodeRange.new(CodeLocation.new(1, 2), CodeLocation.new(1, 4))
147
+ cr3 = CodeRange.new(CodeLocation.new(2, 0), CodeLocation.new(2, 2))
148
+ cr4 = CodeRange.new(CodeLocation.new(2, 3), CodeLocation.new(2, 5))
149
+ cr1and2 = CodeRange.new(CodeLocation.new(1, 0), CodeLocation.new(1, 5))
150
+ cr3and4 = CodeRange.new(CodeLocation.new(2, 0), CodeLocation.new(2, 5))
151
+ [[cr1, "A"], [cr2, "B"], [cr3, "C"], [cr4, "D"], [cr1and2, "AB"], [cr3and4, "CD"]].permutation do |ary|
152
+ tbl = CodeRangeTable.new
153
+ ary.each do |cr, v|
154
+ tbl[cr] = v
155
+ end
156
+ values = []
157
+ [1, 2].each do |lineno|
158
+ (0..5).each do |column|
159
+ values << tbl[CodeLocation.new(lineno, column)]
160
+ end
161
+ end
162
+ raise if values != ["A", "A", "B", "B", "AB", nil, "C", "C", "CD", "D", "D", nil]
163
+ end
164
+
165
+ source = <<~EOS
166
+ AB
167
+ CDE
168
+ F
169
+ EOS
170
+ a_loc = CodeLocation.new(1, 0)
171
+ b_loc = a_loc.advance_cursor(1, source)
172
+ raise unless b_loc.inspect == "(1,1)"
173
+ c_loc = a_loc.advance_cursor(3, source)
174
+ raise unless c_loc.inspect == "(2,0)"
175
+ f_loc = c_loc.advance_cursor(4, source)
176
+ raise unless f_loc.inspect == "(3,0)"
177
+ end
@@ -6,12 +6,14 @@ module TypeProf
6
6
  :rbs_files,
7
7
  :output,
8
8
  :gem_rbs_features,
9
- :gem_repo_dirs,
9
+ :collection_path,
10
10
  :verbose,
11
11
  :dir_filter,
12
12
  :max_iter,
13
13
  :max_sec,
14
14
  :options,
15
+ :lsp_options,
16
+ :lsp,
15
17
  keyword_init: true
16
18
  )
17
19
 
@@ -26,7 +28,6 @@ module TypeProf
26
28
  def initialize(**opt)
27
29
  opt[:output] ||= $stdout
28
30
  opt[:gem_rbs_features] ||= []
29
- opt[:gem_repo_dirs] ||= []
30
31
  opt[:dir_filter] ||= DEFAULT_DIR_FILTER
31
32
  opt[:verbose] ||= 0
32
33
  opt[:options] ||= {}
@@ -43,6 +44,10 @@ module TypeProf
43
44
  union_width_limit: 10,
44
45
  stackprof: nil,
45
46
  }.merge(opt[:options])
47
+ opt[:lsp_options] = {
48
+ port: 0,
49
+ stdio: false,
50
+ }.merge(opt[:lsp_options] || {})
46
51
  super(**opt)
47
52
  end
48
53
 
@@ -61,29 +66,36 @@ module TypeProf
61
66
  ]
62
67
  end
63
68
 
64
- def self.analyze(config)
65
- # Deploy the config to the TypeProf::Config (Note: This is thread unsafe)
66
- if TypeProf.const_defined?(:Config)
67
- TypeProf.send(:remove_const, :Config)
69
+ module Config
70
+ def self.current
71
+ Thread.current[:typeprof_config]
68
72
  end
69
- TypeProf.const_set(:Config, config)
70
73
 
71
- if Config.options[:stackprof]
74
+ def self.set_current(config)
75
+ Thread.current[:typeprof_config] = config
76
+ end
77
+ end
78
+
79
+ def self.analyze(config, cancel_token = nil)
80
+ # Deploy the config to the TypeProf::Config (Note: This is thread local)
81
+ Config.set_current(config)
82
+
83
+ if Config.current.options[:stackprof]
72
84
  require "stackprof"
73
- out = "typeprof-stackprof-#{ Config.options[:stackprof] }.dump"
74
- StackProf.start(mode: Config.options[:stackprof], out: out, raw: true)
85
+ out = "typeprof-stackprof-#{ Config.current.options[:stackprof] }.dump"
86
+ StackProf.start(mode: Config.current.options[:stackprof], out: out, raw: true)
75
87
  end
76
88
 
77
89
  scratch = Scratch.new
78
90
  Builtin.setup_initial_global_env(scratch)
79
91
 
80
- Config.gem_rbs_features.each do |feature|
92
+ Config.current.gem_rbs_features.each do |feature|
81
93
  Import.import_library(scratch, feature)
82
94
  end
83
95
 
84
96
  rbs_files = []
85
97
  rbs_codes = []
86
- Config.rbs_files.each do |rbs|
98
+ Config.current.rbs_files.each do |rbs|
87
99
  if rbs.is_a?(Array) # [String name, String content]
88
100
  rbs_codes << rbs
89
101
  else
@@ -95,30 +107,39 @@ module TypeProf
95
107
  Import.import_rbs_code(scratch, name, content)
96
108
  end
97
109
 
98
- Config.rb_files.each do |rb|
110
+ def_code_range_table = nil
111
+ caller_code_range_table = nil
112
+ Config.current.rb_files.each do |rb|
99
113
  if rb.is_a?(Array) # [String name, String content]
100
- iseq = ISeq.compile_str(*rb.reverse)
114
+ iseq, def_tbl, caller_tbl = ISeq.compile_str(*rb.reverse)
115
+ def_code_range_table ||= def_tbl
116
+ caller_code_range_table ||= caller_tbl
101
117
  else
102
118
  iseq = rb
103
119
  end
104
120
  scratch.add_entrypoint(iseq)
105
121
  end
106
122
 
107
- result = scratch.type_profile
123
+ result = scratch.type_profile(cancel_token)
124
+
125
+ if Config.current.options[:lsp]
126
+ return scratch.report_lsp, def_code_range_table, caller_code_range_table
127
+ end
108
128
 
109
- if Config.output.respond_to?(:write)
110
- scratch.report(result, Config.output)
129
+ if Config.current.output.respond_to?(:write)
130
+ scratch.report(result, Config.current.output)
111
131
  else
112
- open(Config.output, "w") do |output|
132
+ open(Config.current.output, "w") do |output|
113
133
  scratch.report(result, output)
114
134
  end
115
135
  end
116
136
 
117
137
  rescue TypeProfError => exc
118
- exc.report(Config.output)
138
+ exc.report(Config.current.output)
119
139
 
140
+ return nil
120
141
  ensure
121
- if Config.options[:stackprof] && defined?(StackProf)
142
+ if Config.current.options[:stackprof] && defined?(StackProf)
122
143
  StackProf.stop
123
144
  StackProf.results
124
145
  end
@@ -307,7 +307,11 @@ module TypeProf
307
307
  def screen_name(scratch)
308
308
  if @rest_ty == Type.bot
309
309
  if @lead_tys.empty?
310
- return "Array[bot]" # RBS does not allow an empty tuple "[]"
310
+ # This is heuristic: in general, an empty array is a wrong guess.
311
+ # Note that an empty array is representable as "[ ]" in RBS, but
312
+ # users often have to modify it to "Array[something]".
313
+ # In this term, "Array[untyped]" is considered more useful than "[ ]".
314
+ return "Array[untyped]"
311
315
  end
312
316
  s = @lead_tys.map do |ty|
313
317
  ty.screen_name(scratch)
@@ -317,6 +321,9 @@ module TypeProf
317
321
  end
318
322
 
319
323
  "*[#{ squash.screen_name(scratch) }]"
324
+ rescue SystemStackError
325
+ p squash
326
+ exit!
320
327
  end
321
328
 
322
329
  def pretty_print(q)
@@ -673,6 +680,8 @@ module TypeProf
673
680
  k_ty = k_ty.union(k)
674
681
  v_ty = v_ty.union(v)
675
682
  end
683
+ k_ty = Type.any if k_ty == Type.bot
684
+ v_ty = Type.any if v_ty == Type.bot
676
685
  k_ty = k_ty.screen_name(scratch)
677
686
  v_ty = v_ty.screen_name(scratch)
678
687
  "Hash[#{ k_ty }, #{ v_ty }]"