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,152 +0,0 @@
1
- # Stdlib Signatures Guide
2
-
3
- This is a guide for contributing to `ruby-signature` by writing/revising stdlib signatures.
4
-
5
- The typical steps of writing signatures will be like the following:
6
-
7
- 1. Generate a prototype
8
- 2. Import RDoc document
9
- 3. Give correct types to the prototype
10
- 4. Add tests
11
-
12
- ## Signatures
13
-
14
- Signatures for standard libraries are located in `stdlib` directory. `stdlib/builtin` is for builtin libraries. Other libraries have directories like `stdlib/set` or `stdlib/pathname`.
15
-
16
- To write signatures see [syntax guide](syntax.md).
17
-
18
- ## Generating prototypes
19
-
20
- `ruby-signature` provides a tool to generate a prototype of signatures, `rbs prototype`.
21
- It provides several options, `rbi` from Sorbet RBI files, `rb` from Ruby code, and `runtime` from runtime API.
22
- `runtime` should be the best option for standard libraries because they may be implemented in C, no Ruby source code.
23
-
24
- The tool `require`s all of the libraries specified with `-r` option, and then use introspection APIs like `instance_methods` to know the structure of the class.
25
- The commandline receives the name of classes you want to prototype, exact class name (like `Pathname`) or pattern with `*` (like `IO::*`).
26
-
27
- ```
28
- $ bundle exec rbs prototype runtime --require pathname Pathname
29
- class Pathname
30
- def self.getwd: () -> untyped
31
-
32
- def self.glob: (*untyped) -> untyped
33
-
34
- def self.pwd: () -> untyped
35
-
36
- def +: (untyped other) -> untyped
37
-
38
- alias / +
39
-
40
- def <=>: (untyped) -> untyped
41
-
42
- # snip
43
- end
44
-
45
- # snip
46
- ```
47
-
48
- The prototype includes:
49
-
50
- * Instance method definitions,
51
- * Singleton method definitions,
52
- * Includes, and
53
- * Constants
54
-
55
- It generate a simple prototype in the sense that all of the types included are `untyped`.
56
- But it will help you to have an overview of the signatures you are trying to write.
57
-
58
- ### What to do with existing RBS files
59
-
60
- Generating prototypes will override everything, so the problem is if there is a RBS files already.
61
- You can try to find missing parts, or you can start from the scratch.
62
-
63
- One non-trivial but absolutely better solution is to make a tool:
64
-
65
- 1. To load type definitions from existing RBS file, and
66
- 2. Generate prototypes only for missing methods.
67
-
68
- ## Import RDoc document
69
-
70
- The next step should be importing RDoc documents.
71
-
72
- ```
73
- $ bundle exec bin/annotate-with-rdoc stdlib/pathname/pathname.rbs
74
- Loading store from /Users/soutaro/.rbenv/versions/2.7.0-dev/share/ri/2.7.0/system...
75
- Loading store from /Users/soutaro/.rbenv/versions/2.7.0-dev/share/ri/2.7.0/site...
76
- Opening stdlib/pathname/pathname.rbs...
77
- Importing documentation for Pathname...
78
- Processing glob...
79
- Processing +...
80
- # snip
81
- Writing stdlib/pathname/pathname.rbs...
82
- ```
83
-
84
- The `annotate-with-rdoc` command adds annotations to RBS files.
85
-
86
- 1. Query RDoc documents to annotate classes, modules, methods, and constants,
87
- 2. Put annotations on RBS AST, and
88
- 3. Update the given .RBS files
89
-
90
- We recommend using the command to annotate the RBS files.
91
-
92
- ## Writing types
93
-
94
- The next step is to replace `untyped` types in the prototype.
95
- See [syntax guide](syntax.md) for the detail of the syntax.
96
-
97
- We can show some of the guides for writing types.
98
-
99
- 1. Use `bool` for truth values, truthy or falsey. More specific types like `TrueClass | FalseClass` may be too strict.
100
- 2. Use `void` if the return value is useless.
101
- 3. Use `nil` instead of `NilClass`.
102
- 4. The most strict types may not be the best types. Use `untyped` if you cannot find the best one.
103
-
104
- ## Add Tests
105
-
106
- We support writing tests for stdlib signatures.
107
-
108
- ### Writing tests
109
-
110
- First, execute `generate:stdlib_test` rake task with a class name that you want to test.
111
-
112
- ```bash
113
- $ bundle exec rake 'generate:stdlib_test[String]'
114
- Created: test/stdlib/String_test.rb
115
- ```
116
-
117
- It generates `test/stdlib/[class_name]_test.rb`.
118
- The test scripts would look like the following:
119
-
120
- ```rb
121
- class StringTest < StdlibTest
122
- target String
123
- using hook.refinement
124
-
125
- def test_gsub
126
- s = "string"
127
- s.gsub(/./, "")
128
- s.gsub("a", "b")
129
- s.gsub(/./) {|x| "" }
130
- s.gsub(/./, {"foo" => "bar"})
131
- s.gsub(/./)
132
- s.gsub("")
133
- end
134
- end
135
- ```
136
-
137
- You need two method calls, `target` and `using`.
138
- `target` method call tells which class is the subject of the class.
139
- `using hook.refinement` installs a special instrumentation for stdlib, based on refinements.
140
- And you write the sample programs which calls all of the patterns of overloads.
141
-
142
- Note that the instrumentation is based on refinements and you need to write all method calls in the unit class definitions.
143
- If the execution of the program escape from the class definition, the instrumentation is disabled and no check will be done.
144
-
145
- ### Running tests
146
-
147
- You can run the test with:
148
-
149
- ```
150
- $ bundle exec ruby bin/test_runner.rb # Run all tests
151
- $ bundle exec ruby test/stdlib/String_test.rb # Run specific tests
152
- ```
@@ -1,528 +0,0 @@
1
- # Syntax
2
-
3
- ## Types
4
-
5
- ```markdown
6
- _type_ ::= _class-name_ _type-arguments_ (Class instance type)
7
- | _interface-name_ _type-arguments_ (Interface type)
8
- | `singleton(` _class-name_ `)` (Class singleton type)
9
- | _alias-name_ (Alias type)
10
- | _literal_ (Literal type)
11
- | _type_ `|` _type_ (Union type)
12
- | _type_ `&` _type_ (Intersection type)
13
- | _type_ `?` (Optional type)
14
- | `{` _record-name_ `:` _type_ `,` ... `}` (Record type)
15
- | `[]` | `[` _type_ `,` ... `]` (Tuples)
16
- | _type-variable_ (Type variables)
17
- | `^(` _parameters_ `) ->` _type_ (Proc type)
18
- | `self`
19
- | `instance`
20
- | `class`
21
- | `bool`
22
- | `untyped`
23
- | `nil`
24
- | `top`
25
- | `bot`
26
- | `void`
27
-
28
- _class-name_ ::= _namespace_ /[A-Z]\w*/
29
- _interface-name_ ::= _namespace_ /_[A-Z]\w*/
30
- _alias-name_ ::= _namespace_ /[a-z]\w*/
31
-
32
- _type-variable_ ::= /[A-Z]\w*/
33
-
34
- _namespace_ ::= (Empty namespace)
35
- | `::` (Root)
36
- | _namespace_ /[A-Z]\w*/ `::` (Namespace)
37
-
38
- _type-arguments_ ::= (No application)
39
- | `[` _type_ `,` ... `]` (Type application)
40
-
41
- _literal_ ::= _string-literal_
42
- | _symbol-literal_
43
- | _integer-literal_
44
- | `true`
45
- | `false`
46
- ```
47
-
48
- ### Class instance type
49
-
50
- Class instance type denotes _an instance of a class_.
51
-
52
- ```
53
- Integer # Instance of Integer class
54
- ::Integer # Instance of ::Integer class
55
- Hash[Symbol, String] # Instance of Hash class with type application of Symbol and String
56
- ```
57
-
58
- ### Interface type
59
-
60
- Interface type denotes _type of a value which can be a subtype of the interface_.
61
-
62
- ```
63
- _ToS # _ToS interface
64
- ::MyApp::_Each[String] # Interface name with namespace and type application
65
- ```
66
-
67
- ### Class singleton type
68
-
69
- Class singleton type denotes _the type of a singleton object of a class_.
70
-
71
- ```
72
- singleton(String)
73
- singleton(::Hash) # Class singleton type cannot be parametrized.
74
- ```
75
-
76
- ### Alias type
77
-
78
- Alias type denotes an alias declared with _alias declaration_.
79
-
80
- The name of type aliases starts with lowercase `[a-z]`.
81
-
82
-
83
- ```
84
- name
85
- ::JSON::t # Alias name with namespace
86
- ```
87
-
88
- ### Literal type
89
-
90
- Literal type denotes _a type with only one value of the literal_.
91
-
92
- ```
93
- 123 # Integer
94
- "hello world" # A string
95
- :to_s # A symbol
96
- true # true or false
97
- ```
98
-
99
- ### Union type
100
-
101
- Union type denotes _a type of one of the given types_.
102
-
103
- ```
104
- Integer | String # Integer or String
105
- Array[Integer | String] # Array of Integer or String
106
- ```
107
-
108
- ### Intersection type
109
-
110
- Intersection type denotes _a type of all of the given types_.
111
-
112
- ```
113
- Integer & String # Integer and String
114
- ```
115
-
116
- Note that `&` has higher precedence than `|` that `Integer & String | Symbol` is `(Integer & String) | Symbol`.
117
-
118
- ### Optional type
119
-
120
- Optional type denotes _a type of value or nil_.
121
-
122
- ```
123
- Integer?
124
- Array[Integer?]
125
- ```
126
-
127
- ### Record type
128
-
129
- Records are `Hash` objects, fixed set of keys, and heterogeneous.
130
-
131
- ```
132
- { id: Integer, name: String } # Hash object like `{ id: 31, name: String }`
133
- ```
134
-
135
- ### Tuple type
136
-
137
- Tuples are `Array` objects, fixed size and heterogeneous.
138
-
139
- ```
140
- [ ] # Empty like `[]`
141
- [String] # Single string like `["hi"]`
142
- [Integer, Integer] # Pair of integers like `[1, 2]`
143
- [Symbol, Integer, Integer] # Tuple of Symbol, Integer, and Integer like `[:pair, 30, 22]`
144
- ```
145
-
146
- *Empty tuple* or *1-tuple* sound strange, but RBS allows these types.
147
-
148
- ### Type variable
149
-
150
- ```
151
- U
152
- T
153
- S
154
- Elem
155
- ```
156
-
157
- Type variables cannot be distinguished from _class instance types_.
158
- They are scoped in _class/module/interface declaration_ or _generic method types_.
159
-
160
- ```
161
- class Ref[T] # Object is scoped in the class declaration.
162
- @value: T # Type variable `T`
163
- def map: [X] { (T) -> X } -> Ref[X] # X is a type variable scoped in the method type.
164
- end
165
- ```
166
-
167
- ### Proc type
168
-
169
- Proc type denots type of procedures, `Proc` instances.
170
-
171
- ```
172
- ^(Integer) -> String # A procedure with an `Integer` parameter and returns `String`
173
- ^(?String, size: Integer) -> bool # A procedure with `String` optional parameter, `size` keyword of `Integer`, and returns `bool`
174
- ```
175
-
176
- ### Base types
177
-
178
- `self` denotes the type of receiver. The type is used to model the open recursion via `self`.
179
-
180
- `instance` denotes the type of instance of the class. `class` is the singleton of the class.
181
-
182
- `bool` is an abstract type for truth value.
183
-
184
- `untyped` is for _a type without type checking_. It is `?` in gradual typing, _dynamic_ in some languages like C#, and _any_ in TypeScript. It is both subtype _and_ supertype of all of the types. (The type was `any` but renamed to `untyped`.)
185
-
186
- `nil` is for _nil_.
187
-
188
- `top` is a supertype of all of the types. `bot` is a subtype of all of the types.
189
-
190
- `void` is a supertype of all of the types.
191
-
192
- #### `nil` or `NilClass`?
193
-
194
- We recommend using `nil`.
195
-
196
- #### `bool` or `TrueClass | FalseClass`
197
-
198
- We recommend using `bool` because it is more close to Ruby's semantics. If the type of a parameter of a method is `bool`, we usually pass `true` and `false`, and also `nil` or any other values. `TrueClass | FalseClass` rejects other values than `true` and `false`.
199
-
200
- #### `void`, `bool`, or `top`?
201
-
202
- They are all equivalent for the type system; they are all _top type_.
203
-
204
- `void` tells developers a hint that _the value should not be used_. `bool` implies the value is used as a truth value. `top` is anything else.
205
-
206
- ## Method Types
207
-
208
- ```markdown
209
- _method-type_ ::= `(` _parameters_ `) ->` _type_ # Method without block
210
- | `(` _parameters_ `) { (` _parameters_ `) -> ` _type_ `} ->` _type_ # Method with required block
211
- | `(` _parameters_ `) ?{ (` _parameters_ `) -> ` _type_ `} ->` _type_ # Method with optional block
212
-
213
- _parameters_ ::= _required-positionals_ _optional-positionals_ _rest-positional_ _trailing-positionals_ _keywords_
214
-
215
- _paramater_ ::= _type_ _var-name_ # Parameter with var name
216
- | _type_ # Parameter without var name
217
- _required-positionals_ ::= _parameter_ `,` ...
218
- _optional-positionals_ ::= `?` _parameter_ `,` ...
219
- _rest-positional_ ::= # Empty
220
- | `*` _parameter_
221
- _trailing-positionals_ ::= _parameter_ `,` ...
222
- _keywords_ ::= # Empty
223
- | `**` _parameter_ # Rest keyword
224
- | _keyword_ `:` _parameter_ `,` _keywords_ # Required keyword
225
- | `?` _keyword_ `:` _parameter_ `,` _keywords_ # Optional keyword
226
-
227
- _var-name_ ::= /[a-z]\w*/
228
- ```
229
-
230
- ### Parameters
231
-
232
- A parameter can be a type or a pair of type and variable name.
233
- Variable name can be used for documentation.
234
-
235
- ### Examples
236
-
237
- ```
238
- # Two required positional `Integer` parameters, and returns `String`
239
- (Integer, Integer) -> String
240
-
241
- # Two optional parameters `size` and `name`.
242
- # `name` is a optional parameter with optional type so that developer can omit, pass a string, or pass `nil`.
243
- (?Integer size, ?String? name) -> String
244
-
245
- # Method type with a rest parameter
246
- (*Integer, Integer) -> void
247
-
248
- # `size` is a required keyword, with variable name of `sz`.
249
- # `name` is a optional keyword.
250
- # `created_at` is a optional keyword, and the value can be `nil`.
251
- (size: Integer sz, ?name: String, ?created_at: Time?) -> void
252
- ```
253
-
254
- ## Members
255
-
256
- ```markdown
257
- _member_ ::= _ivar-member_ # Ivar definition
258
- | _method-member_ # Method definition
259
- | _attribute-member_ # Attribute definition
260
- | _include-member_ # Mixin (include)
261
- | _extend-member_ # Mixin (extend)
262
- | _prepend-member_ # Mixin (prepend)
263
- | _alias-member_ # Alias
264
- | `public` # Public
265
- | `private` # Private
266
-
267
- _ivar-member_ ::= _ivar-name_ `:` _type_
268
-
269
- _method-member_ ::= `def` _method-name_ `:` _method-types_ # Instance method
270
- | `def self.` _method-name_ `:` _method-types_ # Singleton method
271
- | `def self?.` _method-name_ `:` _method-types_ # Singleton and instance method
272
-
273
- _method-types_ ::= # Empty
274
- | `super` # `super` overloading
275
- | _type-parameters_ _method-type_ `|` _method-types_ # Overloading types
276
-
277
- _type-parameters_ ::= # Empty
278
- | `[` _type-variable_ `,` ... `]`
279
-
280
- _attribute-member_ ::= _attribute-type_ _method-name_ `:` _type_ # Attribute
281
- | _attribute-type_ _method-name_ `(` _ivar-name_ `) :` _type_ # Attribute with variable name specification
282
- | _attribute-type_ _method-name_ `() :` _type_ # Attribute without variable
283
-
284
- _attribute-type_ ::= `attr_reader` | `attr_writer` | `attr_accessor`
285
-
286
- _include-member_ ::= `include` _class-name_ _type-arguments_
287
- | `include` _interface-name_ _type-arguments_
288
- _extend-member_ ::= `extend` _class-name_ _type-arguments_
289
- | `extend` _interface-name_ _type-arguments_
290
- _prepend-member_ ::= `prepend` _class-name_ _type-arguments_
291
-
292
- _alias-member_ ::= `alias` _method-name_ _method-name_
293
- | `alias self.` _method-name_ `self.` _method-name_
294
-
295
- _ivar-name_ ::= /@\w+/
296
- _method-name_ ::= ...
297
- | /`[^`]+`/
298
- ```
299
-
300
- ### Ivar definition
301
-
302
- An instance variable definition consists of the name of an instance variable and its type.
303
-
304
- ```
305
- @name: String
306
- @value: Hash[Symbol, Key]
307
- ```
308
-
309
- ### Method definition
310
-
311
- Method definition has several syntax variations.
312
-
313
- You can write `self.` or `self?.` before the name of the method to specify the kind of method: instance, singleton, or both instance and singleton.
314
-
315
- ```
316
- def to_s: () -> String # Defines a instance method
317
- def self.new: () -> AnObject # Defines singleton method
318
- def self?.sqrt: (Numeric) -> Numeric # self? is for `module_function`s
319
- ```
320
-
321
- The method type can be connected with `|`s to define an overloaded method.
322
-
323
- ```
324
- def +: (Float) -> Float
325
- | (Integer) -> Integer
326
- | (Numeric) -> Numeric
327
- ```
328
-
329
- You need extra parentheses on return type to avoid ambiguity.
330
-
331
- ```
332
- def +: (Float | Integer) -> (Float | Integer)
333
- | (Numeric) -> Numeric
334
- ```
335
-
336
- Method types can end with `super` which means the methods from existing definitions.
337
- This is useful to define an _extension_, which adds a new variation to the existing method preserving the original behavior.
338
-
339
- ### Attribute definition
340
-
341
- Attribute definitions help to define methods and instance variables based on the convention of `attr_reader`, `attr_writer` and `attr_accessor` methods in Ruby.
342
-
343
- You can specify the name of instance variable using `(@some_name)` syntax and also omit the instance variable definition by specifying `()`.
344
-
345
- ```
346
- # Defines `id` method and `@id` instance variable.
347
- attr_reader id: Integer
348
- # @id: Integer
349
- # def id: () -> Integer
350
-
351
- # Defines `name=` method and `raw_name` instance variable.
352
- attr_writer name (@raw_name) : String
353
- # @raw_name: String
354
- # def name=: (String) -> String
355
-
356
- # Defines `people` and `people=` methods, but no instance variable.
357
- attr_accessor people (): Array[Person]
358
- # def people: () -> Array[Person]
359
- # def people=: (Array[Person]) -> Array[Person]
360
- ```
361
-
362
- ### Mixin (include), Mixin (extend), Mixin (prepend)
363
-
364
- You can define mixins between class and modules.
365
-
366
- ```
367
- include Kernel
368
- include Enumerable[String, void]
369
- extend ActiveSupport::Concern
370
- ```
371
-
372
- You can also `include` or `extend` an interface.
373
-
374
- ```
375
- include _Hashing
376
- extend _LikeString
377
- ```
378
-
379
- This allows importing `def`s from the interface to help developer implementing a set of methods.
380
-
381
- ### Alias
382
-
383
- You can define an alias between methods.
384
-
385
- ```
386
- def map: [X] () { (String) -> X } -> Array[X]
387
- alias collect map # `#collect` has the same type with `map`
388
- ```
389
-
390
- ### `public`, `private`
391
-
392
- `public` and `private` allows specifying the visibility of methods.
393
-
394
- These work only as _statements_, not per-method specifier.
395
-
396
- ## Declarations
397
-
398
- ```markdown
399
- _decl_ ::= _class-decl_ # Class declaration
400
- | _module-decl_ # Module declaration
401
- | _interface-decl_ # Interface declaration
402
- | _extension-decl_ # Extension declaration
403
- | _type-alias-decl_ # Type alias declaration
404
- | _const-decl_ # Constant declaration
405
- | _global-decl_ # Global declaration
406
-
407
- _class-decl_ ::= `class` _class-name_ _module-type-parameters_ _members_ `end`
408
- | `class` _class-name_ _module-type-parameters_ `<` _class-name_ _type-arguments_ _members_ `end`
409
-
410
- _module-decl_ ::= `module` _module-name_ _module-type-parameters_ _members_ `end`
411
- | `module` _module-name_ _module-type-parameters_ `:` _class-name_ _type-arguments_ _members_ `end`
412
-
413
- _interface-decl_ ::= `interface` _interface-name_ _module-type-parameters_ _interface-members_ `end`
414
-
415
- _interface-members_ ::= _method-member_ # Method
416
- | _include-member_ # Mixin (include)
417
- | _alias-member_ # Alias
418
-
419
- _extension-decl_ ::= `extension` _class-name_ _type-parameters_ `(` _extension-name_ `)` _members_ `end`
420
-
421
- _type-alias-decl_ ::= `type` _alias-name_ `=` _type_
422
-
423
- _const-decl_ ::= _const-name_ `:` _type_
424
-
425
- _global-decl_ ::= _global-name_ `:` _type_
426
-
427
- _const-name_ ::= _namespace_ /[A-Z]\w*/
428
- _global-name_ ::= /$[a-zA-Z]\w+/ | ...
429
-
430
- _module-type-parameters_ ::= # Empty
431
- | `[` _module-type-parameter_ `,` ... `]`
432
-
433
- _module-type-parameter_ ::= _variance_ _type-variable_
434
- _variance_ ::= `out` | `in`
435
- ```
436
-
437
- ### Class declaration
438
-
439
- Class declaration can have type parameters and superclass. When you omit superclass, `::Object` is assumed.
440
-
441
- ```
442
- class Ref[A] < Object
443
- attr_reader value: A
444
- def initialize: (value: A) -> void
445
- end
446
- ```
447
-
448
- ### Module declaration
449
-
450
- Module declaration takes optional _self type_ parameter, which defines a constraint about a class when the module is mixed.
451
-
452
- ```
453
- interface _Each[A, B]
454
- def each: { (A) -> void } -> B
455
- end
456
-
457
- module Enumerable[A, B] : _Each[A, B]
458
- def count: () -> Integer
459
- end
460
- ```
461
-
462
- The `Enumerable` method above requires `each` method for enumerating objects.
463
-
464
- ### Interface declaration
465
-
466
- Interface declaration can have parameters but allows only a few of the members.
467
-
468
- ```
469
- interface _Hashing
470
- def hash: () -> Integer
471
- def eql?: (any) -> bool
472
- end
473
- ```
474
-
475
- There are several limitations which are not described in the grammar.
476
-
477
- 1. Interface cannot `include` modules
478
- 2. Interface cannot have singleton method definitions
479
-
480
- ```
481
- interface _Foo
482
- include Bar # Error: cannot include modules
483
- def self.new: () -> Foo # Error: cannot include singleton method definitions
484
- end
485
- ```
486
-
487
- ### Extension declaration
488
-
489
- Extension is to model _open class_.
490
-
491
- ```
492
- extension Kernel (Pathname)
493
- def Pathname: (String) -> Pathname
494
- end
495
-
496
- extension Array[A] (ActiveSupport)
497
- def to: (Integer) -> Array[A]
498
- def from: (Integer) -> Array[A]
499
- def second: () -> A?
500
- def third: () -> A?
501
- end
502
- ```
503
-
504
- ### Type alias declaration
505
-
506
- You can declare an alias of types.
507
-
508
- ```
509
- type subject = Attendee | Speaker
510
- type JSON::t = Integer | TrueClass | FalseClass | String | Hash[Symbol, t] | Array[t]
511
- ```
512
-
513
- ### Constant type declaration
514
-
515
- You can declare a constant.
516
-
517
- ```
518
- Person::DefaultEmailAddress: String
519
- ```
520
-
521
- ### Global type declaration
522
-
523
- You can declare a global variable.
524
-
525
- ```
526
- $LOAD_PATH: Array[String]
527
- ```
528
-