steep 0.13.0 → 0.16.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (214) hide show
  1. checksums.yaml +4 -4
  2. data/.gitmodules +0 -3
  3. data/CHANGELOG.md +28 -0
  4. data/Rakefile +0 -13
  5. data/bin/setup +0 -2
  6. data/bin/smoke_runner.rb +0 -1
  7. data/exe/steep +0 -1
  8. data/lib/steep.rb +33 -1
  9. data/lib/steep/annotation_parser.rb +4 -4
  10. data/lib/steep/ast/buffer.rb +11 -7
  11. data/lib/steep/ast/builtin.rb +8 -0
  12. data/lib/steep/ast/types/factory.rb +124 -89
  13. data/lib/steep/cli.rb +16 -1
  14. data/lib/steep/drivers/annotations.rb +1 -1
  15. data/lib/steep/drivers/check.rb +20 -4
  16. data/lib/steep/drivers/init.rb +5 -5
  17. data/lib/steep/drivers/langserver.rb +13 -287
  18. data/lib/steep/drivers/utils/driver_helper.rb +1 -1
  19. data/lib/steep/drivers/vendor.rb +2 -2
  20. data/lib/steep/drivers/watch.rb +97 -85
  21. data/lib/steep/drivers/worker.rb +51 -0
  22. data/lib/steep/project.rb +9 -5
  23. data/lib/steep/project/completion_provider.rb +298 -0
  24. data/lib/steep/project/dsl.rb +14 -0
  25. data/lib/steep/project/file.rb +54 -47
  26. data/lib/steep/project/hover_content.rb +17 -8
  27. data/lib/steep/project/options.rb +25 -3
  28. data/lib/steep/project/target.rb +40 -24
  29. data/lib/steep/server/base_worker.rb +56 -0
  30. data/lib/steep/server/code_worker.rb +151 -0
  31. data/lib/steep/server/interaction_worker.rb +281 -0
  32. data/lib/steep/server/master.rb +196 -0
  33. data/lib/steep/server/signature_worker.rb +148 -0
  34. data/lib/steep/server/utils.rb +36 -0
  35. data/lib/steep/server/worker_process.rb +62 -0
  36. data/lib/steep/signature/errors.rb +1 -1
  37. data/lib/steep/signature/validator.rb +13 -13
  38. data/lib/steep/source.rb +1 -1
  39. data/lib/steep/type_construction.rb +1004 -727
  40. data/lib/steep/type_inference/constant_env.rb +3 -11
  41. data/lib/steep/type_inference/context.rb +8 -3
  42. data/lib/steep/type_inference/context_array.rb +111 -0
  43. data/lib/steep/type_inference/local_variable_type_env.rb +226 -0
  44. data/lib/steep/type_inference/logic.rb +130 -0
  45. data/lib/steep/type_inference/type_env.rb +5 -69
  46. data/lib/steep/typing.rb +91 -23
  47. data/lib/steep/version.rb +1 -1
  48. data/smoke/alias/Steepfile +1 -0
  49. data/smoke/alias/a.rb +1 -1
  50. data/smoke/and/Steepfile +1 -0
  51. data/smoke/array/Steepfile +1 -0
  52. data/smoke/array/b.rb +0 -2
  53. data/smoke/block/Steepfile +1 -0
  54. data/smoke/case/Steepfile +1 -0
  55. data/smoke/class/Steepfile +1 -0
  56. data/smoke/const/Steepfile +1 -0
  57. data/smoke/dstr/Steepfile +1 -0
  58. data/smoke/ensure/Steepfile +1 -0
  59. data/smoke/enumerator/Steepfile +1 -0
  60. data/smoke/extension/Steepfile +1 -0
  61. data/smoke/extension/c.rb +1 -0
  62. data/smoke/hash/Steepfile +1 -0
  63. data/smoke/hello/Steepfile +1 -0
  64. data/smoke/if/Steepfile +1 -0
  65. data/smoke/if/a.rb +1 -1
  66. data/smoke/implements/Steepfile +1 -0
  67. data/smoke/initialize/Steepfile +1 -0
  68. data/smoke/integer/Steepfile +1 -0
  69. data/smoke/interface/Steepfile +1 -0
  70. data/smoke/kwbegin/Steepfile +1 -0
  71. data/smoke/lambda/Steepfile +1 -0
  72. data/smoke/literal/Steepfile +1 -0
  73. data/smoke/map/Steepfile +1 -0
  74. data/smoke/method/Steepfile +1 -0
  75. data/smoke/module/Steepfile +1 -0
  76. data/smoke/regexp/Steepfile +1 -0
  77. data/smoke/regexp/b.rb +4 -4
  78. data/smoke/regression/Steepfile +1 -0
  79. data/smoke/rescue/Steepfile +1 -0
  80. data/smoke/rescue/a.rb +1 -1
  81. data/smoke/self/Steepfile +1 -0
  82. data/smoke/skip/Steepfile +1 -0
  83. data/smoke/stdout/Steepfile +1 -0
  84. data/smoke/super/Steepfile +1 -0
  85. data/smoke/type_case/Steepfile +1 -0
  86. data/smoke/yield/Steepfile +1 -0
  87. data/steep.gemspec +8 -8
  88. metadata +38 -138
  89. data/exe/rbs +0 -3
  90. data/exe/ruby-signature +0 -3
  91. data/vendor/ruby-signature/.github/workflows/ruby.yml +0 -27
  92. data/vendor/ruby-signature/.gitignore +0 -12
  93. data/vendor/ruby-signature/.rubocop.yml +0 -15
  94. data/vendor/ruby-signature/BSDL +0 -22
  95. data/vendor/ruby-signature/COPYING +0 -56
  96. data/vendor/ruby-signature/Gemfile +0 -6
  97. data/vendor/ruby-signature/README.md +0 -93
  98. data/vendor/ruby-signature/Rakefile +0 -66
  99. data/vendor/ruby-signature/bin/annotate-with-rdoc +0 -156
  100. data/vendor/ruby-signature/bin/console +0 -14
  101. data/vendor/ruby-signature/bin/query-rdoc +0 -103
  102. data/vendor/ruby-signature/bin/setup +0 -10
  103. data/vendor/ruby-signature/bin/sort +0 -88
  104. data/vendor/ruby-signature/bin/test_runner.rb +0 -17
  105. data/vendor/ruby-signature/docs/CONTRIBUTING.md +0 -97
  106. data/vendor/ruby-signature/docs/sigs.md +0 -148
  107. data/vendor/ruby-signature/docs/stdlib.md +0 -152
  108. data/vendor/ruby-signature/docs/syntax.md +0 -528
  109. data/vendor/ruby-signature/exe/rbs +0 -3
  110. data/vendor/ruby-signature/exe/ruby-signature +0 -7
  111. data/vendor/ruby-signature/lib/ruby/signature.rb +0 -64
  112. data/vendor/ruby-signature/lib/ruby/signature/ast/annotation.rb +0 -29
  113. data/vendor/ruby-signature/lib/ruby/signature/ast/comment.rb +0 -29
  114. data/vendor/ruby-signature/lib/ruby/signature/ast/declarations.rb +0 -391
  115. data/vendor/ruby-signature/lib/ruby/signature/ast/members.rb +0 -364
  116. data/vendor/ruby-signature/lib/ruby/signature/buffer.rb +0 -52
  117. data/vendor/ruby-signature/lib/ruby/signature/builtin_names.rb +0 -54
  118. data/vendor/ruby-signature/lib/ruby/signature/cli.rb +0 -534
  119. data/vendor/ruby-signature/lib/ruby/signature/constant.rb +0 -28
  120. data/vendor/ruby-signature/lib/ruby/signature/constant_table.rb +0 -152
  121. data/vendor/ruby-signature/lib/ruby/signature/definition.rb +0 -172
  122. data/vendor/ruby-signature/lib/ruby/signature/definition_builder.rb +0 -921
  123. data/vendor/ruby-signature/lib/ruby/signature/environment.rb +0 -283
  124. data/vendor/ruby-signature/lib/ruby/signature/environment_loader.rb +0 -138
  125. data/vendor/ruby-signature/lib/ruby/signature/environment_walker.rb +0 -126
  126. data/vendor/ruby-signature/lib/ruby/signature/errors.rb +0 -189
  127. data/vendor/ruby-signature/lib/ruby/signature/location.rb +0 -104
  128. data/vendor/ruby-signature/lib/ruby/signature/method_type.rb +0 -125
  129. data/vendor/ruby-signature/lib/ruby/signature/namespace.rb +0 -93
  130. data/vendor/ruby-signature/lib/ruby/signature/parser.y +0 -1343
  131. data/vendor/ruby-signature/lib/ruby/signature/prototype/rb.rb +0 -441
  132. data/vendor/ruby-signature/lib/ruby/signature/prototype/rbi.rb +0 -579
  133. data/vendor/ruby-signature/lib/ruby/signature/prototype/runtime.rb +0 -383
  134. data/vendor/ruby-signature/lib/ruby/signature/substitution.rb +0 -48
  135. data/vendor/ruby-signature/lib/ruby/signature/test.rb +0 -28
  136. data/vendor/ruby-signature/lib/ruby/signature/test/errors.rb +0 -63
  137. data/vendor/ruby-signature/lib/ruby/signature/test/hook.rb +0 -290
  138. data/vendor/ruby-signature/lib/ruby/signature/test/setup.rb +0 -58
  139. data/vendor/ruby-signature/lib/ruby/signature/test/spy.rb +0 -324
  140. data/vendor/ruby-signature/lib/ruby/signature/test/test_helper.rb +0 -185
  141. data/vendor/ruby-signature/lib/ruby/signature/test/type_check.rb +0 -256
  142. data/vendor/ruby-signature/lib/ruby/signature/type_name.rb +0 -72
  143. data/vendor/ruby-signature/lib/ruby/signature/types.rb +0 -932
  144. data/vendor/ruby-signature/lib/ruby/signature/variance_calculator.rb +0 -140
  145. data/vendor/ruby-signature/lib/ruby/signature/vendorer.rb +0 -49
  146. data/vendor/ruby-signature/lib/ruby/signature/version.rb +0 -5
  147. data/vendor/ruby-signature/lib/ruby/signature/writer.rb +0 -271
  148. data/vendor/ruby-signature/ruby-signature.gemspec +0 -45
  149. data/vendor/ruby-signature/stdlib/abbrev/abbrev.rbs +0 -3
  150. data/vendor/ruby-signature/stdlib/base64/base64.rbs +0 -15
  151. data/vendor/ruby-signature/stdlib/builtin/array.rbs +0 -1997
  152. data/vendor/ruby-signature/stdlib/builtin/basic_object.rbs +0 -280
  153. data/vendor/ruby-signature/stdlib/builtin/binding.rbs +0 -177
  154. data/vendor/ruby-signature/stdlib/builtin/builtin.rbs +0 -35
  155. data/vendor/ruby-signature/stdlib/builtin/class.rbs +0 -145
  156. data/vendor/ruby-signature/stdlib/builtin/comparable.rbs +0 -116
  157. data/vendor/ruby-signature/stdlib/builtin/complex.rbs +0 -400
  158. data/vendor/ruby-signature/stdlib/builtin/constants.rbs +0 -37
  159. data/vendor/ruby-signature/stdlib/builtin/data.rbs +0 -5
  160. data/vendor/ruby-signature/stdlib/builtin/deprecated.rbs +0 -2
  161. data/vendor/ruby-signature/stdlib/builtin/dir.rbs +0 -419
  162. data/vendor/ruby-signature/stdlib/builtin/encoding.rbs +0 -606
  163. data/vendor/ruby-signature/stdlib/builtin/enumerable.rbs +0 -404
  164. data/vendor/ruby-signature/stdlib/builtin/enumerator.rbs +0 -260
  165. data/vendor/ruby-signature/stdlib/builtin/errno.rbs +0 -781
  166. data/vendor/ruby-signature/stdlib/builtin/errors.rbs +0 -582
  167. data/vendor/ruby-signature/stdlib/builtin/exception.rbs +0 -193
  168. data/vendor/ruby-signature/stdlib/builtin/false_class.rbs +0 -40
  169. data/vendor/ruby-signature/stdlib/builtin/fiber.rbs +0 -68
  170. data/vendor/ruby-signature/stdlib/builtin/fiber_error.rbs +0 -12
  171. data/vendor/ruby-signature/stdlib/builtin/file.rbs +0 -476
  172. data/vendor/ruby-signature/stdlib/builtin/file_test.rbs +0 -59
  173. data/vendor/ruby-signature/stdlib/builtin/float.rbs +0 -696
  174. data/vendor/ruby-signature/stdlib/builtin/gc.rbs +0 -121
  175. data/vendor/ruby-signature/stdlib/builtin/hash.rbs +0 -1029
  176. data/vendor/ruby-signature/stdlib/builtin/integer.rbs +0 -710
  177. data/vendor/ruby-signature/stdlib/builtin/io.rbs +0 -683
  178. data/vendor/ruby-signature/stdlib/builtin/kernel.rbs +0 -574
  179. data/vendor/ruby-signature/stdlib/builtin/marshal.rbs +0 -135
  180. data/vendor/ruby-signature/stdlib/builtin/match_data.rbs +0 -141
  181. data/vendor/ruby-signature/stdlib/builtin/math.rbs +0 -66
  182. data/vendor/ruby-signature/stdlib/builtin/method.rbs +0 -182
  183. data/vendor/ruby-signature/stdlib/builtin/module.rbs +0 -248
  184. data/vendor/ruby-signature/stdlib/builtin/nil_class.rbs +0 -82
  185. data/vendor/ruby-signature/stdlib/builtin/numeric.rbs +0 -409
  186. data/vendor/ruby-signature/stdlib/builtin/object.rbs +0 -824
  187. data/vendor/ruby-signature/stdlib/builtin/proc.rbs +0 -426
  188. data/vendor/ruby-signature/stdlib/builtin/process.rbs +0 -354
  189. data/vendor/ruby-signature/stdlib/builtin/random.rbs +0 -93
  190. data/vendor/ruby-signature/stdlib/builtin/range.rbs +0 -226
  191. data/vendor/ruby-signature/stdlib/builtin/rational.rbs +0 -424
  192. data/vendor/ruby-signature/stdlib/builtin/rb_config.rbs +0 -10
  193. data/vendor/ruby-signature/stdlib/builtin/regexp.rbs +0 -131
  194. data/vendor/ruby-signature/stdlib/builtin/ruby_vm.rbs +0 -14
  195. data/vendor/ruby-signature/stdlib/builtin/signal.rbs +0 -55
  196. data/vendor/ruby-signature/stdlib/builtin/string.rbs +0 -770
  197. data/vendor/ruby-signature/stdlib/builtin/string_io.rbs +0 -13
  198. data/vendor/ruby-signature/stdlib/builtin/struct.rbs +0 -40
  199. data/vendor/ruby-signature/stdlib/builtin/symbol.rbs +0 -230
  200. data/vendor/ruby-signature/stdlib/builtin/thread.rbs +0 -1112
  201. data/vendor/ruby-signature/stdlib/builtin/thread_group.rbs +0 -23
  202. data/vendor/ruby-signature/stdlib/builtin/time.rbs +0 -739
  203. data/vendor/ruby-signature/stdlib/builtin/trace_point.rbs +0 -91
  204. data/vendor/ruby-signature/stdlib/builtin/true_class.rbs +0 -46
  205. data/vendor/ruby-signature/stdlib/builtin/unbound_method.rbs +0 -159
  206. data/vendor/ruby-signature/stdlib/builtin/warning.rbs +0 -17
  207. data/vendor/ruby-signature/stdlib/erb/erb.rbs +0 -18
  208. data/vendor/ruby-signature/stdlib/find/find.rbs +0 -44
  209. data/vendor/ruby-signature/stdlib/pathname/pathname.rbs +0 -21
  210. data/vendor/ruby-signature/stdlib/prime/integer-extension.rbs +0 -23
  211. data/vendor/ruby-signature/stdlib/prime/prime.rbs +0 -188
  212. data/vendor/ruby-signature/stdlib/securerandom/securerandom.rbs +0 -9
  213. data/vendor/ruby-signature/stdlib/set/set.rbs +0 -77
  214. data/vendor/ruby-signature/stdlib/tmpdir/tmpdir.rbs +0 -53
@@ -1,14 +0,0 @@
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__)
@@ -1,103 +0,0 @@
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
@@ -1,10 +0,0 @@
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
@@ -1,88 +0,0 @@
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
@@ -1,17 +0,0 @@
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
@@ -1,97 +0,0 @@
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
- ```
@@ -1,148 +0,0 @@
1
- # Writing Signatures Guide
2
-
3
- You can write the signature of your applications and libraries.
4
- Signature of your Ruby program would help:
5
-
6
- 1. Understanding the code structure
7
- 2. Finding APIs
8
-
9
- And if you ship your gem with signature, the gem users can type check their applications!
10
-
11
- ## Writing signatures
12
-
13
- You first need to write your program's signature.
14
- See [syntax guide](syntax.md).
15
-
16
- ## Testing signatures
17
-
18
- When you finish writing signature, you may want to test the signature.
19
- ruby-signature provides a feature to test your signature.
20
-
21
- ```
22
- $ RBS_TEST_TARGET='Foo::*' bundle exec ruby -r ruby/signature/test/setup test/foo_test.rb
23
- ```
24
-
25
- The test installs instrumentations to spy the method calls and check if arguments/return values are correct with respect to the type of the method in signature.
26
- If errors are reported by the test, you will fix the signature.
27
- You will be sure that you ship a correct signature finally.
28
-
29
- The instrumentations are implemneted using `Module#prepend`.
30
- It defines a module with same name of methods, which asserts the type of arguments/return values and calls `super`.
31
-
32
- ## Type errors
33
-
34
- If the test detects type errors, it will print error messages.
35
-
36
- ### ArgumentTypeError, BlockArgumentTypeError
37
-
38
- The message means there is an unexpected type of argument or block argument.
39
-
40
- ```
41
- ERROR -- : [Kaigi::Speaker.new] ArgumentTypeError: expected `::String` (email) but given `:"matsumoto@soutaro.com"`
42
- ```
43
-
44
- ### ArgumentError, BlockArgumentError
45
-
46
- The message means there is an unexpected argument or missing argument.
47
-
48
- ```
49
- [Kaigi::Speaker.new] ArgumentError: expected method type (size: ::Symbol, email: ::String, name: ::String) -> ::Kaigi::Speaker
50
- ```
51
-
52
- ### ReturnTypeError, BlockReturnTypeError
53
-
54
- The message means the return value from method or block is incorrect.
55
-
56
- ```
57
- ERROR -- : [Kaigi::Conference#each_speaker] ReturnTypeError: expected `self` but returns `[#<Kaigi::Speaker:0x00007fb2b249e5a0 @name="Soutaro Matsumoto", @email=:"matsumoto@soutaro.com">]`
58
- ```
59
-
60
- ### UnexpectedBlockError, MissingBlockError
61
-
62
- The errors are reported when required block is not given or unused block is given.
63
-
64
- ```
65
- ERROR -- : [Kaigi::Conference#speakers] UnexpectedBlockError: unexpected block is given for `() -> ::Array[::Kaigi::Speaker]`
66
- ```
67
-
68
- ### UnresolvedOverloadingError
69
-
70
- The error means there is a type error on overloaded methods.
71
- The `ruby-signature` test framework tries to the best error message for overloaded methods too, but it reports the `UnresolvedOverloadingError` when it fails.
72
-
73
- ## Setting up the test
74
-
75
- The design of the signature testing aims to be non-intrusive. The setup is done in two steps:
76
-
77
- 1. Loading the testing library
78
- 2. Setting up the test through environment variables
79
-
80
- ### Loading the library
81
-
82
- You need to require `ruby/signature/test/setup` for signature testing.
83
- You can do it using `-r` option through command line argument or the `RUBYOPT` environment variable.
84
-
85
- ```
86
- $ ruby -r ruby/signature/test/setup run_tests.rb
87
- $ RUBYOPT='-rruby/signature/test/setup' rake test
88
- ```
89
-
90
- When you are using Bundler, you may need to require `bundler/setup` explicitly.
91
-
92
- ```
93
- $ RUBYOPT='-rbundler/setup -rruby/signature/test/setup' bundle exec rake test
94
- ```
95
-
96
- ### Environment variables
97
-
98
- You need to specify `RBS_TEST_TARGET` to run the test, and you can customize the test with the following environment variables.
99
-
100
- - `RBS_TEST_SKIP` (optional)
101
- - `RBS_TEST_OPT` (optional)
102
- - `RBS_TEST_LOGLEVEL` (optional)
103
- - `RBS_TEST_RAISE` (optional)
104
-
105
- `RBS_TEST_TARGET` is to specify the classes you want to test. `RBS_TEST_TARGET` can contain comma-separated class name pattern, which is one of an exact class name or with wildcard `*`.
106
-
107
- - `RBS_TEST_TARGET=Foo::Bar,Foo::Baz` comma separated exact class names
108
- - `RBS_TEST_TARGET=Foo::*` using wildcard
109
-
110
- `RBS_TEST_SKIP` is to skip some of the classes which matches with `RBS_TEST_TARGET`.
111
-
112
- `RBS_TEST_OPT` is to pass the options for ruby signature handling.
113
- You may need to specify `-r` or `-I` to load signatures.
114
- The default is `-I sig`.
115
-
116
- ```
117
- RBS_TEST_OPT='-r set -r pathname -I sig'
118
- ```
119
-
120
- `RBS_TEST_LOGLEVEL` can be used to configure log level. Defaults to `info`.
121
-
122
- `RBS_TEST_RAISE` may help to debug the type signatures.
123
- If the environment variable is set, it raises an exception when a type error is detected.
124
- You can see the backtrace how the type error is caused and debug your program or signature.
125
-
126
- So, a typical command line to start the test would look like the following:
127
-
128
- ```
129
- $ RBS_TEST_LOGLEVEL=error \
130
- RBS_TEST_TARGET='Kaigi::*' \
131
- RBS_TEST_SKIP='Kaigi::MonkeyPatch' \
132
- RBS_TEST_OPT='-rset -rpathname -Isig -Iprivate' \
133
- RBS_TEST_RAISE=true \
134
- RUBYOPT='-rbundler/setup -rruby/signature/test/setup' \
135
- bundle exec rake test
136
- ```
137
-
138
- ## Testing tips
139
-
140
- ### Skipping a method
141
-
142
- You can skip installing the instrumentation per-method basis using `rbs:test:skip` annotation.
143
-
144
- ```
145
- class String
146
- %a{rbs:test:skip} def =~: (Regexp) -> Integer?
147
- end
148
- ```