parlour 2.0.0 → 5.0.0.beta.1

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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug-report.md +0 -0
  3. data/.github/ISSUE_TEMPLATE/feature-request.md +0 -0
  4. data/.gitignore +1 -1
  5. data/.parlour +5 -0
  6. data/.rspec +0 -0
  7. data/.travis.yml +3 -3
  8. data/CHANGELOG.md +64 -0
  9. data/CODE_OF_CONDUCT.md +0 -0
  10. data/Gemfile +0 -0
  11. data/LICENSE.txt +0 -0
  12. data/README.md +233 -19
  13. data/Rakefile +0 -0
  14. data/exe/parlour +109 -4
  15. data/lib/parlour.rb +29 -1
  16. data/lib/parlour/conflict_resolver.rb +75 -27
  17. data/lib/parlour/conversion/converter.rb +34 -0
  18. data/lib/parlour/conversion/rbi_to_rbs.rb +223 -0
  19. data/lib/parlour/debugging.rb +0 -0
  20. data/lib/parlour/detached_rbi_generator.rb +1 -6
  21. data/lib/parlour/detached_rbs_generator.rb +25 -0
  22. data/lib/parlour/generator.rb +34 -0
  23. data/lib/parlour/kernel_hack.rb +0 -0
  24. data/lib/parlour/options.rb +71 -0
  25. data/lib/parlour/parse_error.rb +0 -0
  26. data/lib/parlour/plugin.rb +1 -1
  27. data/lib/parlour/rbi_generator.rb +24 -37
  28. data/lib/parlour/rbi_generator/arbitrary.rb +5 -2
  29. data/lib/parlour/rbi_generator/attribute.rb +14 -5
  30. data/lib/parlour/rbi_generator/class_namespace.rb +8 -3
  31. data/lib/parlour/rbi_generator/constant.rb +28 -8
  32. data/lib/parlour/rbi_generator/enum_class_namespace.rb +32 -5
  33. data/lib/parlour/rbi_generator/extend.rb +5 -2
  34. data/lib/parlour/rbi_generator/include.rb +5 -2
  35. data/lib/parlour/rbi_generator/method.rb +15 -10
  36. data/lib/parlour/rbi_generator/module_namespace.rb +7 -2
  37. data/lib/parlour/rbi_generator/namespace.rb +115 -27
  38. data/lib/parlour/rbi_generator/parameter.rb +13 -7
  39. data/lib/parlour/rbi_generator/rbi_object.rb +19 -78
  40. data/lib/parlour/rbi_generator/struct_class_namespace.rb +110 -0
  41. data/lib/parlour/rbi_generator/struct_prop.rb +139 -0
  42. data/lib/parlour/rbi_generator/type_alias.rb +101 -0
  43. data/lib/parlour/rbs_generator.rb +24 -0
  44. data/lib/parlour/rbs_generator/arbitrary.rb +92 -0
  45. data/lib/parlour/rbs_generator/attribute.rb +82 -0
  46. data/lib/parlour/rbs_generator/block.rb +49 -0
  47. data/lib/parlour/rbs_generator/class_namespace.rb +106 -0
  48. data/lib/parlour/rbs_generator/constant.rb +95 -0
  49. data/lib/parlour/rbs_generator/extend.rb +92 -0
  50. data/lib/parlour/rbs_generator/include.rb +92 -0
  51. data/lib/parlour/rbs_generator/interface_namespace.rb +34 -0
  52. data/lib/parlour/rbs_generator/method.rb +146 -0
  53. data/lib/parlour/rbs_generator/method_signature.rb +104 -0
  54. data/lib/parlour/rbs_generator/module_namespace.rb +35 -0
  55. data/lib/parlour/rbs_generator/namespace.rb +627 -0
  56. data/lib/parlour/rbs_generator/parameter.rb +145 -0
  57. data/lib/parlour/rbs_generator/rbs_object.rb +78 -0
  58. data/lib/parlour/rbs_generator/type_alias.rb +96 -0
  59. data/lib/parlour/type_loader.rb +30 -10
  60. data/lib/parlour/type_parser.rb +440 -43
  61. data/lib/parlour/typed_object.rb +87 -0
  62. data/lib/parlour/types.rb +445 -0
  63. data/lib/parlour/version.rb +1 -1
  64. data/parlour.gemspec +2 -2
  65. data/plugin_examples/foobar_plugin.rb +0 -0
  66. data/rbi/parlour.rbi +1799 -0
  67. metadata +42 -15
  68. data/lib/parlour/rbi_generator/options.rb +0 -74
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 382331994bebd14df33b96b084d725b0375fa84e0a3aa263e944bad22bb5ef3f
4
- data.tar.gz: 33b9014173a85bc6dddec5aa3ad38cc7e23d869636694fbbe96d4e07c7e78886
3
+ metadata.gz: 8117de48194856013f343430fd893e1b8bc75e51fc8b8811e70bc89a3f9989aa
4
+ data.tar.gz: bc980c3cb70a33c60fc92c23f10f2d844da076161a65e2c24fde49e24d4aceb9
5
5
  SHA512:
6
- metadata.gz: 6ecd35a473c689909a7ef3b84af799cfa718b1901929743676c557d95f6dd717b3c9cd60dcec1c4274ce1ecc4e69310aa3213505c6f3ef479cfa580ccb39f187
7
- data.tar.gz: 7dddda7cb3a9d123e74f0ed218d62b17697f63451b7389d6d5c92bb4712d41b1cc920380eb8ee3b84c7916be5ad8c32c5d2bb0f3b46c7828acefa45fa0581683
6
+ metadata.gz: 6bcf142fd126d52f38d2d0d5f597e85d7a4274c321b927230ce100aae9d3941bd6abb7e2cf35ccf597c2b5eaf71121126d5bd85c814d63cdece0e479536740c3
7
+ data.tar.gz: 5af1d6099e12dff2105dca26c4a6db90bba1190018ab7e514dd413e272e3942ef3b608666e91e5fa26b6bdc23f2d886e41ab1d1655085e36ca5f0b94b461448f
File without changes
File without changes
data/.gitignore CHANGED
@@ -8,7 +8,7 @@
8
8
  /tmp/
9
9
  Gemfile.lock
10
10
  /.vscode
11
- /sorbte/rbi/hidden-definitions/errors.txt
11
+ /sorbet/rbi/hidden-definitions/errors.txt
12
12
 
13
13
  # rspec failure tracking
14
14
  .rspec_status
@@ -0,0 +1,5 @@
1
+ excluded_paths:
2
+ - lib/parlour/kernel_hack.rb
3
+
4
+ excluded_modules:
5
+ - Parlour::DetachedRbiGenerator
data/.rspec CHANGED
File without changes
@@ -10,9 +10,6 @@ rvm:
10
10
  - 2.6
11
11
  - 2.7
12
12
  - ruby-head
13
- matrix:
14
- allow_failures:
15
- - rvm: ruby-head
16
13
 
17
14
  jobs:
18
15
  include:
@@ -26,3 +23,6 @@ jobs:
26
23
  keep_history: true
27
24
  on:
28
25
  branch: master
26
+ allow_failures:
27
+ - rvm: 2.3
28
+ - rvm: ruby-head
@@ -3,6 +3,70 @@ All notable changes to this project will be documented in this file.
3
3
 
4
4
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
5
5
 
6
+ ## [5.0.0.beta.1] - 2020-09-13
7
+ ### Added
8
+ - Added RBS generation support! This includes:
9
+ - The new `RbsGenerator` class
10
+ - `RbsObject` and a set of subclasses representing different RBS components
11
+ - Added the `Types` module, which is used to describe types agnostic of the
12
+ underlying type system
13
+ - Added `RbiGenerator::Namespace#generalize_from_rbi!` to convert RBI string
14
+ types into `Types` types
15
+ - **Specifying types as strings is still currently supported, but may be
16
+ phased out in future, and should be avoided in new projects**.
17
+ - Added conversion from RBI to RBS type trees
18
+ - Added a couple of classes to deduplicate functionality between type systems:
19
+ - `TypedObject`, which `RbiObject` and `RbsObject` both inherit from
20
+ - `Generator`, which `RbiGenerator` and `RbsGenerator` both inherit from
21
+ - Added RBI type aliases
22
+
23
+ ### Changed
24
+ - `Parlour::RbiGenerator::Options` is now `Parlour::Options`. An alias exists
25
+ for now, but **`Parlour::RbiGenerator::Options` is deprecated** and could be
26
+ removed in future versions.
27
+ - Updated README and gem metadata to refer to Parlour as a type information
28
+ generator, rather than just an RBI generator
29
+
30
+ ## [4.0.1] - 2020-08-05
31
+ ### Fixed
32
+ - Fixed duplicate includes and extends.
33
+ - Fixed the block return type for `#resolve_conflicts` not being nilable.
34
+
35
+ ## [4.0.0] - 2020-05-23
36
+ ### Added
37
+ - Parlour now defaults to loading the current project when running its command
38
+ line tool, allowing it to be used as a "`sig` extractor" when run without
39
+ plugins! **Breaking if you invoke Parlour from its command line tool** - to
40
+ revert to the old behaviour of having nothing loaded into the root namespace
41
+ initially, add `parser: false` to your `.parlour` file.
42
+ - Generating constants in an eigenclass context (`class << self`) is now
43
+ supported.
44
+
45
+ ## [3.0.0] - 2020-05-15
46
+ ### Added
47
+ - `T::Struct` classes can now be generated and parsed.
48
+ - `T::Enum` classes can now be parsed.
49
+ - Constants are now parsed.
50
+ - `TypeParser` now detects and parses methods which do not have a `sig`.
51
+ **Potentially breaking if there is a strict set of methods you are expecting Parlour to detect.**
52
+
53
+ ### Fixed
54
+ - "Specialized" classes, such as enums and now structs, have had many erroneous
55
+ conflicts with standard classes or namespaces fixed.
56
+ - Attributes writers and methods with the same name no longer conflict incorrectly.
57
+
58
+ ## [2.1.0] - 2020-03-22
59
+ ### Added
60
+ - Files can now be excluded from the `TypeLoader`.
61
+
62
+ ### Changed
63
+ - A block argument in the definition but not in the signature no longer causes
64
+ an error in the `TypeParser`.
65
+ - Sorting of namespace children is now a stable sort.
66
+
67
+ ### Fixed
68
+ - Type parameters are now parsed by the `TypeParser`.
69
+
6
70
  ## [2.0.0] - 2020-02-10
7
71
  ### Added
8
72
  - Parlour can now load types back out of RBI files or Ruby source files by
File without changes
data/Gemfile CHANGED
File without changes
File without changes
data/README.md CHANGED
@@ -3,39 +3,77 @@
3
3
  [![Build Status](https://travis-ci.org/AaronC81/parlour.svg?branch=master)](https://travis-ci.org/AaronC81/parlour)
4
4
  ![Gem](https://img.shields.io/gem/v/parlour.svg)
5
5
 
6
- Parlour is an RBI generator, merger and parser for Sorbet. It consists of three
7
- key parts:
6
+ Parlour is a Ruby type information generator, merger and parser, supporting both
7
+ **Sorbet RBI files and Ruby 3/Steep RBS files**. It consists of three key parts:
8
8
 
9
- - The generator, which outputs beautifully formatted RBI files, created using
10
- an intuitive DSL.
9
+ - The generator, which outputs beautifully formatted RBI/RBS files, created
10
+ using an intuitive DSL.
11
11
 
12
12
  - The plugin/build system, which allows multiple Parlour plugins to generate
13
13
  RBIs for the same codebase. These are combined automatically as much as
14
14
  possible, but any other conflicts can be resolved manually through prompts.
15
15
 
16
- - The parser, which can read an RBI and convert it back into a tree of
17
- generator objects.
16
+ - The parser (currently RBI-only), which can read an RBI and convert it back
17
+ into a tree of generator objects.
18
18
 
19
19
  ## Why should I use this?
20
20
 
21
- - Parlour enables **much easier creation of RBI generators**, as formatting
22
- is all handled for you, and you don't need to write your own CLI.
21
+ - Parlour enables **much easier creation of RBI/RBS generators**, as
22
+ formatting is all handled for you, and you don't need to write your own CLI.
23
23
 
24
24
  - You can **use many plugins together seamlessly**, running them all with a
25
25
  single command and consolidating all of their definitions into a single
26
- RBI output file.
26
+ output file.
27
27
 
28
28
  - You can **effortlessly build tools which need to access types within an RBI**;
29
- no need to write your own parser!
29
+ no need to write your own parser!
30
+
31
+ - You can **generate RBI/RBS to ship with your gem** for consuming projects to
32
+ use ([see "RBIs within gems" in Sorbet's
33
+ docs](https://sorbet.org/docs/rbi#rbis-within-gems)).
30
34
 
31
35
  Please [**read the wiki**](https://github.com/AaronC81/parlour/wiki) to get
32
36
  started!
33
37
 
34
- ## Creating RBIs
38
+ ## Feature Support
39
+
40
+ | Feature | RBI | RBS |
41
+ |---------|-----|-----|
42
+ | **GENERATION** | | |
43
+ | Classes | ✅ | ⚠️ (missing `extension`) |
44
+ | Modules | ✅ | ⚠️ (missing `extension`) |
45
+ | Interfaces | ✅ | ✅ |
46
+ | Attributes | ✅ | ✅ |
47
+ | Methods | ✅ | ✅ |
48
+ | Overloaded methods | ❌* | ✅ |
49
+ | Structs | ✅ | ✅† |
50
+ | Enums | ✅ | ✅† |
51
+ | Generation with plugins | ✅ | ❌ |
52
+ | **MANIPULATION** | | |
53
+ | Parsing | ✅ | ❌ |
54
+ | Merging | ✅ | ❌ |
55
+
56
+ - ✅ - Well supported
57
+ - ⚠️ - Some missing features
58
+ - ❌ - Not currently supported
59
+
60
+ - \* Only supported in stdlib types anyway
61
+ - † Not natively supported; available as a one-way conversion from RBI
62
+
63
+ ## Creating Type Information
35
64
 
36
- ### Using just the generator
65
+ Each file format has its own type information generator class, so there are two
66
+ different generators you can use: `RbiGenerator` and `RbsGenerator`. Both
67
+ generators are similar to use, however they provide different object types and
68
+ parameters to match the functionality of their underlying type systems.
37
69
 
38
- Here's a quick example of how you can generate an RBI:
70
+ You can also convert your type information between formats; see
71
+ [converting between formats](#converting-between-formats).
72
+
73
+ ### Using Just the Generator
74
+
75
+ Here's a quick example of how you can generate some type information. Here
76
+ we'll generate an RBI using the `RbiGenerator` classes:
39
77
 
40
78
  ```ruby
41
79
  require 'parlour'
@@ -69,11 +107,50 @@ module A
69
107
  end
70
108
  ```
71
109
 
72
- ### Writing a plugin
110
+ Using the RBS generator looks similar, but has an intermediary
111
+ `MethodSignature` class to support RBS' method overloading:
112
+
113
+ ```ruby
114
+ require 'parlour'
115
+
116
+ generator = Parlour::RbsGenerator.new
117
+ generator.root.create_module('A') do |a|
118
+ a.create_class('Foo') do |foo|
119
+ foo.create_method('add_two_integers', [
120
+ Parlour::RbsGenerator::MethodSignature.new(
121
+ [
122
+ Parlour::RbsGenerator::Parameter.new('a', type: 'Integer'),
123
+ Parlour::RbsGenerator::Parameter.new('b', type: 'Integer')
124
+ ],
125
+ 'Integer'
126
+ )
127
+ ])
128
+ end
129
+
130
+ a.create_class('Bar', superclass: 'Foo')
131
+ end
132
+
133
+ generator.rbs # => Our RBS as a string
134
+ ```
135
+
136
+ This generates an equivalent RBS file:
137
+
138
+ ```ruby
139
+ module A
140
+ class Foo
141
+ def add_two_integers: (Integer a, Integer b) -> Integer
142
+ end
143
+
144
+ class Bar < Foo
145
+ end
146
+ end
147
+ ```
148
+
149
+ ### Writing a Plugin
73
150
  Plugins are better than using the generator alone, as your plugin can be
74
- combined with others to produce larger RBIs without conflicts.
151
+ combined with others to produce larger files without conflicts.
75
152
 
76
- We could write the above example as a plugin like this:
153
+ We could write the above example as an RBI plugin like this:
77
154
 
78
155
  ```ruby
79
156
  require 'parlour'
@@ -104,7 +181,8 @@ called `plugin.rb`, then using this `.parlour` file and then running `parlour`
104
181
  would save the RBI into `output.rbi`:
105
182
 
106
183
  ```yaml
107
- output_file: output.rbi
184
+ output_file:
185
+ rbi: output.rbi
108
186
 
109
187
  relative_requires:
110
188
  - plugin.rb
@@ -128,7 +206,8 @@ You can also use plugins from gems. If that plugin was published as a gem called
128
206
  `parlour-gem`:
129
207
 
130
208
  ```yaml
131
- output_file: output.rbi
209
+ output_file:
210
+ rbi: output.rbi
132
211
 
133
212
  requires:
134
213
  - parlour-gem
@@ -140,7 +219,8 @@ plugins:
140
219
  The real power of this is the ability to use many plugins at once:
141
220
 
142
221
  ```yaml
143
- output_file: output.rbi
222
+ output_file:
223
+ rbi: output.rbi
144
224
 
145
225
  requires:
146
226
  - gem1
@@ -153,6 +233,92 @@ plugins:
153
233
  Gem3::Plugin: {}
154
234
  ```
155
235
 
236
+ Currently, only plugins which generate RBI files are supported. However, you can
237
+ use [Parlour's type conversion](#converting-between-formats) to convert the RBI
238
+ types into RBS types:
239
+
240
+ ```yaml
241
+ output_file:
242
+ rbi: output.rbi
243
+ rbs: output.rbs
244
+ ```
245
+
246
+ ## Using Types
247
+
248
+ The most important part of your type information is the types themselves, which
249
+ you'll be specifying for method parameters, method returns, and attributes.
250
+ These include simple types like `String`, up to more complex types like
251
+ "an array of elements which are one of `Integer`, `String`, or nil".
252
+
253
+ There are two ways to represent these types in Parlour:
254
+
255
+ 1. As **generalized types**; that is, instances of classes in the
256
+ `Parlour::Types` namespace. This is the **recommended way**, as it is
257
+ format-agnostic and can be compiled to RBI or RBS. For more information
258
+ about these types and how to use them, see
259
+ [this wiki page](https://github.com/AaronC81/parlour/wiki/The-Types-namespace).
260
+
261
+ 2. As **strings of code** written in the format that your type system expects.
262
+ The given strings are directly inserted into the final type file. These types
263
+ are **not portable across formats**, and as such are
264
+ **not recommended and may be phased out** in the future.
265
+
266
+ Currently most type values within Parlour are typed as `Types::TypeLike`,
267
+ which accepts a `String` or a `Types::Type` subclass.
268
+
269
+ ```ruby
270
+ include Parlour
271
+
272
+ # Two ways to express an attribute called 'example', which is:
273
+ # an array of nilable strings or integers
274
+
275
+ # 1. With generalised types - type is agnostic to the underlying type system
276
+ root.create_attr_accessor('example', type:
277
+ Types::Array.new(
278
+ Types::Nilable.new(
279
+ Types::Union.new(['String', 'Integer'])
280
+ )
281
+ )
282
+ )
283
+
284
+ # 2. With string types - format depends on type system
285
+ # If using RBI...
286
+ root.create_attr_accessor('example', type:
287
+ 'T::Array[T.nilable(T.any(String, Integer))]'
288
+ )
289
+ # If using RBS...
290
+ root.create_attr_accessor('example', type:
291
+ 'Array[?(String | Integer)]'
292
+ )
293
+ ```
294
+
295
+ ### Generalizing String Types
296
+
297
+ If you have loaded an RBI project or created a structure of nodes on an
298
+ `RbiGenerator`, you can use `#generalize_from_rbi!` on your root namespace
299
+ to attempt to permanently convert the RBI string types into generalized types:
300
+
301
+ ```ruby
302
+ # Build up an RBI tree with string types
303
+ root.create_attr_accessor('example', type:
304
+ 'T::Array[T.nilable(T.any(String, Integer))]'
305
+ )
306
+
307
+ # Generalize it
308
+ root.generalize_from_rbi!
309
+
310
+ # Take a look at our generalized type!
311
+ pp root.children.first.type
312
+ # => #<Parlour::Types::Array:0x0000557cdcebfdf8
313
+ # @element=
314
+ # #<Parlour::Types::Nilable:0x0000557cdcef8c70
315
+ # @type=
316
+ # #<Parlour::Types::Union:0x0000557cdcea0a70
317
+ # @types=
318
+ # [#<Parlour::Types::Raw:0x0000557cdcea1920 @str="String">,
319
+ # #<Parlour::Types::Raw:0x0000557cdcea0ae8 @str="Integer">]>>>
320
+ ```
321
+
156
322
  ## Parsing RBIs
157
323
 
158
324
  You can either parse individual RBI files, or point Parlour to the root of a
@@ -174,6 +340,54 @@ Parlour::TypeLoader.load_project('root/of/the/project')
174
340
  The structure of the returned object trees is identical to those you would
175
341
  create when generating an RBI, built of instances of `RbiObject` subclasses.
176
342
 
343
+ ## Generating RBI for a Gem
344
+
345
+ Include `parlour` as a development_dependency in your `.gemspec`:
346
+
347
+ ```ruby
348
+ spec.add_development_dependency 'parlour'
349
+ ```
350
+
351
+ Run Parlour from the command line:
352
+
353
+ ```ruby
354
+ bundle exec parlour
355
+ ```
356
+
357
+ Parlour is configured to use sane defaults assuming a standard gem structure
358
+ to generate an RBI that Sorbet will automatically find when your gem is included
359
+ as a dependency. If you require more advanced configuration you can add a
360
+ `.parlour` YAML file in the root of your project (see this project's `.parlour`
361
+ file as an example).
362
+
363
+ To disable the parsing step entire and just run plugins you can set `parser: false`
364
+ in your `.parlour` file.
365
+
366
+ ## Converting Between Formats
367
+
368
+ _For more information, see the [wiki page](https://github.com/AaronC81/parlour/wiki/Converting-between-RBI-and-RBS)._
369
+
370
+ Currently, only RBI to RBS conversion is supported, and if you've used string
371
+ types (or are using a freshly-loaded project) you
372
+ **must [generalize them](#generalizing-string-types) first**.
373
+
374
+ Then, all you need to do is create an `RbsGenerator` (which the converter will
375
+ add your converted types to) and a `Conversion::RbiToRbs` instance (which
376
+ performs the conversion). Then you can convert each object at your
377
+ `RbiGenerator`'s root namespace:
378
+
379
+ ```ruby
380
+ rbi_gen = Parlour::RbiGenerator.new
381
+ # Then, after populating the RbiGenerator with types...
382
+
383
+ # Create an RbsGenerator and a converter
384
+ rbs_gen = Parlour::RbsGenerator.new
385
+ converter = Parlour::Conversion::RbiToRbs.new(rbs_gen)
386
+
387
+ # Convert each item at the root of the RbiGenerator and it to the root of the RbsGenerator
388
+ converter.convert_all(rbi_gen.root, rbs_gen.root)
389
+ ```
390
+
177
391
  ## Parlour Plugins
178
392
 
179
393
  _Have you written an awesome Parlour plugin? Please submit a PR to add it to this list!_
data/Rakefile CHANGED
File without changes