sord 3.0.0.beta.1 → 3.0.0.beta.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +71 -43
- data/lib/sord/type_converter.rb +28 -28
- data/lib/sord/version.rb +1 -1
- data/rbi/sord.rbi +1 -2
- data/sord.gemspec +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7a96fafb7c0a8a07c5462a5138b836837e65e2dd14f68d9f51ebd502170c84f9
|
4
|
+
data.tar.gz: 8d82f8e1848f0422cdd4729933f867f78daffeeb226a54b826d5fd75660e73ac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f885ba62dd5b528f63e644d6cc6d000b33f372ea07ec7f372b1231464f5989e5353db508d553d997cdb772dc5ad075cf8fc3d37ede901f16efaa031438b59474
|
7
|
+
data.tar.gz: 859a054fdf1e1609035862c4f95d3b03622dcf7fe97c97afae120e80168102af0806dd8463aa00815f2e294cb0c895f511a9387b4f22e8464dc8aa9dc4f9a333
|
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,11 @@ 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
|
+
## [3.0.0.beta.2] - 2020-10-05
|
7
|
+
### Added
|
8
|
+
- Sord is no longer limited to a known set of generics, and will instead
|
9
|
+
generate `Parlour::Types::Generic` types for user-defined generics.
|
10
|
+
|
6
11
|
## [3.0.0.beta.1] - 2020-09-16
|
7
12
|
### Added
|
8
13
|
- Sord now uses the Parlour 5 beta's RBS generation to generate RBS files!
|
data/README.md
CHANGED
@@ -3,24 +3,27 @@
|
|
3
3
|
## Overview
|
4
4
|
|
5
5
|
Sord is a [**So**rbet](https://sorbet.org) and [YA**RD**](https://yardoc.org/)
|
6
|
-
crossover. It can automatically generate
|
7
|
-
looking at the types specified in YARD documentation comments.
|
6
|
+
crossover. It can **automatically generate RBI and RBS type signature files** by
|
7
|
+
looking at the **types specified in YARD documentation** comments.
|
8
8
|
|
9
9
|
If your project is already YARD documented, then this can generate most of the
|
10
|
-
|
10
|
+
type signatures you need!
|
11
|
+
|
12
|
+
Sord is the perfect way to jump-start the adoption of types in your project,
|
13
|
+
whether you plan to use Sorbet's RBI format or Ruby 3/Steep's RBS format.
|
11
14
|
|
12
15
|
Sord has the following features:
|
13
16
|
- Automatically generates signatures for modules, classes and methods
|
14
|
-
- Support for multiple parameter or return types (`T.any
|
15
|
-
- Gracefully handles missing YARD types (`T.untyped`)
|
17
|
+
- Support for multiple parameter or return types (`T.any`/`|`)
|
18
|
+
- Gracefully handles missing YARD types (`T.untyped`/`untyped`)
|
16
19
|
- Can infer setter parameter type from the corresponding getter's return type
|
17
20
|
- Recognises mixins (`include` and `extend`)
|
18
21
|
- Support for generic types such as `Array<T>` and `Hash<K, V>`
|
19
22
|
- Can infer namespaced classes (`[Bar]` can become `GemName::Foo::Bar`)
|
20
|
-
- Handles return types which can be `nil` (`T.nilable`)
|
21
|
-
- Handles duck types (`T.untyped`)
|
23
|
+
- Handles return types which can be `nil` (`T.nilable`/`untyped`)
|
24
|
+
- Handles duck types (`T.untyped`/`untyped`)
|
22
25
|
- Support for ordered list types (`[Array(Integer, Symbol)]` becomes `[Integer, Symbol]`)
|
23
|
-
- Support for boolean types (`[true, false]` becomes `T::Boolean`)
|
26
|
+
- Support for boolean types (`[true, false]` becomes `T::Boolean`/`bool`)
|
24
27
|
- Support for `&block` parameters documented with `@yieldparam` and `@yieldreturn`
|
25
28
|
|
26
29
|
## Usage
|
@@ -29,7 +32,7 @@ Install Sord with `gem install sord`.
|
|
29
32
|
|
30
33
|
Sord is a command line tool. To use it, open a terminal in the root directory
|
31
34
|
of your project and invoke `sord`, passing a path where you'd like to save your
|
32
|
-
|
35
|
+
file (this file will be overwritten):
|
33
36
|
|
34
37
|
```
|
35
38
|
sord defs.rbi
|
@@ -37,7 +40,12 @@ sord defs.rbi
|
|
37
40
|
|
38
41
|
Sord will generate YARD docs and then print information about what it's inferred
|
39
42
|
as it runs. It is best to fix any issues in the YARD documentation, as any edits
|
40
|
-
made to the resulting
|
43
|
+
made to the resulting file will be replaced if you re-run Sord.
|
44
|
+
|
45
|
+
The output type is inferred by the file extension you use, but you can also
|
46
|
+
specify it explicitly with `--rbi` or `--rbs`.
|
47
|
+
|
48
|
+
## Shipping RBI Types
|
41
49
|
|
42
50
|
RBI files generated by Sord can be used in two main ways:
|
43
51
|
|
@@ -50,18 +58,22 @@ where the maintainer is unwilling to ship type signatures with the gem itself.
|
|
50
58
|
|
51
59
|
### Flags
|
52
60
|
|
53
|
-
Sord also takes some flags to alter the generated
|
61
|
+
Sord also takes some flags to alter the generated file:
|
54
62
|
|
55
|
-
- `--
|
56
|
-
|
57
|
-
|
63
|
+
- `--rbi`/`--rbs`: Override the output format inferred from the file
|
64
|
+
extension.
|
65
|
+
- `--no-sord-comments`: Generates the file without any Sord comments about
|
66
|
+
warnings/inferences/errors. (The original file's comments will still be
|
67
|
+
included.)
|
58
68
|
- `--no-regenerate`: By default, Sord will regenerate a repository's YARD
|
59
69
|
docs for you. This option skips regenerating the YARD docs.
|
60
70
|
- `--break-params`: Determines how many parameters are necessary before
|
61
71
|
the signature is changed from a single-line to a multi-line block.
|
62
72
|
(Default: 4)
|
63
|
-
- `--replace-errors-with-untyped`: Uses `T.untyped` instead of `SORD_ERROR_*`
|
64
|
-
|
73
|
+
- `--replace-errors-with-untyped`: Uses `T.untyped` instead of `SORD_ERROR_*`
|
74
|
+
constants.
|
75
|
+
- `--replace-unresolved-with-untyped`: Uses `T.untyped` when Sord is unable to
|
76
|
+
resolve a constant.
|
65
77
|
- `--include-messages` and `--exclude-messages`: Used to filter the logging
|
66
78
|
messages given by Sord. `--include-messages` acts as a whitelist, printing
|
67
79
|
only messages of the specified logging kinds, whereas `--exclude-messages`
|
@@ -85,10 +97,10 @@ module Example
|
|
85
97
|
@age = age
|
86
98
|
end
|
87
99
|
|
88
|
-
# @return
|
100
|
+
# @return [String]
|
89
101
|
attr_accessor :name
|
90
102
|
|
91
|
-
# @return
|
103
|
+
# @return [Integer]
|
92
104
|
attr_accessor :age
|
93
105
|
|
94
106
|
# @param possible_names [Array<String>] An array of potential names to choose from.
|
@@ -106,9 +118,8 @@ First, generate a YARD registry by running `yardoc test.rb`. Then, we can run
|
|
106
118
|
files! Note the `.rbi` file extension.) In doing this, Sord prints:
|
107
119
|
|
108
120
|
```
|
109
|
-
[INFER]
|
110
|
-
[
|
111
|
-
[DONE ] Processed 8 objects
|
121
|
+
[INFER] Assuming from filename you wish to generate in RBI format
|
122
|
+
[DONE ] Processed 8 objects (2 namespaces and 6 methods)
|
112
123
|
```
|
113
124
|
|
114
125
|
The `test.rbi` file then contains a complete RBI file for `test.rb`:
|
@@ -117,29 +128,45 @@ The `test.rbi` file then contains a complete RBI file for `test.rb`:
|
|
117
128
|
# typed: strong
|
118
129
|
module Example
|
119
130
|
class Person
|
120
|
-
# @
|
121
|
-
#
|
122
|
-
|
131
|
+
# _@param_ `name` — The name of the Person to create.
|
132
|
+
#
|
133
|
+
# _@param_ `age` — The age of the Person to create.
|
134
|
+
sig { params(name: String, age: Integer).void }
|
123
135
|
def initialize(name, age); end
|
124
136
|
|
125
|
-
|
126
|
-
|
137
|
+
# _@param_ `possible_names` — An array of potential names to choose from.
|
138
|
+
#
|
139
|
+
# _@param_ `possible_ages` — An array of potential ages to choose from.
|
140
|
+
sig { params(possible_names: T::Array[String], possible_ages: T::Array[Integer]).returns(Example::Person) }
|
141
|
+
def self.construct_randomly(possible_names, possible_ages); end
|
127
142
|
|
128
|
-
|
129
|
-
|
130
|
-
def name=(value); end
|
143
|
+
sig { returns(String) }
|
144
|
+
attr_accessor :name
|
131
145
|
|
132
146
|
sig { returns(Integer) }
|
133
|
-
|
147
|
+
attr_accessor :age
|
148
|
+
end
|
149
|
+
end
|
150
|
+
```
|
134
151
|
|
135
|
-
|
136
|
-
sig { params(value: Integer).returns(Integer) }
|
137
|
-
def age=(value); end
|
152
|
+
If we had instead generated `test.rbs`, we would get this file in RBS format:
|
138
153
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
154
|
+
```ruby
|
155
|
+
module Example
|
156
|
+
class Person
|
157
|
+
# _@param_ `name` — The name of the Person to create.
|
158
|
+
#
|
159
|
+
# _@param_ `age` — The age of the Person to create.
|
160
|
+
def initialize: (String name, Integer age) -> void
|
161
|
+
|
162
|
+
# _@param_ `possible_names` — An array of potential names to choose from.
|
163
|
+
#
|
164
|
+
# _@param_ `possible_ages` — An array of potential ages to choose from.
|
165
|
+
def self.construct_randomly: (Array[String] possible_names, Array[Integer] possible_ages) -> Example::Person
|
166
|
+
|
167
|
+
attr_accessor name: String
|
168
|
+
|
169
|
+
attr_accessor age: Integer
|
143
170
|
end
|
144
171
|
end
|
145
172
|
```
|
@@ -148,12 +175,13 @@ end
|
|
148
175
|
|
149
176
|
The general rule of thumb for type conversions is:
|
150
177
|
|
151
|
-
- If Sord understands the YARD type, then it is converted into the
|
178
|
+
- If Sord understands the YARD type, then it is converted into the RBI or RBS
|
179
|
+
type.
|
152
180
|
- If the YARD type is missing, Sord fills in `T.untyped`.
|
153
181
|
- If the YARD type can't be understood, Sord creates an undefined Ruby constant
|
154
182
|
with a similar name to the unknown YARD type. For example, the obviously
|
155
183
|
invalid YARD type `A%B` will become a constant called `SORD_ERROR_AB`.
|
156
|
-
You should search through your resulting
|
184
|
+
You should search through your resulting file to find and fix and
|
157
185
|
`SORD_ERROR`s.
|
158
186
|
|
159
187
|
## Contributing
|
@@ -161,11 +189,11 @@ The general rule of thumb for type conversions is:
|
|
161
189
|
Bug reports and pull requests are welcome on GitHub at https://github.com/AaronC81/sord. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
162
190
|
|
163
191
|
While contributing, if you want to see the results of your changes to Sord you
|
164
|
-
can use the `examples:seed` Rake task. The task uses Sord to generate
|
192
|
+
can use the `examples:seed` Rake task. The task uses Sord to generate types for
|
165
193
|
a number of open source Ruby gems, including Bundler, Haml, Rouge, and RSpec.
|
166
|
-
`rake examples:seed` (and `rake examples:reseed` to regenerate the
|
167
|
-
|
168
|
-
|
194
|
+
`rake examples:seed` (and `rake examples:reseed` to regenerate the files) will
|
195
|
+
clone the repositories of these gems into `sord_examples/` and then generate the
|
196
|
+
files into the same directory.
|
169
197
|
|
170
198
|
## License
|
171
199
|
|
data/lib/sord/type_converter.rb
CHANGED
@@ -7,7 +7,7 @@ require 'parlour'
|
|
7
7
|
module Sord
|
8
8
|
# Contains methods to convert YARD types to Parlour types.
|
9
9
|
module TypeConverter
|
10
|
-
# A regular expression which matches Ruby namespaces and identifiers.
|
10
|
+
# A regular expression which matches Ruby namespaces and identifiers.
|
11
11
|
# "Foo", "Foo::Bar", and "::Foo::Bar" are all matches, whereas "Foo.Bar"
|
12
12
|
# or "Foo#bar" are not.
|
13
13
|
SIMPLE_TYPE_REGEX =
|
@@ -20,26 +20,25 @@ module Sord
|
|
20
20
|
# "Hash{String => Symbol}", etc.
|
21
21
|
GENERIC_TYPE_REGEX =
|
22
22
|
/(#{SIMPLE_TYPE_REGEX})\s*[<{]\s*(.*)\s*[>}]/
|
23
|
-
|
23
|
+
|
24
24
|
# Match duck types which require the object implement one or more methods,
|
25
25
|
# like '#foo', '#foo & #bar', '#foo&#bar&#baz', and '#foo&#bar&#baz&#foo_bar'.
|
26
26
|
DUCK_TYPE_REGEX =
|
27
27
|
/^\#[a-zA-Z_][\w]*(?:[a-zA-Z_][\w=]*)*(?:( ?\& ?\#)*[a-zA-Z_][\w=]*)*$/
|
28
|
-
|
28
|
+
|
29
29
|
# A regular expression which matches ordered lists in the format of
|
30
30
|
# either "Array(String, Symbol)" or "(String, Symbol)".
|
31
31
|
ORDERED_LIST_REGEX = /^(?:Array|)\((.*)\s*\)$/
|
32
32
|
|
33
|
-
# A regular expression which matches the shorthand Hash syntax,
|
33
|
+
# A regular expression which matches the shorthand Hash syntax,
|
34
34
|
# "{String => Symbol}".
|
35
35
|
SHORTHAND_HASH_SYNTAX = /^{\s*(.*)\s*}$/
|
36
36
|
|
37
|
-
# A regular expression which matches the shorthand Array syntax,
|
37
|
+
# A regular expression which matches the shorthand Array syntax,
|
38
38
|
# "<String>".
|
39
39
|
SHORTHAND_ARRAY_SYNTAX = /^<\s*(.*)\s*>$/
|
40
40
|
|
41
|
-
#
|
42
|
-
SUPPORTED_GENERIC_TYPES = %w{Array Set Enumerable Enumerator Range Hash Class}
|
41
|
+
# Built in parlour single arg generics
|
43
42
|
SINGLE_ARG_GENERIC_TYPES = %w{Array Set Enumerable Enumerator Range}
|
44
43
|
|
45
44
|
# Given a string of YARD type parameters (without angle brackets), splits
|
@@ -51,7 +50,7 @@ module Sord
|
|
51
50
|
buffer = ""
|
52
51
|
current_bracketing_level = 0
|
53
52
|
character_pointer = 0
|
54
|
-
|
53
|
+
|
55
54
|
while character_pointer < params.length
|
56
55
|
should_buffer = true
|
57
56
|
|
@@ -161,29 +160,30 @@ module Sord
|
|
161
160
|
generic_type = $1
|
162
161
|
type_parameters = $2
|
163
162
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
Parlour::Types::Hash.new(*parameters)
|
174
|
-
else
|
175
|
-
handle_sord_error(parameters.map(&:describe).join, "Invalid hash, must have exactly two types: #{yard.inspect}.", item, replace_errors_with_untyped)
|
176
|
-
end
|
163
|
+
parameters = split_type_parameters(type_parameters)
|
164
|
+
.map { |x| yard_to_parlour(x, item, replace_errors_with_untyped, replace_unresolved_with_untyped) }
|
165
|
+
if SINGLE_ARG_GENERIC_TYPES.include?(generic_type) && parameters.length > 1
|
166
|
+
Parlour::Types.const_get(generic_type).new(Parlour::Types::Union.new(parameters))
|
167
|
+
elsif generic_type == 'Class' && parameters.length == 1
|
168
|
+
Parlour::Types::Class.new(parameters.first)
|
169
|
+
elsif generic_type == 'Hash'
|
170
|
+
if parameters.length == 2
|
171
|
+
Parlour::Types::Hash.new(*parameters)
|
177
172
|
else
|
178
|
-
|
173
|
+
handle_sord_error(parameters.map(&:describe).join, "Invalid hash, must have exactly two types: #{yard.inspect}.", item, replace_errors_with_untyped)
|
179
174
|
end
|
180
175
|
else
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
176
|
+
if Parlour::Types.const_defined?(generic_type)
|
177
|
+
# This generic is built in to parlour, but sord doesn't
|
178
|
+
# explicitly know about it.
|
179
|
+
Parlour::Types.const_get(generic_type).new(*parameters)
|
180
|
+
else
|
181
|
+
# This is a user defined generic
|
182
|
+
Parlour::Types::Generic.new(
|
183
|
+
yard_to_parlour(generic_type),
|
184
|
+
parameters
|
185
|
+
)
|
186
|
+
end
|
187
187
|
end
|
188
188
|
# Converts ordered lists like Array(Symbol, String) or (Symbol, String)
|
189
189
|
# into tuples.
|
data/lib/sord/version.rb
CHANGED
data/rbi/sord.rbi
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# typed: strong
|
2
2
|
module Sord
|
3
|
-
VERSION = T.let('3.0.0.beta.
|
3
|
+
VERSION = T.let('3.0.0.beta.2', T.untyped)
|
4
4
|
|
5
5
|
# Handles writing logs to stdout and any other classes which request them.
|
6
6
|
module Logging
|
@@ -318,7 +318,6 @@ module Sord
|
|
318
318
|
ORDERED_LIST_REGEX = T.let(/^(?:Array|)\((.*)\s*\)$/, T.untyped)
|
319
319
|
SHORTHAND_HASH_SYNTAX = T.let(/^{\s*(.*)\s*}$/, T.untyped)
|
320
320
|
SHORTHAND_ARRAY_SYNTAX = T.let(/^<\s*(.*)\s*>$/, T.untyped)
|
321
|
-
SUPPORTED_GENERIC_TYPES = T.let(%w{Array Set Enumerable Enumerator Range Hash Class}, T.untyped)
|
322
321
|
SINGLE_ARG_GENERIC_TYPES = T.let(%w{Array Set Enumerable Enumerator Range}, T.untyped)
|
323
322
|
|
324
323
|
# Given a string of YARD type parameters (without angle brackets), splits
|
data/sord.gemspec
CHANGED
@@ -25,7 +25,7 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.add_dependency 'yard'
|
26
26
|
spec.add_dependency 'sorbet-runtime'
|
27
27
|
spec.add_dependency 'commander', '~> 4.5'
|
28
|
-
spec.add_dependency 'parlour', '5.0.0.beta.
|
28
|
+
spec.add_dependency 'parlour', '5.0.0.beta.6'
|
29
29
|
|
30
30
|
spec.add_development_dependency "bundler", "~> 2.0"
|
31
31
|
spec.add_development_dependency "rake", "~> 10.0"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sord
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.0.beta.
|
4
|
+
version: 3.0.0.beta.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Aaron Christiansen
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-10-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: yard
|
@@ -58,14 +58,14 @@ dependencies:
|
|
58
58
|
requirements:
|
59
59
|
- - '='
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: 5.0.0.beta.
|
61
|
+
version: 5.0.0.beta.6
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
66
|
- - '='
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 5.0.0.beta.
|
68
|
+
version: 5.0.0.beta.6
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: bundler
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|