sord 0.9.0 → 0.10.0

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: bfebf9f7b35b936d5a448430b99c0aaa79cb13af0183cdf438c9d210b79fcbe4
4
- data.tar.gz: fd5d9f369fbc55d34bac6b3338cb481a3a0a3ed748d47130327f841e5ac3d8a7
3
+ metadata.gz: ca2e726bf2e1ec8e4baa524ae7111296a18068d1a5d63959abc967bcc01b2651
4
+ data.tar.gz: 6e71373e3eb57ed98395aa0ecca42a5da3cd45ae5212712de151230f0cfa0870
5
5
  SHA512:
6
- metadata.gz: 0407ed5b5770dd46c40df84dd40ba598d650a237f5f5a59127c66d30078970b36c803165dccbb9c6057784bee7763031f15d081fb0aabede6d100d5e943acd10
7
- data.tar.gz: '07849f1278d3d40a3230c45293bc23d6c5ab31360f1d43a55ebc04eefc448e80481fc740180a776d6d999193798a30e1aa961a406c77e9f92d998a67ae43c4e2'
6
+ metadata.gz: 04c0bc1d1b2a74d5d428530cfafe9d21686be9d2bfb032379e7a705478f16ba53c027d85736d4f378104bb443d99706feca733ee1d465b2bf59200bfc61dbd70
7
+ data.tar.gz: 11a6fab0f1bd64e0c3b454bfa4c32ec84cc36b9f7dc2d30d726ab950e1091a0a53328b81666d3767adde2b6ff733af46647e4129a747a15f55db9a39227df8e9
data/CHANGELOG.md CHANGED
@@ -3,6 +3,17 @@ 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
+ ## [0.10.0] - 2019-09-14
7
+ ### Added
8
+ - Comments in RBIs are now converted from YARD into Markdown format, making them
9
+ look much better when viewed in an IDE. (To restore the old behaviour of copying
10
+ the YARD comments verbatim, use the `--keep-original-comments` flag.)
11
+
12
+ ### Changed
13
+ - Parlour 0.8.0 is now being used.
14
+ - References to `self` as a type in YARD docs are now generated as
15
+ `T.self_type`, rather than a fixed self type determined by Sord.
16
+
6
17
  ## [0.9.0] - 2019-08-09
7
18
  ### Added
8
19
  - Add the `--replace-constants-with-untyped` flag, which generates `T.untyped` instead of `SORD_ERROR` constants.
data/README.md CHANGED
@@ -52,8 +52,9 @@ where the maintainer is unwilling to ship type signatures with the gem itself.
52
52
 
53
53
  Sord also takes some flags to alter the generated `.rbi` file:
54
54
 
55
- - `--no-comments`: Generates the `.rbi` file without any comments about
56
- warnings/inferences/errors.
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.)
57
58
  - `--no-regenerate`: By default, Sord will regenerate a repository's YARD
58
59
  docs for you. This option skips regenerating the YARD docs.
59
60
  - `--break-params`: Determines how many parameters are necessary before
@@ -76,22 +77,22 @@ Say we have this file, called `test.rb`:
76
77
  ```ruby
77
78
  module Example
78
79
  class Person
79
- # @param [String] name
80
- # @param [Integer] age
80
+ # @param name [String] The name of the Person to create.
81
+ # @param age [Integer] The age of the Person to create.
81
82
  # @return [Example::Person]
82
83
  def initialize(name, age)
83
84
  @name = name
84
85
  @age = age
85
86
  end
86
87
 
87
- # @return [String] name
88
+ # @return name [String]
88
89
  attr_accessor :name
89
90
 
90
- # @return [Integer] age
91
+ # @return age [Integer]
91
92
  attr_accessor :age
92
93
 
93
- # @param [Array<String>] possible_names
94
- # @param [Array<Integer>] possible_ages
94
+ # @param possible_names [Array<String>] An array of potential names to choose from.
95
+ # @param possible_ages [Array<Integer>] An array of potential ages to choose from.
95
96
  # @return [Example::Person]
96
97
  def self.construct_randomly(possible_names, possible_ages)
97
98
  Person.new(possible_names.sample, possible_ages.sample)
@@ -116,23 +117,27 @@ The `test.rbi` file then contains a complete RBI file for `test.rb`:
116
117
  # typed: strong
117
118
  module Example
118
119
  class Person
120
+ # @param `name` — The name of the Person to create.
121
+ # @param `age` — The age of the Person to create.
119
122
  sig { params(name: String, age: Integer).returns(Example::Person) }
120
123
  def initialize(name, age); end
121
124
 
122
125
  sig { returns(String) }
123
- def name(); end
126
+ def name; end
124
127
 
125
128
  # sord infer - inferred type of parameter "value" as String using getter's return type
126
129
  sig { params(value: String).returns(String) }
127
130
  def name=(value); end
128
131
 
129
132
  sig { returns(Integer) }
130
- def age(); end
133
+ def age; end
131
134
 
132
135
  # sord infer - inferred type of parameter "value" as Integer using getter's return type
133
136
  sig { params(value: Integer).returns(Integer) }
134
137
  def age=(value); end
135
138
 
139
+ # @param `possible_names` — An array of potential names to choose from.
140
+ # @param `possible_ages` — An array of potential ages to choose from.
136
141
  sig { params(possible_names: T::Array[String], possible_ages: T::Array[Integer]).returns(Example::Person) }
137
142
  def self.construct_randomly(possible_names, possible_ages); end
138
143
  end
data/Rakefile CHANGED
@@ -45,7 +45,7 @@ namespace :examples do
45
45
  # Generate sri
46
46
  puts "Generating rbi for #{name}..."
47
47
  if args[:clean]
48
- system("bundle exec sord ../#{name}.rbi --no-comments --replace-errors-with-untyped --replace-unresolved-with-untyped")
48
+ system("bundle exec sord ../#{name}.rbi --no-sord-comments --replace-errors-with-untyped --replace-unresolved-with-untyped")
49
49
  else
50
50
  system("bundle exec sord ../#{name}.rbi")
51
51
  end
@@ -70,7 +70,7 @@ namespace :examples do
70
70
  puts "Regenerating rbi file for #{name}..."
71
71
  Bundler.with_clean_env do
72
72
  if args[:clean]
73
- system("bundle exec sord ../#{name}.rbi --no-regenerate --no-comments --replace-errors-with-untyped --replace-unresolved-with-untyped")
73
+ system("bundle exec sord ../#{name}.rbi --no-regenerate --no-sord-comments --replace-errors-with-untyped --replace-unresolved-with-untyped")
74
74
  else
75
75
  system("bundle exec sord ../#{name}.rbi --no-regenerate")
76
76
  end
data/exe/sord CHANGED
@@ -11,23 +11,25 @@ default_command :gen
11
11
  command :gen do |c|
12
12
  c.syntax = 'sord gen <output-file> [options]'
13
13
  c.description = 'Generates an RBI file from this directory\'s YARD docs'
14
- c.option '--[no-]comments', 'Controls informational/warning comments in the RBI file'
14
+ c.option '--[no-]sord-comments', 'Controls informational/warning comments in the RBI file'
15
15
  c.option '--[no-]regenerate', 'Controls whether YARD is executed before Sord runs'
16
16
  c.option '--break-params INTEGER', Integer, 'Break params onto their own lines if there are this many'
17
17
  c.option '--replace-errors-with-untyped', 'Uses T.untyped rather than SORD_ERROR_ constants'
18
18
  c.option '--replace-unresolved-with-untyped', 'Uses T.untyped when Sord is unable to resolve a constant'
19
19
  c.option '--exclude-messages STRING', String, 'Blacklists a comma-separated string of log message types'
20
20
  c.option '--include-messages STRING', String, 'Whitelists a comma-separated string of log message types'
21
+ c.option '--keep-original-comments', 'Retains original YARD comments rather than converting them to Markdown'
21
22
 
22
23
  c.action do |args, options|
23
24
  options.default(
24
- comments: true,
25
+ sord_comments: true,
25
26
  regenerate: true,
26
27
  break_params: 4,
27
28
  replace_errors_with_untyped: false,
28
29
  replace_unresolved_with_untyped: false,
29
30
  exclude_messages: nil,
30
31
  include_messages: nil,
32
+ keep_original_comments: false
31
33
  )
32
34
 
33
35
  if args.length != 1
@@ -10,7 +10,7 @@ module Sord
10
10
  @parlour = nil
11
11
  @options = options
12
12
 
13
- options[:comments] = true if options[:comments].nil?
13
+ options[:sord_comments] = true if options[:sord_comments].nil?
14
14
  options[:regenerate] = true if options[:regenerate].nil?
15
15
  options[:replace_errors_with_untyped] ||= false
16
16
  options[:replace_unresolved_with_untyped] ||= false
@@ -38,11 +38,12 @@ module Sord
38
38
 
39
39
  @replace_errors_with_untyped = options[:replace_errors_with_untyped]
40
40
  @replace_unresolved_with_untyped = options[:replace_unresolved_with_untyped]
41
+ @keep_original_comments = options[:keep_original_comments]
41
42
 
42
43
  # Hook the logger so that messages are added as comments to the RBI file
43
44
  Logging.add_hook do |type, msg, item|
44
45
  @current_object.add_comment_to_next_child("sord #{type} - #{msg}")
45
- end if options[:comments]
46
+ end if options[:sord_comments]
46
47
 
47
48
  # Hook the logger so that warnings are collected
48
49
  Logging.add_hook do |type, msg, item|
@@ -88,7 +89,9 @@ module Sord
88
89
  constant_name = constant.to_s.split('::').last
89
90
 
90
91
  # Add the constant to the current object being generated.
91
- @current_object.create_constant(constant_name, value: "T.let(#{constant.value}, T.untyped)")
92
+ @current_object.create_constant(constant_name, value: "T.let(#{constant.value}, T.untyped)") do |c|
93
+ c.add_comments(constant.docstring.all.split("\n"))
94
+ end
92
95
  end
93
96
  end
94
97
 
@@ -158,8 +161,13 @@ module Sord
158
161
  end
159
162
  end
160
163
 
164
+ return_types = getter.tags('return').flat_map(&:types)
165
+ unless return_types.any?
166
+ Logging.omit("no YARD type given for #{name.inspect}, using T.untyped", meth)
167
+ next 'T.untyped'
168
+ end
161
169
  inferred_type = TypeConverter.yard_to_sorbet(
162
- getter.tags('return').flat_map(&:types), meth, @replace_errors_with_untyped, @replace_unresolved_with_untyped)
170
+ return_types, meth, @replace_errors_with_untyped, @replace_unresolved_with_untyped)
163
171
 
164
172
  Logging.infer("inferred type of parameter #{name.inspect} as #{inferred_type} using getter's return type", meth)
165
173
  inferred_type
@@ -209,7 +217,89 @@ module Sord
209
217
  parameters: parlour_params,
210
218
  returns: returns,
211
219
  class_method: meth.scope == :class
212
- )
220
+ ) do |m|
221
+ if @keep_original_comments
222
+ m.add_comments(meth.docstring.all.split("\n"))
223
+ else
224
+ parser = YARD::Docstring.parser
225
+ parser.parse(meth.docstring.all)
226
+
227
+ docs_array = parser.text.split("\n")
228
+
229
+ # Add @param tags if there are any with names and descriptions.
230
+ params = parser.tags.select { |tag| tag.tag_name == 'param' && tag.is_a?(YARD::Tags::Tag) && !tag.name.nil? }
231
+ # Add a blank line if there's anything before the params.
232
+ docs_array << '' if docs_array.length.positive? && params.length.positive?
233
+ params.each do |param|
234
+ docs_array << '' if docs_array.last != '' && docs_array.length.positive?
235
+ # Output params in the form of:
236
+ # _@param_ `foo` — Lorem ipsum.
237
+ # _@param_ `foo`
238
+ if param.text.nil?
239
+ docs_array << "_@param_ `#{param.name}`"
240
+ else
241
+ docs_array << "_@param_ `#{param.name}` — #{param.text}"
242
+ end
243
+ end
244
+
245
+ # Add @return tags (there could possibly be more than one, despite this not being supported)
246
+ returns = parser.tags.select { |tag| tag.tag_name == 'return' && tag.is_a?(YARD::Tags::Tag) && !tag.text.nil? && tag.text.strip != '' }
247
+ # Add a blank line if there's anything before the returns.
248
+ docs_array << '' if docs_array.length.positive? && returns.length.positive?
249
+ returns.each do |retn|
250
+ docs_array << '' if docs_array.last != '' && docs_array.length.positive?
251
+ # Output returns in the form of:
252
+ # _@return_ — Lorem ipsum.
253
+ docs_array << "_@return_ — #{retn.text}"
254
+ end
255
+
256
+ # Iterate through the @example tags for a given YARD doc and output them in Markdown codeblocks.
257
+ examples = parser.tags.select { |tag| tag.tag_name == 'example' && tag.is_a?(YARD::Tags::Tag) }
258
+ examples.each do |example|
259
+ # Only add a blank line if there's anything before the example.
260
+ docs_array << '' if docs_array.length.positive?
261
+ # Include the example's 'name' if there is one.
262
+ docs_array << example.name unless example.name.nil? || example.name == ""
263
+ docs_array << "```ruby"
264
+ docs_array.concat(example.text.split("\n"))
265
+ docs_array << "```"
266
+ end if examples.length.positive?
267
+
268
+ # Add @note and @deprecated tags.
269
+ notice_tags = parser.tags.select { |tag| ['note', 'deprecated'].include?(tag.tag_name) && tag.is_a?(YARD::Tags::Tag) }
270
+ # Add a blank line if there's anything before the params.
271
+ docs_array << '' if docs_array.last != '' && docs_array.length.positive? && notice_tags.length.positive?
272
+ notice_tags.each do |notice_tag|
273
+ docs_array << '' if docs_array.last != ''
274
+ # Output note/deprecated/see in the form of:
275
+ # _@note_ — Lorem ipsum.
276
+ # _@note_
277
+ if notice_tag.text.nil?
278
+ docs_array << "_@#{notice_tag.tag_name}_"
279
+ else
280
+ docs_array << "_@#{notice_tag.tag_name}_ — #{notice_tag.text}"
281
+ end
282
+ end
283
+
284
+ # Add @see tags.
285
+ see_tags = parser.tags.select { |tag| tag.tag_name == 'see' && tag.is_a?(YARD::Tags::Tag) }
286
+ # Add a blank line if there's anything before the params.
287
+ docs_array << '' if docs_array.last != '' && docs_array.length.positive? && see_tags.length.positive?
288
+ see_tags.each do |see_tag|
289
+ docs_array << '' if docs_array.last != ''
290
+ # Output note/deprecated/see in the form of:
291
+ # _@see_ `B` — Lorem ipsum.
292
+ # _@see_ `B`
293
+ if see_tag.text.nil?
294
+ docs_array << "_@see_ `#{see_tag.name}`"
295
+ else
296
+ docs_array << "_@see_ `#{see_tag.name}` — #{see_tag.text}"
297
+ end
298
+ end
299
+
300
+ m.add_comments(docs_array)
301
+ end
302
+ end
213
303
  end
214
304
  end
215
305
 
@@ -227,6 +317,7 @@ module Sord
227
317
  @current_object = item.type == :class \
228
318
  ? parent.create_class(item.name.to_s, superclass: superclass)
229
319
  : parent.create_module(item.name.to_s)
320
+ @current_object.add_comments(item.docstring.all.split("\n"))
230
321
 
231
322
  add_mixins(item)
232
323
  add_methods(item)
@@ -107,7 +107,7 @@ module Sord
107
107
  when "bool", "Bool", "boolean", "Boolean", "true", "false"
108
108
  "T::Boolean"
109
109
  when 'self'
110
- item.parent.path
110
+ 'T.self_type'
111
111
  when Array
112
112
  # If there's only one element, unwrap it, otherwise allow for a
113
113
  # selection of any of the types
data/lib/sord/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  # typed: strong
2
2
  module Sord
3
- VERSION = '0.9.0'
3
+ VERSION = '0.10.0'
4
4
  end
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.4'
28
- spec.add_dependency 'parlour', '~> 0.6.1'
28
+ spec.add_dependency 'parlour', '~> 0.8.0'
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: 0.9.0
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Christiansen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-08-09 00:00:00.000000000 Z
11
+ date: 2019-09-14 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: 0.6.1
61
+ version: 0.8.0
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: 0.6.1
68
+ version: 0.8.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: bundler
71
71
  requirement: !ruby/object:Gem::Requirement