sord 2.0.0 → 3.0.0.beta.1

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: 14900bd9ce64eda2373d0844e42032ea041b44dd10a6ca6a82bd66c31b2b0c9b
4
- data.tar.gz: 983e467e872f0e455da6ca618b2a2ffb159d81f6cc1456e8370e33ecd42179bf
3
+ metadata.gz: 6cfc03da2fe9815159c9041a5afff2a0e1e089567cb92da25bcec87137f9e747
4
+ data.tar.gz: acd6551c560c205199ec494930f4628c5357a34263b0cce05757033014ba929b
5
5
  SHA512:
6
- metadata.gz: 6a63ef228f6763653b2be68d46c16f20793118a67adec93d6cc2ec016ed9df254803e3b1fb1bc5c5b26a248020715ee72836c3b4fab6bb07e2d1223e685af97b
7
- data.tar.gz: b9a86b1af67cdfd6d73eb28f2b6b46d10b5e61418d2118693e2103da1d5e9d506c8046b069922b908d1d4ecd908abf832ad4a480868b6720650a386fb010d766
6
+ metadata.gz: a3ef67b5162e55af55f81fd056c0a1f232293c021b145fab2054cd482951c9cd22aa2e9f8874687131c65b209f2217488ce6808f9bd88da75a04928720452a34
7
+ data.tar.gz: 719461ac9a36dc5c636c4f1b79c22923da4e1decb25032ec8e0c6eef8df60454c3eba6d275c61f91fec9d637d200631d3c3003b1aff981d6bafac3c91323e323
File without changes
File without changes
data/.gitignore CHANGED
File without changes
data/.parlour CHANGED
@@ -1,7 +1,11 @@
1
- output_file: rbi/sord.rbi
1
+ parser: false
2
+
3
+ output_file:
4
+ rbi: rbi/sord.rbi
2
5
 
3
6
  requires:
4
7
  - sord
5
8
 
6
9
  plugins:
7
- Sord::ParlourPlugin: {}
10
+ Sord::ParlourPlugin:
11
+ rbi: yes
data/.rspec CHANGED
File without changes
File without changes
@@ -3,6 +3,21 @@ 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.1] - 2020-09-16
7
+ ### Added
8
+ - Sord now uses the Parlour 5 beta's RBS generation to generate RBS files!
9
+ - Added `--rbi` and `--rbs` to select an output format to use (if neither given,
10
+ tries to infer from file extension).
11
+
12
+ ### Changed
13
+ - `RbiGenerator` has been renamed to `Generator`.
14
+ - `TypeConverter#yard_to_sorbet` is now `TypeConverter#yard_to_parlour`, and
15
+ returns `Parlour::Types::Type` instances rather than strings.
16
+
17
+ ### Fixed
18
+ - `#return [nil]` no longer produces a union of zero types, instead becoming
19
+ `void` for method returns or `untyped` for attributes.
20
+
6
21
  ## [2.0.0] - 2020-03-16
7
22
  ### Added
8
23
  - Sord now supports generating `attr_accessor`, `attr_reader` and `attr_writer`
File without changes
data/Gemfile CHANGED
File without changes
File without changes
data/README.md CHANGED
File without changes
data/Rakefile CHANGED
@@ -24,12 +24,21 @@ namespace :examples do
24
24
  require 'rainbow'
25
25
 
26
26
  desc "Clone git repositories and run Sord on them as examples"
27
- task :seed, [:clean] do |t, args|
27
+ task :seed, [:mode, :clean] do |t, args|
28
28
  if File.directory?('sord_examples')
29
29
  puts Rainbow('sord_examples directory already exists, please delete the directory or run a reseed!').red
30
30
  exit
31
31
  end
32
32
 
33
+ if args[:mode] == 'rbi'
34
+ mode_arg = '--rbi'
35
+ elsif args[:mode] == 'rbs'
36
+ mode_arg = '--rbs'
37
+ else
38
+ puts Rainbow('please specify \'rbi\' or \'rbs\'!').red
39
+ exit
40
+ end
41
+
33
42
  FileUtils.mkdir 'sord_examples'
34
43
  FileUtils.cd 'sord_examples'
35
44
 
@@ -46,11 +55,11 @@ namespace :examples do
46
55
  # Generate sri
47
56
  puts "Generating rbi for #{name}..."
48
57
  if args[:clean]
49
- system("bundle exec sord ../#{name}.rbi --no-sord-comments --replace-errors-with-untyped --replace-unresolved-with-untyped")
58
+ system("bundle exec sord ../#{name}.#{args[:mode]} #{mode_arg} --no-sord-comments --replace-errors-with-untyped --replace-unresolved-with-untyped")
50
59
  else
51
- system("bundle exec sord ../#{name}.rbi")
60
+ system("bundle exec sord ../#{name}.#{args[:mode]} #{mode_arg}")
52
61
  end
53
- puts "#{name}.rbi generated!"
62
+ puts "#{name}.#{args[:mode]} generated!"
54
63
  FileUtils.cd '..'
55
64
  end
56
65
  end
@@ -59,21 +68,30 @@ namespace :examples do
59
68
  end
60
69
 
61
70
  desc 'Regenerate the rbi files in sord_examples.'
62
- task :reseed, [:clean] do |t, args|
71
+ task :reseed, [:mode, :clean] do |t, args|
63
72
  if Dir.exist?('sord_examples')
64
73
  FileUtils.cd 'sord_examples'
65
74
  else
66
75
  raise Rainbow("The sord_examples directory does not exist. Have you run the seed task?").red.bold
67
76
  end
68
77
 
78
+ if args[:mode] == 'rbi'
79
+ mode_arg = '--rbi'
80
+ elsif args[:mode] == 'rbs'
81
+ mode_arg = '--rbs'
82
+ else
83
+ puts Rainbow('please specify \'rbi\' or \'rbs\'!').red
84
+ exit
85
+ end
86
+
69
87
  REPOS.keys.each do |name|
70
88
  FileUtils.cd name.to_s
71
89
  puts "Regenerating rbi file for #{name}..."
72
90
  Bundler.with_clean_env do
73
91
  if args[:clean]
74
- system("bundle exec sord ../#{name}.rbi --no-regenerate --no-sord-comments --replace-errors-with-untyped --replace-unresolved-with-untyped")
92
+ system("bundle exec sord ../#{name}.#{args[:mode]} #{mode_arg} --no-regenerate --no-sord-comments --replace-errors-with-untyped --replace-unresolved-with-untyped")
75
93
  else
76
- system("bundle exec sord ../#{name}.rbi --no-regenerate")
94
+ system("bundle exec sord ../#{name}.#{args[:mode]} #{mode_arg} --no-regenerate")
77
95
  end
78
96
  end
79
97
  FileUtils.cd '..'
data/exe/sord CHANGED
@@ -10,8 +10,10 @@ program :description, 'Generate Sorbet RBIs from YARD documentation'
10
10
  default_command :gen
11
11
  command :gen do |c|
12
12
  c.syntax = 'sord gen <output-file> [options]'
13
- c.description = 'Generates an RBI file from this directory\'s YARD docs'
14
- c.option '--[no-]sord-comments', 'Controls informational/warning comments in the RBI file'
13
+ c.description = 'Generates a type signature file from this directory\'s YARD docs'
14
+ c.option '--rbi', 'Use Sorbet\'s RBI format'
15
+ c.option '--rbs', 'Use Steep/Ruby 3\'s RBS format'
16
+ c.option '--[no-]sord-comments', 'Controls informational/warning comments in the file'
15
17
  c.option '--[no-]regenerate', 'Controls whether YARD is executed before Sord runs'
16
18
  c.option '--break-params INTEGER', Integer, 'Break params onto their own lines if there are this many'
17
19
  c.option '--replace-errors-with-untyped', 'Uses T.untyped rather than SORD_ERROR_ constants'
@@ -19,11 +21,13 @@ command :gen do |c|
19
21
  c.option '--exclude-messages STRING', String, 'Blacklists a comma-separated string of log message types'
20
22
  c.option '--include-messages STRING', String, 'Whitelists a comma-separated string of log message types'
21
23
  c.option '--keep-original-comments', 'Retains original YARD comments rather than converting them to Markdown'
22
- c.option '--skip-constants', 'Excludes constants from generated RBI'
24
+ c.option '--skip-constants', 'Excludes constants from generated file'
23
25
  c.option '--use-original-initialize-return', 'Uses the specified return type for #initialize rather than void'
24
26
 
25
27
  c.action do |args, options|
26
28
  options.default(
29
+ rbi: false,
30
+ rbs: false,
27
31
  sord_comments: true,
28
32
  regenerate: true,
29
33
  break_params: 4,
@@ -40,15 +44,47 @@ command :gen do |c|
40
44
  Sord::Logging.error('Must specify filename')
41
45
  exit 1
42
46
  end
43
-
47
+
44
48
  plugin_options = options.__hash__
45
49
  plugin_options[:exclude_options] = plugin_options[:exclude_options]&.split(',')
46
50
  plugin_options[:include_options] = plugin_options[:include_options]&.split(',')
47
51
 
52
+ if !(plugin_options[:rbi] || plugin_options[:rbs])
53
+ if args.first
54
+ if args.first.end_with?('.rbi')
55
+ Sord::Logging.infer('Assuming from filename you wish to generate in RBI format')
56
+ plugin_options[:rbi] = true
57
+ elsif args.first.end_with?('.rbs')
58
+ Sord::Logging.infer('Assuming from filename you wish to generate in RBS format')
59
+ plugin_options[:rbs] = true
60
+ else
61
+ Sord::Logging.error('An output format could not be inferred from your filename; please specify --rbi or --rbs')
62
+ exit 1
63
+ end
64
+ else
65
+ Sord::Logging.error('No output format given; please specify --rbi or --rbs')
66
+ exit 1
67
+ end
68
+ end
69
+
70
+ if (plugin_options[:rbi] && plugin_options[:rbs])
71
+ Sord::Logging.error('You cannot specify both --rbi and --rbs; please use only one')
72
+ exit 1
73
+ end
74
+
48
75
  plugin = Sord::ParlourPlugin.new(plugin_options)
49
- plugin.parlour = Parlour::RbiGenerator.new(break_params: plugin_options[:break_params])
76
+
77
+ if plugin_options[:rbi]
78
+ klass = Parlour::RbiGenerator
79
+ generator_method = :rbi
80
+ elsif plugin_options[:rbs]
81
+ klass = Parlour::RbsGenerator
82
+ generator_method = :rbs
83
+ end
84
+
85
+ plugin.parlour = klass.new(break_params: plugin_options[:break_params])
50
86
  plugin.generate(plugin.parlour.root)
51
87
 
52
- File.write(args.first, plugin.parlour.rbi)
88
+ File.write(args.first, plugin.parlour.send(generator_method))
53
89
  end
54
90
  end
@@ -1,6 +1,6 @@
1
1
  # typed: strong
2
2
  require 'sord/version'
3
- require 'sord/rbi_generator'
3
+ require 'sord/generator'
4
4
  require 'sord/parlour_plugin'
5
5
  require 'yard'
6
6
  require 'sorbet-runtime'
@@ -6,8 +6,11 @@ require 'parlour'
6
6
  require 'rainbow'
7
7
 
8
8
  module Sord
9
- # Converts the current working directory's YARD registry into an RBI file.
10
- class RbiGenerator
9
+ # Converts the current working directory's YARD registry into an type
10
+ # signature file.
11
+ class Generator
12
+ VALID_MODES = [:rbi, :rbs]
13
+
11
14
  # @return [Integer] The number of objects this generator has processed so
12
15
  # far.
13
16
  def object_count
@@ -19,17 +22,28 @@ module Sord
19
22
  # [message, item, line].
20
23
  attr_reader :warnings
21
24
 
22
- # Create a new RBI generator.
25
+ # Create a new generator.
23
26
  # @param [Hash] options
27
+ # @option options [Symbol] mode
24
28
  # @option options [Integer] break_params
25
29
  # @option options [Boolean] replace_errors_with_untyped
26
30
  # @option options [Boolean] replace_unresolved_with_untyped
27
31
  # @option options [Boolean] comments
28
- # @option options [Parlour::RbiGenerator] generator
29
- # @option options [Parlour::RbiGenerator::Namespace] root
32
+ # @option options [Parlour::Generator] generator
33
+ # @option options [Parlour::TypedObject] root
30
34
  # @return [void]
31
35
  def initialize(options)
32
- @parlour = options[:parlour] || Parlour::RbiGenerator.new
36
+ @mode = options[:mode].to_sym rescue options[:mode]
37
+ raise "invalid mode #{@mode}, expected one of: #{VALID_MODES.join(', ')}" \
38
+ unless VALID_MODES.include?(@mode)
39
+
40
+ @parlour = options[:parlour] || \
41
+ case @mode
42
+ when :rbi
43
+ Parlour::RbiGenerator.new
44
+ when :rbs
45
+ Parlour::RbsGenerator.new
46
+ end
33
47
  @current_object = options[:root] || @parlour.root
34
48
 
35
49
  @namespace_count = 0
@@ -42,7 +56,7 @@ module Sord
42
56
  @skip_constants = options[:skip_constants]
43
57
  @use_original_initialize_return = options[:use_original_initialize_return]
44
58
 
45
- # Hook the logger so that messages are added as comments to the RBI file
59
+ # Hook the logger so that messages are added as comments
46
60
  Logging.add_hook do |type, msg, item|
47
61
  @current_object.add_comment_to_next_child("sord #{type} - #{msg}")
48
62
  end if options[:sord_comments]
@@ -67,7 +81,7 @@ module Sord
67
81
  end
68
82
 
69
83
  # Given a YARD CodeObject, add lines defining its mixins (that is, extends
70
- # and includes) to the current RBI file. Returns the number of mixins.
84
+ # and includes) to the current file. Returns the number of mixins.
71
85
  # @param [YARD::CodeObjects::Base] item
72
86
  # @return [Integer]
73
87
  def add_mixins(item)
@@ -85,25 +99,39 @@ module Sord
85
99
  # @param [YARD::CodeObjects::NamespaceObject] item
86
100
  # @return [void]
87
101
  def add_constants(item)
88
- item.constants.each do |constant|
102
+ inserted_constant_names = Set.new
103
+
104
+ item.constants(included: false).each do |constant|
89
105
  # Take a constant (like "A::B::CONSTANT"), split it on each '::', and
90
106
  # set the constant name to the last string in the array.
91
107
  constant_name = constant.to_s.split('::').last
108
+ if inserted_constant_names.include?(constant_name) && @mode == :rbs
109
+ Logging.warn("RBS doesn't support duplicate constants, but '#{constant_name}' was duplicated - dropping future occurences", constant)
110
+ next
111
+ end
112
+ inserted_constant_names << constant_name
92
113
 
93
114
  # Add the constant to the current object being generated.
94
- @current_object.create_constant(constant_name, value: "T.let(#{constant.value}, T.untyped)") do |c|
95
- c.add_comments(constant.docstring.all.split("\n"))
115
+ case @mode
116
+ when :rbi
117
+ @current_object.create_constant(constant_name, value: "T.let(#{constant.value}, T.untyped)") do |c|
118
+ c.add_comments(constant.docstring.all.split("\n"))
119
+ end
120
+ when :rbs
121
+ @current_object.create_constant(constant_name, type: Parlour::Types::Untyped.new) do |c|
122
+ c.add_comments(constant.docstring.all.split("\n"))
123
+ end
96
124
  end
97
125
  end
98
126
  end
99
127
 
100
- # Adds comments to an RBI object based on a docstring.
128
+ # Adds comments to an object based on a docstring.
101
129
  # @param [YARD::CodeObjects::NamespaceObject] item
102
- # @param [Parlour::RbiGenerator::RbiObject] rbi_object
130
+ # @param [Parlour::TypedObject] typed_object
103
131
  # @return [void]
104
- def add_comments(item, rbi_object)
132
+ def add_comments(item, typed_object)
105
133
  if @keep_original_comments
106
- rbi_object.add_comments(item.docstring.all.split("\n"))
134
+ typed_object.add_comments(item.docstring.all.split("\n"))
107
135
  else
108
136
  parser = YARD::Docstring.parser
109
137
  parser.parse(item.docstring.all)
@@ -184,12 +212,12 @@ module Sord
184
212
  # fix: yard text may contains multiple line. should deal \n.
185
213
  # else generate text will be multiple line and only first line is commented
186
214
  docs_array = docs_array.flat_map {|line| line.empty? ? [""] : line.split("\n")}
187
- rbi_object.add_comments(docs_array)
215
+ typed_object.add_comments(docs_array)
188
216
  end
189
217
  end
190
218
 
191
219
  # Given a YARD NamespaceObject, add lines defining its methods and their
192
- # signatures to the current RBI file.
220
+ # signatures to the current file.
193
221
  # @param [YARD::CodeObjects::NamespaceObject] item
194
222
  # @return [void]
195
223
  def add_methods(item)
@@ -197,7 +225,7 @@ module Sord
197
225
  count_method
198
226
 
199
227
  # If the method is an alias, skip it so we don't define it as a
200
- # separate method. Sorbet will handle it automatically.
228
+ # separate method.
201
229
  if meth.is_alias?
202
230
  next
203
231
  end
@@ -221,7 +249,7 @@ module Sord
221
249
  name = name_and_default.first
222
250
 
223
251
  if tag
224
- TypeConverter.yard_to_sorbet(tag.types, meth, @replace_errors_with_untyped, @replace_unresolved_with_untyped)
252
+ TypeConverter.yard_to_parlour(tag.types, meth, @replace_errors_with_untyped, @replace_unresolved_with_untyped)
225
253
  elsif name.start_with? '&'
226
254
  # Find yieldparams and yieldreturn
227
255
  yieldparams = meth.tags('yieldparam')
@@ -230,18 +258,19 @@ module Sord
230
258
  yieldreturn&.first&.downcase == 'void'
231
259
 
232
260
  # Create strings
233
- params_string = yieldparams.map do |param|
234
- "#{param.name.gsub('*', '')}: #{TypeConverter.yard_to_sorbet(param.types, meth, @replace_errors_with_untyped, @replace_unresolved_with_untyped)}" unless param.name.nil?
235
- end.join(', ')
236
- return_string = TypeConverter.yard_to_sorbet(yieldreturn, meth, @replace_errors_with_untyped, @replace_unresolved_with_untyped)
261
+ params = yieldparams.map do |param|
262
+ Parlour::Types::Proc::Parameter.new(
263
+ param.name.gsub('*', ''),
264
+ TypeConverter.yard_to_parlour(param.types, meth, @replace_errors_with_untyped, @replace_unresolved_with_untyped)
265
+ )
266
+ end
267
+ returns = TypeConverter.yard_to_parlour(yieldreturn, meth, @replace_errors_with_untyped, @replace_unresolved_with_untyped)
237
268
 
238
269
  # Create proc types, if possible
239
270
  if yieldparams.empty? && yieldreturn.nil?
240
- 'T.untyped'
241
- elsif yieldreturn.nil?
242
- "T.proc#{params_string.empty? ? '' : ".params(#{params_string})"}.void"
271
+ Parlour::Types::Untyped.new
243
272
  else
244
- "T.proc#{params_string.empty? ? '' : ".params(#{params_string})"}.returns(#{return_string})"
273
+ Parlour::Types::Proc.new(params, yieldreturn.nil? ? nil : returns)
245
274
  end
246
275
  elsif meth.path.end_with? '='
247
276
  # Look for the matching getter method
@@ -254,22 +283,22 @@ module Sord
254
283
  && meth.tag('param').types
255
284
 
256
285
  Logging.infer("argument name in single @param inferred as #{parameter_names_and_defaults_to_tags.first.first.first.inspect}", meth)
257
- next TypeConverter.yard_to_sorbet(meth.tag('param').types, meth, @replace_errors_with_untyped, @replace_unresolved_with_untyped)
286
+ next TypeConverter.yard_to_parlour(meth.tag('param').types, meth, @replace_errors_with_untyped, @replace_unresolved_with_untyped)
258
287
  else
259
- Logging.omit("no YARD type given for #{name.inspect}, using T.untyped", meth)
260
- next 'T.untyped'
288
+ Logging.omit("no YARD type given for #{name.inspect}, using untyped", meth)
289
+ next Parlour::Types::Untyped.new
261
290
  end
262
291
  end
263
292
 
264
293
  return_types = getter.tags('return').flat_map(&:types)
265
294
  unless return_types.any?
266
- Logging.omit("no YARD type given for #{name.inspect}, using T.untyped", meth)
267
- next 'T.untyped'
295
+ Logging.omit("no YARD type given for #{name.inspect}, using untyped", meth)
296
+ next Parlour::Types::Untyped.new
268
297
  end
269
- inferred_type = TypeConverter.yard_to_sorbet(
298
+ inferred_type = TypeConverter.yard_to_parlour(
270
299
  return_types, meth, @replace_errors_with_untyped, @replace_unresolved_with_untyped)
271
300
 
272
- Logging.infer("inferred type of parameter #{name.inspect} as #{inferred_type} using getter's return type", meth)
301
+ Logging.infer("inferred type of parameter #{name.inspect} as #{inferred_type.describe} using getter's return type", meth)
273
302
  inferred_type
274
303
  else
275
304
  # Is this the only argument, and was a @param specified without an
@@ -279,10 +308,10 @@ module Sord
279
308
  && meth.tag('param').types
280
309
 
281
310
  Logging.infer("argument name in single @param inferred as #{parameter_names_and_defaults_to_tags.first.first.first.inspect}", meth)
282
- TypeConverter.yard_to_sorbet(meth.tag('param').types, meth, @replace_errors_with_untyped, @replace_unresolved_with_untyped)
311
+ TypeConverter.yard_to_parlour(meth.tag('param').types, meth, @replace_errors_with_untyped, @replace_unresolved_with_untyped)
283
312
  else
284
- Logging.omit("no YARD type given for #{name.inspect}, using T.untyped", meth)
285
- 'T.untyped'
313
+ Logging.omit("no YARD type given for #{name.inspect}, using untyped", meth)
314
+ Parlour::Types::Untyped.new
286
315
  end
287
316
  end
288
317
  end
@@ -291,42 +320,74 @@ module Sord
291
320
  returns = if meth.name == :initialize && !@use_original_initialize_return
292
321
  nil
293
322
  elsif return_tags.length == 0
294
- Logging.omit("no YARD return type given, using T.untyped", meth)
295
- 'T.untyped'
296
- elsif return_tags.length == 1 && return_tags&.first&.types&.first&.downcase == "void"
323
+ Logging.omit("no YARD return type given, using untyped", meth)
324
+ Parlour::Types::Untyped.new
325
+ elsif return_tags.length == 1 && %w{void nil}.include?(return_tags&.first&.types&.first&.downcase)
297
326
  nil
298
327
  else
299
- TypeConverter.yard_to_sorbet(meth.tag('return').types, meth, @replace_errors_with_untyped, @replace_unresolved_with_untyped)
328
+ TypeConverter.yard_to_parlour(meth.tag('return').types, meth, @replace_errors_with_untyped, @replace_unresolved_with_untyped)
300
329
  end
301
330
 
331
+ rbs_block = nil
302
332
  parlour_params = parameter_names_and_defaults_to_tags
303
333
  .zip(parameter_types)
304
334
  .map do |((name, default), _), type|
305
335
  # If the default is "nil" but the type is not nilable, then it
306
336
  # should become nilable
307
337
  # (T.untyped can include nil, so don't alter that)
308
- type = "T.nilable(#{type})" \
309
- if default == 'nil' && !type.start_with?('T.nilable') && type != 'T.untyped'
310
- Parlour::RbiGenerator::Parameter.new(
311
- name.to_s,
312
- type: type,
313
- default: default
314
- )
338
+ type = Parlour::Types::Nilable.new(type) \
339
+ if default == 'nil' && !type.is_a?(Parlour::Types::Nilable) && !type.is_a?(Parlour::Types::Untyped)
340
+
341
+ case @mode
342
+ when :rbi
343
+ Parlour::RbiGenerator::Parameter.new(
344
+ name.to_s,
345
+ type: type,
346
+ default: default
347
+ )
348
+ when :rbs
349
+ if name.start_with?('&')
350
+ rbs_block = type
351
+ nil
352
+ else
353
+ Parlour::RbsGenerator::Parameter.new(
354
+ name.to_s,
355
+ type: type,
356
+ required: default.nil?
357
+ )
358
+ end
359
+ end
315
360
  end
316
-
317
- @current_object.create_method(
318
- meth.name.to_s,
319
- parameters: parlour_params,
320
- returns: returns,
321
- class_method: meth.scope == :class
322
- ) do |m|
323
- add_comments(meth, m)
324
- end
361
+ .compact
362
+
363
+ case @mode
364
+ when :rbi
365
+ @current_object.create_method(
366
+ meth.name.to_s,
367
+ parameters: parlour_params,
368
+ returns: returns,
369
+ class_method: meth.scope == :class
370
+ ) do |m|
371
+ add_comments(meth, m)
372
+ end
373
+ when :rbs
374
+ @current_object.create_method(
375
+ meth.name.to_s,
376
+ [Parlour::RbsGenerator::MethodSignature.new(
377
+ parlour_params, returns, block: rbs_block && !rbs_block.is_a?(Parlour::Types::Untyped) \
378
+ ? Parlour::RbsGenerator::Block.new(rbs_block, false)
379
+ : nil
380
+ )],
381
+ class_method: meth.scope == :class
382
+ ) do |m|
383
+ add_comments(meth, m)
384
+ end
385
+ end
325
386
  end
326
387
  end
327
388
 
328
389
  # Given a YARD NamespaceObject, add lines defining either its class
329
- # and instance attributes and their signatures to the current RBI file.
390
+ # and instance attributes and their signatures to the current file.
330
391
  # @param [YARD::CodeObjects::NamespaceObject] item
331
392
  # @return [void]
332
393
  def add_attributes(item)
@@ -353,13 +414,16 @@ module Sord
353
414
  writer.tags('param').flat_map(&:types)
354
415
  end
355
416
 
356
- # Use T.untyped if not types specified anywhere, otherwise try to
357
- # compute Sorbet type given all these types
417
+ # Use untyped if not types specified anywhere, otherwise try to
418
+ # compute Parlour type given all these types
358
419
  if yard_types.empty?
359
- Logging.omit("no YARD type given for #{name.inspect}, using T.untyped", reader || writer)
360
- sorbet_type = 'T.untyped'
420
+ Logging.omit("no YARD type given for #{name.inspect}, using untyped", reader || writer)
421
+ parlour_type = Parlour::Types::Untyped.new
422
+ elsif yard_types.all? { |x| x == 'nil' }
423
+ # Nil attributes are extremely unusual, so just use untyped
424
+ parlour_type = Parlour::Types::Untyped.new
361
425
  else
362
- sorbet_type = TypeConverter.yard_to_sorbet(
426
+ parlour_type = TypeConverter.yard_to_parlour(
363
427
  yard_types, reader || writer, @replace_errors_with_untyped, @replace_unresolved_with_untyped)
364
428
  end
365
429
 
@@ -372,20 +436,35 @@ module Sord
372
436
  kind = :writer
373
437
  end
374
438
 
375
- @current_object.create_attribute(
376
- name.to_s,
377
- kind: kind,
378
- type: sorbet_type,
379
- class_attribute: (attr_loc == :class)
380
- ) do |m|
381
- add_comments(reader || writer, m)
439
+ case @mode
440
+ when :rbi
441
+ @current_object.create_attribute(
442
+ name.to_s,
443
+ kind: kind,
444
+ type: parlour_type,
445
+ class_attribute: (attr_loc == :class)
446
+ ) do |m|
447
+ add_comments(reader || writer, m)
448
+ end
449
+ when :rbs
450
+ if attr_loc == :class
451
+ Logging.warn("RBS doesn't support class attributes, dropping", reader || writer)
452
+ else
453
+ @current_object.create_attribute(
454
+ name.to_s,
455
+ kind: kind,
456
+ type: parlour_type,
457
+ ) do |m|
458
+ add_comments(reader || writer, m)
459
+ end
460
+ end
382
461
  end
383
462
  end
384
463
  end
385
464
  end
386
465
 
387
466
  # Given a YARD NamespaceObject, add lines defining its mixins, methods
388
- # and children to the RBI file.
467
+ # and children to the file.
389
468
  # @param [YARD::CodeObjects::NamespaceObject] item
390
469
  # @return [void]
391
470
  def add_namespace(item)
@@ -411,7 +490,7 @@ module Sord
411
490
  @current_object = parent
412
491
  end
413
492
 
414
- # Populates the RBI generator with the contents of the YARD registry. You
493
+ # Populates the generator with the contents of the YARD registry. You
415
494
  # must load the YARD registry first!
416
495
  # @return [void]
417
496
  def populate
@@ -421,23 +500,23 @@ module Sord
421
500
  .each { |child| add_namespace(child) }
422
501
  end
423
502
 
424
- # Populates the RBI generator with the contents of the YARD registry, then
425
- # uses the loaded Parlour::RbiGenerator to generate the RBI file. You must
503
+ # Populates the generator with the contents of the YARD registry, then
504
+ # uses the loaded Parlour::Generator to generate the file. You must
426
505
  # load the YARD registry first!
427
506
  # @return [void]
428
507
  def generate
429
508
  populate
430
- @parlour.rbi
509
+ @parlour.send(@mode)
431
510
  end
432
511
 
433
- # Loads the YARD registry, populates the RBI file, and prints any relevant
512
+ # Loads the YARD registry, populates the file, and prints any relevant
434
513
  # final logs.
435
514
  # @return [void]
436
515
  def run
437
516
  # Get YARD ready
438
517
  YARD::Registry.load!
439
518
 
440
- # Populate the RBI
519
+ # Populate the type information file
441
520
  populate
442
521
 
443
522
  if object_count.zero?
@@ -451,9 +530,9 @@ module Sord
451
530
  Logging.hooks.clear
452
531
 
453
532
  unless warnings.empty?
454
- Logging.warn("There were #{warnings.length} important warnings in the RBI file, listed below.")
533
+ Logging.warn("There were #{warnings.length} important warnings in the output file, listed below.")
455
534
  if @replace_errors_with_untyped
456
- Logging.warn("The types which caused them have been replaced with T.untyped.")
535
+ Logging.warn("The types which caused them have been replaced with untyped.")
457
536
  else
458
537
  Logging.warn("The types which caused them have been replaced with SORD_ERROR_ constants.")
459
538
  end