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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6cfc03da2fe9815159c9041a5afff2a0e1e089567cb92da25bcec87137f9e747
4
- data.tar.gz: acd6551c560c205199ec494930f4628c5357a34263b0cce05757033014ba929b
3
+ metadata.gz: 7a96fafb7c0a8a07c5462a5138b836837e65e2dd14f68d9f51ebd502170c84f9
4
+ data.tar.gz: 8d82f8e1848f0422cdd4729933f867f78daffeeb226a54b826d5fd75660e73ac
5
5
  SHA512:
6
- metadata.gz: a3ef67b5162e55af55f81fd056c0a1f232293c021b145fab2054cd482951c9cd22aa2e9f8874687131c65b209f2217488ce6808f9bd88da75a04928720452a34
7
- data.tar.gz: 719461ac9a36dc5c636c4f1b79c22923da4e1decb25032ec8e0c6eef8df60454c3eba6d275c61f91fec9d637d200631d3c3003b1aff981d6bafac3c91323e323
6
+ metadata.gz: f885ba62dd5b528f63e644d6cc6d000b33f372ea07ec7f372b1231464f5989e5353db508d553d997cdb772dc5ad075cf8fc3d37ede901f16efaa031438b59474
7
+ data.tar.gz: 859a054fdf1e1609035862c4f95d3b03622dcf7fe97c97afae120e80168102af0806dd8463aa00815f2e294cb0c895f511a9387b4f22e8464dc8aa9dc4f9a333
@@ -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 Sorbet type signatures files by
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
- Sorbet signatures you need!
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
- `.rbi` (this file will be overwritten):
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 RBI file will be replaced if you re-run Sord.
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 `.rbi` file:
61
+ Sord also takes some flags to alter the generated file:
54
62
 
55
- - `--no-sord-comments`: Generates the `.rbi` file without any Sord comments
56
- about warnings/inferences/errors. (The original file's comments will still
57
- be included.)
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_*` constants.
64
- - `--replace-unresolved-with-untyped`: Uses `T.untyped` when Sord is unable to resolve a constant.
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 name [String]
100
+ # @return [String]
89
101
  attr_accessor :name
90
102
 
91
- # @return age [Integer]
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] (Example::Person#name=) inferred type of parameter "value" as String using getter's return type
110
- [INFER] (Example::Person#age=) inferred type of parameter "value" as Integer using getter's return type
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
- # @param `name` — The name of the Person to create.
121
- # @param `age` — The age of the Person to create.
122
- sig { params(name: String, age: Integer).returns(Example::Person) }
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
- sig { returns(String) }
126
- def name; end
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
- # sord infer - inferred type of parameter "value" as String using getter's return type
129
- sig { params(value: String).returns(String) }
130
- def name=(value); end
143
+ sig { returns(String) }
144
+ attr_accessor :name
131
145
 
132
146
  sig { returns(Integer) }
133
- def age; end
147
+ attr_accessor :age
148
+ end
149
+ end
150
+ ```
134
151
 
135
- # sord infer - inferred type of parameter "value" as Integer using getter's return type
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
- # @param `possible_names` — An array of potential names to choose from.
140
- # @param `possible_ages` — An array of potential ages to choose from.
141
- sig { params(possible_names: T::Array[String], possible_ages: T::Array[Integer]).returns(Example::Person) }
142
- def self.construct_randomly(possible_names, possible_ages); end
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 Sorbet type.
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 RBI to find and fix and
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 RBIs for
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 RBI files)
167
- will clone the repositories of these gems into `sord_examples/` and then
168
- generate the RBI files into the same directory.
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
 
@@ -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
- # An array of built-in types supported by Parlour.
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
- if SUPPORTED_GENERIC_TYPES.include?(generic_type)
165
- parameters = split_type_parameters(type_parameters)
166
- .map { |x| yard_to_parlour(x, item, replace_errors_with_untyped, replace_unresolved_with_untyped) }
167
- if SINGLE_ARG_GENERIC_TYPES.include?(generic_type) && parameters.length > 1
168
- Parlour::Types.const_get(generic_type).new(Parlour::Types::Union.new(parameters))
169
- elsif generic_type == 'Class' && parameters.length == 1
170
- Parlour::Types::Class.new(parameters.first)
171
- elsif generic_type == 'Hash'
172
- if parameters.length == 2
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
- Parlour::Types.const_get(generic_type).new(*parameters)
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
- return handle_sord_error(
182
- generic_type,
183
- "unsupported generic type #{generic_type.inspect} in #{yard.inspect}",
184
- item,
185
- replace_errors_with_untyped
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.
@@ -1,4 +1,4 @@
1
1
  # typed: strong
2
2
  module Sord
3
- VERSION = '3.0.0.beta.1'
3
+ VERSION = '3.0.0.beta.2'
4
4
  end
@@ -1,6 +1,6 @@
1
1
  # typed: strong
2
2
  module Sord
3
- VERSION = T.let('3.0.0.beta.1', T.untyped)
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
@@ -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.3'
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.1
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-09-16 00:00:00.000000000 Z
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.3
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.3
68
+ version: 5.0.0.beta.6
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: bundler
71
71
  requirement: !ruby/object:Gem::Requirement