steep 0.11.1 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (299) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +27 -0
  3. data/.gitmodules +3 -0
  4. data/CHANGELOG.md +5 -0
  5. data/README.md +48 -90
  6. data/Rakefile +10 -6
  7. data/Steepfile +1 -0
  8. data/bin/setup +1 -0
  9. data/bin/smoke_runner.rb +9 -14
  10. data/exe/rbs +3 -0
  11. data/exe/ruby-signature +3 -0
  12. data/exe/steep +1 -0
  13. data/lib/steep.rb +32 -26
  14. data/lib/steep/annotation_parser.rb +167 -0
  15. data/lib/steep/ast/annotation/collection.rb +7 -7
  16. data/lib/steep/ast/types.rb +60 -0
  17. data/lib/steep/ast/types/any.rb +1 -1
  18. data/lib/steep/ast/types/factory.rb +535 -0
  19. data/lib/steep/ast/types/name.rb +3 -3
  20. data/lib/steep/ast/types/var.rb +1 -1
  21. data/lib/steep/cli.rb +56 -240
  22. data/lib/steep/drivers/annotations.rb +36 -19
  23. data/lib/steep/drivers/check.rb +55 -91
  24. data/lib/steep/drivers/init.rb +54 -0
  25. data/lib/steep/drivers/langserver.rb +241 -150
  26. data/lib/steep/drivers/print_project.rb +56 -0
  27. data/lib/steep/drivers/signature_error_printer.rb +25 -0
  28. data/lib/steep/drivers/trace_printer.rb +25 -0
  29. data/lib/steep/drivers/utils/driver_helper.rb +26 -0
  30. data/lib/steep/drivers/validate.rb +18 -38
  31. data/lib/steep/drivers/vendor.rb +46 -0
  32. data/lib/steep/drivers/watch.rb +78 -140
  33. data/lib/steep/errors.rb +22 -13
  34. data/lib/steep/interface/interface.rb +91 -0
  35. data/lib/steep/interface/method.rb +0 -4
  36. data/lib/steep/interface/method_type.rb +362 -2
  37. data/lib/steep/interface/substitution.rb +22 -0
  38. data/lib/steep/project.rb +25 -233
  39. data/lib/steep/project/dsl.rb +132 -0
  40. data/lib/steep/project/file.rb +93 -76
  41. data/lib/steep/project/file_loader.rb +63 -0
  42. data/lib/steep/project/options.rb +7 -0
  43. data/lib/steep/project/target.rb +190 -0
  44. data/lib/steep/signature/errors.rb +25 -77
  45. data/lib/steep/signature/validator.rb +122 -0
  46. data/lib/steep/source.rb +12 -7
  47. data/lib/steep/subtyping/check.rb +357 -633
  48. data/lib/steep/subtyping/constraints.rb +2 -2
  49. data/lib/steep/subtyping/trace.rb +23 -0
  50. data/lib/steep/type_construction.rb +509 -455
  51. data/lib/steep/type_inference/constant_env.rb +16 -24
  52. data/lib/steep/type_inference/type_env.rb +26 -18
  53. data/lib/steep/version.rb +1 -1
  54. data/sample/Steepfile +6 -0
  55. data/sample/lib/conference.rb +12 -0
  56. data/sample/sig/conference.rbs +6 -0
  57. data/smoke/alias/Steepfile +4 -0
  58. data/smoke/alias/a.rb +2 -2
  59. data/smoke/alias/{a.rbi → a.rbs} +1 -1
  60. data/smoke/and/Steepfile +4 -0
  61. data/smoke/array/Steepfile +4 -0
  62. data/smoke/array/a.rb +2 -2
  63. data/smoke/array/b.rb +4 -4
  64. data/smoke/array/c.rb +2 -2
  65. data/smoke/block/Steepfile +5 -0
  66. data/smoke/block/{a.rbi → a.rbs} +1 -1
  67. data/smoke/block/{c.rbi → c.rbs} +0 -0
  68. data/smoke/block/d.rb +6 -6
  69. data/smoke/case/Steepfile +4 -0
  70. data/smoke/case/a.rb +4 -3
  71. data/smoke/class/Steepfile +4 -0
  72. data/smoke/class/a.rb +1 -4
  73. data/smoke/class/a.rbs +24 -0
  74. data/smoke/class/h.rb +6 -2
  75. data/smoke/class/{h.rbi → h.rbs} +1 -2
  76. data/smoke/class/i.rb +1 -2
  77. data/smoke/class/i.rbs +9 -0
  78. data/smoke/const/Steepfile +4 -0
  79. data/smoke/dstr/Steepfile +4 -0
  80. data/smoke/ensure/Steepfile +4 -0
  81. data/smoke/ensure/a.rb +1 -1
  82. data/smoke/enumerator/Steepfile +4 -0
  83. data/smoke/enumerator/a.rb +7 -7
  84. data/smoke/enumerator/b.rb +6 -6
  85. data/smoke/extension/Steepfile +4 -0
  86. data/smoke/extension/{a.rbi → a.rbs} +2 -2
  87. data/smoke/extension/{e.rbi → e.rbs} +2 -2
  88. data/smoke/hash/Steepfile +4 -0
  89. data/smoke/hash/{a.rbi → a.rbs} +0 -0
  90. data/smoke/hash/b.rb +2 -2
  91. data/smoke/hash/c.rb +1 -1
  92. data/smoke/hash/e.rbs +3 -0
  93. data/smoke/hash/f.rb +1 -1
  94. data/smoke/hello/Steepfile +4 -0
  95. data/smoke/hello/hello.rbs +7 -0
  96. data/smoke/if/Steepfile +4 -0
  97. data/smoke/implements/Steepfile +4 -0
  98. data/smoke/implements/a.rbs +6 -0
  99. data/smoke/initialize/Steepfile +4 -0
  100. data/smoke/initialize/a.rbs +3 -0
  101. data/smoke/integer/Steepfile +4 -0
  102. data/smoke/integer/a.rb +5 -3
  103. data/smoke/interface/Steepfile +4 -0
  104. data/smoke/interface/{a.rbi → a.rbs} +0 -0
  105. data/smoke/kwbegin/Steepfile +4 -0
  106. data/smoke/lambda/Steepfile +4 -0
  107. data/smoke/lambda/a.rb +9 -2
  108. data/smoke/literal/Steepfile +4 -0
  109. data/smoke/literal/{literal_methods.rbi → literal_methods.rbs} +0 -0
  110. data/smoke/map/Steepfile +4 -0
  111. data/smoke/map/a.rb +1 -1
  112. data/smoke/method/Steepfile +4 -0
  113. data/smoke/method/{a.rbi → a.rbs} +0 -0
  114. data/smoke/method/b.rb +1 -4
  115. data/smoke/method/d.rb +1 -0
  116. data/smoke/method/d.rbs +3 -0
  117. data/smoke/module/Steepfile +4 -0
  118. data/smoke/module/a.rb +1 -1
  119. data/smoke/module/a.rbs +16 -0
  120. data/smoke/module/c.rb +1 -1
  121. data/smoke/regexp/Steepfile +4 -0
  122. data/smoke/regexp/a.rb +2 -2
  123. data/smoke/regexp/b.rb +16 -16
  124. data/smoke/regression/Steepfile +5 -0
  125. data/smoke/regression/array.rb +2 -2
  126. data/smoke/regression/hash.rb +2 -2
  127. data/smoke/regression/poly_new.rb +2 -0
  128. data/smoke/regression/poly_new.rbs +4 -0
  129. data/smoke/regression/set_divide.rb +2 -2
  130. data/smoke/rescue/Steepfile +4 -0
  131. data/smoke/rescue/a.rb +1 -1
  132. data/smoke/self/Steepfile +4 -0
  133. data/smoke/self/a.rbs +4 -0
  134. data/smoke/skip/Steepfile +4 -0
  135. data/smoke/stdout/Steepfile +4 -0
  136. data/smoke/stdout/{a.rbi → a.rbs} +1 -1
  137. data/smoke/super/Steepfile +4 -0
  138. data/smoke/super/a.rbs +10 -0
  139. data/smoke/type_case/Steepfile +4 -0
  140. data/smoke/type_case/a.rb +1 -1
  141. data/smoke/yield/Steepfile +4 -0
  142. data/smoke/yield/a.rb +2 -2
  143. data/steep.gemspec +14 -7
  144. data/vendor/ruby-signature/.github/workflows/ruby.yml +27 -0
  145. data/vendor/ruby-signature/.gitignore +12 -0
  146. data/vendor/ruby-signature/.rubocop.yml +15 -0
  147. data/vendor/ruby-signature/BSDL +22 -0
  148. data/vendor/ruby-signature/COPYING +56 -0
  149. data/vendor/ruby-signature/Gemfile +6 -0
  150. data/vendor/ruby-signature/README.md +93 -0
  151. data/vendor/ruby-signature/Rakefile +66 -0
  152. data/vendor/ruby-signature/bin/annotate-with-rdoc +156 -0
  153. data/vendor/ruby-signature/bin/console +14 -0
  154. data/vendor/ruby-signature/bin/query-rdoc +103 -0
  155. data/vendor/ruby-signature/bin/setup +10 -0
  156. data/vendor/ruby-signature/bin/sort +88 -0
  157. data/vendor/ruby-signature/bin/test_runner.rb +17 -0
  158. data/vendor/ruby-signature/docs/CONTRIBUTING.md +97 -0
  159. data/vendor/ruby-signature/docs/sigs.md +148 -0
  160. data/vendor/ruby-signature/docs/stdlib.md +152 -0
  161. data/vendor/ruby-signature/docs/syntax.md +528 -0
  162. data/vendor/ruby-signature/exe/rbs +3 -0
  163. data/vendor/ruby-signature/exe/ruby-signature +7 -0
  164. data/vendor/ruby-signature/lib/ruby/signature.rb +64 -0
  165. data/vendor/ruby-signature/lib/ruby/signature/ast/annotation.rb +29 -0
  166. data/vendor/ruby-signature/lib/ruby/signature/ast/comment.rb +29 -0
  167. data/vendor/ruby-signature/lib/ruby/signature/ast/declarations.rb +391 -0
  168. data/vendor/ruby-signature/lib/ruby/signature/ast/members.rb +364 -0
  169. data/vendor/ruby-signature/lib/ruby/signature/buffer.rb +52 -0
  170. data/vendor/ruby-signature/lib/ruby/signature/builtin_names.rb +54 -0
  171. data/vendor/ruby-signature/lib/ruby/signature/cli.rb +534 -0
  172. data/vendor/ruby-signature/lib/ruby/signature/constant.rb +28 -0
  173. data/vendor/ruby-signature/lib/ruby/signature/constant_table.rb +152 -0
  174. data/vendor/ruby-signature/lib/ruby/signature/definition.rb +172 -0
  175. data/vendor/ruby-signature/lib/ruby/signature/definition_builder.rb +921 -0
  176. data/vendor/ruby-signature/lib/ruby/signature/environment.rb +283 -0
  177. data/vendor/ruby-signature/lib/ruby/signature/environment_loader.rb +138 -0
  178. data/vendor/ruby-signature/lib/ruby/signature/environment_walker.rb +126 -0
  179. data/vendor/ruby-signature/lib/ruby/signature/errors.rb +189 -0
  180. data/vendor/ruby-signature/lib/ruby/signature/location.rb +104 -0
  181. data/vendor/ruby-signature/lib/ruby/signature/method_type.rb +125 -0
  182. data/vendor/ruby-signature/lib/ruby/signature/namespace.rb +93 -0
  183. data/vendor/ruby-signature/lib/ruby/signature/parser.y +1343 -0
  184. data/vendor/ruby-signature/lib/ruby/signature/prototype/rb.rb +441 -0
  185. data/vendor/ruby-signature/lib/ruby/signature/prototype/rbi.rb +579 -0
  186. data/vendor/ruby-signature/lib/ruby/signature/prototype/runtime.rb +383 -0
  187. data/vendor/ruby-signature/lib/ruby/signature/substitution.rb +48 -0
  188. data/vendor/ruby-signature/lib/ruby/signature/test.rb +28 -0
  189. data/vendor/ruby-signature/lib/ruby/signature/test/errors.rb +63 -0
  190. data/vendor/ruby-signature/lib/ruby/signature/test/hook.rb +290 -0
  191. data/vendor/ruby-signature/lib/ruby/signature/test/setup.rb +58 -0
  192. data/vendor/ruby-signature/lib/ruby/signature/test/spy.rb +324 -0
  193. data/vendor/ruby-signature/lib/ruby/signature/test/test_helper.rb +185 -0
  194. data/vendor/ruby-signature/lib/ruby/signature/test/type_check.rb +256 -0
  195. data/vendor/ruby-signature/lib/ruby/signature/type_name.rb +72 -0
  196. data/vendor/ruby-signature/lib/ruby/signature/types.rb +932 -0
  197. data/vendor/ruby-signature/lib/ruby/signature/variance_calculator.rb +140 -0
  198. data/vendor/ruby-signature/lib/ruby/signature/vendorer.rb +49 -0
  199. data/vendor/ruby-signature/lib/ruby/signature/version.rb +5 -0
  200. data/vendor/ruby-signature/lib/ruby/signature/writer.rb +271 -0
  201. data/vendor/ruby-signature/ruby-signature.gemspec +45 -0
  202. data/vendor/ruby-signature/stdlib/abbrev/abbrev.rbs +3 -0
  203. data/vendor/ruby-signature/stdlib/base64/base64.rbs +15 -0
  204. data/vendor/ruby-signature/stdlib/builtin/array.rbs +1997 -0
  205. data/vendor/ruby-signature/stdlib/builtin/basic_object.rbs +280 -0
  206. data/vendor/ruby-signature/stdlib/builtin/binding.rbs +177 -0
  207. data/vendor/ruby-signature/stdlib/builtin/builtin.rbs +35 -0
  208. data/vendor/ruby-signature/stdlib/builtin/class.rbs +145 -0
  209. data/vendor/ruby-signature/stdlib/builtin/comparable.rbs +116 -0
  210. data/vendor/ruby-signature/stdlib/builtin/complex.rbs +400 -0
  211. data/vendor/ruby-signature/stdlib/builtin/constants.rbs +37 -0
  212. data/vendor/ruby-signature/stdlib/builtin/data.rbs +5 -0
  213. data/vendor/ruby-signature/stdlib/builtin/deprecated.rbs +2 -0
  214. data/vendor/ruby-signature/stdlib/builtin/dir.rbs +419 -0
  215. data/vendor/ruby-signature/stdlib/builtin/encoding.rbs +606 -0
  216. data/vendor/ruby-signature/stdlib/builtin/enumerable.rbs +404 -0
  217. data/vendor/ruby-signature/stdlib/builtin/enumerator.rbs +260 -0
  218. data/vendor/ruby-signature/stdlib/builtin/errno.rbs +781 -0
  219. data/vendor/ruby-signature/stdlib/builtin/errors.rbs +582 -0
  220. data/vendor/ruby-signature/stdlib/builtin/exception.rbs +193 -0
  221. data/vendor/ruby-signature/stdlib/builtin/false_class.rbs +40 -0
  222. data/vendor/ruby-signature/stdlib/builtin/fiber.rbs +68 -0
  223. data/vendor/ruby-signature/stdlib/builtin/fiber_error.rbs +12 -0
  224. data/vendor/ruby-signature/stdlib/builtin/file.rbs +476 -0
  225. data/vendor/ruby-signature/stdlib/builtin/file_test.rbs +59 -0
  226. data/vendor/ruby-signature/stdlib/builtin/float.rbs +696 -0
  227. data/vendor/ruby-signature/stdlib/builtin/gc.rbs +121 -0
  228. data/vendor/ruby-signature/stdlib/builtin/hash.rbs +1029 -0
  229. data/vendor/ruby-signature/stdlib/builtin/integer.rbs +710 -0
  230. data/vendor/ruby-signature/stdlib/builtin/io.rbs +683 -0
  231. data/vendor/ruby-signature/stdlib/builtin/kernel.rbs +574 -0
  232. data/vendor/ruby-signature/stdlib/builtin/marshal.rbs +135 -0
  233. data/vendor/ruby-signature/stdlib/builtin/match_data.rbs +141 -0
  234. data/vendor/ruby-signature/stdlib/builtin/math.rbs +66 -0
  235. data/vendor/ruby-signature/stdlib/builtin/method.rbs +182 -0
  236. data/vendor/ruby-signature/stdlib/builtin/module.rbs +248 -0
  237. data/vendor/ruby-signature/stdlib/builtin/nil_class.rbs +82 -0
  238. data/vendor/ruby-signature/stdlib/builtin/numeric.rbs +409 -0
  239. data/vendor/ruby-signature/stdlib/builtin/object.rbs +824 -0
  240. data/vendor/ruby-signature/stdlib/builtin/proc.rbs +426 -0
  241. data/vendor/ruby-signature/stdlib/builtin/process.rbs +354 -0
  242. data/vendor/ruby-signature/stdlib/builtin/random.rbs +93 -0
  243. data/vendor/ruby-signature/stdlib/builtin/range.rbs +226 -0
  244. data/vendor/ruby-signature/stdlib/builtin/rational.rbs +424 -0
  245. data/vendor/ruby-signature/stdlib/builtin/rb_config.rbs +10 -0
  246. data/vendor/ruby-signature/stdlib/builtin/regexp.rbs +131 -0
  247. data/vendor/ruby-signature/stdlib/builtin/ruby_vm.rbs +14 -0
  248. data/vendor/ruby-signature/stdlib/builtin/signal.rbs +55 -0
  249. data/vendor/ruby-signature/stdlib/builtin/string.rbs +770 -0
  250. data/vendor/ruby-signature/stdlib/builtin/string_io.rbs +13 -0
  251. data/vendor/ruby-signature/stdlib/builtin/struct.rbs +40 -0
  252. data/vendor/ruby-signature/stdlib/builtin/symbol.rbs +230 -0
  253. data/vendor/ruby-signature/stdlib/builtin/thread.rbs +1112 -0
  254. data/vendor/ruby-signature/stdlib/builtin/thread_group.rbs +23 -0
  255. data/vendor/ruby-signature/stdlib/builtin/time.rbs +739 -0
  256. data/vendor/ruby-signature/stdlib/builtin/trace_point.rbs +91 -0
  257. data/vendor/ruby-signature/stdlib/builtin/true_class.rbs +46 -0
  258. data/vendor/ruby-signature/stdlib/builtin/unbound_method.rbs +159 -0
  259. data/vendor/ruby-signature/stdlib/builtin/warning.rbs +17 -0
  260. data/vendor/ruby-signature/stdlib/erb/erb.rbs +18 -0
  261. data/vendor/ruby-signature/stdlib/find/find.rbs +44 -0
  262. data/vendor/ruby-signature/stdlib/pathname/pathname.rbs +21 -0
  263. data/vendor/ruby-signature/stdlib/prime/integer-extension.rbs +23 -0
  264. data/vendor/ruby-signature/stdlib/prime/prime.rbs +188 -0
  265. data/vendor/ruby-signature/stdlib/securerandom/securerandom.rbs +9 -0
  266. data/vendor/ruby-signature/stdlib/set/set.rbs +77 -0
  267. data/vendor/ruby-signature/stdlib/tmpdir/tmpdir.rbs +53 -0
  268. metadata +244 -54
  269. data/.travis.yml +0 -7
  270. data/lib/steep/ast/signature/alias.rb +0 -19
  271. data/lib/steep/ast/signature/class.rb +0 -33
  272. data/lib/steep/ast/signature/const.rb +0 -17
  273. data/lib/steep/ast/signature/env.rb +0 -138
  274. data/lib/steep/ast/signature/extension.rb +0 -21
  275. data/lib/steep/ast/signature/gvar.rb +0 -17
  276. data/lib/steep/ast/signature/interface.rb +0 -31
  277. data/lib/steep/ast/signature/members.rb +0 -115
  278. data/lib/steep/ast/signature/module.rb +0 -21
  279. data/lib/steep/drivers/print_interface.rb +0 -94
  280. data/lib/steep/drivers/scaffold.rb +0 -321
  281. data/lib/steep/drivers/utils/each_signature.rb +0 -31
  282. data/lib/steep/interface/abstract.rb +0 -68
  283. data/lib/steep/interface/builder.rb +0 -637
  284. data/lib/steep/interface/instantiated.rb +0 -163
  285. data/lib/steep/interface/ivar_chain.rb +0 -26
  286. data/lib/steep/parser.y +0 -1278
  287. data/lib/steep/project/listener.rb +0 -53
  288. data/smoke/class/a.rbi +0 -24
  289. data/smoke/class/d.rb +0 -9
  290. data/smoke/class/e.rb +0 -12
  291. data/smoke/class/i.rbi +0 -9
  292. data/smoke/hash/e.rbi +0 -3
  293. data/smoke/hello/hello.rbi +0 -7
  294. data/smoke/implements/a.rbi +0 -6
  295. data/smoke/initialize/a.rbi +0 -3
  296. data/smoke/module/a.rbi +0 -16
  297. data/smoke/self/a.rbi +0 -4
  298. data/smoke/super/a.rbi +0 -10
  299. data/stdlib/builtin.rbi +0 -787
@@ -0,0 +1,156 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "ruby/signature"
4
+ require "rdoc"
5
+
6
+ def store_for_class(name, stores:)
7
+ stores.find do |store|
8
+ store.find_class_named(name) || store.find_module_named(name)
9
+ end
10
+ end
11
+
12
+ def format_comment(comment)
13
+ out = RDoc::Markup::Document.new
14
+ out << comment
15
+ formatter = RDoc::Markup::ToMarkdown.new
16
+ out.accept(formatter)
17
+ end
18
+
19
+ def comment_for_constant(decl, stores:)
20
+ class_name = decl.name.namespace.to_type_name.to_s
21
+ klass = store_for_class(class_name, stores: stores)&.yield_self {|store|
22
+ store.find_class_named(class_name) || store.find_module_named(class_name)
23
+ }
24
+
25
+ if klass
26
+ constant = klass.constants.find do |const|
27
+ const.name == decl.name.name.to_s
28
+ end
29
+
30
+ if constant&.documented?
31
+ string = format_comment(constant.comment)
32
+ Ruby::Signature::AST::Comment.new(location: nil, string: string)
33
+ end
34
+ end
35
+ end
36
+
37
+ def comment_for_class(decl, stores:)
38
+ name = decl.name.to_s
39
+ klass = store_for_class(name, stores: stores)&.yield_self {|store|
40
+ store.find_class_named(name) || store.find_module_named(name)
41
+ }
42
+
43
+ if klass&.documented?
44
+ string = format_comment(klass.comment)
45
+ Ruby::Signature::AST::Comment.new(location: nil, string: string)
46
+ end
47
+ end
48
+
49
+ def comment_for_method(klass, method, stores:)
50
+ method = store_for_class(klass, stores: stores)&.load_method(klass, method)
51
+
52
+ if method&.documented?
53
+ out = RDoc::Markup::Document.new
54
+
55
+ out << method.comment
56
+
57
+ if method.arglists
58
+ out << RDoc::Markup::Heading.new(1, "arglists 💪👽🚨 << Delete this section")
59
+ arglists = method.arglists.chomp.split("\n").map {|line| line + "\n" }
60
+ out << RDoc::Markup::Verbatim.new(*arglists)
61
+ end
62
+
63
+ string = out.accept(RDoc::Markup::ToMarkdown.new)
64
+ Ruby::Signature::AST::Comment.new(location: nil, string: string)
65
+ end
66
+
67
+ rescue RDoc::Store::MissingFileError
68
+ puts " 👺 No document found for #{klass}#{method}"
69
+ nil
70
+ end
71
+
72
+ if ARGV.empty?
73
+ puts 'annotate-with-rdoc [RBS files...]'
74
+ exit
75
+ end
76
+
77
+ def print_members(stores, klass_name, members)
78
+ members.each do |member|
79
+ case member
80
+ when Ruby::Signature::AST::Members::MethodDefinition
81
+ puts " Processing #{member.name}..."
82
+
83
+ method_name = case
84
+ when member.instance?
85
+ "##{member.name}"
86
+ when member.singleton?
87
+ "::#{member.name}"
88
+ end
89
+
90
+ comment = comment_for_method(klass_name, method_name, stores: stores)
91
+
92
+ unless comment
93
+ if member.instance? && member.name == :initialize
94
+ comment = comment_for_method(klass_name, '::new', stores: stores)
95
+ end
96
+ end
97
+
98
+ member.instance_variable_set(:@comment, comment)
99
+ when Ruby::Signature::AST::Members::AttrReader, Ruby::Signature::AST::Members::AttrAccessor, Ruby::Signature::AST::Members::AttrWriter
100
+ puts " 👻 Attributes not supported (#{klass_name})"
101
+ when Ruby::Signature::AST::Members::Alias
102
+ puts " Processing #{member.new_name}(alias)..."
103
+ prefix = case
104
+ when member.instance?
105
+ "#"
106
+ when member.singleton?
107
+ "."
108
+ end
109
+ name = "#{prefix}#{member.new_name}"
110
+
111
+ comment = comment_for_method(klass_name, name, stores: stores)
112
+ member.instance_variable_set(:@comment, comment)
113
+ end
114
+ end
115
+ end
116
+
117
+ stores = []
118
+ RDoc::RI::Paths.each true, true, false, false do |path, type|
119
+ puts "Loading store from #{path}..."
120
+ store = RDoc::RI::Store.new(path, type)
121
+ store.load_all
122
+ stores << store
123
+ end
124
+
125
+ ARGV.map {|f| Pathname(f) }.each do |path|
126
+ puts "Opening #{path}..."
127
+
128
+ buffer = Ruby::Signature::Buffer.new(name: path, content: path.read)
129
+ sigs = Ruby::Signature::Parser.parse_signature(buffer)
130
+
131
+ sigs.each do |decl|
132
+ case decl
133
+ when Ruby::Signature::AST::Declarations::Constant
134
+ puts " Importing documentation for #{decl.name}..."
135
+ comment = comment_for_constant(decl, stores: stores)
136
+ decl.instance_variable_set(:@comment, comment)
137
+ when Ruby::Signature::AST::Declarations::Class, Ruby::Signature::AST::Declarations::Module
138
+ puts " Importing documentation for #{decl.name}..."
139
+ comment = comment_for_class(decl, stores: stores)
140
+ decl.instance_variable_set(:@comment, comment)
141
+
142
+ print_members stores, decl.name.to_s, decl.members
143
+ when Ruby::Signature::AST::Declarations::Extension
144
+ puts " Importing documentation for #{decl.name} (#{decl.extension_name})"
145
+
146
+ print_members stores, decl.name.to_s, decl.members
147
+ end
148
+ end
149
+
150
+ puts "Writing #{path}..."
151
+ path.open('w') do |out|
152
+ writer = Ruby::Signature::Writer.new(out: out)
153
+ writer.write sigs
154
+ end
155
+ end
156
+
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "ruby/signature"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "rdoc"
4
+
5
+ def store_for_class(name, stores:)
6
+ stores.find do |store|
7
+ store.find_class_named(name) || store.find_module_named(name)
8
+ end
9
+ end
10
+
11
+ def format_comment(comment)
12
+ out = RDoc::Markup::Document.new
13
+ out << comment
14
+ formatter = RDoc::Markup::ToMarkdown.new
15
+ out.accept(formatter)
16
+ end
17
+
18
+ def comment_for_constant(name, stores:)
19
+ *class_components, const_name = name.split(/::/)
20
+ class_name = class_components.join("::")
21
+
22
+ klass = store_for_class(class_name, stores: stores)&.yield_self {|store|
23
+ store.find_class_named(class_name) || store.find_module_named(class_name)
24
+ }
25
+
26
+ constant = klass.constants.find do |const|
27
+ const.name == const_name
28
+ end
29
+
30
+ if constant&.documented?
31
+ format_comment(constant.comment)
32
+ end
33
+ end
34
+
35
+ def comment_for_class(class_name, stores:)
36
+ klass = store_for_class(class_name, stores: stores)&.yield_self {|store|
37
+ store.find_class_named(class_name) || store.find_module_named(class_name)
38
+ }
39
+
40
+ if klass&.documented?
41
+ format_comment(klass.comment)
42
+ end
43
+ end
44
+
45
+ def comment_for_method(klass, method, stores:)
46
+ method = store_for_class(klass, stores: stores)&.load_method(klass, method)
47
+
48
+ if method&.documented?
49
+ out = RDoc::Markup::Document.new
50
+
51
+ out << method.comment
52
+
53
+ if method.arglists
54
+ out << RDoc::Markup::Heading.new(1, "arglists 💪👽🚨 << Delete this section")
55
+ arglists = method.arglists.chomp.split("\n").map {|line| line + "\n" }
56
+ out << RDoc::Markup::Verbatim.new(*arglists)
57
+ end
58
+
59
+ out.accept(RDoc::Markup::ToMarkdown.new)
60
+ end
61
+ rescue RDoc::Store::MissingFileError
62
+ nil
63
+ end
64
+
65
+ if ARGV.empty?
66
+ puts 'query-rdoc [subject]'
67
+ puts " subject ::= ClassName (class, module, or constant)"
68
+ puts " | ClassName.method (singleton method)"
69
+ puts " | ClassName#method (instance method)"
70
+ exit
71
+ end
72
+
73
+ stores = []
74
+ RDoc::RI::Paths.each true, true, false, false do |path, type|
75
+ STDERR.puts "Loading store from #{path}..."
76
+ store = RDoc::RI::Store.new(path, type)
77
+ store.load_all
78
+ stores << store
79
+ end
80
+
81
+ subject = ARGV[0]
82
+
83
+ case
84
+ when match = subject.match(/(?<constant_name>[^#]+)#(?<method_name>.+)/)
85
+ STDERR.puts "Finding instance method #{match[:constant_name]} # #{match[:method_name]} ..."
86
+ comment = comment_for_method(match[:constant_name], "##{match[:method_name]}", stores: stores)
87
+ when match = subject.match(/(?<constant_name>[^.]+)\.(?<method_name>.+)/)
88
+ STDERR.puts "Finding singleton method #{match[:constant_name]} . #{match[:method_name]} ..."
89
+ comment = comment_for_method(match[:constant_name], "::#{match[:method_name]}", stores: stores)
90
+ else
91
+ STDERR.puts "Finding class/module/constant #{subject} ..."
92
+ comment = comment_for_class(subject, stores: stores) || comment_for_constant(subject, stores: stores)
93
+ end
94
+
95
+ if comment
96
+ STDERR.puts "Printing document..."
97
+ comment.each_line do |line|
98
+ puts "# #{line}"
99
+ end
100
+ else
101
+ STDERR.puts "Nothing to print; failed to query the document..."
102
+ exit 1
103
+ end
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
9
+
10
+ bundle exec rake parser
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "ruby/signature"
4
+
5
+ Members = Ruby::Signature::AST::Members
6
+
7
+ def group(member)
8
+ case member
9
+ when Members::Include, Members::Extend, Members::Prepend
10
+ 0
11
+ when Members::ClassVariable
12
+ -3
13
+ when Members::ClassInstanceVariable
14
+ -2
15
+ when Members::InstanceVariable
16
+ -1
17
+ when Members::AttrAccessor, Members::AttrWriter, Members::AttrReader
18
+ 2
19
+ when Members::MethodDefinition
20
+ if member.singleton?
21
+ if member.name == :new
22
+ 0.4
23
+ else
24
+ 1
25
+ end
26
+ else
27
+ if member.name == :initialize
28
+ 0.5
29
+ else
30
+ 3
31
+ end
32
+ end
33
+ when Members::Alias
34
+ if member.singleton?
35
+ 1
36
+ else
37
+ 3
38
+ end
39
+ when Members::Private, Members::Public
40
+ -4
41
+ end
42
+ end
43
+
44
+ def key(member)
45
+ case member
46
+ when Members::Include, Members::Extend, Members::Prepend
47
+ member.name.to_s
48
+ when Members::ClassVariable, Members::ClassInstanceVariable, Members::InstanceVariable
49
+ member.name.to_s
50
+ when Members::AttrAccessor, Members::AttrWriter, Members::AttrReader
51
+ member.name.to_s
52
+ when Members::MethodDefinition
53
+ member.name.to_s
54
+ when Members::Alias
55
+ member.new_name.to_s
56
+ else
57
+ 1
58
+ end
59
+ end
60
+
61
+ ARGV.map {|f| Pathname(f) }.each do |path|
62
+ puts "Opening #{path}..."
63
+
64
+ buffer = Ruby::Signature::Buffer.new(name: path, content: path.read)
65
+ sigs = Ruby::Signature::Parser.parse_signature(buffer)
66
+
67
+ sigs.each do |sig|
68
+ case sig
69
+ when Ruby::Signature::AST::Declarations::Class, Ruby::Signature::AST::Declarations::Module, Ruby::Signature::AST::Declarations::Interface
70
+ sig.members.sort! do |m1, m2|
71
+ group1 = group(m1)
72
+ group2 = group(m2)
73
+
74
+ if group1 == group2
75
+ key(m1) <=> key(m2)
76
+ else
77
+ group1 <=> group2
78
+ end
79
+ end
80
+ end
81
+ end
82
+
83
+ puts "Writing #{path}..."
84
+ path.open('w') do |out|
85
+ writer = Ruby::Signature::Writer.new(out: out)
86
+ writer.write sigs
87
+ end
88
+ end
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ RUBY_27_OR_LATER = Gem::Version.new('2.7.0') <= Gem::Version.new(RUBY_VERSION)
4
+ RUBY_27 = Gem::Version.new(RUBY_VERSION).yield_self do |ruby_version|
5
+ Gem::Version.new('2.7.0') <= ruby_version && ruby_version < Gem::Version.new("2.8.0")
6
+ end
7
+
8
+ unless RUBY_27
9
+ STDERR.puts "🚨🚨🚨 stdlib test requires Ruby 2.7 but RUBY_VERSION==#{RUBY_VERSION}, exiting... 🚨🚨🚨"
10
+ exit
11
+ end
12
+
13
+ require "pathname"
14
+
15
+ ARGV.each do |arg|
16
+ load arg
17
+ end
@@ -0,0 +1,97 @@
1
+ # Standard Library Signatures Contribution Guide
2
+
3
+ ## Guides
4
+
5
+ * [Stdlib Signatures Guide](stdlib.md)
6
+ * [Syntax](syntax.md)
7
+ * [Writing Signature Guide](sigs.md)
8
+
9
+ ## Steps for Contribution
10
+
11
+ 1. Pick the class/library you will work for.
12
+ 2. Assign yourself on the [work spreadsheet](https://docs.google.com/spreadsheets/d/199rRB93I16H0k4TGZS3EGojns2R0W1oCsN8UPJzOpyU/edit#gid=1383307992) (optional but recommended to avoid duplication).
13
+ 3. Sort RBS members (if there is RBS files for the classes).
14
+ - Use `bin/sort stdlib/path/to/signature.rbs` command and confirm it does not break definitions.
15
+ - Committing the sorted RBSs is recommended.
16
+ 4. Add method prototypes.
17
+ - Use `rbs prototype runtime --merge CLASS_NAME` command to generate the missing method definitions.
18
+ - Committing the auto generated signatures is recommended.
19
+ 5. Annotate with RDoc.
20
+ - Use `bin/annotate-with-rdoc stdlib/path/to/signature.rbs` to annotate the RBS files.
21
+ - Committing the generated annotations is recommended.
22
+ 6. Fix method types and comments.
23
+ - The auto generated RDoc comments include `argslist` section, which we don't expect to be included the RBS files.
24
+ - Delete the `argslist` sections.
25
+ - Give methods correct types.
26
+ - Write tests, if possible. (If it is too difficult to write test, skip it.)
27
+
28
+ ## The Target Version
29
+
30
+ * The standard library signatures targets Ruby 2.7 for now.
31
+ * The library code targets Ruby 2.6, 2.7, and 3.0.
32
+
33
+ ## Stdlib Worksheet
34
+
35
+ You can find the list of classes/libraries:
36
+
37
+ * https://docs.google.com/spreadsheets/d/199rRB93I16H0k4TGZS3EGojns2R0W1oCsN8UPJzOpyU/edit#gid=1383307992
38
+
39
+ Assign yourself when you start working for a class or library.
40
+ After reviewing and merging your pull request, I will update the status of the library.
41
+
42
+ You may find the *Good for first contributor* column where you can find some classes are recommended for new contributors (👍), and some classes are not-recommended (👎).
43
+
44
+ ## Useful Tools
45
+
46
+ * `rbs prototype runtime --merge String`
47
+ * Generate a prototype using runtime API.
48
+ * `--merge` tells to use the method types in RBS if exists.
49
+ * `rbs prototype runtime --merge --method-owner=Numeric Integer`
50
+ * You can use --method-owner if you want to print method of other classes too, for documentation purpose.
51
+ * `bin/annotate-with-rdoc stdlib/builtin/string.rbs`
52
+ * Write comments using RDoc.
53
+ * It contains argslist section, but I don't think we should have it in RBS files.
54
+ * `bin/query-rdoc String#initialize`
55
+ * Print RDoc documents in the format you can copy-and-paste to RBS.
56
+ * `bin/sort stdlib/builtin/string.rbs`
57
+ * Sort declarations members in RBS files.
58
+ * `rbs validate -r LIB`
59
+ Validate the syntax and some of the semantics.
60
+ * `rake generate::stdlib_test[String]`
61
+ Scaffold the stdlib test.
62
+
63
+ ## Standard STDLIB Members Order
64
+
65
+ We define the standard members order so that ordering doesn't bother reading diffs or git-annotate outputs.
66
+
67
+ 1. `def self.new` or `def initialize`
68
+ 2. Mixins
69
+ 3. Attributes
70
+ 4. Singleton methods
71
+ 5. `public` & public instance methods
72
+ 6. `private` & private instance methods
73
+
74
+ ```
75
+ class HelloWorld[X]
76
+ def self.new: [A] () { (void) -> A } -> HelloWorld[A] # new or initialize comes first
77
+ def initialize: () -> void
78
+
79
+ include Enumerable[X, void] # Mixin comes next
80
+
81
+ attr_reader language: (:ja | :en) # Attributes
82
+
83
+ def self.all_languages: () -> Array[Symbol] # Singleton methods
84
+
85
+ public # Public instance methods
86
+
87
+ def each: () { (A) -> void } -> void # Members are sorted dicionary order
88
+
89
+ def to_s: (?Locale) -> String
90
+
91
+ private # Private instance methods
92
+
93
+ alias validate validate_locale
94
+
95
+ def validate_locale: () -> void
96
+ end
97
+ ```